你的位置:首页 > Java教程

[Java教程]原生js实现autotemplete插件

        在实际的项目中,能用别人写好的插件实现相关功能是最好不过,为了节约时间成本,因为有的项目比较紧急,没充分时间让你自己来写,即便写了,你还要花大量时间调试兼容性。但是出于学习的目的,你可以利用闲暇时间,自己动手写写,看一些原生js的东西,根据自己的思路做插件,这样能提高水平。

          说到autotemplete,好多人都用过,引用autotemplete.js,然后就可以实现在输入框输入值的时候提示下拉选项,类似于百度搜索框那种提示功能,下面就来说说自己的思路。

  1.  为输入框添加input事件

      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标准浏览器支持input事件

    2.输入事件触发的时候获取数据

        这里数据有两种形式,一种是直接设置的对象数组,一种是ajax请求返回数据

        这时候我们需要一个ajax请求函数,这里写了一个get请求

       

get: function(url, paraobj, fn, timeout) {        var xhr = null;        try {         ////兼容firefox,chrom          if (window.

 

    3. ajax请求成功,且有数据的时候创建下拉框并在下拉框中追加选项       ////创建下拉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);      }      //创建下拉Div      var div = document.createElement('div');      div.id = this.config.showdivId;      //设置下拉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; }

 

    

      追加选项代码:

     

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);      });    }

 

上面说的是主要的几步思路,现在看一下怎么将这些代码封装到一个对象中,让它成为插件。这时候我们用到匿名闭包:

   (function(win) {
      var autoTemplete = function() {
        this.Init.apply(this, arguments);

      }

      autoTemplete.prototype = {

             ////添加相关操作代码

            Init:{},///初始化参数

           Render:{},

           createShowDiv:{ },///创建下拉div

          appendChild:{},///在下拉div里面追加显示项

          closeDiv:{},////关闭下拉框

         //////工具对象,事件,请求,还有dom节点操作的函数

          util:{

              AddEvt:{},///添加事件

             insertAfter:{},///在某元素后面追加元素

             get:{}////  Ajax get请求

         }

      }

      win.AutoTemplete = function(paraobj) {
        new autoTemplete(paraobj).Render();
      }
    })(window)

 

主体的代码添加好了,我们把具体的实现代码展示出来:

     

(function(win) {	var autoTemplete = function() {		this.Init.apply(this, arguments);	}	autoTemplete.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: [], //数据						textFiled: '', //显示的文字的属性名						valueFiled: '', //获取value的属性名						style: {}, //显示的下拉div的样式设置						url: '', //ajax请求的url						paraName:'name',//ajax请求的参数						select: function() {}, //选择选项时触发的事件,						showdivId: '' //下拉选择区域的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请求获取数据的方式						    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);						    }                ////直接设置对象数组的形式						    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);						}					});				}			}		},		////创建下拉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);			}			//创建下拉Div			var div = document.createElement('div');			div.id = this.config.showdivId;			//设置下拉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);			});		},    ////关闭下拉框		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.

 

下面是使用的代码

           页面调用

            

  window.onload = function () {    AutoTemplete({      id: 'txtTest', //控件id      url: '/Home/Test4', //数据      paraName:'name',      textFiled: 'name', //显示的文字的属性名      valueFiled: 'id', //获取value的属性名      //					style: {}, //显示的下拉div的样式设置      //						url: '', //ajax请求的url      select: function (val, text) {        alert(val + '---' + text);      }, //选择选项时触发的事件,      showdivId: 'showDIv' //下拉选择区域的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);    }

 

  现在基本的功能实现和调用讲完了,从开始到最后的过程是比较麻烦的,每个方法都是一步步实现,没有引用其他的库,要考虑到各个浏览器的兼容性。如果你有什么疑问,请留言,我会回复。