作者Rebecca Murphey
原文链接地址http://jqfundamentals.com/
With contributions by James Padolsey, Paul Irish, and others. See the GitHub repository for a complete history of contributions.
Copyright © 2011
【译】jquery基础教程(jQuery Fundamentals)——概述
【译】jquery基础教程(jQuery Fundamentals)——javascript基础
【译】jquery基础教程(jQuery Fundamentals)——jquery基础
【译】jquery基础教程(jQuery Fundamentals)——jquery核心
【译】jquery基础教程(jQuery Fundamentals)——事件
【译】jquery基础教程(jQuery Fundamentals)——效果
【译】jquery基础教程(jQuery Fundamentals)——Ajax
【译】jquery基础教程(jQuery Fundamentals)——插件
【译】jquery基础教程(jQuery Fundamentals)——最佳性能实践
【译】jquery基础教程(jQuery Fundamentals)——代码组织
【译】jquery基础教程(jQuery Fundamentals)——定制事件
在页面中,只有当document对象加载好之后你才可以操作页面内容。jquery为你提供了确定这种状态准备就绪的方法:在$(document).ready()的括号内包含的代码,会在页面加载就绪并可以执行javascript代码后执行。
例3.1:$(document).ready()代码块
$(document).ready(function() {
console.log('ready!');
});
你有时候会看到一些$(document).ready()的一些简写;但是对于jquery编程不太熟练的人,我非常不建议他们有简写。
例3.2:$(document).ready()的简写
$(function() {
console.log('ready!');
});
jquery的最基本的概念就是“选择某些元素,并对它们进行操作”。jquery提供了大部分css3中的选择器,同事也提供了一些非标准的选择器。想要获得完整的选择器介绍,可以访问http://api.jquery.com/category/selectors/.
下面提供一些比较常用的选择技巧。
例3.4:通过ID选择元素
$('#myId'); // note IDs must be unique per page
例3.5:通过class名称选择元素
$('div.myClass'); // performance improves if you specify element type
例3.6:通过属性选择元素
$('input[name=first_name]'); // beware, this can be very slow
例3.7:通过复合的css选择器选择元素
$('#contents ul.people li');
例3.8:通过伪选择器选择元素
$('a.external:first');
$('tr:odd');
$('#myForm :input'); // select all input-like elements in a form
$('div:visible');
$('div:gt(2)'); // all except the first three divs
$('div:animated'); // all currently animated divs
注解:
当你用到visible和:hidden伪选择器的时候,jquery会检查元素的实际可见属性,而不是他的css属性或者显示属性——也就是说,它会查看这个元素在页面上的物理属性的高和低是否大于0.但是这种机制并不会检查<tr>元素;这个时候,jquery检查的是它的CSS显示属性,并且认为当这个属性的display属性为none的时候是隐藏的。对于所有没被添加到DOM上的元素,通通会被认为是隐藏的,即使是CSS可以影响到它们并且渲染了它们。(在这章的后面我们会讲到怎样将元素添加到DOM中)。
作为参考,下面提供了一些jquery来判断元素可见或者隐藏的代码。
jQuery.expr.filters.hidden = function( elem ) {
var width = elem.offsetWidth, height = elem.offsetHeight,
skip = elem.nodeName.toLowerCase() === "tr";
// does the element have 0 height, 0 width,
// and it's not a <tr>?
return width === 0 && height === 0 && !skip ?
// then it must be hidden
true :
// but if it has width and height
// and it's not a <tr>
width > 0 && height > 0 && !skip ?
// then it must be visible
false :
// if we get here, the element has width
// and height, but it's also a <tr>,
// so check its display property to
// decide whether it's hidden
jQuery.curCSS(elem, "display") === "none";
};
jQuery.expr.filters.visible = function( elem ) {
return !jQuery.expr.filters.hidden( elem );
};
选择合适的选择器对于提高你的javascript代码的性能是一个很好方式。具体的特征——例如,当你通过class名称选择包含div标签的的标签时——是不错的选择。总体来说,你应该给jquery一些暗示,关于它会在哪里找到你所希望找到的元素。但是从另一方面讲,过于具体的特征将会变的有害。如果像#myTable th.special
这样的选择器可以找到你所要的元素,那么
像#myTable thead tr th.special
这样的的选择器就过于具体了。
jquery提供了许多基于属性的选择器,允许你利用正则表达式创建基于各种属性的选择器
// find all <a>s whose rel attribute
// ends with "thinger"
$("a[rel$='thinger']");
然而这种选择器在少量的情况下还是很有用,不过它们的性能就不敢恭维了——曾经又一次我写了一个基于属性的选择器,它把页面锁死了整整好几秒。如果有可能,还是选择通过ID,class名称和标签名称来创建选择器吧。
想知道更多么?Paul Irish has a great presentation about improving performance in JavaScript, 这里提供了一个关于选择器性能的下降的例子。
一旦你创建了一个选择器,你通常会想知道通过这个选择器你是否得到了元素。你或许会用下面的方式来做些什么:
if ($('div.foo')) { ... }
这样不会有用的!当你通过$()进行了选择后,一个object总是会被返回的,而object计算的值则总是true。即使通过你的选择器并没有得到任何的元素,if下的语句块总是会被执行的。
你需要通过测试结果的length属性,它会告诉你有多少个元素被选中了。如果结果是0,在被用作boolean变量时计算出的length属性是false。
例3.9:检查选择结果中是否包含元素
if ($('div.foo').length) { ... }
你每一次执行选择操作,都会执行很多的代码,jquery并不会帮助你把选择结果缓存起来。执行了一个以后会经常用的选择并得到了结果,你可以把他保存到一个变量中,而不是反复的执行。这样会提高性能。
例3.10:将选择结果存储到变量中
var $divs = $('div');
注解:
在3.10的例子中,变量名字是一$开头的。与其他语言中不同,$在javascript中没有什么特殊的含义——它仅仅是一个字符。我们在这里有它声明一个包含jquery对象的变量。这是惯例,但并不是强制的。
在你将选择结果存储起来之后,你可以用jquery的方法调用存储的变量,这和你调用原始的选择器返回的结果没有什么不同。
注解:
当你执行选择器的时候,它只会得到当前页面的元素。如果之后你又添加了元素在页面上,你就不得不重新执行一次选择,然后再存储。也就是说,当DOM改变的时候,被存储起来的选择结果并不会神奇的更新的。
有时候你回得到这样一个选择结果,它里面不仅仅包含了你所需要的;这种情况下,你就会想提炼你的选择结果。jquery提供了一些方法用来精简选择结果。
例3.11:提炼选择结果
$('div.foo').has('p'); // div.foo elements that contain <p>'s
$('h1').not('.bar'); // h1 elements that don't have a class of bar
$('ul li').filter('.current'); // unordered list items with class of current
$('ul li').first(); // just the first unordered list item
$('ul li').eq(5);
jquery提供了一些伪选择器来帮助你在Forms中选择元素;它们特别的有用,因为通过标准的css选择器,很难基于元素的状态和类型来分辨它们。
选择<button>元素和带有属性type=”button”的元素
选择带有属性type=”checkbox”的元素
选择被选中的input
选择不可用的元素
选择可用的元素
选择带有属性type=file的元素
选择带有type=”image”的元素
选择<input>
, <textarea>
, <select>
元素
选择带有属性type="password"的元素
选择带有属性type="radio"的元素
选择带有属性type="reset"的元素
选择么有被选中的元素
选择带有属性type="submit"的元素
选择带有属性type="text"的input
例3.12:与form有关的伪选择器的运用
$('#myForm :input'); // get all elements that accept input
一旦你得到了选择结果,你可以再选择结果上面调用方法。方法一般分为两类:getters和setters。getters返回第一个被选元素的一个属性;setters是在所有被选元素中添加一个属性。
如果你在一个选择结果上调用了一个方法,并且方法返回一个jquery对象类型,你可以在这个jquery对象上继续调用jquery方法,而不需要结束语句。
例3.13:
$('#content').find('h3').eq(2).html('new text for the third h3!');
如果你所写的语句链包含了几个步骤,你会发现,如果你将他们分成多行书写,你的代码会变得很有可读性。
例3.14:链式代码格式化
$('#content')
.find('h3')
.eq(2)
.html('new text for the third h3!');
如果你想在语句链的中间改变选择结果,jquery提供了$.fn.end方法另你可以返回到起始的选择结果。
例3.15:用$.fn.end回复原始的选择结果
$('#content')
.find('h3')
.eq(2)
.html('new text for the third h3!')
.end() // restores the selection to all h3's in #content
.eq(0)
.html('new text for the first h3!');
注解:
链式语句非常强大,自从jquery变得流行起来后,许多js库提供了这一特性。但是,应用起来要非常小心。大量的链式语句会是代码调试起来极其的困难。并没有什么强行的规定一条语句链应该有多长——只要确保它理解起来比较容易就好。
jquery “重载”了这两个方法,这样添加一个和得到一个值得方法就一样了。当方法被用来添加一个值得时候,就叫做一个setter。当方法被用来获得一个值得时候就,就叫做getter。setters作用于所有被选中的元素,getters仅仅做用于选择结果中的第一个元素。
例3.16:$.fn.html用作setter
$('h1').html('hello world');
例3.17:$.fn.html用作getter
$('h1').html();
setters返回一个jquery对象,允许你在选择结果上继续调用jquery方法;getters返回一个被要求的对象,也就是说,你不能够在选择结果上继续调用jquery方法。
jquery包含了一个非常便利的得到和设置元素css属性的方法。
注解:
css属性在javascript中通常是骆驼命名法的。例如,css属性font-size在javascript中通常以fontSize这种方式命名一种属性。这并不是说其他的命名方式不予许,这仅是一种惯例。
例3.18:获得css属性
$('h1').css('fontSize'); // returns a string such as "19px"
$('h1').css('font-size'); // also works
例3.19:设置css属性
$('h1').css('fontSize', '100px'); // setting an individual property
$('h1').css({ 'fontSize' : '100px', 'color' : 'red' }); // setting multiple properties
注意,我们在上例中的第二句中,我们用的参数格式是一个对象——它包括了多个属性。这是一个用来传递多个参数比较常用的方法,许多的jquery setter方法都通过接受对象来一次性传递多个值。
作为一个getter,$.fn.css方法是很有价值的;但是,应该避免在一个成品的代码上应用这个方法作为setter,因为你并不应该在你的javascript代码中描述这些信息。而是应该在classes中编写css规则来描述不同的视觉效果,然后再用jquery来方便的变换你所需要的效果。
例3.20:classes的运用
var $h1 = $('h1');
$h1.addClass('big');
$h1.removeClass('big');
$h1.toggleClass('big');
if ($h1.hasClass('big')) { ... }
classes同样也可用来存储元素的状态信息,比如声明元素是被删除的。
jquery提供了许多方法来获得和修改元素的尺寸和位置信息。
例3.21中的代码就是jquery中尺寸变换的典型应用;想要了解更多的jquery尺寸的方法,请访问:http://api.jquery.com/category/dimensions/.
例3.21:基本尺寸方法
$('h1').width('50px'); // sets the width of all H1 elements
$('h1').width(); // gets the width of the first H1
$('h1').height('50px'); // sets the height of all H1 elements
$('h1').height(); // gets the height of the first H1
$('h1').position(); // returns an object containing position
// information for the first H1 relative to
// its "offset (positioned) parent"
对于应用来说,一个元素的属性包含了许多的有用信息,所以获得和设置他们是非常重要的。
$.fn.attr方法既可以作为getter又可以作为setter。$.fn.attr作为setter既能够接受一个键值对,又能够接受一个包含多个键值对的对象。
例3.22:设置属性
$('a').attr('href', 'allMyHrefsAreTheSameNow.html');
$('a').attr({
'title' : 'all titles are the same too!',
'href' : 'somethingNew.html'
});
这回我们把对象划分成了多行的书写方式,空格在javascript中没有意义,所以你可以随意的应用他们以使你的代码看起来更清晰!你可以利用一些工具为成品(要发布的)的代码去除空格。
例3.23:获得属性
$('a').attr('href'); // returns the href for the first a element in the document
(不知道翻译的对不对……)
当你得到一个jquery的选择结果的时候,你可以以这个选择结构为出发点,找到其他的元素。
更详尽的关于关联查找方法,你可以在这里看到http://api.jquery.com/category/traversing/.
注解:
在你的代码中一定要谨慎应用过长的关联查找——复杂的关联查找需要维持你的页面的结构保持不变,但有的时候很难保证,即使只有你一个开发人员。一步到两步的关联查找就可以了,但同时也避免跨域容器的关联。
例3.24:利用关联查找的方法移动DOM元素
$('h1').next('p');
$('div:visible').parent();
$('input[name=first_name]').closest('form');
$('#myList').children();
$('li.selected').siblings();
你可以通过$.fn.each来遍历一个选择结果。这个方法遍历选择结果中的所有元素,并且为每个元素执行一个函数。这个函数接受当前元素的下标和DOM元素本身作为参数。在函数的内部,DOM元素可以用this关键字默认代替。
例3.25:
$('#myList li').each(function(idx, el) {
console.log(
'Element ' + idx +
'has the following html: ' +
$(el).html()
);
});
一旦你执行了一个选择语句,好戏开始了。你可以改变,移动,移除和复制元素。你同样可以通过简单的语法创建新的元素。
进一步的了解更多的juquery操作方法,请访问:http://api.jquery.com/category/manipulation/.
你可以通过很多方法来改变一个已经存在的元素。在你日常的编码中,你最经常干得事就是改变一个元素的内部html代码或者它的属性。jquery为这些操作提供了很多简单的,跨浏览器的方法。你可以通过同时拥有get和set的功能的方法来获得元素的信息。在这一段中我们会提供几个例子。
注解:
修改关于元素的信息是非常琐碎的,但是要记住,修改会影响选择结果中所有的元素,所以如果你只想改变一个元素,你要确保在调用setter之前,你的选择结果中只有一个元素。
注解:
当你把方法用作getter的时候,它们通常只作用于选择结果中的第一个元素,并且不会返回jquery对象,所以不能够运用链式语句。其中一个例外就是$.fn.text,就像下面例子中所提到的一样,它得到了选择结果中所有元素的文本信息。
获取或设置html内容
获取或者设置剥掉html后的文本内容
获取或者设置提供的属性
获取或者设置选择结果中的第一个元素的项像素宽度为整型
获取或者设置选择结果中的第一个元素的项像素高度为整型
获取一个带有选择结果中第一个元素的位置信息的对象,相对于它的被确定祖先标签的位置。(只能用于getter)
获取或者设置元素的值
有许多方法可以在DOM中移动元素;总体来说有两只途径:
1、根据另一个对象来放置被选中对象
2、根据被选中对象来放置另一对象
例如,jquery提供了$.fn.insertAfter和$.fn.after。$.fn.insertAfter这个方法将会把选中的元素放在作为参数的元素的后面;$.fn.after这个方法则是把作为参数的元素放在被选中的元素后面。其他的几个方法也遵循这个模式。$.fn.insertBefore和$.fn.before;$.fn.appendTo和$.fn.append;还有$.fn.prependTo和$.fn.prepend。
这些方法对于你的作用完全依赖于你所选中的元素,和你是否需要新加入页面的元素的引用。如果你需要存储这个引用,你应该选中第一种方式——根据另一个元素来放置被选中的元素——它回返回你将要放置的元素。在这种情况下,你用$.fn.insertAfter,$.fn.insertBefore
, $.fn.appendTo
, 和$.fn.prependTo
例3.27:用不同的方式移动元素
// make the first list item the last list item
var $li = $('#myList li:first').appendTo('#myList');
// another approach to the same problem
$('#myList').append($('#myList li:first'));
// note that there's no way to access the
// list item that we moved, as this returns
// the list itself
当你用$.fn.appendTo方法的时候,你移动了元素;有时候你要的不仅仅是移动,你想要复制元素。这是,你需要$.fn.clone方法
例3.28:复制元素
// copy the first list item to the end of the list
$('#myList li:first').clone().appendTo('#myList');
注解:
如果你想复制有关联的数据或者事件,确保传递一个true作为参数给$.fn.clone
在页面中有两种方法来移除元素:$.fn.remove和$.fn.detach。当你想彻底的从页面中删除选择结果的时候,你可以用$.fn.remove;这个方法返回被移除的元素,如果你将他们重新添加到页面中,那些以前关联的数据和事件都会消失。
如果你想保持哪些关联的数据和事件,你可以用$.fn.detach来替代。像$.fn.remove一样,它也返回被选中的元素,但确同时维护着关联的数据和事件,所以你可以在一段时间后恢复这个元素。
注解:
$.fn.detach方法在你对一个元素有大量操作的时候是非常的有用的。此时,将元素detach出页面,然后在代码中对其进行操作,当你结束后再把它恢复到页面中。这种做法在你进行维护元素数据和事件的时候可以使你免于昂贵的DOM细节。
如果你想将元素保持在页面中,仅仅是移除他的内容,你可以用$.fn.empty方法来释放元素的内部html。
jquery提供了丰富的方法来创建新的元素——就像用$()方法来选择元素一样。
例3.29:创建新元素
$('<p>This is a new paragraph</p>');
$('<li class="new">new list item</li>');
例3.29:通过属性对象创建新元素
$('<a/>', {
html : 'This is a <strong>new</strong> link',
'class' : 'new',
href : 'foo.html'
});
注意,在上例中,我们添加了第二个参数,属性的名的类被括起来了,
而href和html确没有。当属性的名字不是保留字的时候,必须被括起来。
当我们创建一个新的元素的时候,并不是立即的添加到页面中的。这里有几个当页面被创建后添加到页面中的方法。
例3.31:将新元素添加到页面中
var $myNewElement = $('<p>New element</p>');
$myNewElement.appendTo('#content');
$myNewElement.insertAfter('ul:last'); // this will remove the p from #content!
$('ul').last().after($myNewElement.clone()); // clone the p so now we have 2
严格的说,你没必要将新元素存储到变量中——你可以直接通过$()将元素直接添加到页面中。但是大多数时候,你需要一个新添加元素的引用,这样你就不用再选择他们一次了。
你可以在创建新元素的同时就把他添加到页面中,但是这样你就失去了新添加对象的引用。
例3.32:
$('ul').append('<li>list item</li>');
注解:
添加新元素到页面的语法非常的简单,以至于人们都忘记了重复的添加是一个巨大的性能浪费。如果你给同一个容器添加许多元素,你会将所有的
html代码连接成为一个字符串,然后将这个字符串添加到容器,而不是每次只
添加一个元素。你可以用数组收集所有的元素片段,然后用join将他们变成一
个字符串再添加。
var myItems = [], $myList = $('#myList');
for (var i=0; i<100; i++) {
myItems.push('<li>item ' + i + '</li>');
}
$myList.append(myItems.join(''));
jquery包含大量的属性操作。基本的操作很简单,但是$.fn.attr方法同时提供了许多复杂的操作,它即可以设置一个简单的值,也可以通过函数的返回值来设置一个值。当用函数语法的时候,函数接受2个参数:被改变属性的元素的0基索引,和当前属性被改变的值。
例3.33:
$('#myDiv a:first').attr('href', 'newDestination.html');
例3.34:
$('#myDiv a:first').attr({
href : 'newDestination.html',
rel : 'super-special'
});
例3.35:
$('#myDiv a:first').attr({
rel : 'super-special',
href : function(idx, href) {
return '/new/' + href;
}
});
$('#myDiv a:first').attr('href', function(idx, href) {
return '/new/' + href;
});
(略)