Home >Web Front-end >JS Tutorial >Native js implements autocomplete plug-in_javascript skills
In actual projects, it is best to use plug-ins written by others to implement related functions. In order to save time and cost, because some projects are more urgent and there is not enough time for you to write it yourself. Even if you write it, you Also spend a lot of time debugging compatibility. But for the purpose of learning, you can use your free time to write by yourself, read some native js things, and make plug-ins according to your own ideas, which can improve your level.
Speaking of autotemplete, many people have used it. By citing autotemplete.js, you can prompt drop-down options when entering values in the input box, similar to the prompt function of Baidu search box. Let’s talk about my ideas below.
Add input event to input box
1.The input event compatibility code is as follows:
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; } }
The input event is different from other events. Lower versions of IE do not support input events and can only use propertychange events. Higher versions of IE and w3c standard browsers support input events
2. Get data when the input event is triggered
There are two forms of data here, one is an array of objects set directly, and the other is the data returned by the ajax request
At this time we need an ajax request function, here is a get request
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. The ajax request is successful and when there is data, create a drop-down box and add options to the drop-down box ////Create a drop-down Div
Create drop-down box code:
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' };<br> for (var prop in style) { div.style[prop] = style[prop]; } this.showdiv = div; }
Append option code:
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); }); }
The above are the main steps. Now let’s look at how to encapsulate these codes into an object and make it a plug-in. At this time we use anonymous closure:
(function(win) { var autocomplete= function() { this.Init.apply(this, arguments); } autocomplete.prototype = { ////添加相关操作代码 Init: {}, ///初始化参数 Render: {}, createShowDiv: {}, ///创建下拉div appendChild: {}, ///在下拉div里面追加显示项 closeDiv: {}, ////关闭下拉框 //////工具对象,事件,请求,还有dom节点操作的函数 util: { AddEvt: {}, ///添加事件 insertAfter: {}, ///在某元素后面追加元素 get: {} //// Ajax get请求 } } win.Autocomplete= function(paraobj) { new autocomplete(paraobj).Render(); } })(window)
The main body code has been added, let’s show the specific implementation code:
(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: [], //数据 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.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)
Here is the code used
Page call
window.onload = function () { AutoComplete({ 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}); }); }
The background code is as follows, here I use 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); }
Now that the basic function implementation and calling are finished, the process from the beginning to the end is quite troublesome. Each method is implemented step by step, without referencing other libraries, and the compatibility of each browser must be taken into consideration.
The above is the entire content of this article, I hope it will be helpful to everyone’s study.