首页 > 代码库 > 如何搭建一个可以链式调用,批量操作的前端框架

如何搭建一个可以链式调用,批量操作的前端框架

用jquery写代码的时候总是很方便,少写很多代码。那么为什么会这样呢?我觉得主要有三个原因:

① jquery封装了获取dom的方法,只需要一个$就可以方便地获取你想要得dmo节点

② 链式调用,比如你可以这样写代码:

$("#a").show().height(20);

而不需要这样写

$("#a").show();$("#a").height(20);

③ 对象的批量操作。假如你需要对下面的列表进行同样的操作

<li class="list">列表</li><li class="list">列表</li><li class="list">列表</li><li class="list">列表</li><li class="list">列表</li><li class="list">列表</li><li class="list">列表</li><li class="list">列表</li><li class="list">列表</li><li class="list">列表</li>

那么你需要这样写:

var list = document.getElementsByClassName("list");for (var i = 0, len = list.length; i < len; i++) {    list[i].innerHTML = "修改";}

很麻烦是吧,要使用for循环。但是如果你用jquery写,只需要这样:

$(".list").html("修改");

那么这样方便的代码编写方式,它的背后是如何运作的。

首先是实现$方法,按照直线思维,你一定以为$方法是这样的:

function $(selector){     if(selector带#号){          return document.getElementById(selector);     }else if(selector带.号){          return document.getElementsByClassName(selector);     }else{          .................     }}

其实不是,如果是这样,那就太简单了,充其量只是对 document.getElement 的封装。你既不能实现链式调用也不能实现批量操作

先上完整代码,再做分析:

 1        function _$(els) { 2                 3             this.elements = []; 4             element = document.getElementsByClassName(els); 5             for (var i = 0, len = element.length; i < len; i++) { 6                this.elements.push(element[i]); 7             } 8              9        }10        _$.prototype = {11            each: function(fn) {12                 for ( var i = 0, len = this.elements.length; i < len; ++i ) {13                     fn.call(this, this.elements[i]);14                 }15                 return this;16            },17            html: function(text) {18               var that = this;19               this.each(function(el) {20                  el.innerHTML = text;21               });22               return this;23            }24         25        };26        window.$ = function(selector) {27            return new _$(selector); 28        };29      30      31        $("list").html("修改").hide();

为了方便理解,这里的_$方法只实现使用class来获取dom结点。如果要实现完整的,类似jquery的获取dom结点的方法,还需要写一些正则和字符串操作。

这里_$通过 document.getElementsByClassName 来获取到dom节点后通过push将这些dom结点放到了数组 elements中。

而且最关键的是,我在_$的prototype上定义了两个方法。

第一个方法 each ,这个方法的作用就是实现批量操作。

它会循环获取我们在_$的时候放置的数组 elements中的每一个元素,并使用 call将参数fn的上下文设置为this,再将每个elements中的dom结点传递给fn。这就产生了批量操作的效果。

看到第二个方法 html,这个方法是改变dom的内容。可以看到在html中使用了each方法来批量操作。最后还 return this; 这句使得原形上的方法可以链式调用。

所以,现在我们可以不依赖jquery而可以这样写代码:

$("list").html("修改")

 

在这个基础上你还可以实现很多方法,例如可以在实现一个hide()方法来隐藏结点:

 1        function _$(els) { 2                 3             this.elements = []; 4             element = document.getElementsByClassName(els); 5             for (var i = 0, len = element.length; i < len; i++) { 6                this.elements.push(element[i]); 7             } 8              9        }10        _$.prototype = {11            each: function(fn) {12                 for ( var i = 0, len = this.elements.length; i < len; ++i ) {13                     fn.call(this, this.elements[i]);14                 }15                 return this;16            },17            html: function(text) {18               var that = this;19               this.each(function(el) {20                  el.innerHTML = text;21               });22               return this;23            },24            hide: function() {25               var that = this;26               this.each(function(el) {27                  el.style["display"] = "none";28               });29               return this;30            }31         32        };33        window.$ = function(selector) {34            return new _$(selector); 35        };36      37      38        $("list").html("修改").hide();

 

可以看出来,这篇文章没有将很多代码细节,意在让你理解一个可以批量操作,链式调用的框架的大概架构师如何的。

补充:jquery使用方便还有一个很重要的原因,它兼容各个浏览器。

 

 

 

如何搭建一个可以链式调用,批量操作的前端框架