真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

js公式編輯器-自定義匹配規(guī)則-帶提示下拉框-動(dòng)態(tài)獲取光標(biāo)像素坐標(biāo)

引言

在古藺等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專(zhuān)注、極致的服務(wù)理念,為客戶提供成都做網(wǎng)站、成都網(wǎng)站建設(shè) 網(wǎng)站設(shè)計(jì)制作按需開(kāi)發(fā),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),成都營(yíng)銷(xiāo)網(wǎng)站建設(shè),成都外貿(mào)網(wǎng)站制作,古藺網(wǎng)站建設(shè)費(fèi)用合理。

前段時(shí)間發(fā)了一個(gè)編輯器的插件,忙完后自己再次進(jìn)行了詳細(xì)的測(cè)試,然后心里冒出一句:“這誰(shuí)寫(xiě)的這么奇葩的插件?完全沒(méi)什么luan用??!”

自己做了讓自己不滿意的事,咋整?男人不怕累,花了時(shí)間重寫(xiě)(為世界上所有像我一樣勤勞的男人點(diǎn)贊)~

思維導(dǎo)圖

在小生看來(lái),在開(kāi)發(fā)每一個(gè)新功能的時(shí)候都應(yīng)該做到心中有一張思維導(dǎo)圖:功能實(shí)現(xiàn)邏輯和實(shí)現(xiàn)功能大致的方法。當(dāng)然我們不可能在還沒(méi)動(dòng)手

前就考慮得面面俱到,但在正式開(kāi)發(fā)之前心里對(duì)整個(gè)流程有個(gè)清晰的印象肯定會(huì)讓我們?cè)趧?dòng)手時(shí)愈加流暢(喝口娃哈哈美滋滋,看圖~):

js 公式編輯器 - 自定義匹配規(guī)則 - 帶提示下拉框 - 動(dòng)態(tài)獲取光標(biāo)像素坐標(biāo)

流程效果圖

js 公式編輯器 - 自定義匹配規(guī)則 - 帶提示下拉框 - 動(dòng)態(tài)獲取光標(biāo)像素坐標(biāo)

觸發(fā)檢索事件字符可自定義,默認(rèn)為 $,輸入 $ 觸發(fā)檢索顯示,此時(shí)檢索值為空,所以顯示所有選項(xiàng),繼續(xù)輸入 a ,檢索值為 a,顯示匹配選項(xiàng),當(dāng)再輸入 . 時(shí), 檢索值獲取條件發(fā)生改變(具體我們等下看代碼),

圖四中為整個(gè)流程在控制臺(tái)中的記錄。

js代碼 -- 監(jiān)聽(tīng)輸入框

全局變量

考慮到里面小方法比較多,為了簡(jiǎn)化代碼,這里我選擇模塊化一下,需要用到以下全局變量。這里特別提一下:持續(xù)事件和點(diǎn)事件的區(qū)別,持續(xù)顧名思義,持續(xù)事件就是一直觸發(fā)的事件,這里 $ 觸發(fā)檢索事件后,檢索值 selectVal

是變化的,但是我們又不需要它一直處于觸發(fā)狀態(tài),怎么辦呢?對(duì),開(kāi)關(guān),我們可以給這個(gè)事件設(shè)置一個(gè)開(kāi)關(guān),條件滿足時(shí)打開(kāi)開(kāi)關(guān),事件持續(xù)觸發(fā),結(jié)束后關(guān)閉開(kāi)關(guān),結(jié)束檢索事件,這里設(shè)置的開(kāi)關(guān)是:searchStart;而點(diǎn)事件

這里就是輸入 . 時(shí)觸發(fā)的事件,它只需要在輸入 . 時(shí)獲取相關(guān)的值就行了,不需要連續(xù)觸發(fā),這里我們?cè)O(shè)置參數(shù) enterCharacter : 當(dāng)前輸入的字符

