在實際的項目中,能用別人寫好的插件實現(xiàn)相關(guān)功能是最好不過,為了節(jié)約時間成本,因為有的項目比較緊急,沒充分時間讓你自己來寫,即便寫了,你還要花大量時間調(diào)試兼容性。但是出于學(xué)習(xí)的目的,你可以利用閑暇時間,自己動手寫寫,看一些原生js的東西,根據(jù)自己的思路做插件,這樣能提高水平。
說到autotemplete,好多人都用過,引用autotemplete.js,然后就可以實現(xiàn)在輸入框輸入值的時候提示下拉選項,類似于百度搜索框那種提示功能,下面就來說說自己的思路。
為輸入框添加input事件
1.input事件兼容性代碼如下:
AddEvt:function(ele, evt, fn) {      if (document.addEventListener) {        ele.addEventListener(evt, fn, false);      } else if (document.attachEvent) {        ele.attachEvent('on' + (evt == "input" ? "propertychange" : evt), fn);      } else {        ele['on' + (evt == "input" ? "propertychange" : evt)] = fn;      }    }input事件和其他的事件不一樣,低版本的ie不支持input事件,只能用propertychange事件,高版本的ie和w3c標(biāo)準(zhǔn)瀏覽器支持input事件
2.輸入事件觸發(fā)的時候獲取數(shù)據(jù)
這里數(shù)據(jù)有兩種形式,一種是直接設(shè)置的對象數(shù)組,一種是ajax請求返回數(shù)據(jù)
這時候我們需要一個ajax請求函數(shù),這里寫了一個get請求
get: function(url, paraobj, fn, timeout) {        var xhr = null;        try {          ////兼容firefox,chrom          if (window.XMLHttpRequest) {            xhr = new XMLHttpRequest();          }          //////兼容IE          else if (Window.ActiveXObject) {             xhr = new ActiveXObject("Msxml2.Xmlhttp");          }        } catch (e) {          //TODO handle the exception          xhr = new ActiveXObject('Microsoft.Xmlhttp');        }        xhr.onreadystatechange = function() {          if (this.readyState == 4 && this.status == 200) {            fn.call(this, this.responseText);           } else {            setTimeout(function() {                xhr.abort();            }, timeout);          }        };        var parastr = '';        parastr += "?";        for (var prop in paraobj) {          parastr += prop + "=" + paraobj[prop] + "&";        }         xhr.open('get', parastr != "?" ? (url + parastr) : url, true);         xhr.send();       }3. ajax請求成功,且有數(shù)據(jù)的時候創(chuàng)建下拉框并在下拉框中追加選項       ////創(chuàng)建下拉Div
創(chuàng)建下拉框代碼:
createShowDiv: function() {       ///如果下拉div已存在,刪除掉      var parentNode = this.autoElement.parentNode || this.autoElement.parentElement;      var childNodes = parentNode.childNodes;      var showDiv = document.getElementById(this.config.showdivId);      if (showDiv) {        parentNode.removeChild(showDiv);      }      //創(chuàng)建下拉Div      var div = document.createElement('div');      div.id = this.config.showdivId;      //設(shè)置下拉div樣式      var style = this.config.style || {        width: '200px',        height: 'auto',        backgroundColor: '#1c5683',        cursor: 'pointer',        display: 'block'      };<br>           for (var prop in style) {        div.style[prop] = style[prop];      }      this.showdiv = div;    }追加選項代碼:
appendChild: function(data) {      var self = this;      var data = data;      var fragment = document.createDocumentFragment();      for (var i = 0; i < data.length; i++) {        var obj = data[i];        var child = document.createElement('div');        child.style.width = self.showdiv.style.width;        child.style.border = '1px';        child.style.borderStyle = 'solid';        child.style.borderTopColor = 'white';        child.setAttribute('key', obj[self.config.valueFiled]);        child.innerHTML = obj[self.config.textFiled];        fragment.appendChild(child);      }      self.showdiv.appendChild(fragment);      self.util.insertAfter(self.showdiv, self.autoElement);       //為下拉框添加點擊事件      self.util.AddEvt(self.showdiv, 'click', function(e) {        var evt = e || window.event;        var target = evt.srcElement || evt.target;        var key = target.getAttribute("key");        var val = target.innerHTML;        self.autoElement.value = val;        self.closeDiv();        self.config.select.call(self, key, val);      });    } 上面說的是主要的幾步思路,現(xiàn)在看一下怎么將這些代碼封裝到一個對象中,讓它成為插件。這時候我們用到匿名閉包:
(function(win) {  var autocomplete= function() {    this.Init.apply(this, arguments);   }   autocomplete.prototype = {     ////添加相關(guān)操作代碼     Init: {}, ///初始化參數(shù)     Render: {},     createShowDiv: {}, ///創(chuàng)建下拉div     appendChild: {}, ///在下拉div里面追加顯示項     closeDiv: {}, ////關(guān)閉下拉框     //////工具對象,事件,請求,還有dom節(jié)點操作的函數(shù)     util: {       AddEvt: {}, ///添加事件       insertAfter: {}, ///在某元素后面追加元素         get: {} //// Ajax get請求     }   }   win.Autocomplete= function(paraobj) {    new autocomplete(paraobj).Render();  }})(window)
主體的代碼添加好了,我們把具體的實現(xiàn)代碼展示出來:
(function(win) {  var autocomplete = function () {    this.Init.apply(this, arguments);  }  autocomplete.prototype = {    Init: function() {      var args = Array.prototype.slice.call(arguments);      if (args && args.length > 0) {        var config = args[0];        var getType = Object.prototype.toString;        if (config && getType.call(config) == "[object Object]") {          //       this.config = config;          this.config = config || {            id: '', //控件id            data: [], //數(shù)據(jù)            textFiled: '', //顯示的文字的屬性名            valueFiled: '', //獲取value的屬性名            style: {}, //顯示的下拉div的樣式設(shè)置            url: '', //ajax請求的url            paraName:'name',//ajax請求的參數(shù)            select: function() {}, //選擇選項時觸發(fā)的事件,            showdivId: '' //下拉選擇區(qū)域的id          };        }      }    },    Render: function() {      var self = this;      if (self.config) {        var autoElement = document.getElementById(self.config.id);        this.autoElement = autoElement;        if (autoElement) {          self.util.AddEvt(this.autoElement, 'input', function() {            try {              if (autoElement.value) {                ////ajax請求獲取數(shù)據(jù)的方式                if (self.config.url && !self.config.data) {                  var paraobj = {};                  paraobj[self.config.paraName] = autoElement.value;                  self.util.get(self.config.url, paraobj, function (data) {                    self.createShowDiv();                    self.appendChild(eval('(' + data + ')'));                  }, 10000);                }                ////直接設(shè)置對象數(shù)組的形式                else if                  (!self.config.url && self.config.data) {                  self.createShowDiv();                  self.appendChild(self.config.data);                }               } else {                self.closeDiv();              }             } catch (e) {              //TODO handle the exception              alert(e);            }          });        }       }    },    ////創(chuàng)建下拉Div    createShowDiv: function() {       ///如果下拉div已存在,刪除掉      var parentNode = this.autoElement.parentNode || this.autoElement.parentElement;      var childNodes = parentNode.childNodes;      var showDiv = document.getElementById(this.config.showdivId);      if (showDiv) {        parentNode.removeChild(showDiv);      }      //創(chuàng)建下拉Div      var div = document.createElement('div');      div.id = this.config.showdivId;      //設(shè)置下拉div樣式      var style = this.config.style || {        width: '200px',        height: 'auto',        backgroundColor: '#1c5683',        cursor: 'pointer',        display: 'block'      };      for (var prop in style) {        div.style[prop] = style[prop];      }      this.showdiv = div;    },    ///在下拉div里面追加顯示項    appendChild: function(data) {      var self = this;      var data = data;      var fragment = document.createDocumentFragment();      for (var i = 0; i < data.length; i++) {        var obj = data[i];        var child = document.createElement('div');        child.style.width = self.showdiv.style.width;        child.style.border = '1px';        child.style.borderStyle = 'solid';        child.style.borderTopColor = 'white';        child.setAttribute('key', obj[self.config.valueFiled]);        child.innerHTML = obj[self.config.textFiled];        fragment.appendChild(child);      }      self.showdiv.appendChild(fragment);      self.util.insertAfter(self.showdiv, self.autoElement);       //為下拉框添加點擊事件      self.util.AddEvt(self.showdiv, 'click', function(e) {        var evt = e || window.event;        var target = evt.srcElement || evt.target;        var key = target.getAttribute("key");        var val = target.innerHTML;        self.autoElement.value = val;        self.closeDiv();        self.config.select.call(self, key, val);      });    },    ////關(guān)閉下拉框    closeDiv: function () {      if (this.showdiv) {        this.showdiv.style.display = 'none';      }     }    ,    util: {      ///添加事件      AddEvt: function(ele, evt, fn) {        if (document.addEventListener) {          ele.addEventListener(evt, fn, false);        } else if (document.attachEvent) {          ele.attachEvent('on' + (evt == "input" ? "propertychange" : evt), fn);        } else {          ele['on' + (evt == "input" ? "propertychange" : evt)] = fn;        }      },      ///在某元素后面追加元素      insertAfter: function(ele, targetELe) {        var parentnode = targetELe.parentNode || targetELe.parentElement;        if (parentnode.lastChild == targetELe) {          parentnode.appendChild(ele);        } else {          parentnode.insertBefore(ele, targetELe.nextSibling);        }      },      ///Get請求      get: function(url, paraobj, fn, timeout) {        var xhr = null;        try {          if (window.XMLHttpRequest) {            xhr = new XMLHttpRequest();          } else if (Window.ActiveXObject) {             xhr = new ActiveXObject("Msxml2.Xmlhttp");          }        } catch (e) {          //TODO handle the exception          xhr = new ActiveXObject('Microsoft.Xmlhttp');        }        xhr.onreadystatechange = function() {          if (this.readyState == 4 && this.status == 200) {            fn.call(this, this.responseText);           } else {            setTimeout(function() {                xhr.abort();            }, timeout);          }        };        var parastr = '';        parastr += "?";        for (var prop in paraobj) {          parastr += prop + "=" + paraobj[prop] + "&";        }         xhr.open('get', parastr != "?" ? (url + parastr) : url, true);         xhr.send();       }    }  }   win.AutoComplete = function (paraobj) {    new autocomplete(paraobj).Render();   } })(window)下面是使用的代碼
頁面調(diào)用
window.onload = function () {  AutoComplete({    id: 'txtTest', //控件id    url: '/Home/Test4', //數(shù)據(jù)    paraName:'name',    textFiled: 'name', //顯示的文字的屬性名    valueFiled: 'id', //獲取value的屬性名    //         style: {}, //顯示的下拉div的樣式設(shè)置    //           url: '', //ajax請求的url    select: function (val, text) {      alert(val + '---' + text);    }, //選擇選項時觸發(fā)的事件,    showdivId: 'showDIv' //下拉選擇區(qū)域的id});  }); }后臺代碼如下,這里我用的是mvc
public JsonResult Test4(string  name){  var list=new List<Student>();  list.Add(new Student { id="1",name="aaaaa"});  list.Add(new Student { id = "2", name = "aacc" });   list.Add(new Student { id = "3", name = "aabb" });  list.Add(new Student { id = "4", name = "bbcc" });   if (!string.IsNullOrEmpty(name))  {    list = list.Where(p => p.name.Contains(name)).ToList();  }  return Json(list,JsonRequestBehavior.AllowGet);} 現(xiàn)在基本的功能實現(xiàn)和調(diào)用講完了,從開始到最后的過程是比較麻煩的,每個方法都是一步步實現(xiàn),沒有引用其他的庫,要考慮到各個瀏覽器的兼容性。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助。
新聞熱點
疑難解答