jQuery on DOMNodeInserted plus html()导致无限循环

时间:2017-06-16 18:42:21

标签: javascript jquery

为不正确的标签构建自定义jQuery解决方案 - 纠正我们使用的第三方插件需要更新,因此我不想编辑插件的php代码,因为一旦更新,我们的编辑显然会消失。

这是一个Select元素,表示“我的朋友”,我们希望将其更改为“我的连接”,以及“我的朋友在群组中”,我们希望将其更改为“我在群组中的连接”。

当使用另一个选择时,通过ajax重新插入选择器,所以每次插入选择器时我都需要进行此更改。因此我写了以下代码

   jQuery(document).ready(function() {
        jQuery('#wrapper').on('DOMNodeInserted', '#selector', function() {
                //alert('Friends inserted!');
                var title1 = jQuery(this).children('.fa-friends');
                if(title1.length > 0) {
                        title1.html('My Connections'); 
                }
                var title2 = jQuery(this).children('.fa-groupfriends');
                if(title2.length > 0) {
                        title2.html('My Connections in Group'); 
                }
                alert(title1.html() + ' ' + title2.html() );           
        }); // end on 
}); // end ready 

如果我注释掉html()函数,代码执行完全正常,让我知道事件已被触发。

如果我试图让html()函数开始,代码会陷入无限循环,并且永远无法进行替换。

为什么这会导致无意的无限循环?如何防止或停止循环?

3 个答案:

答案 0 :(得分:0)

你在这里创建了循环:

 jQuery('#wrapper').on('DOMNodeInserted', '#selector', function() {

这是在DOMNodeInserted发生的任何时候添加处理程序。

然后,一旦进入方法,就会在执行此操作时触发DOMNodeInserted:

 title2.html('My Connections in Group'); 

html()正在添加新文本,当再次触发DOMNodeInserted时,循环继续。

要修复,您需要在第一次触发后禁用侦听器。

在方法中添加:

 jQuery('#wrapper').off('DOMNodeInserted');

答案 1 :(得分:0)

事实是,Javascript中的事件以低于>向上的方式传播。这意味着当你向孩子插入一些内容时,它会触发孩子的${NUM[@]},而不是传播给父母并触发父母DOMNodeInserted,而不是父母的父母,所以直到没有父母。所有活动都以这种方式运作。

您有一个经典问题,但是当您将html插入子节点时,您无法阻止传播,因此您可以这样做:

DOMNodeInserted

jQuery(document).ready(function() { jQuery('#wrapper').on('DOMNodeInserted', '#selector', function(e) { if ($(e.originalEvent.relatedNode).is($('#selector'))) { //alert('Friends inserted!'); var title1 = jQuery(this).children('.fa-friends'); if(title1.length > 0) { title1.html('My Connections in Group'); } var title2 = jQuery(this).children('.fa-groupfriends'); if(title2.length > 0) { title2.html('My Connections in Group'); } alert(title1.html() + ' ' + title2.html() ); } }); // end on }); // end ready - 将确保该功能仅在某些内容直接插入$(e.originalEvent.relatedNode).is($('#selector'))

时才有效

答案 2 :(得分:0)

毕竟想出办法。在运行时添加一个类,并将on函数设置为在具有该类时不触发。当另一个选择器再次调用它时,该类将不会出现,它将再次触发。

jQuery(document).ready(function() {
        jQuery('#activity-visibility').on('DOMNodeInserted', '#activity-privacy:not(.altered)', function() {
                jQuery(this).addClass('altered');
                var title1 = jQuery(this).children('.fa-friends');
                if(title1.length > 0) {
                        title1.html('My Connections');
                }
                var title2 = jQuery(this).children('.fa-groupfriends');
                if(title2.length > 0) {
                        title2.html('My Connections in Group');  
                }
        }); // end on
}); // end ready