征象
IE这货果真异乎寻常,当光标核心在input时,点击同页面内其他地区的scrollbar,会致使核心挪动到body,从而触发绑定在input上的blur事宜,假如input中的值与之前差别,以至还会触发change事宜…
Chrome曾也有相似的题目,但在最新版中已修改了,而Firefox则完整没有如许的题目。
影响
这个题目看起来眇乎小哉,实际上影响照样非常大的,重要表现在下面2个方面
多半的suggest控件会失足
suggest往往是经由过程input(输入部份)和div(下拉框部份)构成。偶然,下拉框内容过量,用户须要挪动滚动条才能看全选项,但由于点击滚动条会让input落空核心,致使控件误认为用户完毕输入,从而封闭suggest的下拉部份,致使用户实际上没法准确的举行滚动条操纵。
form
这个更轻易理解了,一般来说form的考证都是绑定在blur或许change事宜上,假如form太长,须要挪动滚动条才能看全的情况下,一旦鼠标点击滚动条就会毛病的触发form考证操纵,将无用的毛病信息显现给用户。
处置惩罚方案
我们来看看jQueryUI的Autocomplete是怎样处置惩罚这个题目的。
// input's blur event
blur: function( event ) {
if ( this.cancelBlur ) {
delete this.cancelBlur;
return;
}
clearTimeout( this.searching );
this.close( event );
this._change( event );
}
// dropdown's mousedown event
mousedown: function( event ) {
// prevent moving focus out of the text field
event.preventDefault();
// IE doesn't prevent moving focus even with event.preventDefault()
// so we set a flag to know when we should ignore the blur event
this.cancelBlur = true;
this._delay(function() {
delete this.cancelBlur;
});
// clicking on the scrollbar causes focus to shift to the body
// but we can't detect a mouseup or a click immediately afterward
// so we have to track the next mousedown and close the menu if
// the user clicks somewhere outside of the autocomplete
var menuElement = this.menu.element[ 0 ];
if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
this._delay(function() {
var that = this;
this.document.one( "mousedown", function( event ) {
if ( event.target !== that.element[ 0 ] &&
event.target !== menuElement &&
!$.contains( menuElement, event.target ) ) {
that.close();
}
});
});
}
}
这下就很清晰了,要处置惩罚这个题目,要点有两个:
经由过程自定义的flag推断是不是须要跳过(直接return)input的blur事宜
全局(document)看管下一次mousedown事宜,假如不是特定地区才实行blur相干操纵