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

用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使用方便还有一个很重要的原因,它兼容各个浏览器。

原文地址:https://www.cnblogs.com/haoming/p/3315284.html