我正在用jQuery开始一个项目。
您在jQuery项目中遇到了哪些陷阱/错误/误解/滥用/误用?
答案 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');
});
$('#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 */ });
了解到这一点
更新 - 这个答案是在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 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,$.validate和thickbox。其余的我主要开发自己的插件。
答案 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;
了解详情
答案 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);
答案 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和类。