【问题标题】:JavaScript (JQuery): Cancelling a selection in select control in FireFoxJavaScript (JQuery):在 FireFox 中取消选择控件中的选择
【发布时间】:2015-08-25 15:26:47
【问题描述】:

在我的应用程序中,我有一个<select> 控件列表。 在用户确认后才能更改每个控件中的选择。所以我是这样处理的:

<select onchange="changeSelect(this)" onmousedown="clickSelect(this)">
    <option value="1" selected="true">A</option> // here is 'default' value 1
    <option value="2" >B</option>
</select>

<select onchange="changeSelect(this)" onmousedown="clickSelect(this)">
    <option value="1" >A</option>
    <option value="2" selected="true">B</option> // here is 'default' value 2
</select>

// more select controls with arbitrary 'default' values, they can be added and removed dynamically

当用户单击选择选择另一个选项时,clickSelect(this) 方法会保存当前选择的(旧)选择:

function clickSelect(select) {
    globalScope.previouslySelected = $(select).val();
}

而现在,如果用户真的想改变选择,我要求用户确认,如果她不确认,我使用保存的值恢复之前的状态:

function changeSelect(select) {
    var response = confirm("Current changes to the threat log will be lost. Continue anyway?");
        if (response == false) {
            // change it back
            $(select).val(globalScope.previouslySelected);
            return;
        }
    }
}

现在,在 IE、Chrome 和 Opera 上运行良好。但是,当我使用 Firefox 时,它不起作用。原因是 FF 在选择期间调用了两次onmousedown 处理程序——第一次是当用户单击以向下滚动选择控件时,第二次是当她选择新的选择时。因此,最后一次记住的值 globalScope.previouslySelected 将成为新的选定值,而不是真正的旧值,就像在其他浏览器中一样。

我知道使用全局变量被认为是不好的做法。这不是这里的问题。使用任何其他存储将无法正常工作。

我现在唯一的想法是在 clickSelect(select) 处理程序中编写一段 Firefox 特定的代码并忽略第二个通知。但是,由于某种原因,我在堆栈溢出中发现的以下代码不起作用:

if($.browser.mozilla) {
     console.log("Olalala");
}

例如,在 Chrome 中它会抛出以下异常:

Uncaught TypeError: Cannot read property 'mozilla' of undefined

那么我怎样才能让它工作,以便 ti 只能在 FF 中运行?或者,如果你们中的任何人对确认问题有更好的解决方案,我很乐意听到。请记住,有一组动态的选择控件,而不仅仅是一个。它必须对所有人都有效。此外,它们可以动态添加或删除,因此在单个页面请求中,它们的数量可能会有所不同。用户使用单个选择控件加载页面,按下“+”按钮并添加另一个选择控件等,但解决方案必须与所有控件统一工作。

【问题讨论】:

    标签: javascript jquery firefox


    【解决方案1】:

    您使用 onmousedown 侦听器保存当前选择的选项是否有特定原因?您只需初始化全局变量以保存默认选项,并在做出新选择时更新它。

    类似这样的:

    HTML

    <select id="mySelect" onchange="changeSelect(this)">
        <option value="1" >A</option>
        <option value="2" >B</option>
    </select>
    

    JS

    var globalScope = {previouslySelected: $("#mySelect").val()};
    function changeSelect(select) {
        var response = confirm("Current changes to the threat log will be lost. Continue anyway?");
        if (response == false) {
            // change it back
            $(select).val(globalScope.previouslySelected);
            return;
        }
    
        globalScope.previouslySelected = $(select).val();
    }
    

    编辑

    我注意到在 Firefox 上,第二个 mousedown 事件的目标是选项,所以在这种情况下,您可以使用以下代码忽略该事件:

    $("select").mousedown(function(e) {
        if ($(e.target).is('option'))
            return;
    
        globalScope.previouslySelected = $(this).val();
    });
    

    使用此代码,您可以从 DOM 中删除 onmousedown 注册。

    【讨论】:

    • 听起来不错。您可以通过 onChange 事件完成所有操作。
    • 没有。所有选择控件都没有一个默认选项。第一个控件可以从值 1 开始,第二个控件可以从值 2 开始,等等。为每个选择控件设置一个变量会导致代码更复杂。将编辑问题以使其更清晰。
    • 我可以想象它可以按照你的方式完成。但是,如果可以仅确定代码是否在 FF 上运行,我想我需要对我的代码做的就是添加几行代码。不是一个非常强大的解决方案,但可以工作。
    • 我真的认为编写代码来专门识别和处理 FF 是一个坏主意。我编辑了我的答案以包含另一个应该适用于所有浏览器的解决方案,并且不涉及为每个选择保存一个变量。
    • 谢谢,正是我需要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    • 2017-03-17
    • 1970-01-01
    相关资源
    最近更新 更多