在这种情况下,当使用事件监听器(使用jQuery)时,我有点混淆什么是最佳选择,性能方面。
案例1 : 假设你有一个包含两个输入的div,你想要"听"同时为 keyUp 事件。 (这个div是文档中唯一的东西,它的高度和宽度也是完整文档的那个)
<div id=formContainer>
<input type="text" id="a">
<input type="text" id="b">
</div>
什么会更好? :附加&#39;委派的事件监听器&#39;到 formContainer 或将事件监听器附加到每个输入?
案例2 : 现在,假设你有一个像这样的html结构(同样,chatContainer是文档的完整高度和宽度,它和它的子节点只是它的内容)
<div id=chatContainer>
<div id="menu"></div> //Has to listen to clicks for interactivity
<div id="messagesWindow"></div> //Has to listen to clicks on every message appended
<input type="text" id="inputSomething"> //Has to listen to keyUp events
</div>
在这种情况下,最好将事件监听器附加到每个div /输入或将所有需要的事件监听器附加到 chatContainer(keyUp,click)?
我已经阅读了委托活动,但我不知道我是否做对了。即使性能差异很小,我也希望做得更好。 非常感谢你。
答案 0 :(得分:0)
我也不知道哪个更快(即使差异很小)。所以我写了测试代码
由coffeescript编写的代码
虽然你可以在jsfiddle看到javascript代码,但它们是编译后的代码。
案例1 http://jsfiddle.net/5mnroam3/
(你的问题案例)
<div id=formContainer>
<input type="text" id="a">
<input type="text" id="b">
</div>
counterA = counterB = 0
$("#formContainer").click( (e) ->
switch $(e.target).attr("id")
when "a"
counterA++
when "b"
counterB++
)
startTime = new Date()
for i in [0...10000]
$("#a").trigger("click")
$("#b").trigger("click")
endTime = new Date() - startTime
console.log("listen to container : #{endTime} ms","counterA is #{counterA}","counterB is #{counterB}")
counterA = counterB = 0
$("#formContainer").off("click")
$("#a").click((e) ->
counterA++
)
$("#b").click((e) ->
counterB++
)
startTime = new Date()
for i in [0...10000]
$("#a").trigger("click")
$("#b").trigger("click")
endTime = new Date() - startTime
console.log("listen to each elem : #{endTime} ms","counterA is #{counterA}","counterB is #{counterB}")
上面的代码正在进行10000次点击&#34;#a&#34;和&#34;#b&#34;并做&#34;反++&#34;每次事件发生时。 在我的macbook(MBP2013mid chrome latest)中,结果是
listen to container : 2224 ms counterA is 10000 counterB is 10000
listen to each elem : 1952 ms counterA is 10000 counterB is 10000
听每个元素都快一点。
案例2 http://jsfiddle.net/fbjyp5yL/
(Case目标元素有一个子元素,这意味着当你监听外部元素时,你必须检查被点击的元素是否将目标元素作为其父元素,因为e.target
或this
在事件回调函数总是最可靠的内部元素)
<div id="outer">
<div id="element1">
<div class="children1"></div>
<div class="children2"></div>
</div>
<div id="element2">
<div class="children1"></div>
<div class="children2"></div>
</div>
</div>
counterA = counterB = 0
$("#outer").click( (e) ->
if $(e.target).closest("#element1").length
counterA++
else if $(e.target).closest("#element2").length
counterB++
else
console.log("unexpected event")
)
startTime = new Date()
for i in [0...5000]
$("#element1 .children1").trigger("click")
$("#element1 .children2").trigger("click")
$("#element2 .children1").trigger("click")
$("#element2 .children2").trigger("click")
endTime = new Date() - startTime
console.log("listen to outer : #{endTime} ms",counterA,counterB)
$("#outer").off("click")
counterA = counterB = 0
$("#element1 .children1,#element1 .children2").click( (e) ->
counterA++
)
$("#element2 .children1,#element2 .children2").click( (e) ->
counterB++
)
startTime = new Date()
for i in [0...5000]
$("#element1 .children1").trigger("click")
$("#element1 .children2").trigger("click")
$("#element2 .children1").trigger("click")
$("#element2 .children2").trigger("click")
endTime = new Date() - startTime
console.log("listen to each elem : #{endTime} ms",counterA,counterB)
在这种情况下,我的结果是
listen to outer : 2547 ms 10000 10000
listen to each elem : 2159 ms 10000 10000
因此,侦听外部元素就像情况1一样慢,并且差异大于case1,即使它只是300-400ms到20000次点击。
<强>结论强>
虽然使用外部元素或每个内部元素之间的差异很小,但是在每个div /输入上监听事件的速度更快。我确定如果有10个或20个内部元素,差异仍然很小。所以选择你喜欢的任何你喜欢的。