我有一个相当大的javascript类,可以生成一个完整的ajax生成的应用程序。在ajax页面的一个版本中,有许多下拉菜单。在应用程序的生命周期中,可以在各个点创建和销毁这些菜单。
这是我看到的行为:
用户打开页面版本1:没有下拉菜单 用户转到页面版本2:使用jQuery onchange事件添加了下拉列表。按预期工作。 用户返回页面版本1,删除了下拉列表。 用户返回页面版本2,再次添加下拉列表(使用相同的元素ID) 下拉列表现在将具有“双重”事件处理功能,为每个onchange触发事件。
我正在努力的行为如下。
在初始页面加载时,我添加了一个onchange事件:
function myClass(){
//Initiate once for current and future elements.
jQuery(document).on('change',".mydropdowns",
function(e){
self.submitDescriptionChange(this);
}
);
}
myClass.prototype.submitDescriptionChange = function (el){
doSomeAjaxStuff();
}
这很好用,除了每次用户转到页面版本1并返回页面版本2时,事件都会成倍增加。很快你就可以在每个更改事件中触发事件20次,在这种情况下会创建20个ajax调用。
逻辑上,通过使用jQuery.off(),我应该可以避免这种情况。但是会发生的事情是从过去和未来的元素中删除事件,这意味着当我重新创建页面版本2时,下拉列表将不起作用。
我尝试过的每一种方式(我都尝试过LOADS),我要么最终没有事件触发,要么触发多个事件。我似乎无法找到一种方法来添加/替换事件只被触发一次的元素。
我有什么想法可以解决这个问题吗?
已更新
是的,事实证明我误解了这个问题。它实际上来自反复重新绑定'hashchange'事件,而不是重新绑定onchange事件。抱歉误导。转到bind()函数到某个地方,只有在修复了问题后才执行它。答案 0 :(得分:1)
我不确定你用于下拉菜单的插件是什么,但该插件上应该有一个“destroy”方法。如果你在删除应该工作的下拉列表时调用它。此外,如果您只是隐藏第二页并且实际上没有从DOM中删除它,则不必重新调用插件,因为插件仍将保存在元素上。
答案 1 :(得分:1)
由于您不希望.off()从其他页面中删除您的事件,我建议您为事件使用命名空间。例如,像这样:
function myClass(pageno) {
var pref_ev = 'mypage' + pageno + '.' + 'change';
$(document).off(pref_ev).on(pref_ev, ".mydropdowns", function(e) {
self.submitDescriptionChange(this);
});
}
这样,每个页面都会有自己的“更改”事件,例如“mypage1.change”。该事件仍然正常注册为更改事件;前缀命名空间“mypage1”仅用于对正确的事件执行.off()调用。