Javascript 在滚动条上单击关闭下拉插件
我正在自学如何编写jQuery插件。我将使用作为基本示例。不过,这不仅仅是复制/粘贴,我还做了一些修改,试图更好地理解这一切。例如,我没有合并Javascript 在滚动条上单击关闭下拉插件,javascript,jquery,Javascript,Jquery,我正在自学如何编写jQuery插件。我将使用作为基本示例。不过,这不仅仅是复制/粘贴,我还做了一些修改,试图更好地理解这一切。例如,我没有合并hover事件,我添加了一个过滤器,目前没有使用任何默认值来命名一些。这是我找到的唯一一篇解决这个问题的好文章,我尝试了一些类似的方法,但没有成功 完整示例: 问题: 我点击输入,下拉菜单打开,但第一次点击滚动条时,下拉菜单关闭。当我再次打开下拉列表并单击滚动条时,它不会关闭(正如我所期望的那样)。据我所知,我的问题在于输入上的模糊。我知道当我点击滚动条时
hover
事件,我添加了一个过滤器,目前没有使用任何默认值来命名一些。这是我找到的唯一一篇解决这个问题的好文章,我尝试了一些类似的方法,但没有成功
完整示例:
问题:我点击
输入
,下拉菜单打开,但第一次点击滚动条时,下拉菜单关闭。当我再次打开下拉列表并单击滚动条时,它不会关闭(正如我所期望的那样)。据我所知,我的问题在于输入
上的模糊
。我知道当我点击滚动条时,输入
失去焦点。我试图在上实现类似于本文的东西,但无法使其工作
复制步骤:
输入
打开下拉列表输入
,下拉菜单打开当我第一次点击滚动条时,下拉菜单关闭的原因是什么 我所尝试的:
当我将
ul
附加到div
(目前在jsFiddle的第68行注释掉)时,我添加了下面的代码。我想,如果我用ul
上的mousedown
停止触发该操作,就会解决我的问题。虽然它在Chrome中解决了这个问题,但在IE8中仍然存在
更新:我将下面的代码从$list.mousedown…
更改为$container.mousedown…
,因为$list
是ul
,而$container
是包含它的div
。我的想法是它扩大了这个区域。结果是一样的
...
$container.append($list);
$list.mousedown(function(e) {
e.preventDefault();
});
...
由于这似乎很接近,我尝试在blur
事件中采用类似的方法。当我使用这段代码时,上面解释的问题就会发生。在Chrome中,单击滚动条不会触发blur
事件,但在IE8中会触发。第一次打开下拉列表并单击滚动条时,它会记录“隐藏”。再次打开下拉列表,单击滚动条,它会记录“绑定鼠标向下”。单击下拉列表之外的任何位置,它将关闭(应关闭)并记录“隐藏”(应关闭)。对我来说,这似乎是倒退,但显然我没有正确地理解它。(下面的代码在JSFIDLE的第134行附近)
代码编辑:更新为以防止发生多个绑定
...
// where $dom is the 'div' containing the 'ul'
$dom.unbind('mousedown.auto_dropdown_box_ul')
.bind('mousedown.auto_dropdown_box_ul', function(e) {
console.log('bind mousedown');
e.preventDefault();
});
setTimeout(function() {
console.log('hiding');
$dom.addClass('auto_dropdown_hide').hide();
}, 100);
...
我还尝试删除了blur
事件。我知道,如果您将标签从输入中移出,这将阻止下拉列表关闭,但我认为值得一试。在Chrome中,它的工作方式与我预期的完全相同,在输入
外部单击关闭下拉列表,单击滚动条不关闭下拉列表,而弹出选项卡不关闭下拉列表。在IE8中,在下拉列表外单击不会关闭它,当您退出tab时也不会关闭它,但在滚动条中单击会起作用。这是我在删除blur
后添加的代码(它不包含在JSFIDLE中)
再一次,这是我的第一次尝试,我还在学习。我确信有很多事情我可能做错了,我可以改进,等等。在我解决这些问题之前,我只想了解我做错了什么,以及我需要做什么来纠正它。阅读后,我知道有很多东西需要我学习。我第一次看时发现一些问题,您应该更改:
$dom.bind('mousedown.auto_dropdown_box_ul'
致:
为了防止多个事件绑定到dom节点,还可以使用jQuery的.one事件处理。
在相同的事件处理中,您还应:
console.log('bind mousedown');
e.preventDefault();
return false;
确保事件未触发
希望这有帮助(我已经很久没有IE8了)我相信我终于找到了这个答案。在多次尝试之后,我想我应该把格式改成一种更直接的格式,至少对我来说是这样
这是完整的
基本解决方案是正确设置/调整哪个元素具有焦点以及何时具有焦点。由于mousedown
是在单击之前执行的,因此我在下拉列表中保留了该事件。在mousedown
事件中,我设置了isVisible=true
,并将焦点放回到输入上(尽管后者并非完全必要)。在blur
事件中,我正在检查isVisible
。如果是真的,这意味着在滚动条中发生了单击,因此不要关闭下拉列表。如果为false,请关闭下拉列表。在整个事件中,我一直跟踪isVisible
,因此我知道执行blur
时它的状态。再次,我改变了格式,使两个小提琴看起来不同。我相信我可以回去实现一些类似于最初的小提琴的东西,让它工作,但我更喜欢这种方式。以下是相关更改的片段:
{
// some code above
// where $list is the 'ul'
$list.bind('mousedown', methods.onDropdownMousedown);
// where $obj is the 'input'
$obj.bind('blur', methods.doOnBlur);
},
onDropdownMousedown: function(e) {
$input.focus(); // not really needed, just in case
isVisible = true;
},
doOnBlur: function(e) {
if (isVisible) {
$input.focus();
isVisible = false;
} else {
// where $container is the 'div' containing the list
$container.addClass('auto_dropdown_box_hide').hide();
isVisible = false;
}
isVisible = false;
}
谢谢你的建议。防止多事件绑定是我试图解决的另一个问题,您的建议确实解决了这一问题。我尝试了.one
事件和您建议的更改,但不幸的是,问题(第一次单击滚动条时关闭)仍然存在。但是请注意,我非常感谢您解释如何解决多事件绑定!
console.log('bind mousedown');
e.preventDefault();
return false;
{
// some code above
// where $list is the 'ul'
$list.bind('mousedown', methods.onDropdownMousedown);
// where $obj is the 'input'
$obj.bind('blur', methods.doOnBlur);
},
onDropdownMousedown: function(e) {
$input.focus(); // not really needed, just in case
isVisible = true;
},
doOnBlur: function(e) {
if (isVisible) {
$input.focus();
isVisible = false;
} else {
// where $container is the 'div' containing the list
$container.addClass('auto_dropdown_box_hide').hide();
isVisible = false;
}
isVisible = false;
}