jQuery需要避免的陷阱

我开始一个项目与jQuery。

在你的jQuery项目中有哪些陷阱/错误/误解/滥用/误用?

39980 次浏览

过度使用链条。

看到这个:

this.buttonNext[n ? 'bind' : 'unbind'](this.options.buttonNextEvent, this.funcNext)[n ? 'removeClass' : 'addClass'](this.className('jcarousel-next-disabled')).attr('disabled', n ? false : true);

1075870 < a href = " https://stackoverflow.com/questions/1075651/help-understanding-jquery-button-enable-disable-code/1075870 " > < / >解释

不理解事件绑定。JavaScript和jQuery的工作方式不同。

根据大众需求,一个例子:

jQuery:

$("#someLink").click(function(){//do something});

没有jQuery:

<a id="someLink" href="page.html" onClick="SomeClickFunction(this)">Link</a>
<script type="text/javascript">
SomeClickFunction(item){
//do something
}
</script>

基本上JavaScript所需要的钩子不再是必要的。例如,使用内联标记(onClick等),因为您可以简单地使用开发人员通常用于CSS目的的ID和类。

如果你多次bind()同一个事件,它将多次触发。为了安全起见,我通常总是去unbind('click').bind('click')

当使用$.ajax函数处理服务器的Ajax请求时,应该避免使用complete事件来处理响应数据。无论请求是否成功,它都会触发。

使用success而不是complete

请参阅文档中的Ajax事件

尝试分离出匿名函数,这样就可以重用它们。

//Avoid
$('#div').click( function(){
//do something
});


//Do do
function divClickFn (){
//do something
}


$('#div').click( divClickFn );

避免创建多个相同的jQuery对象

//Avoid
function someFunc(){
$(this).fadeIn();
$(this).fadeIn();
}


//Cache the obj
function someFunc(){
var $this = $(this).fadeIn();
$this.fadeIn();
}

没有意识到性能受到了影响,并且过度使用选择器而不是将它们分配给局部变量。例如:-

$('#button').click(function() {
$('#label').method();
$('#label').method2();
$('#label').css('background-color', 'red');
});

而不是:

$('#button').click(function() {
var $label = $('#label');
$label.method();
$label.method2();
$label.css('background-color', 'red');
});

用链条就更好了: -

$('#button').click(function() {
$("#label").method().method2().css("background-color", "red");
});

当我意识到调用栈是如何工作的时候,我发现是具有启发性的时刻。

编辑:在评论中加入建议。

误解在正确的上下文中使用此标识符。例如:

$( "#first_element").click( function( event)
{
$(this).method( ); //referring to first_element
$(".listOfElements").each( function()
{
$(this).someMethod( ); // here 'this' is not referring first_element anymore.
})
});

这里有一个解决方法的例子:

$( "#first_element").click( function( event)
{
$(this).method( ); //referring to first_element
var $that = this;
$(".listOfElements").each( function()
{
$that.someMethod( ); // here 'that' is referring to first_element still.
})
});

使用ClientID在ASP中获取控件的“真实”id。网络项目。

jQuery('#<%=myLabel.ClientID%>');

另外,如果你在SharePoint内部使用jQuery,你必须调用jQuery. noconflict()。

  • 避免滥用文件准备。
  • 保持文档仅为初始化代码准备。
  • 始终在文档外部提取函数,以便它们可以被重用。

我在doc ready语句中看到了数百行代码。丑陋,不可读,不可能维护。

不要使用裸类选择器,像这样:

$('.button').click(function() { /* do something */ });

这将检查每一个元素,看它是否有一个“button”类。

相反,你可以帮助它,比如:

$('span.button').click(function() { /* do something */ });
$('#userform .button').click(function() { /* do something */ });

这是我去年从丽贝卡·墨菲的博客中学到的

更新 -这个答案是2年前给出的,对于jQuery的当前的版本是不正确的。 其中一个评论包括一个测试来证明这一点。 还有一个测试的更新版本,它包含了这个答案时jQuery的版本

理解如何使用上下文。通常,jQuery选择器会搜索整个文档:

// This will search whole doc for elements with class myClass
$('.myClass');

但是你可以通过在上下文中搜索来加快速度:

var ct = $('#myContainer');
// This will search for elements with class myClass within the myContainer child elements
$('.myClass', ct);

缺陷:使用循环而不是选择器。

如果你发现自己在寻找jQuery '。每个方法迭代DOM元素,问问自己是否可以使用选择器来获取元素。

更多关于jQuery选择器的信息 http://docs.jquery.com/Selectors < / p >

缺点:没有使用Firebug这样的工具

Firebug实际上就是为这种调试而设计的。如果您打算在DOM中使用Javascript,则需要像Firebug这样的好工具来提供可见性。

关于Firebug的更多信息: http://getfirebug.com/ < / p >

其他很棒的想法都在这一期的多态播客中: (jQuery秘密与戴夫沃德) http://polymorphicpodcast.com/shows/jquery/ < / p >

如果您计划在大量数据中使用Ajax,比如一个有20列的1500行表,那么甚至不要考虑使用jQuery将这些数据插入到HTML中。使用纯JavaScript。jQuery在较慢的机器上太慢了。

而且,有一半的时间jQuery会做一些导致它变慢的事情,比如试图解析传入HTML中的脚本标记,以及处理浏览器的异常。如果您想要更快的插入速度,请坚持使用纯JavaScript。

“Chaining"带有回调的动画事件。

假设你想让一个段落在点击后消失。您还希望随后从DOM中删除该元素。你可能认为你可以简单地链接这些方法:

$("p").click(function(e) {
$(this).fadeOut("slow").remove();
});

在这个例子中,.remove()将在. fadeout()完成之前被调用,破坏渐变效果,只是让元素立即消失。相反,当你想在完成前一个命令后才触发一个命令时,使用回调函数:

$("p").click(function(e){
$(this).fadeOut("slow", function(){
$(this).remove();
});
});

. fadeout()的第二个参数是一个匿名函数,它将在. fadeout()动画完成后运行。这使得逐渐褪色,并随后删除元素。

将id而不是jQuery对象传递给函数:

myFunc = function(id) { // wrong!
var selector = $("#" + id);
selector.doStuff();
}


myFunc("someId");

传递一个包装集要灵活得多:

myFunc = function(elements) {
elements.doStuff();
}


myFunc($("#someId")); // or myFunc($(".someClass")); etc.

避免多次搜索整个DOM。这确实会耽误你的剧本。

缺点:

$(".aclass").this();
$(".aclass").that();
...

好:

$(".aclass").this().that();

缺点:

$("#form .text").this();
$("#form .int").that();
$("#form .choice").method();

好:

$("#form")
.find(".text").this().end()
.find(".int").that().end()
.find(".choice").method();
总是缓存$(this)到一个有意义的变量 特别是在.each()

像这样

$(selector).each(function () {
var eachOf_X_loop = $(this);
})

跟“回购人”说的差不多,但不完全一样。

在开发ASP时。NET winforms,我经常这样做

$('<%= Label1.ClientID %>');

忘记#符号。正确的形式是

$('#<%= Label1.ClientID %>');

事件

$("selector").html($("another-selector").html());

不会克隆任何事件-你必须重新绑定它们。

按照JP的惯例t - clone()如果传入true则重新绑定事件。

不要滥用插件。

大多数情况下,您只需要库和用户界面。如果你保持简单,你的代码在长期运行中是可维护的。并不是所有插件都得到支持和维护,实际上大多数插件都不是。如果你可以使用核心元素模拟功能,我强烈推荐你这么做。

插件很容易插入到代码中,为您节省了一些时间,但是当您需要额外的东西时,修改它们是一个坏主意,因为您失去了可能的更新。您在开始时节省的时间将在稍后更改已弃用插件时浪费掉。

明智地选择您使用的插件。 除了库和用户界面,我经常使用.cookie美元美元,养成. validate美元thickbox的。至于其余的,我主要是开发自己的插件

我对JavaScript也这么说,但是jQuery, JavaScript永远不应该取代CSS。

另外,确保站点对于关闭JavaScript的人来说是可用的(现在不像以前那么重要了,但拥有一个完全可用的站点总是好的)。

在一个小项目中使用jQuery,只需几行普通的JavaScript就可以完成。

如果你想让用户在他们的浏览器中看到html实体,使用'html'而不是'text'来注入Unicode字符串,例如:

$('p').html("Your Unicode string")

我的意见)

通常,使用jquery意味着你不必一直担心DOM元素。你可以这样写——$('div.mine').addClass('someClass').bind('click', function(){alert('lalala')})——这段代码将执行而不会抛出任何错误。

在某些情况下,这是有用的,在某些情况下-根本不是,但这是一个事实,jquery倾向于,嗯,空匹配友好。然而,如果试图将replaceWith与不属于文档的元素一起使用,则会抛出错误。我觉得这是违反直觉的。

另一个陷阱是,在我看来,由prevAll()方法返回的节点顺序- $('<div><span class="A"/><span class="B"/><span class="C"/><span class="D"/></div>').find('span:last-child').prevAll()。其实没什么大不了的,但我们应该记住这个事实。

进行过多的DOM操作。虽然.html(), .append(), .prepend()等方法很棒,但由于浏览器呈现和重新呈现页面的方式,经常使用它们会导致速度变慢。通常更好的方法是将html创建为字符串,并将其包含到DOM中一次,而不是多次更改DOM。

而不是:

var $parent = $('#parent');
var iterations = 10;


for (var i = 0; i < iterations; i++){
var $div = $('<div class="foo-' + i + '" />');
$parent.append($div);
}

试试这个:

var $parent = $('#parent');
var iterations = 10;
var html = '';


for (var i = 0; i < iterations; i++){
html += '<div class="foo-' + i + '"></div>';
}


$parent.append(html);

甚至这个($wrapper是一个新创建的元素,还没有注入到DOM中。将节点附加到这个包装器div不会导致速度变慢,最后我们将$wrapper附加到$parent,只使用了一个DOM操作):

var $parent = $('#parent');
var $wrapper = $('<div class="wrapper" />');
var iterations = 10;


for (var i = 0; i < iterations; i++){
var $div = $('<div class="foo-' + i + '" />');
$wrapper.append($div);
}


$parent.append($wrapper);

使用字符串累加器样式

使用+运算符在内存中创建一个新的字符串,并将连接的值赋给它。只有在此之后,结果才被赋值给一个变量。 为了避免连接结果的中间变量,可以使用+=运算符直接分配结果。 缓慢:< / p >
a += 'x' + 'y';

速度:

a += 'x';
a += 'y';

基元操作可能比函数调用快

考虑在性能关键循环和函数中使用替代基元操作而不是函数调用。 缓慢:< / p >
var min = Math.min(a, b);
arr.push(val);

速度:

var min = a < b ? a : b;
arr[arr.length] = val;

更多信息请访问JavaScript性能最佳实践