var _this = $(this);
var e = event || window.event; // 鍵值兼容
var searchStart = false; // 設(shè)置檢索事件開(kāi)關(guān)
var checkCharacter = false; // 輸入字符檢索開(kāi)關(guān)  
var oldCurrentPos = ''; // 檢索值開(kāi)始的位置
var currentPos = ''; // 檢索值結(jié)束的位置
var selectVal = ''; // 檢索值
var pos = ''; // 設(shè)置光標(biāo)位置
var enterCharacter = ''; // 當(dāng)前輸入的字符
var dotVal; // 輸入 . 時(shí)從0到當(dāng)前光標(biāo)位置文本
var dotDollerPos; // 獲取往后查找離 . 最近的 $ 的下標(biāo),引文輸入 . 時(shí)的檢索值即dotSelectVal不包含 $ 本身,所以需要加1 
var dotSelectVal; // 輸入 . 時(shí)的檢索值

  插入輸入框 

  首先插入下拉框,當(dāng)然留到后面插入也可以(你開(kāi)心你說(shuō)什么都是對(duì)的),但是這里有個(gè)點(diǎn)需要注意一下:為什么選擇插入在body下?因?yàn)槲覀儷@取到的下拉框的位置是絕對(duì)定位坐標(biāo)。

 // 插入下拉框
 _this.dropdown = $('
    '); // 獲取到的彈出的下拉框的位置是絕對(duì)定位的坐標(biāo),所以得把彈出的層放到$("body").after(_this.dropdown); _this.dropdown.css({ 'width':opts.dropdownWidth, 'position':'absolute', }); _this.css({ 'position': 'relative', });

    注意:這里我們提一下,要獲取檢索值,即 selectVal,我們需要知道事件觸發(fā)時(shí)光標(biāo)所在的位置,即 oldCurrentPos,以及光標(biāo)當(dāng)前位置 currentPos,有了這兩個(gè) 下標(biāo),我們才能動(dòng)態(tài)獲取 selectVal

    獲取光標(biāo)當(dāng)前位置

    關(guān)于獲取輸入框光標(biāo)以及獲取值等方法,不了解的朋友可以去看一下 range 方法,當(dāng)然無(wú)數(shù)前輩已經(jīng)做過(guò)無(wú)數(shù)歸納總結(jié)講解(向前輩們敬禮~):

     // 獲取當(dāng)前光標(biāo)位置 currentPos
      var getStart =function() {  
       var all_range = '';
       if (navigator.userAgent.indexOf("MSIE") > -1) { //IE
       if( _this.get(0).tagName == "TEXTAREA" ){ 
        // 根據(jù)body創(chuàng)建textRange
        all_range = document.body.createTextRange();
        // 讓textRange范圍包含元素里所有內(nèi)容
        all_range.moveToElementText(_this.get(0));
       } else {
        // 根據(jù)當(dāng)前輸入元素類(lèi)型創(chuàng)建textRange
        all_range = _this.get(0).createTextRange();
       }
       // 輸入元素獲取焦點(diǎn)
       _this.focus();
       // 獲取當(dāng)前的textRange,如果當(dāng)前的textRange是一個(gè)具體位置而不是范圍,textRange的范圍從currentPos到end.此時(shí)currentPos等于end
       var cur_range = document.selection.createRange();
       // 將當(dāng)前的textRange的end向前移"選中的文本.length"個(gè)單位.保證currentPos=end
       cur_range.moveEnd('character',-cur_range.text.length)
       // 將當(dāng)前textRange的currentPos移動(dòng)到之前創(chuàng)建的textRange的currentPos處, 此時(shí)當(dāng)前textRange范圍變?yōu)檎麄€(gè)內(nèi)容的currentPos處到當(dāng)前范圍end處
       cur_range.setEndPoint("StartToStart",all_range);
    
       // 此時(shí)當(dāng)前textRange的Start到End的長(zhǎng)度,就是光標(biāo)的位置
       currentPos = cur_range.text.length;
       } else {
       // 文本框獲取焦點(diǎn)
       _this.focus();
       // 獲取當(dāng)前元素光標(biāo)位置
       currentPos = _this.get(0).selectionStart;
       //console.log("光標(biāo)當(dāng)前位置:"+currentPos);
       }
       // 返回光標(biāo)位置
       return currentPos;
      };  

                     獲取檢索值開(kāi)始位置

    檢索開(kāi)始位置,即事件觸發(fā)時(shí)光標(biāo)所在位置,直白來(lái)說(shuō),就是把事件觸發(fā)時(shí)光標(biāo)所在位置 currentPos 賦值給 oldCurrentPos 儲(chǔ)存起來(lái),然后與新的 currentPos 組

    成的區(qū)域 (oldCurrentPos,currentPos)就是我們檢索值所在區(qū)域 

                   

     // 獲取檢索值開(kāi)始位置 oldCurrentPos
      var getOldCurrentPos = function(){
       getStart(); // 開(kāi)始輸入的時(shí)候的光標(biāo)位置 currentPos
       oldCurrentPos = currentPos; // 儲(chǔ)存輸入開(kāi)始位置
       console.log(oldCurrentPos);
      }

    設(shè)置光標(biāo)位置

    選擇當(dāng)前項(xiàng)重組輸入框 value 值后光標(biāo)是默認(rèn)顯示在最后的,這當(dāng)然不符合我們的開(kāi)發(fā)需求,我們想要的效果是事件結(jié)束時(shí)光標(biāo)能在我們編輯結(jié)束的位置(關(guān)于value值重組我們?cè)谙旅娴姆椒ㄖ性倏矗?nbsp;              

     // 設(shè)置光標(biāo)位置
      var setCarePosition = function(start,end) {
       if(navigator.userAgent.indexOf("MSIE") > -1){
       var all_range = '';
       if( _this.get(0).tagName == "TEXTAREA" ){ 
        // 根據(jù)body創(chuàng)建textRange
        all_range = document.body.createTextRange();
        // 讓textRange范圍包含元素里所有內(nèi)容
        all_range.moveToElementText(_this.get(0));
       } else {
        // 根據(jù)當(dāng)前輸入元素類(lèi)型創(chuàng)建textRange
        all_range = _this.get(0).createTextRange();
       }
       _this.focus();
       // 將textRange的start設(shè)置為想要的start
       all_range.moveStart('character',start);
       // 將textRange的end設(shè)置為想要的end. 此時(shí)我們需要的textRange長(zhǎng)度=end-start; 所以用總長(zhǎng)度-(end-start)就是新end所在位置
       all_range.moveEnd('character',-(all_range.text.length-(end-start)));
       // 選中從start到end間的文本,若start=end,則光標(biāo)定位到start處
       all_range.select();
       }else{
       // 文本框獲取焦點(diǎn)
       _this.focus();
       // 選中從start到end間的文本,若start=end,則光標(biāo)定位到start處
       _this.get(0).setSelectionRange(start,end);
       }
      };

    結(jié)束檢索事件

    在結(jié)束檢索事件中我們需要初始化下拉框以及關(guān)閉開(kāi)關(guān),這里需要將該方法聲明在獲取檢索值方法前面,因?yàn)楂@取值后整個(gè)事件流程結(jié)束,我們需要初始化變量為下一次事件觸發(fā)做好準(zhǔn)備             

    // 結(jié)束檢索事件
      var endSearch = function(){
       _this.dropdown.find("li").remove(); // 移除下拉框中的選項(xiàng)
       _this.dropdown.hide(); // 隱藏下拉框
       searchStart = false; // 初始化檢索開(kāi)關(guān) searchStart
       enterCharacter=''; // 初始化當(dāng)前字符
      }

       獲取檢索的值

    看下方代碼,我們能夠獲取值的前提是 searchStart 開(kāi)關(guān) 打開(kāi)狀態(tài),這里我們?yōu)榱吮3植寮撵`活性,將觸發(fā)字符設(shè)置為變量,這里默認(rèn)為 $ 和 . ,enterCharacter為當(dāng)前輸入的字符,

            因?yàn)楫?dāng)我們輸入 . 時(shí),selectVal 的獲取規(guī)則會(huì)改變,所以這里我們需要將 selectVal 獲取方式區(qū)分開(kāi)來(lái),注意:這里我們要考慮到存在一個(gè)操作 -- 回刪,輸入 $,下拉框出來(lái)了,但是我

            們又覺(jué)得此處 $ 出現(xiàn)得還不是時(shí)候(反正就是要?jiǎng)h),刪除 $,那么檢索事件也就結(jié)束,初始化相關(guān)變量。當(dāng)輸入的是 . 時(shí),如果要替換值,那么我們需要的獲取從 . 在的位置往后找

    到離 . 最近的 $ 符號(hào),得到其在文本中的位置,這樣我們才能重組 value            

     // 獲取檢索的值 selctVal
      var getSelectVal = function(){
       var val = _this.val();
       if( searchStart == true && enterCharacter != opts.levelCharacter ){ // 當(dāng)輸入的是字符 triggerCharacter 的時(shí)候 默認(rèn)為 $
       selectVal = val.substring(oldCurrentPos,currentPos); // 檢索值直接為獲取的文本區(qū)域
       }
       if( searchStart == true && enterCharacter == opts.levelCharacter ){ // 當(dāng)輸入的是字符 levelCharacter 的時(shí)候 默認(rèn)為 .
       dotVal = val.slice(0,currentPos);
       dotDollerPos = dotVal.lastIndexOf(opts.triggerCharacter)+1;
       dotSelectVal = dotVal.substring(dotDollerPos,currentPos);
       selectVal = dotSelectVal;
       console.log("到當(dāng)前下標(biāo)的字符串為:"+dotVal);
       console.log("到當(dāng)前下標(biāo)最近的$下標(biāo)是:"+dotDollerPos);
       console.log("輸入 . 時(shí)檢索值為:"+dotSelectVal);
       }  
       console.log("獲取的值區(qū)域?yàn)椋?+oldCurrentPos+"-"+currentPos);
       if( oldCurrentPos > currentPos ){ // 回刪時(shí)清除選項(xiàng)li 隱藏下拉框
       endSearch()
       }  
      }

    改變輸入框 value 值,定位光標(biāo)位置

    因?yàn)槲覀冞@里存在兩種選擇方式,鼠標(biāo)點(diǎn)擊和按 enter 鍵,兩者的區(qū)別只在于執(zhí)行事件的方式,將同樣的代碼寫(xiě)兩遍未免有點(diǎn)不美,這里我們將它摘出來(lái)

    注意:此處需要區(qū)分觸發(fā)檢索事件的符號(hào)是 $ 還是 . ,因?yàn)榉?hào)不同,我們獲取的值是不同的,光標(biāo)定位也是不同            

     // 選中l(wèi)i當(dāng)前項(xiàng) 改變輸入框value值 定位光標(biāo)
      var changeValue = function(){
       var val = _this.val(); 
       var liTxt = _this.dropdown.find(".active").text();
       var liTxtLength = liTxt.length;
       var valLength = val.length;
       // 此處需要區(qū)分觸發(fā)檢索事件的符號(hào)是
       if( enterCharacter == opts.levelCharacter ){ // 如果是 .
       var beforeSelectVal = val.substring(0,dotDollerPos);  
       }
       else{ // 如果是 &
       var beforeSelectVal = val.substring(0,oldCurrentPos);
       }
       var beforeSelectValLength = beforeSelectVal.length;
       var afterSelectVal = val.substring(currentPos,valLength);
       var pos = liTxtLength + beforeSelectValLength;
       val = beforeSelectVal+liTxt+afterSelectVal;
       _this.val(val);
       setCarePosition(pos,pos); // 將光標(biāo)定位在插入值后面
       endSearch();
       console.log("文本長(zhǎng)度:"+beforeSelectVal.length);
       console.log("li文本為:"+liTxt);
       console.log("前部為:"+beforeSelectVal);
       console.log("后部分為:"+afterSelectVal);
       return false; // 此處必須加上return false 不然會(huì)調(diào)用callbacktips 初始化 dropdown
      }

    定義回調(diào)函數(shù)

       獲取檢索值之后就需要發(fā)送請(qǐng)求了,我們拿到返回的數(shù)組 arr_json 后,將其遍歷生成 li 添加到下拉框中              

     // 定義回調(diào)函數(shù) callbacktips
      var callbacktips = function(arr_json){
       // 初始化 UL 
       _this.dropdown.find("li").remove();
       if( arr_json ){
       for( i=0;i'+arr_json[i]+''); 
        }else{
        return;
        }     
       };
       }   
       _this.dropdown.show();
       _this.dropdown.find("li:first-child").addClass("active");
       // 自定義樣式
       _this.dropdown.find("li").css({ 
       'width':'100%',
       });
      };

    獲得焦點(diǎn)時(shí)獲取光標(biāo)位置

    這里我們直接調(diào)用上面的方法就行了     

      // 獲得焦點(diǎn)的時(shí)候獲取光標(biāo)位置
      _this.click(function(){
       getOldCurrentPos()
      });

    阻止鍵盤(pán)默認(rèn)事件

    這里我們需要判斷下拉框的狀態(tài):顯示還是隱藏      

     //下拉框顯示時(shí) 阻止鍵盤(pán)方向鍵默認(rèn)事件
      _this.keydown(function(e){
       var dropdownIsshow = _this.dropdown.css("display");
       if( dropdownIsshow == "block" ){
       if( e.keyCode == 38 || e.keyCode == 40 || e.keyCode == 13 ){
        e.preventDefault();
       }
       }
      })

    keyup 事件

    通過(guò)keyuo事件:”我們能實(shí)時(shí)監(jiān)聽(tīng)輸入框;也能通過(guò)按鍵切換當(dāng)前項(xiàng)以及改變光標(biāo)位置;也能限制輸入字符范圍,比如這里:當(dāng)輸入某些字符時(shí),將會(huì)被認(rèn)為輸入了不合法字符而終止檢索事件;

    我們的事件開(kāi)關(guān)也是通過(guò)該事件能改變其狀態(tài)的以及 enter 鍵選取當(dāng)前項(xiàng)        

    // 監(jiān)聽(tīng)輸入框value值變化
      _this.keyup(function(e){
       var val = _this.val(); 
       // 當(dāng)前項(xiàng)索引
       var n = _this.dropdown.find(".active").index();
       // li 個(gè)數(shù)
       var n_max = _this.dropdown.find("li").length;  
       getStart(); // 獲得最新光標(biāo)位置
       // 方向鍵控制 li 選項(xiàng)
       if( e.keyCode == 38 ){   
       if(n-1>=0){
        _this.dropdown.find('li').eq(n-1).addClass("active").siblings().removeClass("active");
       }
       if( n == 0){
        _this.dropdown.find('li').eq(n_max-1).addClass("active").siblings().removeClass("active");
       }
       return false; // 此處必須加上return false 不然會(huì)重復(fù)初始化
       }  
       if( e.keyCode == 40 ){
       if(n/?~!@#¥……&*()——|{}【】‘;:”“'。,、?]");
       enterCharacter = val.substring(currentPos-1,currentPos); // 當(dāng)前輸入的字符
       //console.log(enterCharacter);
       if( reg.test(enterCharacter) == false && enterCharacter != " "){ // 輸入的字符合法 可以執(zhí)行檢索事件
        //console.log("輸入字符合法");
        checkCharacter = true;
       }else{
        checkCharacter = false;
        endSearch()
        console.log("輸入了不合法字符");
        //console.log(selectVal);   
       }   
       }   
       console.log("當(dāng)前輸入的字符是:"+enterCharacter);
       if( enterCharacter == opts.triggerCharacter || enterCharacter == opts.levelCharacter){
       console.log("輸入了$或者.");
       // 輸入了 $,打開(kāi)開(kāi)關(guān),允許檢索事件執(zhí)行
       searchStart = true;
       getOldCurrentPos(); // 輸入 $ 的時(shí)候重置 oldCurrentPos
       }
       getSelectVal(); // 外度調(diào)用獲取檢索值方法 保證實(shí)時(shí)更新 selectVal 及 searchStart
       if( searchStart == true && checkCharacter == true && e.keyCode != 13 ){
       console.log("獲取的值:"+selectVal);
       if( $.isFunction(opts.keyPressAction) ){   
        opts.keyPressAction(selectVal, function(arr_json){
        // 調(diào)用回調(diào)函數(shù)
        callbacktips(arr_json);   
        });
       }
       }
       if( e.keyCode == 13 ){ // 按enter鍵選取當(dāng)前l(fā)i文本值 重組輸入框 value值
       var dropdownIsshow = _this.dropdown.css("display");
       if( dropdownIsshow == "block" ){ // 為了在下拉框隱藏時(shí)按 enter鍵 能換行,需要加上這個(gè)判斷
        changeValue();
        console.log("這是點(diǎn)擊enter后searchStart:"+searchStart);
       }
       }
       console.log("這是整個(gè)事件執(zhí)行完成以后:"+searchStart);
      });

    鼠標(biāo)滑入切換當(dāng)前項(xiàng)       

     // 切換當(dāng)前項(xiàng)
      _this.dropdown.on('mouseenter','li',function(){
       $(this).addClass("active").siblings().removeClass("active");
      });

    點(diǎn)擊選取當(dāng)前項(xiàng) 失去焦點(diǎn)事件

    這里采用了 event.target 方法來(lái)獲得事件源,如果是 下拉框中的 li ,則執(zhí)行 changeValue() 方法,否則結(jié)束檢索事件 endSearch()       

     // 點(diǎn)擊當(dāng)前項(xiàng)獲取文本值 重組輸入框 value值 失去焦點(diǎn)時(shí)隱藏下拉框 清空下拉框
      $(document).click(function(e){
       var e = event || window.event;
       var el = e.target.localName; // 獲取事件源 標(biāo)簽名
       el == "li" ? changeValue() : endSearch();
       //console.log(el);
      })

    js代碼 -- 動(dòng)態(tài)獲取光標(biāo)位置

    這個(gè)方法是借鑒一位前輩的,這里附上原文地址(前輩大善):http://blog.csdn.net/kingwolfofsky/article/details/6586029

    /*********以下為獲取下拉框像素坐標(biāo)方法*********/ 
      var kingwolfofsky = { 
       getInputPositon: function (elem) { 
       if (document.selection) { //IE Support 
        elem.focus(); 
        var Sel = document.selection.createRange(); 
        return { 
        left: Sel.boundingLeft, 
        top: Sel.boundingTop, 
        bottom: Sel.boundingTop + Sel.boundingHeight 
        }; 
       } else { 
        var that = this; 
        var cloneDiv = '{$clone_div}', cloneLeft = '{$cloneLeft}', cloneFocus = '{$cloneFocus}', cloneRight = '{$cloneRight}'; 
        var none = ' '; 
        var div = elem[cloneDiv] || document.createElement('div'), focus = elem[cloneFocus] || document.createElement('span'); 
        var text = elem[cloneLeft] || document.createElement('span'); 
        var offset = that._offset(elem), index = this._getFocus(elem), focusOffset = { left: 0, top: 0 }; 
       
        if (!elem[cloneDiv]) { 
        elem[cloneDiv] = div, elem[cloneFocus] = focus; 
        elem[cloneLeft] = text; 
        div.appendChild(text); 
        div.appendChild(focus); 
        document.body.appendChild(div); 
        focus.innerHTML = '|'; 
        focus.style.cssText = 'display:inline-block;width:0px;overflow:hidden;z-index:-100;word-wrap:break-word;word-break:break-all;'; 
        div.className = this._cloneStyle(elem); 
        div.style.cssText = 'visibility:hidden;display:inline-block;position:absolute;z-index:-100;word-wrap:break-word;word-break:break-all;overflow:hidden;'; 
        }; 
        div.style.left = this._offset(elem).left + "px"; 
        div.style.top = this._offset(elem).top + "px"; 
        var strTmp = elem.value.substring(0, index).replace(//g, '>').replace(/\n/g, '
    ').replace(/\s/g, none); text.innerHTML = strTmp; focus.style.display = 'inline-block'; try { focusOffset = this._offset(focus); } catch (e) { }; focus.style.display = 'none'; return { left: focusOffset.left, top: focusOffset.top, bottom: focusOffset.bottom }; } }, // 克隆元素樣式并返回類(lèi) _cloneStyle: function (elem, cache) { if (!cache && elem['${cloneName}']) return elem['${cloneName}']; var className, name, rstyle = /^(number|string)$/; var rname = /^(content|outline|outlineWidth)$/; //Opera: content; IE8:outline && outlineWidth var cssText = [], sStyle = elem.style; for (name in sStyle) { if (!rname.test(name)) { val = this._getStyle(elem, name); if (val !== '' && rstyle.test(typeof val)) { // Firefox 4 name = name.replace(/([A-Z])/g, "-$1").toLowerCase(); cssText.push(name); cssText.push(':'); cssText.push(val); cssText.push(';'); }; }; }; cssText = cssText.join(''); elem['${cloneName}'] = className = 'clone' + (new Date).getTime(); this._addHeadStyle('.' + className + '{' + cssText + '}'); return className; }, // 向頁(yè)頭插入樣式 _addHeadStyle: function (content) { var style = this._style[document]; if (!style) { style = this._style[document] = document.createElement('style'); document.getElementsByTagName('head')[0].appendChild(style); }; style.styleSheet && (style.styleSheet.cssText += content) || style.appendChild(document.createTextNode(content)); }, _style: {}, // 獲取最終樣式 _getStyle: 'getComputedStyle' in window ? function (elem, name) { return getComputedStyle(elem, null)[name]; } : function (elem, name) { return elem.currentStyle[name]; }, // 獲取光標(biāo)在文本框的位置 _getFocus: function (elem) { var index = 0; if (document.selection) {// IE Support elem.focus(); var Sel = document.selection.createRange(); if (elem.nodeName === 'TEXTAREA') {//textarea var Sel2 = Sel.duplicate(); Sel2.moveToElementText(elem); var index = -1; while (Sel2.inRange(Sel)) { Sel2.moveStart('character'); index++; }; } else if (elem.nodeName === 'INPUT') {// input Sel.moveStart('character', -elem.value.length); index = Sel.text.length; } } else if (elem.selectionStart || elem.selectionStart == '0') { // Firefox support index = elem.selectionStart; } return (index); }, // 獲取元素在頁(yè)面中位置 _offset: function (elem) { var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement; var clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0; var top = box.top + (self.pageYOffset || docElem.scrollTop) - clientTop, left = box.left + (self.pageXOffset || docElem.scrollLeft) - clientLeft; return { left: left, top: top, right: left + box.width, bottom: top + box.height }; } };

    調(diào)用獲取坐標(biāo)方法      

      // 調(diào)用獲取坐標(biāo)方法 show(elem)
      $(this).keyup(function(){
       show(this);
      });  
      // 調(diào)用 kingwolfofsky, 獲取光標(biāo)坐標(biāo)
      function show(elem) { 
       var p = kingwolfofsky.getInputPositon(elem); 
       var s = _this.dropdown.get(0); 
       var ttop = parseInt(_this.css("marginTop"));
       var tleft = parseInt(_this.css("marginLeft"));
       s.style.top = p.bottom-ttop+10+'px'; 
       s.style.left = p.left-tleft + 'px';   
      }

    js代碼 -- 設(shè)置默認(rèn)參數(shù)

    var defaults = { 
     triggerCharacter : '$', // 默認(rèn)觸發(fā)事件 字符
     levelCharacter: '.', // 默認(rèn)多層檢索觸發(fā)字符
     dropdownWidth:'150px' // 下拉框默認(rèn)寬度
     };

    js代碼 -- 插件調(diào)用

    此處只為展示效果 在 keyPressAction 中能自定義匹配規(guī)則進(jìn)行拓展 

     $("#test").editTips({
      triggerCharacter : '$',
      levelCharacter: '.',
      dropdownWidth:'150px', 
      keyPressAction:function(selectVal,callbacktips){
      var arr_json;
      if( selectVal == "" ){
       arr_json = ["a","ab","b","bb"]
      }
      if(selectVal && selectVal.indexOf("a")== 0){
       arr_json = ["a","ab"];
      }
      if(selectVal && selectVal.indexOf("b")== 0){
       arr_json = ["b","bb"];
      }
      if(selectVal && selectVal.indexOf("a.")== 0){
       arr_json = ["a.a","a.b","a.c"];
      }
      if(selectVal && selectVal.indexOf("b.")== 0){
       arr_json = ["b.a","b.b","b.c"];
      }
      if(selectVal && selectVal.indexOf("ab.")== 0){
       arr_json = ["ab.a","ab.b","ab.c"];
      }
      if(selectVal && selectVal.indexOf("bb.")== 0){
       arr_json = ["bb.a","bb.b","bb.c"];
      }
      callbacktips(arr_json);
      }  
     });

    由于代碼比較多,這里就不展示所有代碼了,最終效果圖:

    js 公式編輯器 - 自定義匹配規(guī)則 - 帶提示下拉框 - 動(dòng)態(tài)獲取光標(biāo)像素坐標(biāo)

    在此附上demo下載鏈接:

    不管你信不信,我已經(jīng)設(shè)置了下載口令,親們必須在心里說(shuō)出我的一個(gè)優(yōu)點(diǎn)才能點(diǎn)擊下載~

    下載demo

    總結(jié)

    以上所述是小編給大家介紹的js 公式編輯器 - 自定義匹配規(guī)則 - 帶提示下拉框 - 動(dòng)態(tài)獲取光標(biāo)像素坐標(biāo),希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)創(chuàng)新互聯(lián)網(wǎng)站的支持!


    當(dāng)前標(biāo)題:js公式編輯器-自定義匹配規(guī)則-帶提示下拉框-動(dòng)態(tài)獲取光標(biāo)像素坐標(biāo)
    標(biāo)題鏈接:http://weahome.cn/article/goigeh.html

    其他資訊

    在線咨詢

    微信咨詢

    電話咨詢

    028-86922220(工作日)

    18980820575(7×24)

    提交需求

    返回頂部