当前位置:  开发笔记 > 编程语言 > 正文

jQuery要避免的陷阱

如何解决《jQuery要避免的陷阱》经验,为你挑选了19个好方法。

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

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



1> Gavin Gilmou..:

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

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

当我意识到调用栈如何工作时,我发现这是一个启发性的时刻.

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


我认为将事物分配给局部变量是很好的但不要忘记链接的力量(来自你的例子):$("#label").method().method2().css("background-color","红色");
为youtube链接+1.神圣的废话我学到了很多东西.
使用带有jQuery上下文的变量的美元符号是一种惯例.所以你可能想写`var $ label = $('#label');`

2> slolife..:

了解如何使用上下文.通常,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);


Aaaaaaah!好吧,我修复了大约1,000,000个错误.+1
看来你的最后一点是不正确的 - http://groups.google.co.uk/group/jquery-dev/browse_thread/thread/b8c414b373163895
jQuery检查上下文是否是jQuery的实例,因此没有理由"[0]`.`$('.myClass',ct);`或者如果你知道ct是jQuery的一个实例,你可以使用find`ct.find(".myClass")`

3> BrianH..:

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

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

这将最终查看每个元素,看它是否有一个"按钮"类.

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

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

我去年从Rebecca Murphy的博客中了解到这一点

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


你正在减少它必须做的工作量.这就像告诉别人把你的袜子从梳妆台的抽屉里拿出来,而不是告诉他们把袜子从你的房间拿出来.减少它必须大幅度"看"的数量.
@Sneakyness并非所有事物都具有现实生活的准确模拟.例如,`$('.b')`可以使用`document.getElementsByClassName('b')`如果浏览器支持它,但执行`$('a.b')`将导致它获取所有匹配的元素用类'b`然后确认它们是两阶段操作的锚点.后者听起来对我来说更多的工作.对于现实生活的类比,试试这个:*找到我房间里的所有袜子.现在,扔掉那些不在我梳妆台里的东西.*
我的印象也是相反的.也许在没有实现getElementsByClassName的浏览器中就是这种情况,但是你只是给jQuery做更多的工作.我非常希望看到丽贝卡发布一些基准:)
当您编写CSS(至少包括元素标记)时,反之亦然.请参阅http://code.google.com/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors
我认为对选择器的误解是由于在旧版本的jquery中,执行$('#foo')而不是$('div#foo')更快,因为根据定义,id是唯一的.我很确定这在以后的版本中已得到修复,但该建议仅适用于ID,而不适用于其他类型的选择器
令人失望的是,这样一个错误的答案是第二好的.Sizzle从右到左工作; 它将首先获得所有`.button`元素,然后检查它们是否有`span`父元素.这比简单地搜索`.button`要慢一点.(以id开头的选择器是例外,因为Sizzle将首先处理id,但这仍然不会使事情变得更快 - 请参阅[test](http://jsperf.com/sizzle-id-specificity).)

4> redsquare..:

尝试拆分匿名函数,以便重用它们.

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

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

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


我认为这适用于大致相同的程度,即同步(内联)代码应该分解为命名函数.如果你有一大堆代码要求给出一个名字,那就去吧.但是不要仅仅因为你将代码包装在一个函数中而将代码移出行; 匿名函数存在是有充分理由的.
其实我喜欢给我的功能"命名".当您调试代码时,它非常有用,而不是看到无穷无尽的匿名函数列表,您会看到正确命名的函数.

5> Artem Barger..:

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

而不是complete,使用success.

请参阅文档中的Ajax事件.


好吧它总是被召唤.但是我不同意.完整最适合隐藏加载的GIF等.当然,您应该使用成功处理响应和错误.

6> redsquare..:

避免滥用文件准备.

保持文档准备好仅初始化代码.

始终在doc准备之外提取函数,以便可以重用它们.

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


+1.一般来说,我见过的大多数jQuery代码都使用了数百行的函数.我不知道为什么'jQuery开发者'不喜欢使用更小的函数.
@SolutionYogi因为大多数只是JS新手?

7> Sampson..:

"链接"动画事件与回调.

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

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

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

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

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



8> Scott Evernd..:

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


您可以使用实时事件来不必将同一事件绑定两次.
这不是特定于jQuery,但要记住重要的事情.

9> Elzo Valugi..:

不要滥用插件.

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

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

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


网格怎么样?你自己做?

10> Dan Esparza..:

陷阱:使用循环而不是选择器.

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

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

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

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

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

其他伟大的想法都出现在Polymorphic Podcast的这一集中:( 与Dave Ward的jQuery Secrets) http://polymorphicpodcast.com/shows/jquery/



11> Artem Barger..:

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

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



12> googletorp..:

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


虽然避免反复搜索DOM是一件好事 - 最后一个例子是一个难以理解的混乱,我不知道发生了什么.如果计划多次使用获取结果,请将其存储在变量中.它使代码更易于维护.
.$( "ACLASS")这个()是(); 不好!只有类选择器很慢

13> adardesign..:

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

像这样

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


如果你懒得想一个好的变量名,可以使用`$ self`或`$ this`.

14> Ron..:

与Repo Man所说的相似,但并不完全相同.

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

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

忘了#符号.正确的形式是

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



15> Chris S..:

活动

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

没有克隆任何事件 - 你必须重新绑定它们.

根据JP的命令,如果传递true,clone()会重新绑定事件.


如果传递true,Clone()会执行.

16> redsquare..:

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

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

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


这是有效的,但我认为将'$ this = $(this);`放在一个单独的行上更具可读性.如果你可以(不弄乱),忘记`$ this`并链接所有东西:`$(this).fadeIn().fadeIn();`
它返回元素,它称为链接!

17> Martin..:

我也说这个用于JavaScript,但是jQuery,JavaScript应该永远不会取代CSS.

此外,请确保该网站可用于关闭JavaScript的人(今天不像今天那样重要,但总是很高兴有一个完全可用的网站).



18> Alex Heyd..:

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

代替:

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

for (var i = 0; i < iterations; i++){
    var $div = $('
'); $parent.append($div); }

试试这个:

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

for (var i = 0; i < iterations; i++){
    html += '
'; } $parent.append(html);

或者甚至这个($ wrapper是一个新创建的元素,尚未注入到DOM中.将节点附加到此包装器div不会导致速度减慢,最后我们将$ wrapper附加到$ parent,只使用一个DOM操作):

var $parent = $('#parent');
var $wrapper = $('
'); var iterations = 10; for (var i = 0; i < iterations; i++){ var $div = $('
'); $wrapper.append($div); } $parent.append($wrapper);



19> Repo Man..:

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

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

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


?这怎么会陷入困境?这是ASP.NET行为的解决方法.
同意.但无论如何,在ASP.NET中使用jQuery时都需要注意这一点.
OP没有提到asp.net
推荐阅读
mylvfamily
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有