jQuery要避免的陷阱

时间:2009-08-04 18:52:37

标签: javascript jquery

我正在用jQuery开始一个项目。

您在jQuery项目中遇到了哪些陷阱/错误/误解/滥用/误用?

27 个答案:

答案 0 :(得分:188)

不知道性能损失和过度使用选择器而不是将它们分配给局部变量。例如: -

$('#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');
});

even better with chaining: -

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

当我意识到调用堆栈如何工作时,我发现了this这一启发性的时刻。

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

答案 1 :(得分:89)

了解如何使用上下文。通常,jQuery选择器将搜索整个doc:

// 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);

答案 2 :(得分:62)

不要使用裸类选择器,如下所示:

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

这将最终查看每个元素,看它是否有一个“按钮”类。

相反,您可以提供帮助,例如:

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

我去年从Rebecca Murphy's blog

了解到这一点

更新 - 这个答案是在2年前提出的,对于当前的版本的jQuery来说是不正确的。 其中一条评论包括一项证明这一点的测试。 还有一个updated version of the test,其中包含了此答案时jQuery的版本。

答案 3 :(得分:35)

尝试拆分匿名函数,以便重复使用它们。

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

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

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

答案 4 :(得分:34)

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

而不是complete,请使用success

请参阅文档中的Ajax Events

答案 5 :(得分:34)

  • 避免滥用文档。
  • 保持文档准备好仅初始化代码。
  • 始终在doc准备之外提取函数,以便可以重复使用它们。

我在doc ready语句中看到了数百行代码。丑陋,难以理解,无法维持。

答案 6 :(得分:24)

使用回调“链接”动画事件。

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

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

在这个例子中,.remove()将在.fadeOut()完成之前被调用,破坏逐渐消失的效果,并简单地使元素立即消失。相反,当您只想在完成前一个命令时触发命令时,请使用回调函数:

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

.fadeOut()的第二个参数是一个匿名函数,它将在.fadeOut()动画完成后运行。这会逐渐消失,并随后移除元素。

答案 7 :(得分:23)

不要滥用插件。

大多数时候,您只需要图书馆,也许还需要用户界面。如果你保持简单,那么从长远来看,你的代码将是可维护的。并非所有插件都受支持和维护,实际上大部分插件都不支持和维护。如果您可以使用核心元素模仿功能,我强烈推荐它。

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

明智地选择您使用的插件。 除了库和用户界面,我经常使用$.cookie$.form$.validatethickbox。其余的我主要开发自己的插件。

答案 8 :(得分:23)

如果多次绑定()同一事件,它将多次触发。我通常总是unbind('click').bind('click')只是为了安全

答案 9 :(得分:22)

陷阱:使用循环代替选择器。

如果你发现自己要使用jQuery'.each'方法迭代DOM元素,那么问问自己是否可以使用选择器来获取元素。

有关jQuery选择器的更多信息:
http://docs.jquery.com/Selectors

陷阱:不使用像Firebug这样的工具

Firebug实际上是为这种调试而制作的。如果您打算使用Javascript在DOM中捣乱,您需要一个像Firebug这样的好工具来为您提供可见性。

有关Firebug的更多信息: http://getfirebug.com/

其他伟大的想法出现在Polymorphic Podcast的这一集中: (与戴夫沃德的jQuery秘密) http://polymorphicpodcast.com/shows/jquery/

答案 10 :(得分:14)

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

$( "#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.
   })
});

答案 11 :(得分:12)

避免多次搜索整个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();

答案 12 :(得分:12)

始终将$(this)缓存到有意义的变量中 特别是在.each()

喜欢这个

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

答案 13 :(得分:10)

类似于Repo Man所说的,但并不完全。

在开发ASP.NET winforms时,我经常

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

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

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

答案 14 :(得分:10)

<强>事件

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

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

根据JP的commen t - 如果传递true,clone()会重新绑定事件。

答案 15 :(得分:9)

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

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

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

答案 16 :(得分:8)

我也是这样说的JavaScript,但jQuery,JavaScript应该永远不会取代CSS。

此外,请确保该网站可用于关闭JavaScript的用户(今天不像当天那样具有相关性,但总是很高兴拥有一个完全可用的网站)。

答案 17 :(得分:6)

制作太多的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);

答案 18 :(得分:5)

使用ClientID获取ASP.NET项目中控件的“真实”ID。

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

此外,如果您在SharePoint中使用jQuery,则必须调用jQuery.noConflict()。

答案 19 :(得分:4)

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

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

myFunc("someId");

传递包裹的集更灵活:

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

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

答案 20 :(得分:3)

使用字符串累加器式

使用+运算符在内存中创建一个新字符串,并为其分配连接值。只有在此之后才将结果分配给变量。 要避免连接结果的中间变量,可以使用+ =运算符直接分配结果。 慢:

a += 'x' + 'y';

更快:

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

原始操作可以比函数调用更快

考虑在性能关键循环和函数中使用替代原语操作而不是函数调用。 慢:

var min = Math.min(a, b);
arr.push(val);

更快:

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

JavaScript Performance Best Practices

了解详情

答案 21 :(得分:3)

过度使用链接。

见:

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

Explanation

答案 22 :(得分:1)

如果您希望用户在浏览器中查看html实体,请使用“html”代替“text”来注入Unicode字符串,例如:

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

答案 23 :(得分:1)

我的两分钱)

通常,使用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()。实际上并不是什么大不了的事,但我们应该记住这个事实。

答案 24 :(得分:0)

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

此外,有一半时间jQuery会做一些会导致速度变慢的事情,比如尝试解析传入HTML中的脚本标记,并处理浏览器怪癖。如果你想快速插入速度,坚持使用纯JavaScript。

答案 25 :(得分:-2)

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

答案 26 :(得分:-3)

不了解事件绑定。 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和类。