假设我有10个具有唯一ID的div。当我点击每个元素时,我希望显示一个叠加div并根据原始div的ID填充其中的内容。
做得更好:
$('#inventory > div').find('i.icon-plus').on('click', function(){
$('#add-item').slideDown(100);
if ( $(this).parent('div').attr('id') == '#id1' ) {
// load unique template
// or
// create form content here
}
else if ( $(this).parent('div').attr('id') == '#id2' ) {
// load other unique template
// or
// create other form content here
}
...
else if ( $(this).parent('div').attr('id') == '#id10' ) {
// load other unique template
// or
// create other form content here
}
});
或者:
$('#inventory > div#id1').find('i.icon-plus').on('click', function(){
$('#add-item').slideDown(100);
// load unique template
// or
// create form content here
});
$('#inventory > div#id2').find('i.icon-plus').on('click', function(){
$('#add-item').slideDown(100);
// load unique template
// or
// create form content here
});
...
$('#inventory > div#id10').find('i.icon-plus').on('click', function(){
$('#add-item').slideDown(100);
// load other unique template
// or
// create other form content here
});
基本上我要问的是:最好只有一个带有大量if / else语句的事件处理程序或者没有if / else语句的大量事件处理程序,或者它甚至不重要?
答案 0 :(得分:2)
我建议您使用on
将事件处理程序委派给父级,从而避免jQuery必须为每个i.icon-plus
附加处理程序。
然后使用带有id的处理程序映射作为具有运行其相应代码的函数的键。这样,你就不会附加很多if语句。
每个“案例”可能包含重复的代码,如果我们知道,可以进一步优化。但是因为我们不知道每个映射函数块的作用,这里的通用代码应该起到同样的作用:
//add handles here, with id as the key and a
//corresponding function that does what its supposed to do
var handles = {
'#id1' : function(){/*do something*/},
'#id2' : function(){/*do something*/},
...
}
//let's cache this one as well
var addItem = $('#add-item');
$('#inventory > div').on('click','i.icon-plus', function(e){
//get the corresponding handler
var handler = handles[$(this).parent('div').attr('id')];
//return if the handler isn't defined for this id
if(!handler) return;
//otherwise, execute. the context and arguments are passed on
addItem.slideDown(100);
handler.apply(this,arguments);
});
这可以进一步优化如果 #inventory > div
引用的div(我们的delegate target)与$(this).parent('div')
的div相同。如果是这样,可以替换它以减少函数调用:
$(this).parent('div').attr('id')
//can be replaced by
$(e.delegateTarget).attr('id')
答案 1 :(得分:1)
试试这个:
$("#inventory").children("div").on("click", "i.icon-plus", function (e) {
console.log(e.delegateTarget.id);
// Do your logic based on e.delegateTarget.id
});
DEMO: http://jsfiddle.net/7kyGP/
这会将一个事件绑定到每个“父”(目标)<div>
元素。您在代码中使用.parent()
,但使用.find()
获取<i>
。这有点矛盾,因为.find()
得到了后代......因此如果.parent()
嵌套,<i>
不一定是你认为的那样。使用此代码,<i>
元素不必是直接子元素 - 它们可以是后代。
在处理程序中,this
指的是单击的特定<i>
元素,而e.delegateTarget
指的是事件实际绑定的元素 - 子<div>
s #inventory
。当然,您可以使用jQuery通过$(e.delegateTarget)
操作目标。
答案 2 :(得分:0)
我怀疑这里有一个更通用的方法 - 如果你可以添加你需要的数据作为属性,以允许你加载唯一模板或创建表单内容,那么就不需要很多if语句或多个事件处理程序。
<强> HTML 强>
<div id="inventory">
<div id="id1" data-template-url="subform1.htm">
... some content
<i class="icon-plus"></i>
<div>
<div id="id2" data-template-url="subform2.htm">
... some content
<i class="icon-plus"></i>
<div>
<div id="id3" data-panel-id="panel3">
... some content
<i class="icon-plus"></i>
<div>
</div>
<div id="panel3" class="hide-until-required">
... panel content
</div>
<强> JAVASCRIPT 强>
$('#inventory > div').find('i.icon-plus').on('click', function() {
$('#add-item').slideDown(100);
var templateUrl = $(this).parent('div').attr('data-panel-id');
// or
var panelId = $(this).parent('div').attr('data-template-url');
// do something with template or panel data
});