整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          Android開發分享-設計一個簡易富文本編輯器

          Android開發分享-設計一個簡易富文本編輯器

          簡易富文本編輯

          讓HTML標簽的contenteditable屬性設為true即可直接修改內部內容,但是Android和在pc網頁上使用可能存在差異。這里分享一個簡單的富文本編輯,需要配合Android使用。

          這個富文本編輯目前通過于Android端交互可以向其中添加圖片、添加超鏈接、普通文本。主要靠js驅動(我的基礎不行,只能寫成這樣)。詳細解釋看代碼即可,需要配合Android知識。

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>富文本編輯</title>
              <script type="text/javascript">
          		/*每一個被添加的標簽(也就是圖片、超鏈接)都會被一層div包裹,固定其具體位置,并且每次添加完一個都會在其下部添加一個div用于輸入文本(可忽略)*/
                  /*添加外層標簽*/
                  function outDiv(inLabel)
                  {
                      var outdiv=document.createElement("div");
                      outdiv.style.textAlign="center";
                      outdiv.contentEditable=true;
                      outdiv.appendChild(inLabel);
                      document.getElementById("main").appendChild(outdiv);
                      var nextDiv=document.createElement("div");
                      document.getElementById("main").appendChild(nextDiv);
                      nextDiv.outerHTML="<div style='margin-left: 30px; margin-right: 30px;' contenteditable='true'><br></div>"
                  }
          
                  /*添加圖片*/
                  function addPhoto(path)
                  {
                      var addImg=document.createElement("img");
                      outDiv(addImg);
                      addImg.outerHTML="<img src='" + path + "' alt='圖片存在問題' id='" + path + "'/>";
          
                  }
          
          		/*Android端存在圖片傳輸問題,是先將圖片保存到文件夾內,再在html中調用,而在html中使用退格鍵即可刪除標簽,所以Android端在適當的時候清除沒有用到的圖片*/
                  /*確定圖片是否存在于html頁面中*/
                  function isExistedPhoto(id)
                  {
                      if(document.getElementById(id))
                      {
                          return 1;
                      }
                      else
                      {
                          return 0;
                      }
                  }
          		/*受Android端影響,啟用預覽模式時,將整體網頁所有標簽設為不可編輯(代碼在下面),同時為了確保同步,每次預覽都會在Android端存儲,因為js沒法直接存儲文件,所以將網頁代碼整體返回到Android端接收并保存到文件內,注意Android端應對得到的結果轉碼,因為得到的是unicode碼,即使js已經轉過了。*/
                  /*返回整體網頁*/
                  function wholeHtml()
                  {
          
                      return unescape(document.getElementsByTagName('html')[0].outerHTML.toString());
                  }
          
                  /*添加鏈接*/
                  function addHref(href)
                  {
                      var a=document.createElement("a");
                      a.href=href;
                      a.innerText=href;
                      a.contentEditable=true;
                      outDiv(a);
                  }
          		
          		/*開啟預覽模式則不可編輯,此時可以驗證鏈接*/
                  /*可編輯設置*/
                  function setEditAble(type)
                  {
                      if(!type)
                      {
                          getEdit("div", type);
                          getEdit("img", type);
                          getEdit("a", type);
                      }
                      else
                      {
                          getEdit("div", type);
                          getEdit("img", type);
                          getEdit("a", type);
                      }
                  }
                  /*獲取對象*/
                  function getEdit(label, type)
                  {
                      var aa=document.getElementsByTagName(label);
                      if(!type)
                      {
                          for( var a1=0; a1 < aa.length; a1++)
                          {
                              aa[a1].contentEditable=false;
                          }
                      }
                      else
                      {
                          for( var a1=0; a1 < aa.length; a1++)
                          {
                              aa[a1].contentEditable=true;
                          }
                      }
                  }
              </script>
          </head>
          <body>
          	<!--只要一個基礎div就行,甚至可以直接用body添加id代替-->
              <div id="main" contenteditable="true" style="margin-left: 30px; margin-right: 30px;"></div>
          </body>
          </html>

          由于本人技術能力限制,無法很好的寫出代碼,只能提供一個簡易的編輯。

          對應Android端的簡易介紹

          Android端根據js代碼設置對應內容。

          webview建立

          //根據id查找
          webView=rootView.findViewById(R.id.makeArticle);
          		//啟用js支持
                  webView.getSettings().setJavaScriptEnabled(true);
          //下面有一堆設置內容,我也不太明白,大致是啟用js支持、支持網絡傳輸、支持html5格式存儲、支持本地存儲        webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
          		//網頁處理,內部可根據網頁開始、網頁完成等狀態做處響應
                  webClient=new WebClient();
                  webView.setWebViewClient(webClient);
                  //允許操作文件
                  webView.getSettings().setAllowFileAccessFromFileURLs(true);
                  webView.getSettings().setAllowFileAccess(true);
                  webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
                  webView.getSettings().setBlockNetworkLoads(false);
                  webView.getSettings().setBlockNetworkImage(false);
                  webView.getSettings().setDomStorageEnabled(true);
                  webView.getSettings().setDatabaseEnabled(true);
                  //添加js可調用的函數類,函數使用javascriptinterface注釋,內部函數可以被js所調用
                  webView.addJavascriptInterface(new MakeArticleWeb(getContext(), username, articleId, webView), "makeArticle");

          使用Android調用js代碼

          //webview使用要在同一進程中
          //基礎格式
          webView.loadUrl(url);//注意此調用異步加載,可能比后續loadUrl方法加載慢
          //加載js代碼
          webView.loadUrl("javascript:js函數(參數)");//傳入一個字符串,前面javascript固定,后面為要調用的函數名,注意當參數要傳入字符串時,加上單引號。
          //loaddata
          webView.loadData(文本,文本格式(mimetype)(例如text/html為html文本),編碼格式(例如UTF-8));

          WebView的loadUrl異步加載問題

          因loadUrl加載順序不一致導致錯誤,因為webview使用必須在統一進程中,最好避免。如果實在需要,可以通過WebViewCilent中onPageFinsihed方法,在其中運行js可避免頁面未完全加載導致js無法執行的異常。

          示例:

           //網頁監控
              public class WebClient extends WebViewClient
              {
          		//頁面加載完成調用該方法
                  @Override
                  public void onPageFinished(WebView view, String url)
                  {
                      super.onPageFinished(view, url);
                      onCreateViewUpdate();
                      //不為空,更新數據
                      if(addList.size() > 0 && number <=30)
                      {
                          for (Bitmap value : addList.values()) {
                              String savePath=MakeUUID.makeUUID(username + "-" + articleId) + ".png";
                              saveThePhotoWithBitmap(value, savePath);
                              //此處調用了js,而且該js必須在頁面完全加載后才能有效使用
                              webView.loadUrl(addTo(savePath, 0));
                          }
                      }
                      //保存網頁數據
                      saveHtml();
                  }

          webview調用goback方法返回亂七八糟的東西(例如返回url)

          單擊webview中超鏈接進入其它網頁再調用goback返回時可能出現問題,可通過修改默認的gobakc返回流程改善。

          代碼:

          public String startUrl=thePath;//記錄一開始的url,直接通過內部類寫死,或在構造方法中定義
                  private int pageNumber=0;//頁面計數,判斷當前網頁是不是主網頁
                  
                  //重寫該方法,適配Android高版本
          		@Override
                  public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
                  {
                      System.out.println(startUrl);
                      //如果頁面不是主頁面且當前url不是一開始的url,跳轉會主界面
                      if(!request.getUrl().equals(startUrl) && pageNumber !=0)
                      {
                          System.out.println(pageNumber);
                          pageNumber=0;
                          view.loadUrl(startUrl);//返回主界面
                          return true;
                      }
                      else
                      {
                          pageNumber=1;
                          //使用原流程
                          return super.shouldOverrideUrlLoading(view, request);
                      }
                  }

          最好把這些代碼寫在內部類中方便調用。

          NSI(Windows-1252)

          ANSI 是 Windows 95 及其之前的 Windows 系統中默認的字符集。

          ANSI 也稱為 Windows-1252。


          重要提示

          ANSI 和 ISO-8859-1 非常相似,唯一的不同是在 32 個字符上。

          在 ANSI 中,從 128 到 159 的字符用于一些有用的字符,比如歐元符號。

          在 ISO-8859-1 中,這些字符映射為在 HTML 中不起作用的控制字符。

          許多 Web 開發者聲明 ISO-8859-1,并使用這 32 個值,就像它們使用的是 Windows-1252。

          由于這種常見的誤解,當 ISO-8859-1 被聲明時,瀏覽器將更改為 Windows-1252。這對以下文檔類型都適用:HTML4、HTML5 和 XHTML。


          ANSI 和 ASCII

          ANSI 的第一部分(實體編號 0-127)是原來的 ASCII 字符集。它包含數字、大小寫英文字母和一些特殊字符。

          如需深入了解 ASCII,請查看完整的 ASCII 參考手冊。


          ANSI 字符集

          字符編號實體名稱描述
          32空格(space)
          !33感嘆號(exclamation mark)
          "34&quot;引號(quotation mark)
          #35數字符號(number sign)
          $36美元符號(dollar sign)
          %37百分比符號(percent sign)
          &38&amp;& 符號(ampersand)
          '39撇號(apostrophe)
          (40左括號(left parenthesis)
          )41右括號(right parenthesis)
          *42星號(asterisk)
          +43加號(plus sign)
          ,44逗號(comma)
          -45連字符(hyphen-minus)
          .46句號(full stop)
          /47斜線(solidus)
          048數字 0(digit zero)
          149數字 1(digit one)
          250數字 2(digit two)
          351數字 3(digit three)
          452數字 4(digit four)
          553數字 5(digit five)
          654數字 6(digit six)
          755數字 7(digit seven)
          856數字 8(digit eight)
          957數字 9(digit nine)
          :58冒號(colon)
          ;59分號(semicolon)
          <60&lt;小于號(less-than sign)
          =61等于號(equals sign)
          >62&gt;大于號(greater-than sign)
          ?63問號(question mark)
          @64@ 符號(commercial at)
          A65拉丁文大寫字母 A
          B66拉丁文大寫字母 B
          C67拉丁文大寫字母 C
          D68拉丁文大寫字母 D
          E69拉丁文大寫字母 E
          F70拉丁文大寫字母 F
          G71拉丁文大寫字母 G
          H72拉丁文大寫字母 H
          I73拉丁文大寫字母 I
          J74拉丁文大寫字母 J
          K75拉丁文大寫字母 K
          L76拉丁文大寫字母 L
          M77拉丁文大寫字母 M
          N78拉丁文大寫字母 N
          O79拉丁文大寫字母 O
          P80拉丁文大寫字母 P
          Q81拉丁文大寫字母 Q
          R82拉丁文大寫字母 R
          S83拉丁文大寫字母 S
          T84拉丁文大寫字母 T
          U85拉丁文大寫字母 U
          V86拉丁文大寫字母 V
          W87拉丁文大寫字母 W
          X88拉丁文大寫字母 X
          Y89拉丁文大寫字母 Y
          Z90拉丁文大寫字母 Z
          [91左方括號(left square bracket)
          \92反斜線(reverse solidus)
          ]93右方括號(right square bracket)
          ^94插入符號(circumflex accent)
          _95下劃線(low line)
          `96重音符(grave accent)
          a97拉丁文小寫字母 a
          b98拉丁文小寫字母 b
          c99拉丁文小寫字母 c
          d100拉丁文小寫字母 d
          e101拉丁文小寫字母 e
          f102拉丁文小寫字母 f
          g103拉丁文小寫字母 g
          h104拉丁文小寫字母 h
          i105拉丁文小寫字母 i
          j106拉丁文小寫字母 j
          k107拉丁文小寫字母 k
          l108拉丁文小寫字母 l
          m109拉丁文小寫字母 m
          n110拉丁文小寫字母 n
          o111拉丁文小寫字母 o
          p112拉丁文小寫字母 p
          q113拉丁文小寫字母 q
          r114拉丁文小寫字母 r
          s115拉丁文小寫字母 s
          t116拉丁文小寫字母 t
          u117拉丁文小寫字母 u
          v118拉丁文小寫字母 v
          w119拉丁文小寫字母 w
          x120拉丁文小寫字母 x
          y121拉丁文小寫字母 y
          z122拉丁文小寫字母 z
          {123左花括號(left curly bracket)
          |124豎線(vertical line)
          }125右花括號(right curly bracket)
          ~126波浪線(tilde)
          127未使用(NOT USED)
          128&euro;歐元符號(euro sign)
          129未使用(NOT USED)
          ?130&sbquo;下單引號(single low-9 quotation mark)
          ?131&fnof;帶鉤的拉丁文小寫字母 f
          ?132&bdquo;下雙引號(double low-9 quotation mark)
          133&hellip;水平省略號(horizontal ellipsis)
          ?134&dagger;劍號(dagger)
          ?135&Dagger;雙劍號(double dagger)
          ?136&circ;修飾字母抑揚音(modifier letter circumflex accent)
          137&permil;千分比符號(per mille sign)
          ?138&Scaron;帶有 caron 的拉丁文大寫字母 S
          ?139&lsaquo;左單角引號(single left-pointing angle quotation mark)
          ?140&OElig;拉丁文大寫連字 OE
          141未使用(NOT USED)
          ?142&Zcaron;帶有 caron 的拉丁文大寫字母 Z
          143未使用(NOT USED)
          144未使用(NOT USED)
          '145&lsquo;左單引號(left single quotation mark)
          '146&rsquo;右單引號(right single quotation mark)
          "147&ldquo;左雙引號(left double quotation mark)
          "148&rdquo;右雙引號(right double quotation mark)
          ?149&bull;著重號(bullet)
          150&ndash;短破折號/連字符(en dash)
          151&mdash;長破折號(em dash)
          ?152&tilde;小波浪線(small tilde)
          ?153&trade;貿易標記符號(trade mark sign)
          ?154&scaron;帶有 caron 的拉丁文小寫字母 s
          ?155&rsaquo;右單角引號(single right-pointing angle quotation mark)
          ?156&oelig;拉丁文小寫連字 oe
          157未使用(NOT USED)
          ?158&zcaron;帶有 caron 的拉丁文小寫字母 z
          ?159&Yuml;帶有分音符(diaeresis)的拉丁文大寫字母 Y
          160&nbsp;不換行空格(no-break space)
          ?161&iexcl;倒置感嘆號(inverted exclamation mark)
          162&cent;美分符號(cent sign)
          163&pound;英鎊符號(pound sign)
          ¤164&curren;貨幣符號(currency sign)
          165&yen;日元符號(yen sign)
          |166&brvbar;間斷的豎杠(broken bar)
          §167&sect;小節號(section sign)
          ¨168&uml;分音符號(diaeresis)
          ?169&copy;版權所有(copyright sign)
          a170&ordf;陰性序數記號(feminine ordinal indicator)
          ?171&laquo;左雙角引號(left-pointing double angle quotation mark)
          ?172&not;否定符號(not sign)
          173&shy;軟連字符(soft hyphen)
          ?174&reg;注冊商標(registered sign)
          ˉ175&macr;長音符號(macron)
          °176&deg;度符號(degree sign)
          ±177&plusmn;加減號/正負號(plus-minus sign)
          2178&sup2;上標 2(superscript two)
          3179&sup3;上標 3(superscript three)
          180&acute;尖音符號(acute accent)
          μ181&micro;微米符號(micro sign)
          ?182&para;段落符號(pilcrow sign)
          ·183&middot;中間點(middle dot)
          ?184&cedil;變音符號(cedilla)
          1185&sup1;上標 1(superscript one)
          o186&ordm;陽性序數記號(masculine ordinal indicator)
          ?187&raquo;右雙角引號(right-pointing double angle quotation mark)
          ?188&frac14;1/4 分數(vulgar fraction one quarter)
          ?189&frac12;1/2 分數(vulgar fraction one half)
          ?190&frac34;3/4 分數(vulgar fraction three quarters)
          ?191&iquest;倒置問號(inverted question mark)
          à192&Agrave;帶有重音符號(grave)的拉丁文大寫字母 A
          á193&Aacute;帶有尖音符號(acute)的拉丁文大寫字母 A
          ?194&Acirc;帶有抑揚音符號(circumflex)的拉丁文大寫字母 A
          ?195&Atilde;帶有波浪線的拉丁文大寫字母 A
          ?196&Auml;帶有分音符(diaeresis)的拉丁文大寫字母 A
          ?197&Aring;帶有上圓圈的拉丁文大寫字母 A
          ?198&AElig;拉丁文大寫字母 AE
          ?199&Ccedil;帶有變音符號(cedilla)的拉丁文大寫字母 C
          è200&Egrave;帶有重音符號(grave)的拉丁文大寫字母 E
          é201&Eacute;帶有尖音符號(acute)的拉丁文大寫字母 E
          ê202&Ecirc;帶有抑揚符號(circumflex)的拉丁文大寫字母 E
          ?203&Euml;帶有分音符(diaeresis)的拉丁文大寫字母 E
          ì204&Igrave;帶有重音符號(grave)的拉丁文大寫字母 I
          í205&Iacute;帶有尖音符號(acute)的拉丁文大寫字母 I
          ?206&Icirc;帶有抑揚音符號(circumflex)的拉丁文大寫字母 I
          ?207&Iuml;帶有分音符(diaeresis)的拉丁文大寫字母 I
          D208&ETH;拉丁文大寫字母 Eth
          ?209&Ntilde;帶有波浪線的拉丁文大寫字母 N
          ò210&Ograve;帶有重音符號(grave)的拉丁文大寫字母 O
          ó211&Oacute;帶有尖音符號(acute)的拉丁文大寫字母 O
          ?212&Ocirc;帶有抑揚音符號(circumflex)的拉丁文大寫字母 O
          ?213&Otilde;帶有波浪線的拉丁文大寫字母 O
          ?214&Ouml;帶有分音符(diaeresis)的拉丁文大寫字母 O
          ×215&times;乘號(multiplication sign)
          ?216&Oslash;帶有刪除線的拉丁文大寫字母 O
          ù217&Ugrave;帶有重音符號(grave)的拉丁文大寫字母 U
          ú218&Uacute;帶有尖音符號(acute)的拉丁文大寫字母 U
          ?219&Ucirc;帶有抑揚音符號(circumflex)的拉丁文大寫字母 U
          ü220&Uuml;帶有分音符(diaeresis)的拉丁文大寫字母 U
          Y221&Yacute;帶有尖音符號(acute)的拉丁文大寫字母 Y
          T222&THORN;拉丁文大寫字母 Thorn
          ?223&szlig;拉丁文小寫字母 sharp s
          à224&agrave;帶有重音符號(grave)的拉丁文小寫字母 a
          á225&aacute;帶有尖音符號(acute)的拉丁文小寫字母 a
          a226&acirc;帶有抑揚音符號(circumflex)的拉丁文小寫字母 a
          ?227&atilde;帶有波浪線的拉丁文小寫字母 a
          ?228&auml;帶有分音符(diaeresis)的拉丁文小寫字母 a
          ?229&aring;帶有上圓圈的拉丁文小寫字母 a
          ?230&aelig;拉丁文小寫字母 ae
          ?231&ccedil;帶有變音符號(cedilla)的拉丁文小寫字母 c
          è232&egrave;帶有重音符號(grave)的拉丁文小寫字母 e
          é233&eacute;帶有尖音符號(acute)的拉丁文小寫字母 e
          ê234&ecirc;帶有抑揚音符號(circumflex)的拉丁文小寫字母 e
          ?235&euml;帶有分音符(diaeresis)的拉丁文小寫字母 e
          ì236&igrave;帶有重音符號(grave)的拉丁文小寫字母 i
          í237&iacute;帶有尖音符號(acute)的拉丁文小寫字母 i
          ?238&icirc;帶有抑揚音符號(circumflex)的拉丁文小寫字母 i
          ?239&iuml;帶有分音符(diaeresis)的拉丁文小寫字母 i
          e240&eth;拉丁文小寫字母 eth
          ?241&ntilde;帶有波浪線的拉丁文小寫字母 n
          ò242&ograve;帶有重音符號(grave)的拉丁文小寫字母 o
          ó243&oacute;帶有尖音符號(acute)的拉丁文小寫字母 o
          ?244&ocirc;帶有抑揚音符號(circumflex)的拉丁文小寫字母 o
          ?245&otilde;帶有波浪線的拉丁文小寫字母 o
          ?246&ouml;帶有分音符(diaeresis)的拉丁文小寫字母 o
          ÷247&divide;除號(division sign)
          ?248&oslash;帶有刪除線的拉丁文小寫字母 o
          ù249&ugrave;帶有重音符號(grave)的拉丁文小寫字母 u
          ú250&uacute;帶有尖音符號(acute)的拉丁文小寫字母 u
          ?251&ucirc;帶有抑揚音符號(circumflex)的拉丁文小寫字母 u
          ü252&uuml;帶有分音符(diaeresis)的拉丁文小寫字母 u
          y253&yacute;帶有尖音符號(acute)的拉丁文小寫字母 y
          t254&thorn;拉丁文小寫字母 thorn
          ?255&yuml;帶有分音符(diaeresis)的拉丁文小寫字母 y

          ANSI 控制字符

          ANSI 控制字符(00-31,加上 127)最初被設計用來控制諸如打印機和磁帶驅動器之類的硬件設備。

          控制字符(除了水平制表符、換行、回車之外)在 HTML 文檔中不起任何作用。

          字符編號描述
          NUL00空字符(null character)
          SOH01標題開始(start of header)
          STX02正文開始(start of text)
          ETX03正文結束(end of text)
          EOT04傳輸結束(end of transmission)
          ENQ05請求(enquiry)
          ACK06收到通知/響應(acknowledge)
          BEL07響鈴(bell)
          BS08退格(backspace)
          HT09水平制表符(horizontal tab)
          LF10換行(line feed)
          VT11垂直制表符(vertical tab)
          FF12換頁(form feed)
          CR13回車(carriage return)
          SO14不用切換(shift out)
          SI15啟用切換(shift in)
          DLE16數據鏈路轉義(data link escape)
          DC117設備控制 1(device control 1)
          DC218設備控制 2(device control 2)
          DC319設備控制 3(device control 3)
          DC420設備控制 4(device control 4)
          NAK21拒絕接收/無響應(negative acknowledge)
          SYN22同步空閑(synchronize)
          ETB23傳輸塊結束(end transmission block)
          CAN24取消(cancel)
          EM25已到介質末端/介質存儲已滿(end of medium)
          SUB26替補/替換(substitute)
          ESC27溢出/逃離/取消(escape)
          FS28文件分隔符(file separator)
          GS29組分隔符(group separator)
          RS30記錄分隔符(record separator)
          US31單元分隔符(unit separator)
          DEL127刪除(delete)

          如您還有不明白的可以在下面與我留言或是與我探討QQ群308855039,我們一起飛!

          節課我們講了關于事件的基本知識,主要包括事件對象和它的一些應用。從這節課開始我們學習2個更加高級的知識。

          默認行為

          當我們打開一個空白頁面的時候,右鍵點擊頁面會彈出來一個菜單——當然,實際上我們從來沒有通過JS寫過這么一個菜單,而是瀏覽器自帶的功能。這種瀏覽器本身自己帶的功能和事件我們將它稱之為默認行為。

          在這之前,要為大家介紹一個新的事件——oncontextmenu,代表的就是當用戶點擊右鍵呼出菜單的事件。現在我們用oncontextmenu來做一些事情。值得一提的是,oncontextmenu是可以有返回值的,如果我們return一個false的話會發生什么呢?

          <html>
           <head> 
           <meta charset="utf-8" /> 
           <title>無標題文檔</title> 
           <script>document.oncontextmenu=function (){
           return false; //阻止默認事件};</script> 
           </head> 
           <body> 
           </body>
          </html>

          大家可以自己嘗試一下,如果我們return一個false值回去的話,右鍵菜單將會被阻止彈出。在系統默認事件中return false的話可以有效地阻止該默認事件。

          當然,阻止右鍵菜單并不是我們最終的目的,我們最終的目的是為了能彈出自定義右鍵菜單,我們現在來看一下,如何在屏蔽右鍵菜單的基礎之上,再彈出一個自己的菜單。

          <html>
           <head> 
           <meta charset="utf-8" /> 
           <title>無標題文檔</title> 
           <style>
           * {margin:0; padding:0; list-style:none;}
           #div1 {position:absolute; width:80px; background:#CCC; border:1px solid black; display:none;}
           </style> 
           <script>
           document.oncontextmenu=function (ev)
           {
           var oEvent=ev||event;
           var oDiv=document.getElementById('div1');
           oDiv.style.display='block';
           oDiv.style.left=oEvent.clientX+'px';
           oDiv.style.top=oEvent.clientY+'px';
           return false;
           };
           document.onclick=function ()
           {
           var oDiv=document.getElementById('div1');
           oDiv.style.display='none';
           };
           </script> 
           </head> 
           <body> 
           <div id="div1"> 
           <ul> 
           <li>aaa</li>
           <li>bbb</li> 
           <li>ccc</li> 
           <li>ddd</li> 
           </ul> 
           </div> 
           </body>
          </html>

          效果如下:

          這個程序里面,我們除了用return false阻止了默認的系統菜單外,還自定義了一個div,其位置為鼠標點擊的位置,同時添加了一個點擊頁面其他位置時,div消失的效果——這樣就完成了一個自定義右鍵菜單。

          到目前為止,我們學習了一下阻止默認行為最簡單的一種應用。現在我們再來看一個默認行為的另一種應用——大家平時在表單里面會經常需要用戶去填一些用戶名,密碼,郵箱,qq號等信息。當我們輸入qq號時,我們希望用戶只能輸入數字,而不能輸入字母和符號,這應該怎么做到呢?這里我們需要使用上節課提過的onkeydown事件。

          <html>
           <head> 
           <meta charset="utf-8" /> 
           <title>無標題文檔</title> 
           <script>window.onload=function (){
           var oTxt=document.getElementById('txt1');
           oTxt.onkeydown=function ()
           {
           var oEvent=ev||event;
           //alert(oEvent.keyCode);
           //0- 48
           //9- 57
           //如果 用戶按的 不是退格 并且 也不是數字if(oEvent.keyCode!=8 && (oEvent.keyCode<48 || oEvent.keyCode>57))
           {
           return false;
           }
           };
           };
          </script> 
           </head> 
           <body> 
           <input type="text" id="txt1" /> 
           </body>
          </html>

          值得一提的是,如果我們將onkeydown的return值也設為false的話,我們將無法在頁面用鍵盤進行任何輸入——實際上鍵盤輸入本身也是系統的一個默認行為,因此可以用return false將它阻止掉。所以其實這個程序的邏輯很簡單——通過keyCode判斷輸入的字符是否為數字,如果不是數字的話,return false阻止其輸入即可(注意不要把keyCode為8的退格鍵阻止掉)。實際上來說默認行為的各種應用是非常廣的,我們這里只舉了兩個例子,其他的大家可以自己去發掘。

          拖拽

          拖拽的含義大家應該都明白,這里我們先從它的原理開始說起。首先我們先來看一個簡單的布局:

          <html>
           <head> 
           <meta charset="utf-8" /> 
           <title>無標題文檔</title> 
           <style>#div1 {width:200px; height:200px; background:red; position:absolute;}</style> 
           <script>
           window.onload=function ()
           {
           var oDiv=document.getElementById('div1');
           var disX=0;
           var disY=0;
           oDiv.onmousedown=function (ev)
           {
           var oEvent=ev||event;
           disX=oEvent.clientX-oDiv.offsetLeft;
           disY=oEvent.clientY-oDiv.offsetTop;
           document.onmousemove=function (ev)
           {
           var oEvent=ev||event;
           oDiv.style.left=oEvent.clientX-disX+'px';
           oDiv.style.top=oEvent.clientY-disY+'px';
           };
           document.onmouseup=function ()
           {
           document.onmousemove=null;
           document.onmouseup=null;
           };
           return false; //這里是為了阻止火狐瀏覽器的一個小bug。
           };
           };
           </script> 
           </head> 
           <body> 
           <div id="div1"></div> 
           </body>
          </html>

          大家隨便在電腦上拖拽一個東西就可以發現,拖拽的一個性質是:在拖拽時,鼠標和元素右上角的距離是保持不變的。距離的求法也很簡單:用鼠標的位置減去元素右上角的位置即可。

          然后對于拖拽來說,大家可以很容易聯想到它涉及到的幾個JS事件:鼠標按下,鼠標移動和鼠標抬起。通過這些東西的組合,我們就可以輕松寫出一個拖拽了(注意1.onmousemove事件需要添加為在onmousedown事件觸發后才會被觸發的事件2.onmousemove和onmouseup是添加給document而不是div1的事件,原因在于防止鼠標移出div或屏幕)。

          效果如下:

          現在我們就擁有了一個沒有任何bug的拖拽,但雖然沒有程序上的bug,但是有一些用戶體驗不太好的地方,比如,當用戶將拖拽框拖出屏幕后可能就找不到拖拽框了。現在我們要嘗試解決這個問題:

          <html>
           <head> 
           <meta charset="utf-8" /> 
           <title>無標題文檔</title> 
           <style>
           #div1 {width:200px; height:200px; background:red; position:absolute;}
           </style> 
           <script>
           window.onload=function ()
           {
           var oDiv=document.getElementById('div1');
           var disX=0;
           var disY=0;
           oDiv.onmousedown=function (ev)
           {
           var oEvent=ev||event;
           disX=oEvent.clientX-oDiv.offsetLeft;
           disY=oEvent.clientY-oDiv.offsetTop;
           document.onmousemove=function (ev)
           {
           var oEvent=ev||event;
           var l=oEvent.clientX-disX;
           var t=oEvent.clientY-disY;
           if(l<0)
           {
           l=0;
           }
           else if(l>document.documentElement.clientWidth-oDiv.offsetWidth)
           {
           l=document.documentElement.clientWidth-oDiv.offsetWidth;
           }
           if(t<0)
           {
           t=0;
           }
           else if(t>document.documentElement.clientHeight-oDiv.offsetHeight)
           {
           t=document.documentElement.clientHeight-oDiv.offsetHeight;
           }
           oDiv.style.left=l+'px';
           oDiv.style.top=t+'px';
           };
           document.onmouseup=function ()
           {
           document.onmousemove=null;
           document.onmouseup=null;
           };
           return false;
           };
           };</script> 
           </head> 
           <body> 
           <div id="div1"></div> 
           </body>
          </html>

          我們用l和t來儲存div的位置,當二者小于0的時候,將其變為0;當二者大于可視區寬高-元素本身寬高的時候,將其變為可視區寬高-元素本身寬高。這樣就完成了一個完美的拖拽。

          以上,我們就把拖拽常一些問題簡單的講解一下,后面我們還會針對拖拽做更多的應用。


          主站蜘蛛池模板: 亚洲中文字幕无码一区 | 亚洲一区二区三区高清视频| 中文国产成人精品久久一区| 亚洲综合一区无码精品| 无码一区18禁3D| 国产一区二区电影在线观看| 国产一区二区精品久久岳√| 国产在线精品观看一区| 91一区二区三区四区五区| 国产一区二区三区在线| 国产一区精品视频| 无码国产精品一区二区免费虚拟VR| 在线视频国产一区| 亚洲香蕉久久一区二区三区四区| 精品一区二区ww| 亚洲国产精品乱码一区二区| 欧美日本精品一区二区三区| 91久久精品一区二区| 国产综合一区二区| 冲田杏梨高清无一区二区| 国产主播福利一区二区| 国产精品揄拍一区二区久久| 免费视频一区二区| 亚洲爆乳精品无码一区二区三区| 国产精品资源一区二区| 国产av一区二区精品久久凹凸 | 国产一区二区三区免费| 精品久久国产一区二区三区香蕉 | 亚洲欧洲精品一区二区三区| 无码一区二区三区在线观看| 亚洲熟女一区二区三区| 日韩一区二区在线观看视频| 无码午夜人妻一区二区三区不卡视频| 国精品无码A区一区二区| 成人精品视频一区二区三区不卡 | 视频在线观看一区二区| 国产美女av在线一区| 少妇激情一区二区三区视频| 韩国理伦片一区二区三区在线播放| 99精品一区二区三区无码吞精 | 精品无码人妻一区二区三区18|