我在index.html
中有大约60个过滤器按钮,每个按钮都附加了$().click()
个事件处理程序。
$(document).ready(function() {
$('.filter_button_class').click(function(e) {
console.log("filter button clicked");
e.preventDefault();
});
});
在我的CSS文件中,:active
选择器可确保点击过滤器按钮变为蓝色。
现在代码工作正常,大多数情况下。首次在浏览器中加载index.html
时,事件处理程序似乎都正确附加,代码始终按预期工作。这是一个单页面应用程序,因此当用户点击后退按钮返回index.html
并再次单击其中一个过滤器按钮时,它确实变为蓝色,但.click()
处理程序内的代码有时不会不执行。
我怀疑这可能是因为重新加载index.html
时,并非所有点击处理程序都会在用户点击过滤器按钮之前附加。但是当用户再次单击相同的过滤器按钮(总共两次)时,处理程序通常会执行。
问题有没有办法让click()
内的代码等待执行,直到首先连接所有事件处理程序?
而不是.click()
我还试过.on()
,但这没有效果。也许我正在识别的问题(事件处理程序附加到元素太慢)是错误的,但我当然会欣赏任何反馈。
答案 0 :(得分:2)
我能看到的描述行为的唯一解释是HTML非常大,浏览器需要一段时间才能完成解析并创建DOM。虽然它正在这样做,但它将部分呈现页面。通过使用ready
,您告诉jQuery您不希望调用回调中的代码,直到该过程完成为止。这留下了一个(小)机会窗口让用户看到一个按钮并在附加点击处理程序之前单击它(因为DOM解析仍在发生,因此ready
回调没有被触发然而)。这符合所描述的症状,特别是第一次点击不起作用(ready
尚未解雇),但后续的点击(ready
同时被解雇)。< / p>
如果 发生了什么,您可以通过使用事件委派和不来等待ready
回调:
$(document).on("click", ".filter_button_class", function() {
// ...handle the click...
});
挂钩document
上的点击处理程序,只有点击通过.filter_button_class
元素才会被触发。如果是这样,你的处理程序被称为,就好像你已经在该元素上挂钩了事件。
这涉及破坏脚本的一个规则,即将它们放在HTML的末尾,就在结束</body>
标记之前。相反,特别是因为我们正在处理由HTML大小和DOM构建时间引起的问题,我们违反了该规则并将script
标记置于问题内容之上:
<script src="jquery.js"></script>
<script src="yourcode.js"></script>
<!-- problematic (large) content -->
同样,通常我们不会这样做,因为它使得DOM解析器等待获取脚本,但在这种情况下,作为对已知问题的响应,它很好。 (只需确保启用缓存并正常工作。)
您可以通过将this fiddle(使用ready
)与this fiddle进行比较来查看效果(使用委托的前端处理程序,然后通过ready
添加直接处理程序)。第一个,如果您快速,您可以单击一个按钮,让它不显示任何内容。对于第二个,如果您快速,您可以单击一个按钮,只获得&#34;委派:&#34;消息,但稍后如果你点击了,我会得到一个&#34;直接:&#34;消息,然后是&#34;委托:&#34;之一。