每个jQuery开发者应该知道的重要技巧
1. stopPropagation or preventDefault or return false?
开发新手对stopPropagation,preventDefault和返回false经常混淆该使用哪一个技术以及什么时候用。
stopPropagation()
要了解stopPropagation,我们需要首先了解事件冒泡。让我们来举个例子。让我们假设你有链接<a>在<div>里,如下所示:
<div id="divone">
<a href="#" id="aone">Click me</a>
</div>
click事件挂在链接和DIV上:
$("#divone").click(function (e) {
alert("div clicked");
});
$("a").click(function (e) {
alert("link clicked");
});
当你点击链接,click()事件触发以及函数运行显示一个警告框“link clicked”。然而,事件并没有就此止步。你会看到另一个警告框“div clicked”。换句话说,即使你单击<a>,由于<div>是它的祖先元素,也接收到click事件。这就是所谓的事件冒泡或事件传播。
因此为了从阻止冒泡事件,需要以下列方式使用stopPropagation:
$("a").click(function (e) {
alert("link clicked");
e.stopPropagation();
});
现在,当你点击链接,单击事件将激发以及功能运行显示一个警告框“link clicked”。然而,由于e.stopPropagation,该事件不会冒泡。这就是为什么你不会看到第二个警告框。
preventDefault()
如果你想阻止Web浏览器事件的正常反应,使用preventDefault()。默认情况下,当你点击超链接,事件正常反应,转向到超链接href属性所示的网址。让我们以同样的例子定义超链接在div里如下:
<div id="divone">
<a href="http://www.jquerycookbook.com" id="aone">Click me</a>
</div>
在这里,点击超链接将转移到网页www.jquerycookbook.com。如果你想阻止这种默认行为,使用preventDefault(),如下所示:
$("#divone").click(function (e) {
alert("div clicked");
});
$("a").click(function (e) {
e.preventDefault();
});
现在,当您运行代码,你会看到,点击超链接并没有转向到网站地址,因为我们已经阻止了浏览器的默认事件。
然而,“div clicked”警告框显示了,因为我们阻止默认事件,而没有阻止发生事件冒泡/传播。如果你想阻止事件的发生冒泡,再同时使用,如下所示:
$("a").click(function (e) {
e.stopPropagation();
e.preventDefault();
});
现在,我们这两个都做了,所以浏览器不按照链接转向并且div事件也不会触发,因此我们没有看到alert()框。
return false
返回false实际上是调用stopPropagation()和preventDefault()的快捷方式。它告诉jQuery来防止缺省事件和停止冒泡的一种方式。大多数时候,你不想调用stopPropagation,所以我强烈建议不使用return false,而在代码中使用preventDefault()。
2、一些选择器技巧
这里有一些选择器技巧,你可以用它来提高选择的性能:
a。如果可能的话,使用ID选择器去选择代码中的元素。
b。在选择之前,不要在前面加上了标签名。所以,来看看下面:
<input type="text" id="code" value="54325454" />
..不要用 $("input#code"), 应该用 $("#code").
c. 只要有可能,使用过滤器方法来提高性能。可以使用$("div").has('p')来代替$( "div:has(p)"),这里 .has() 使用本地的DOM querySelectorAll() 方法 因此理论上比 :has更快。
d. 使用slice() 代替使用 :lt和 :gt 选择器
e. 推荐优先使用伪选择器,例如带有tag名的:text或者其他的选择器,否则隐含的通用选择器 ("*")就被使用了。也就是,$(":text") 相当于 $( "*:text"),所以应该使用$("input:text")
f. 不用 Not Equal 不等于选择器,尽可能使用 .not()获得小小的性能优势
g。不用过滤器,使用相当的属性选择器。例如用$('[type=image]' 来代替 $(':image')
延伸阅读:
http://learn.jquery.com/performance/optimize-selectors/
http://api.jquery.com/?s=selectors
3 - 使用 attr() 还是 prop()
attr() 处理 attributes 而 prop() 处理 properties. 考虑下面的标签:
<input type="text" value="original" />
输入域有attribute "value",有一个缺省的值并且这个attribute不会随着用户的输入交互而改变。如果用户输入改变了这个输入域,它在DOM Tree里改变了property的"value"而不是attribute的"value"
看看 jsfiddle 上 的demo 来理解两者的不同:
http://jsfiddle.net/jquerycookbook/s1gsLcLb/
运行演示,一旦你从“original”输入别的东西改变文本框的值,回车。你会看到,ATTR()将返回原来的价值,但prop()返回更改后的值。
所以attributes不会改变,但properties可以在后台通过用户操作来改变(选中/取消选中复选框)或以编程方式。
因此,什么时候使用什么?如果你想设置一个HTML标记属性的默认值,可以使用ATTR()。然而,当您在窗口或文档对象设置属性,你应该总是使用道具prop()。
虽然我用这个文本框例子说明目的,实际上,既不用.attr(),也不用.prop()用于获取/设定值。你应该使用.val()方法。
jQuery的1.6之前,我们只有ATTR()。
延伸阅读: http://blog.jquery.com/2011/05/12/jquery-1-6-1-released/
4 - <script> in head or body?
在一个HTML文件里可以在两个地方放置js,在</ body>标记结束之前和<head>里面。网页浏览器处理一个HTML页,从上到下,执行任何它找到<script>标记之间的JavaScript。由于这个原因,如果脚本中的一个需要花费时间来执行,网页的加载被阻止。因此,最好放在body元素结束之前,以确保您的脚本在加载DOM后运行。
在我的一些文章,甚至我的书,我经常选择把脚本中的<head>标签里面,但是这仅仅是为了可读性。不过,我也请务必使用$(document).ready() 或快捷方式$(function(){ }),它可确保只有当浏览器加载所有的HTML文档中的内容后脚本才执行。因此,我把脚本放在结束</ body>标签之前达到相同的效果。
说了这么多,记住,通过在页面底部引入你的脚本,就可以完全避免使用$(document).ready()。事实上,在我所有的生产准备的应用程序,我的脚本都在页面的底部。
5 - Difference between this, $this and $(this)
让我们用一个例子来理解$this和$(this)的不同。看看下面的代码:
$('div').each(function () {
var $this = $(this);
$this.css("background-color", "blue");
$this.slideUp('3000');
$this.slideDown('3000');
});
在这里,我们使用each()遍历了一堆div。一旦在你的循环中,this引用的是不是一个jQuery对象的DOM元素。因此,要使它成为一个jQuery对象,并在其上运行jQuery方法,我们用$(this)。现在就来看看这句话中:var $this = $(this);
如果你要引用的DOM元素多次在代码中,像我们上面这个例子;那么由于性能考虑,你应该获得一个jQuery的引用它,然后保存到一个变量。在这里,$this是那个变量。这也被称为高速缓存选择器,因为它是昂贵的运行jQuery函数$(this)各一次。因此,存储在一个变量的输出可以让您重用这个选择器,而不会再次调用jQuery函数。
注意:不要混淆$this。你可以把它叫做任何你喜欢的。我通常是指包含的jQuery对象作为$ VARIABLENAME变量。