jQuery 事件触发多次
jQuery event fires multiple times
我遇到了 jQuery 事件的问题。
首先让我解释一下页面的设置:
main-page.php 的组成是:
a) a header(徽标所在的位置)
b) 导航栏(各种 selection 所在的位置)
c) 动态内容区域(导航栏上点击元素的内容将被加载)
d) 页脚
假设导航栏由|组成主页 |留言 |关于我们 | ...
HOME的内容是一个单独的PHP文件,有一个单独的CSS和JS文件。所有 select 离子也是如此。
一旦我 select HOME(例如),我就会从动态内容区域中删除所有内容,然后使用 AJAX 放置 HOME 的内容。同时,我删除了与先前内容关联的所有 CSS/JS 文件,并删除了与加载的内容关联的 link 文件。这部分工作完美。
现在,如果我从一个 selection 切换到另一个 selection(假设从主页 --> 消息 --> 关于我们然后返回主页),如果我单击在 HOME 内的按钮上,它将多次触发该事件。如果该事件导致对服务器的 AJAX 调用(想象调用服务器 5 次而不是 1 次),情况会更糟。
** 我在带有 radio-element class 的元素上使用 on()
事件的原因是因为它是一个未来的 DOM 元素。最初此元素不在页面上。
JS代码示例:
$(document).on('click', '.radio-element', function(){
$.ajax({
url: "js/ajax/ajaxcall.php",
success: function(output){
$('#ajaxcall-container').html(output);
}
});
});
我所做的是,只要我单击带有 radio-element 的 class 的元素,我就会进入服务器并获取 ajaxcall.php
脚本的输出。
观察 INSPECT ELEMENT 中的 NETWORK 选项卡,我看到点击事件多次执行 AJAX 调用。有时2个,其他3个甚至5个。
我为解决问题所做的工作(没有 100% 有效):
A) 在使用“off”
绑定之前取消绑定事件
$(document).off('click','.radio-element').on('click', '.radio-element', function(){ .... });
B) 使用事件。stopImmediatePropagation()
$(document).on('click', '.radio-element', function(event){
event.stopImmediatePropagation();
//rest of code
});
下面是一个我还没有尝试过的解决方案,因为我在一篇文章中看到它不会停止事件绑定过程,它只会阻止多个事件执行(不知道这会不会引起其他问题) .
$(document).on('click', '.radio-element', function(event){
if(event.handled !== true)
{
//Code goes here
event.handled = true;
}
});
触发多个事件的问题在于,有 AJAX 次调用执行不应多次执行的操作(例如,向客户发送电子邮件)。
此外,这种行为(多事件触发)不是我可以预测的。有时它工作正常,有时它会连续触发事件 5 次。
我已经在网上搜索了一个星期,但我尝试的一切都没有解决问题。任何解决方案将不胜感激:)
谢谢!
根据我在此处阅读的内容 - 我猜您不止一次通过单击绑定事件打开 js 文件。如果您使用的是自定义路由或单页应用程序并且没有刷新页面,则很可能是基于您所说的。
您可以通过在点击事件中添加一个 console.log(在 ajax 之上)来测试这个理论,然后随意使用它并检查日志。如果您单击它并且它记录了您不止一次记录的任何内容,那么您就知道这就是问题所在。我不认为这是 ajax.
根据您的描述,我的猜测是您没有删除事件侦听器。因此,每次切换 tab/page 时,都会一遍又一遍地添加相同的事件。即使您已尝试这样做,但还是有些事情不对劲。我怀疑它与 Ajax.
有什么关系
同样的问题我也遇到好久了。我通过在执行新的事件处理程序之前取消绑定与该元素关联的所有事件来解决这个问题。
像这样使用:
$('#element').unbind().click()
{
//write something here
}
这将在创建新事件处理程序之前取消绑定以前的事件处理程序。我认为这对你很有效。
如果您使用的是 jquery 版本 1.7+
你可以像这样使用 off()
$('#element').Off().click()
{
//write something here
}
我遇到了 jQuery 事件的问题。
首先让我解释一下页面的设置:
main-page.php 的组成是:
a) a header(徽标所在的位置)
b) 导航栏(各种 selection 所在的位置)
c) 动态内容区域(导航栏上点击元素的内容将被加载)
d) 页脚
假设导航栏由|组成主页 |留言 |关于我们 | ...
HOME的内容是一个单独的PHP文件,有一个单独的CSS和JS文件。所有 select 离子也是如此。
一旦我 select HOME(例如),我就会从动态内容区域中删除所有内容,然后使用 AJAX 放置 HOME 的内容。同时,我删除了与先前内容关联的所有 CSS/JS 文件,并删除了与加载的内容关联的 link 文件。这部分工作完美。
现在,如果我从一个 selection 切换到另一个 selection(假设从主页 --> 消息 --> 关于我们然后返回主页),如果我单击在 HOME 内的按钮上,它将多次触发该事件。如果该事件导致对服务器的 AJAX 调用(想象调用服务器 5 次而不是 1 次),情况会更糟。
** 我在带有 radio-element class 的元素上使用 on()
事件的原因是因为它是一个未来的 DOM 元素。最初此元素不在页面上。
JS代码示例:
$(document).on('click', '.radio-element', function(){
$.ajax({
url: "js/ajax/ajaxcall.php",
success: function(output){
$('#ajaxcall-container').html(output);
}
});
});
我所做的是,只要我单击带有 radio-element 的 class 的元素,我就会进入服务器并获取 ajaxcall.php
脚本的输出。
观察 INSPECT ELEMENT 中的 NETWORK 选项卡,我看到点击事件多次执行 AJAX 调用。有时2个,其他3个甚至5个。
我为解决问题所做的工作(没有 100% 有效):
A) 在使用“off”
绑定之前取消绑定事件$(document).off('click','.radio-element').on('click', '.radio-element', function(){ .... });
B) 使用事件。stopImmediatePropagation()
$(document).on('click', '.radio-element', function(event){
event.stopImmediatePropagation();
//rest of code
});
下面是一个我还没有尝试过的解决方案,因为我在一篇文章中看到它不会停止事件绑定过程,它只会阻止多个事件执行(不知道这会不会引起其他问题) .
$(document).on('click', '.radio-element', function(event){
if(event.handled !== true)
{
//Code goes here
event.handled = true;
}
});
触发多个事件的问题在于,有 AJAX 次调用执行不应多次执行的操作(例如,向客户发送电子邮件)。
此外,这种行为(多事件触发)不是我可以预测的。有时它工作正常,有时它会连续触发事件 5 次。
我已经在网上搜索了一个星期,但我尝试的一切都没有解决问题。任何解决方案将不胜感激:)
谢谢!
根据我在此处阅读的内容 - 我猜您不止一次通过单击绑定事件打开 js 文件。如果您使用的是自定义路由或单页应用程序并且没有刷新页面,则很可能是基于您所说的。
您可以通过在点击事件中添加一个 console.log(在 ajax 之上)来测试这个理论,然后随意使用它并检查日志。如果您单击它并且它记录了您不止一次记录的任何内容,那么您就知道这就是问题所在。我不认为这是 ajax.
根据您的描述,我的猜测是您没有删除事件侦听器。因此,每次切换 tab/page 时,都会一遍又一遍地添加相同的事件。即使您已尝试这样做,但还是有些事情不对劲。我怀疑它与 Ajax.
有什么关系同样的问题我也遇到好久了。我通过在执行新的事件处理程序之前取消绑定与该元素关联的所有事件来解决这个问题。 像这样使用:
$('#element').unbind().click()
{
//write something here
}
这将在创建新事件处理程序之前取消绑定以前的事件处理程序。我认为这对你很有效。
如果您使用的是 jquery 版本 1.7+ 你可以像这样使用 off()
$('#element').Off().click()
{
//write something here
}