您现在的位置: 万盛学电脑网 >> 程序编程 >> 脚本专题 >> javascript >> 正文

超赞的动手创建JavaScript框架的详细教程

作者:佚名    责任编辑:admin    更新时间:2022-06-22

   这篇文章主要介绍了动手创建JavaScript框架的详细教程,包括DOM和各种属性的调试等各个方面,超级推荐!需要的朋友可以参考下

  觉得Mootools不可思议?想知道Dojo是如何实现的?对JQuery的技巧感到好奇?在这篇教程里,我们将探寻框架背后的秘密,然后试着自己动手建立一个你所喜爱的框架的简易版本。

  我们几乎每天都在使用各种各样的JavaScript框架。当你刚入门的时候,方便的DOM(文档对象模型)操作让你觉得JQuery这样的东西非常棒。这是因为:首先,对于新手来说DOM太难理解了;当然,对于一个API来说难以理解可不是什么好事。其次,浏览器间的兼容性问题非常令人困扰。

  我们将元素包装成对象是因为我们想要能够为对象添加方法。

  在这个教程里,我们将试着从头实现这些框架之一。是的,这会很有趣,不过在你太过兴奋前我要澄清几点:

  这不会是一个功能很完善的框架。的确,我们要写很多东西,但它还算不上JQuery。可是我们将要做的事情会让你体验到在真正编写框架的感觉。

  我们不打算保证全方位的兼容性。我们将要编写的框架能够在 Internet Explorer 8+、Firefox 5+、Opera 10+、Chrome和Safari上工作。

  我们的框架不会覆盖到所有可能的功能。比如说,我们的append和preappend方法只有在你传给它一个我们框架的实例时才能工作;我们不会用原生的DOM节点和节点列表。

  另外:尽管在教程中我们不会为我们的框架编写测试用例,但是我已经在第一次开发它的时候做好了。你可以从 Github上获取框架和测试用例的代码。

  第一步: 创建框架模板

  我们将从一些包装代码开始,它将容纳我们的整个框架。这是典型的立即函数(IIFE).

  ?

1 2 3 4 5 6 7 8 9 window.dome = (function () { function Dome (els) { } var dome = { get: function (selector) { } }; return dome; }());

  你可以看到,我们的框架叫做dome,因为它是一个基本的DOM框架。没错,基本(lame有“瘸子”、“不完整”的意思,dom加lame等于dome)的。

  我们已经有了一些东西。 首先,我们有了一个函数;它将成为构造框架的对象实例的构造函数;那些对象将会包含我们选择和创建的元素。

  然后,我们有了一个dome对象,它就是我们的框架对象;你可以看到它最终作为函数的返回值返回给了函数调用者(译注:赋值给了window.dome)。这里还有一个空的get函数,我们将用它从页面里选取元素。那么,我们来填充代码吧。

  第二步: 获取元素

  dome的get函数只有一个参数,但是它可以是很多东西。如果它一个string(字符串),我们将假定它是一个CSS(层叠样式表)选择器;不过我们也可能得到一个DOM节点或者DOM节点列表。

  ?

1 2 3 4 5 6 7 8 9 10 11 get: function (selector) { var els; if (typeof selector === "string") { els = document.querySelectorAll(selector); } else if (selector.length) { els = selector; } else { els = [selector]; } return new Dome(els); }

  我们用document.querySelectorAll来简单的选择元素:当然,这将限制我们的浏览器兼容性,不过对于这种情况还是可以接受的。如果selector不是string类型,我们将检查它的length属性。如果存在,我们就知道我们得到的是一个节点列表;否则,就是一个单独的元素,我们将它放到一个数组里。这是因为我们要在下面向Dome传递一个数组。你可以看到,我们返回了一个新的Dome对象。让我们回到Dome函数并且为它填充代码。

  第三步: 创建Dome实例

  这是Dome函数:

  ?

1 2 3 4 5 6 function Dome (els) { for(var i = 0; i < els.length; i++ ) { this[i] = els[i]; } this.length = els.length; }

  我强烈建议你去深入研究一些你喜欢的框架

  这非常简单:我们只是遍历了els的所有元素,并且把它们存储在一个以数字为索引的新对象里。然后我们添加了一个length属性。

  但是这有什么意义呢?为什么不直接返回元素?因为:我们将元素包装成对象是因为我们想要能够为对象添加方法;这些方法能够让我们遍历这些元素。实际上这正是JQuery的解决方案的浓缩版。

  我们的Dome对象已经返回了,现在让我们来为它的原型(prototype)添加一些方法。我会直接把那些方法写在Dome函数下面。

  第四步:添加几个实用工具

  要添加的第一批功能是些简单的工具函数。由于Dome对象可能包含至少一个DOM元素,那么我们需要在几乎每一个方法里面都遍历所有元素;这样,这些工具才会给力。

  我们从一个map函数开始:

  ?

1 2 3 4 5 6 7 Dome.prototype.map = function (callback) { var results = [], i = 0; for ( ; i < this.length; i++) { results.push(callback.call(this, this[i], i)); } return results; };

  当然,这个map函数有一个入参,一个回调函数。我们遍历Dome对象所有元素,收集回调函数的返回值到结果集中。注意我们是怎样调用回调函数的:

  ?

1 callback.call(this, this[i], i));

  通过这种方式,函数将在Dome实例的上下文中被调用,并且函数接收到两个参数:当前元素和元素序号。

  我们也想要一个foreach函数。事实上这很简单:

  ?

1 2 3 4 Dome.prototype.forEach(callback) { this.map(callback); return this; };

  由于map函数和foreach函数之间的不同仅仅是map需要返回些东西,我们可以仅仅将回调传给this.map然后忽略返回的数组;代替返回的是,我们将返回this,来使我们的库呈链式。foreach会被频繁的调用,所以,注意当一个函数的回调被返回,事实上,返回的是Dome实例。例如,下面的方法事实上就返回了Dome实例:

  ?

1 2 3 4 5 6 7 Dome.prototype.someMethod1 = function (callback) { this.forEach(callback); return this; }; Dome.prototype.someMethod2 = function (callback) { return this.forEach(callback); };

  还有一个:mapOne。很容易就知道这个函数是做什么的,但是真正的问题是,为什么需要它?这就需要一些我们称之为"库哲学"的东西了。

  一个简短的"哲学"阐释

  首先,对于一个初学者来说,DOM很让人纠结;它的API不完善。

  如果构建一个库仅仅是写代码,那就不是什么难事。但是当我开发这个库时,我发现那些不完善的部分决定了一定数量的方法的实现方式。

  很快,我们要去构建一个返回被选择元素的文本的text方法。如果Dome对象包含多个DOM节点(比如dome.get("li")),返回什么?如果你就像jQuery那样($("li").text())很简单的编写,你将得到一个字符串,这个字符串是所有元素的文本的直接拼接。有用吗?我认为没用,但是我不认为没有更好的办法。

  对于这个项目,我将以数组方式返回多个元素的文本,除非数组里只有一个元素,那么我仅仅返回一个文本字符串,而不是一个包含了一个元素的数组。我想你会经常去获取单个元素的文本,所以我们优化了那种情况。但是,如果你想去获取多个元素的文本,我们的返回你也会用着很爽。