-
jQuery的each迭代器 jQuery的each方法从使用上就要分2种情况: ☑ $.each()函数 ☑ $(selector).each() $.each()函数和$(selector).each()是不一样的,后者是专门用来遍历一个jQuery对象的,是为jQuery内部服务的。 $.each()函数可用于迭代任何集合,无论是“名/值”对象(JavaScript对象)或数组。在迭代数组的情况下,回调函数每次传递一个数组索引和相应的数组值作为参数。(该值也可以通过访问this关键字得到,但是JavaScript始终将this值作为一个Object,即使它是一个简单的字符串或数字值。)该方法返回其第一个参数,这是迭代的对象。 jQuery的实例方法最终也是调用的静态方法,我们在之前就解释过jQuery的实例与原型方法共享的设计。 其中each的实例方法如下: 可见内部是直接调用的静态方法: each: function(callback, args) { return jQuery.each(this, callback, args); },查看全部
-
我们简单的修改一下上面的代码: function each(obj, callback, context, arg) { var i = 0; var value; var length = obj.length; for (; i < length; i++) { callback.call(context || null, obj[i], arg); } } var arr = ['a', 'b', 'c']; each(arr, function(name, arg) { console.log(name, arg ,this); }, this, 'aaa') 当然根据回调的处理,从而判断是否要立刻中断这个循环,从而节约性能,也是很简单的,我们可以通过获取处理的返回值来处理,如下代码: function each(obj, callback, context, arg) { var i = 0; var value; var length = obj.length; for (; i < length; i++) { value = callback.call(context || null, obj[i], arg); if (value === false) { break; } } 可见只要通过回调函数callback返回的ture/false的布尔值结果就可以来判断当前是否要强制退出循环。查看全部
-
迭代器 迭代器是一个框架的重要设计。我们经常需要提供一种方法顺序用来处理聚合对象中各个元素,而又不暴露该对象的内部,这也是设计模式中的迭代器模式(Iterator)。 jQuery中的$.each方法就是一个典型的迭代器,通过each我们可以传入额外的function,然后来对所有的item项进行迭代操作,如下代码: $.each([52, 97], function(index, value) { alert(index + ': ' + value); }); $( "li" ).each(function( index ) { console.log( index + ": "" + $(this).text() ); }); 针对迭代器,这里有几个特点: ☑ 访问一个聚合对象的内容而无需暴露它的内部。 ☑ 为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。 ☑ 遍历的同时更改迭代器所在的集合结构可能会导致问题。 简单的说:封装实现,然后迭代器的聚合对象不用关心迭代的过程,从而符合SRP原则。 抛开jQuery的each方法,我们自己实现一个有简单的迭代器功能的代码: 1、简单回调 function each(obj, callback) { var i = 0; var value; var length = obj.length; for (; i < length; i++) { callback(obj[i]); } } var arr = ['a', 'b', 'c']; each(arr, function(name) { console.log(name); }) 这样就满足了迭代模式的设计原则,对于集合内部结果常常变化各异,我们不想暴露其内部结构,但又想让客户代码透明地访问其中的元素,通过回调把逻辑给解耦出来。但是这样的处理其实太简单了,我们还要考虑至少四种情况: ☑ 聚合对象,可能是对象,字符串或者数组等类型 ☑ 支持参数传递 ☑ 支持上下文的传递 ☑ 支持循环中退出查看全部
-
jQuery的考虑很周到,通过eq方法只能产生一个新的对象,但是如果需要的是一个合集对象要怎么处理?因此jQuery便提供了一个slice方法: 语法: .slice( start [, end ] ) 作用: 根据指定的下标范围,过滤匹配的元素集合,并生成一个新的 jQuery 对象。 因为是数组对象,意味着我们可以用silce来直接取值了,所以针对合集对象我们可以这样写代码: var arr = [] arr.push( this.slice(start[,end]) ) this.pushStack(arr) 这个this指的是jQuery对象,因为jQuery对象是数组集合,所以我们可以通过原生的silce方法直接取到集合数,然后通过包装处理即可了。 slice: function() { return this.pushStack( slice.apply( this, arguments ) ); },查看全部
-
get与eq的区别 .eq() 减少匹配元素的集合,根据index索引值,精确指定索引对象。 .get() 通过检索匹配jQuery对象得到对应的DOM元素。 同样是返回元素,那么eq与get有什么区别呢? eq返回的是一个jQuery对象,get返回的是一个DOM对象。举个例子: $( "li" ).get( 0 ).css("color", "red"); //错误 $( "li" ).eq( 0 ).css("color", "red"); //正确 get方法本质上是把jQuery对象转换成DOM对象,但是css属于jQuery构造器的,DOM是不存在这个方法的,如果需要用jQuery的方法,我们必须这样写: var li = $( "li" ).get( 0 ); $( li ).css("color", "red"); //用$包装 取出DOM对象li,然后用$再次包装,使之转变成jQuery对象,才能调用css方法,这样要分2步写太麻烦了,所以jQuery给我们提供了一个便捷方法eq()。 eq()的实现原理就是在上面代码中的把eq方法内部转成jQuery对象: eq: function( i ) { var len = this.length, j = +i + ( i < 0 ? len : 0 ); return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); 上面实现代码的逻辑就是跟get是一样的,区别就是通过了pushStack产生了一个新的jQuery对象。查看全部
-
jQuery提供了.get()、:index()、 :lt()、:gt()、:even()及 :odd()这类索引值相关的选择器,他们的作用可以过滤他们前面的匹配表达式的集合元素,筛选的依据就是这个元素在原先匹配集合中的顺序。 我们来分别看一下这几个选择器的实现原理: get方法--是通过检索匹配jQuery对象得到对应的DOM元素,如下代码实现: get: function(num) { return num != null ? // Return just the one element from the set (num < 0 ? this[num + this.length] : this[num]) : // Return all the elements in a clean array slice.call(this); } 原理很简单,因为jQuery查询出来的是一个数组的DOM集合,所以就可以按照数组的方法通过下标的索引取值,当然如果num的值超出范围,比如小于元素数量的负数或等于或大于元素的数量的数,那么它将返回undefined。 假设我们页面上有一个简单的无序列表,如下代码: <ul> <li id="foo">foo</li> <li id="bar">bar</li> </ul> 如果指定了index参数,.get()则会获取单个元素,如下代码: console.log( $( "li" ).get( 0 ) ); 由于索引 index 是以 0 开始计数的,所以上面代码返回了第一个列表项<li id="foo">foo</li>。 然而,这种语法缺少某些 .get() 所具有的附加功能,比如可以指定索引值为负值: console.log( $( "li" ).get(-1) ); 负的索引值表示从匹配的集合中从末尾开始倒数,所以上面这个例子将会返回列表中最后一项:<li id="bar">bar</li>。 由于是数组的关系,所以我们有几个快速方法,比如头跟尾的取值: first: function() { return this.eq( 0 ); }, last: function() { return this.eq(-1); },查看全部
-
$('ul.first').find('.foo').css('background-color', 'red').end().find('.bar').css('background-color', 'green'); 链式的原理就是要返回当前操作的上下文。查看全部
-
回溯处理的设计: aaron.find('li').click(function() { alert(1); }).end().click(function() { alert(2); }) jQuery为我们操作这个内部对象栈提供个非常有用的2个方法 .end() .addBack()查看全部
-
jQuery整体架构 任何程序代码不是一开始就复杂的,成功也不是一躇而蹴的,早期jQuery的作者John Resig在2005年提议改进Prototype的“Behaviour”库时,只是想让其使用更简单才发布新的jQuery框架。起初John Resig估计也没料想jQuery会如此的火热。我们可以看到从发布的第一个1.0开始到目前最新的2.1.1其代码膨胀到了9000多行,它兼容CSS3,还兼容各种浏览器,jQuery使用户能更方便地处理DOM、事件、实现动画效果,并且方便地为网站提供AJAX交互。查看全部
-
jQuery对象的构建如果在性能上考虑,所以就必须采用原型式的结构: jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context ); } jQuery.fn = jQuery.prototype = { init:function(){ return this }, jquery: version, constructor: jQuery, ……………… } var a = $() ; 使用原型结构,性能上是得到了优化,但是ajQuery类这个结构与目标jQuery的结构的还是有很大不一致: ☑ 没有采用new操作符; ☑ return返回的是一个通过new出来的的对象 。查看全部
-
函数在充当类的构造器时,原型prototype是一个重要的概念。prototype是构造函数的一个属性, 该属性指向一个对象。而这个对象将作为该构造函数所创建的所有实例的基引用(base reference), 可以把对象的基引用想像成一个自动创建的隐藏属性。 当访问对象的一个属性时, 首先查找对象本身, 找到则返回;若不, 则查找基引用指向的对象的属性(如果还找不到实际上还会沿着原型链向上查找, 直至到根)。 只要没有被覆盖的话, 对象原型的属性就能在所有的实例中找到。 类一: function ajQuery() { this.name = 'jQuery'; this.sayName = function(){ return this.name } var a = new ajQuery() var b = new ajQuery() var c = new ajQuery() 类二: function ajQuery() { this.name = 'jQuery' } ajQuery.prototype = { sayName: function() { return this.name } } var a = new ajQuery() var b = new ajQuery() var c = new ajQuery() 类一与类二产生的结构几乎是一样的,而本质区别就是:类二new产生的a、b、c三个实例对象共享了原型的sayName方法,这样的好处节省了内存空间,类一则是要为每一个实例复制sayName方法,每个方法属性都占用一定的内存的空间,所以如果把所有属性方法都声明在构造函数中,就会无形的增大很多开销,这些实例化的对象的属性一模一样,都是对this的引用来处理。除此之外类一的所有方法都是拷贝到当前实例对象上。类二则是要通过scope连接到原型链上查找,这样就无形之中要多一层作用域链的查找了。查看全部
-
Var _jQuery = window.jQuery, _$ = window.$; jQuery.noConflict = function( deep ) { if ( window.$ === jQuery ) { window.$ = _$; } if ( deep && window.jQuery === jQuery ) { window.jQuery = _jQuery; } return jQuery; }; 如果我们需要同时使用jQuery和其他JavaScript库,我们可以使用 $.noConflict()把$的控制权交给其他库。旧引用的$ 被保存在jQuery的初始化; noConflict() 简单的恢复它们。 通过类似swap交换的概念,先把之前的存在的命名空间给缓存起来,通过对比当前的命名空间达到交换的目的,首先,我们先判断下当前的的$空间是不是被jQuery接管了,如果是则让出控制权给之前的_$引用的库,如果传入deep为true的话等于是把jQuery的控制权也让出去了。查看全部
-
如果我们需要同时使用jQuery和其他JavaScript库,我们可以使用 $.noConflict()把$的控制权交给其他库。旧引用的$ 被保存在jQuery的初始化; noConflict() 简单的恢复它们。 通过类似swap交换的概念,先把之前的存在的命名空间给缓存起来,通过对比当前的命名空间达到交换的目的,首先,我们先判断下当前的的$空间是不是被jQuery接管了,如果是则让出控制权给之前的_$引用的库,如果传入deep为true的话等于是把jQuery的控制权也让出去了。查看全部
-
DOM文档加载步骤: 1. 解析HTML结构 2. 加载外部脚本和样式表文件 3. 解析并执行脚本代码 4. 构造HTML DOM模型 // ready 4完成后,$(document).ready(function() {//...}); 或 $(function() {//...})执行 5. 加载图片等外部文件 6. 页面加载完毕 // load 6完成后,$(document).load(function() {//...});执行查看全部
-
首先我们看jQuery的入口都是统一的$, 通过传递参数的不同,实现了9种方法的重载: 1. jQuery([selector,[context]]) 2. jQuery(element) 3. jQuery(elementArray) 4. jQuery(object) 5. jQuery(jQuery object) 6. jQuery(html,[ownerDocument]) 7. jQuery(html,[attributes]) 8. jQuery() 9. jQuery(callback) 9种用法整体来说可以分三大块:选择器、dom的处理、dom加载。 换句话说jQuery就是为了获取DOM、操作DOM而存在的!所以为了更方便这些操作,让节点与实例对象通过一个桥梁给关联起来,jQuery内部就采用了一种叫“类数组对象”的方式作为存储结构,所以我们即可以像对象一样处理jQuery操作,也能像数组一样可以使用push、pop、shift、unshift、sort、each、map等类数组的方法操作jQuery对象了。查看全部
举报
0/150
提交
取消