我想知道这里是否有人可以帮助我解决这个问题。
我需要暂时禁用输入字段的'onblur'属性中的代码,然后重新启用它。我需要这样做的原因是b / c我的工作流程如下:
1)AJAX事件由输入字段的“onblur”属性触发,该属性是由用户从字段中跳出来转到下一个字段。
2)页面更新,我的Javascript代码从“ onafterajax ”挂钩调用。
3)我的代码严重重新安排了DOM,导致失去对当前输入字段的关注。所以,我必须手动恢复焦点。我已将焦点处理程序附加到所有输入字段,因此我可以跟踪哪个字段最后具有焦点,因此我知道将焦点放在何处。
4)我在正确的输入字段上调用 .focus(),由于某种原因导致' onblur '在同一输入字段上触发。这种情况发生在所有浏览器这a)表明该领域仍然有焦点?!和b)创建一个无限循环,因为步骤1再次执行...
为了避免无限循环,我做了以下几点。在执行任何DOM重新排列之前,我这样做:
if ( window.currentFocusId ) {
this.savedFocusId = currentFocusId;
this.onblur_bak = $(this.savedFocusId).onblur;
$(this.savedFocusId).onblur = null;
LOG.warn(" --- Disabling blur on " + this.savedFocusId);
}
然后,在我完成DOM hackery之后,我这样做了:
setFocusAndRestoreBlur : function(req) {
if ( this.savedFocusId ) {
var focusElement = req.form.elements[this.savedFocusId];
LOG.warn(" ------ Focusing on " + focusElement.id);
if (focusElement) {
focusElement.focus();
if (focusElement.select) {
focusElement.select();
}
}
LOG.warn(" --- Enabling blur on " + this.savedFocusId);
$(this.savedFocusId).onblur = this.onblur_bak;
delete this.onblur_bak;
delete this.savedFocusId;
}
}
除IE6外,这适用于所有浏览器(FF,Chrome,Opera)。
在IE6中,有点有效。首先,为了使它在IE中工作,我不得不像以下那样修改对“ setFocusAndRestoreBlur ”的调用:
setTimeout(function() {
this.setFocusAndRestoreBlur(req);
}.bind(this), 0)
这具有在当前线程完成后运行代码的效果。出于某种原因,IE不尊重我已经删除了 onblur 处理程序的事实,如果我尝试将焦点设置在同一个线程中!
所以,通过这个修改,我第一次在几个字段中输入一些数字,一切都很好。我得到的日志输出如下:
输入内容 j_id390 并关闭标签:
warn[16:35:33,091]: blur fired from statementProgramsDataTable:0:j_id390
warn[16:35:33,092]: --- Disabling blur on statementProgramsDataTable:0:j_id397
warn[16:35:33,225]: ------ Focusing on statementProgramsDataTable:0:j_id397
warn[16:35:33,225]: --- Enabling blur on statementProgramsDataTable:0:j_id397
输入内容 j_id397 并关闭标签:
warn[16:35:38,259]: blur fired from statementProgramsDataTable:0:j_id397
warn[16:35:38,260]: --- Disabling blur on statementProgramsDataTable:0:j_id446
warn[16:35:38,390]: ------ Focusing on statementProgramsDataTable:0:j_id446
warn[16:35:38,390]: --- Enabling blur on statementProgramsDataTable:0:j_id446
然而,当我回到第一个输入字段时,覆盖值并关闭标签,我得到了这个:
warn[17:18:15,454]: blur fired from statementProgramsDataTable:0:j_id390
warn[17:18:15,469]: --- Disabling blur on statementProgramsDataTable:0:j_id397
warn[17:18:16,870]: ------ Focusing on statementProgramsDataTable:0:j_id397
warn[17:18:16,874]: --- Enabling blur on statementProgramsDataTable:0:j_id397
warn[17:18:18,097]: blur fired from statementProgramsDataTable:0:j_id397
warn[17:18:18,112]: --- Disabling blur on statementProgramsDataTable:0:j_id397
warn[17:18:19,550]: ------ Focusing on statementProgramsDataTable:0:j_id397
warn[17:18:19,555]: --- Enabling blur on statementProgramsDataTable:0:j_id397
warn[17:18:24,492]: blur fired from statementProgramsDataTable:0:j_id397
warn[17:18:24,187]: --- Disabling blur on statementProgramsDataTable:0:j_id397
warn[17:18:24,531]: ------ Focusing on statementProgramsDataTable:0:j_id397
warn[17:18:24,545]: --- Enabling blur on statementProgramsDataTable:0:j_id397
大多数情况下,此循环会继续进行可变数量的迭代,然后在输入字段正确聚焦的情况下停止。我已经看过几次循环似乎是无限的。
看起来IE不再尊重缺少 onblur 处理程序了吗?但有时候只是?!
所以,这是我感到困惑的地方。为什么IE表现不一致?我究竟做错了什么?还有更好的方法吗?
任何想法都会受到赞赏。
缬氨酸
编辑:
我尝试过JeanK建议的方法。它仍然不起作用,但我从这次尝试中学到了一些可能有用的东西。
我用代理包装原始'onblur'函数,如下所示:
this.allowBlur = false;
if ( !this._functionsEqual($(this.savedFocusId).onblur, this._proxiedBlur) ) {
$(this.savedFocusId).onblur = this.proxyOnBlur($(this.savedFocusId).onblur);
}
代理功能本身:
proxyOnBlur : function(method) {
var object = this;
this._proxiedBlur = function(event) {
if ( object.allowBlur ) {
return method.apply(this, [event || window.event])
}
};
return this._proxiedBlur;
},
现在,我所要做的就是将 this.allowBlur 设置为最后一件事,我应该没问题。这就是问题所在。在所有其他浏览器中,onblur事件在我修改DOM树时被触发,因此它被正确阻止。但是在IE6中,无论我做什么,它都会在所有代码之后触发onblur事件。我甚至试过这个:
setTimeout(function() {
this.allowBlur = true;
}.bind(this), 2)
我将this._proxiedBlur设置为true后仍会被调用!
所以,问题变成了 - 我需要在哪里重置标志,以便在IE6对DOM更改做出反应后执行?
答案 0 :(得分:1)
setTimeout(function() {
this.setFocusAndRestoreBlur(req);
}.bind(this), 0)
然后使用另一个嵌套的 setTimeout()重置该标志。这似乎在IE6中正确地对事件进行了排序:
setFocusAndRestoreBlur : function(req) {
setFocus(req);
setTimeout(function() {
this.allowBlur = true;
}.bind(this), 0)
}
答案 1 :(得分:0)
我建议您以逻辑方式禁用模糊。
我的意思是,像这样:
假设这是你的onblur事件函数,你可以通过flags控制它:
function myOnBlur() {
if (ableToExecute) {
executeWhatYouNeed();
}
}
因此,当您执行请求时,将标志设置为false,然后在响应和所需处理之后,将平面重置为true,这样您的onblur事件就可以再次触发您的请求。
我不知道这个简单的控件是否可以帮到你,但你可以尝试一下。