简体   繁体   English

jQuery focus()事件的无限循环 <select>元件

[英]Infinite loop of jQuery focus() event with a <select> element

I have this HTML: 我有这个HTML:

<select id="select-one">
    <option value="">Choose</option>
    <option value="1">House</option>
</select>

<select id="select-two">
    <option value="">Choose</option>
    <option value="A">Table</option>
</select>

And this Javascript with JQuery 而这个Javascript与JQuery

$("#select-two").focus( function() {

    if( $("#select-one").val() == "" ) {
        alert("Fill select-one first!");
        return false;
    }

});

So i am getting a infinite loop with alerts because after call alert() Javascript puts the focus again in the same select (select-two). 所以我得到了一个带有警报的无限循环,因为在调用alert() Javascript将焦点再次放在同一个select(select-two)中。

Someone can help me to solve this please? 有人可以帮我解决这个问题吗?

Note : based on your comments, this assumes you must listen to the focus event. 注意 :根据您的评论,这假设您必须听取焦点事件。


Solution 1 - using blur() - effective but buggy in Chrome 解决方案1 ​​ - 使用blur() - 在Chrome中有效但有缺陷

In theory, the focus event is not cancelable, so return false or event.preventDefault() will have no effect in this case. 理论上, focus事件不可取消,因此return falseevent.preventDefault()在这种情况下不起作用。 However, in practice, you can reverse the event by using the blur() method. 但是,实际上,您可以使用blur()方法来反转事件。

For example: 例如:

$('#select-two').on('focus',function () {
    if ($("#select-one").val() == "") {
        $(this).blur();
        alert('Fill select-one first!');
        return false;
    }
});

See jsFiddle demo 请参阅jsFiddle演示

This effectively prevents the field from regaining focus after the alert call and so the focus event is not repeated. 这有效地防止了场地在alert呼叫之后重新获得焦点,因此不重复focus事件。 The only problem is that in Chrome even though the field is not focused anymore, the dropdown remains open (see demo). 唯一的问题是,在Chrome中,即使该字段不再聚焦,下拉列表仍然保持打开状态(请参阅演示)。


Solution 2 - using remove() and clone() - costly but cross-browser 解决方案2 - 使用remove()clone() - 昂贵但跨浏览器

If Chrome's behavior is problematic, you can take a more crude approach, whereby you remove() the select from the DOM, clone() it and then reinsert it into the DOM. 如果Chrome的行为有问题,您可以采取更粗略的方法,从而从DOM中remove() selectclone()它然后将其重新插入DOM。 This will effectively "reset" the select element completely, leaving it without focus as well as closed. 这将有效地“重置” select元素,使其无焦点和关闭。

For example: 例如:

$(document).on('focus','#select-two',function (e) {
    if ($("#select-one").val() == "") {
        $(this).remove().clone().insertAfter('#select-one');
        alert('Fill select-one first!');
        return false;
    }
});

See jsFiddle demo 请参阅jsFiddle演示

The upside of this approach is that it works well in Chrome too. 这种方法的好处是它在Chrome中也能很好地运行。 The downside of this approach is that it involves manipulating the DOM for a very trivial issue. 这种方法的缺点是它涉及操纵DOM以解决一个非常微不足道的问题。

I think you need an extra event that change content select-two when the value of select-one has "" like this: 我认为你需要一个额外的事件来改变内容选择 - 当select-one的值有这样的“”时:

HTML HTML

<select id="select-one">
    <option value="">Choose</option>
    <option value="1">House</option>
</select>

<select id="select-two">
    <option value="">Choose</option>
    <option value="A">Table</option>
</select>

JS JS

$("#select-one").change(function() {
    if ($(this).val() == "") {
        $("#select-two").val("");
    }
});

$("#select-two").focus(function() {
    if( $("#select-one option:selected").val() == "" ) {
        alert("Fill select-one first!");
        $("#select-one").focus();
        return false;
    }
});

Demo 演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM