通过 jQuery 在文本输入字段中选择文本会导致其他元素需要双击而不是单击才能触发?

Selecting text in a text input field via jQuery causes other elements to require double click instead of single click to fire?

我有一个 jquery 函数,所以每当 <input type="text"> 元素成为焦点时,其中的所有文本都会被选中。

$('input[type=text]').focusin(function(e) {
    // Selects all text on text field focus
    $(this).select();

});

到目前为止,还不错。页面的其他地方是一个复选框,通过一些花哨的 CSS 伪装成切换开关,使用 topcoat css 库。这是拨动开关的样子:

http://topcoat.io/switch/

当我单击或按 Tab 键进入文本框时,所有文本都按预期被选中。但是,如果我随后单击拨动开关,它就不会触发。我必须双击才能使其工作。它应该只需要单击一下。如果我点击文本框外的页面背景,切换开关将恢复为只需要单击一次。如果我重新加载页面,并且不点击任何文本框,切换开关会正常工作,只需要单击一次。奇怪的是,如果我从 jQuery 函数中删除 $(this).select(); 行,切换开关就会再次正常工作。

这是HTML的结构:

<div class="section-wrapper">

    <div class="section">
        <div class="trough">
            <label class="topcoat-switch">
                <input type="checkbox" class="topcoat-switch__input">
                <div class="topcoat-switch__toggle"></div>
            </label>
        </div>
    </div>

    <div class="section-contents">
        <!-- Input text fields are in here, buried in some more divs -->
    </div>

</div>

为了深入挖掘,我编写了一个小函数来跟踪哪些元素正在注册点击。

$('div, input').on('click', function(e) {
    console.dir(e.currentTarget);
})

当按预期工作时,在关注任何文本框之前,这是单击切换开关时鼠标单击传播的样子:

input.topcoat-switch__input
div.trough
div.section
div.section-wrapper
div.container-inner
div.container

需要注册点击的关键元素是输入元素: input.topcoat-switch__input

不出所料,鼠标点击记录在最深的元素中,并向外传播。但是,在我单击一个文本框然后单击切换开关后,鼠标传播堆栈如下所示:

div.topcoat-switch__toggle
div.trough
div.section
div.section-wrapper
div.container-inner
div.container

输入元素不见了,需要双击注册。而不是输入注册,似乎 div.topcoat-switch__toggle 元素(输入的同级元素)正在注册。

我该怎么做才能保持专注于文本输入时选择所有文本的功能,并修复奇怪的鼠标点击注册行为?

正如 Anthony McGrath 所指出的,问题在于文本选择输入干扰了用于使切换开关起作用的 CSS 样式。 topcoat.io 切换开关样式依赖于 input: focusinput:activeinput:checked 选择器才能正常运行,文本的选择会干扰这些选择器。

我通过向每个文本框的 focusOut 事件添加一个 clearSelection() 函数解决了这个问题。我使用的清除选择功能由 Tim Down 提供: