【问题标题】:Why does this variable prompt in my jQuery function work in Chrome but not Firefox?为什么我的 jQuery 函数中的这个变量提示在 Chrome 中有效,但在 Firefox 中无效?
【发布时间】:2015-10-25 02:24:29
【问题描述】:

我在 Chrome 和 Firefox 如何执行此功能之间遇到了这个怪癖,但我无法弄清楚为什么 Firefox 不会执行。我有复选框,函数监听任何复选框中的任何更改,然后执行一些文本以显示。但是,对于一个复选框,我想打断通常的文本并在完成之前对其进行一些正则表达式。所以,我有一个mousedown 事件监听器,它试图获得这种效果。我的理由是mousedown 将在checkbox 更改事件之前执行代码(不确定这是否适用于所有浏览器)。

当在这个mousedown 函数中,一个名为amt 的变量需要一个值时,就会出现奇怪的情况。如果通过提示对话框输入变量amt,Firefox 将不会执行该函数的其余部分。相反,如果通过<input> 元素输入相同的变量amt,则该函数可以正常工作。在 Chrome 中,使用任何一种方法都可以获得相同的结果。

谁能解释一下区别以及是否有更好的方法来“暂停”一个函数,以便另一个函数可以在完成之前运行?

这里有一个小提琴:http://jsfiddle.net/ufgvoghw/7/

JS

dxOuts = {
    dxOut100: 'ITEM #0:',
    dxOut101: 'ITEM #1:',
    dxOut102: 'ITEM #2: '
};
var final = '';
var sel = null;

$('#_box0').mousedown(function () {
    $('#dxOut100').prop('disabled', true); // <-- disable checkbox to ensure click event doesn't take place when label mousedown occurs
   //  var amt = prompt('Enter amount'); //<-- this doesn't work in firefox, but works in chrome
    var amt = $('#amt').val(); //<-- this works in FF and chrome
    dxOuts.dxOut100 = dxOuts.dxOut100.replace(/#[\d*(?=\d)]/, '#'+amt);
    $('#dxOut100').prop('disabled', false).trigger('click');
});
function printf(){
    final += dxOuts[sel] + '\n\n';
    $('#output').val(final);
}

$('input:checkbox').on('change', function () {
    if($(this).is(':checked')){
    sel = $(this).attr('id');
    printf();

    }
});

HTML

<label id="_box0">
    <input type='checkbox' id='dxOut100'>ITEM #</label>
<input id="amt" size=5>
<br>
<label id="_box1">
    <input type='checkbox' id='dxOut101'>ITEM #1</label>
<br>
<label id="_box2">
    <input type='checkbox' id='dxOut102'>ITEM #2</label>
<br>
<br>
<textarea id='output' cols=25 rows=5></textarea>

【问题讨论】:

  • 禁用它没有意义...阻止更改。首先解释为什么您需要首先进行禁用。逻辑难懂

标签: jquery firefox jquery-events prompt mousedown


【解决方案1】:

实际上,提示下方的代码正在按预期执行。问题是提示阻止了复选框的默认更改事件发生。所以字符串不会添加到输出的末尾。

为什么这么难?

如果您想为第一个复选框单独更改事件逻辑,只需执行此操作,并将公共代码移动到单独的函数:

Fiddle

var dxOuts = {
    dxOut100: 'ITEM #0:',
    dxOut101: 'ITEM #1:',
    dxOut102: 'ITEM #2: '
};
var final = '';
var sel = null;

function printf(){
    final += dxOuts[sel] + '\n\n';
    $('#output').val(final);
}

//common code to call for all checkboxes
function checkboxCnahged(e) {
    var checkBox = $(e.target);

    if(checkBox.is(':checked')){
        sel = checkBox.attr('id');
        printf();
    }
}

$('#dxOut100').change(function (e) {
    if ($(e.target).is(':checked')) { // show prompt only if checked
        var amt = prompt('Enter amount'); // <-- now this works
        //var amt = $('#amt').val(); //<-- this works in FF and chrome
        console.log(amt);
        dxOuts.dxOut100 = dxOuts.dxOut100.replace(/#\d*/, '#' + amt); //fixed the regex to replace the whole number, not only the first digit
    }
    checkboxCnahged.apply(this, arguments);
});

$('input:checkbox:not(#dxOut100)').on('change', function () {
    checkboxCnahged.apply(this, arguments);
});

以及带有一个更改处理程序的较短版本:

Fiddle

var dxOuts = {
    dxOut100: 'ITEM #0:',
    dxOut101: 'ITEM #1:',
    dxOut102: 'ITEM #2: '
};
var final = '';
var sel = null;

function printf(){
    final += dxOuts[sel] + '\n\n';
    $('#output').val(final);
}

$('input:checkbox').change(function (e) {
    if ($(e.target).is(':checked')) { // show prompt only if checked
        if (e.target.id === 'dxOut100') {
          var amt = prompt('Enter amount'); // <-- now this works
          dxOuts.dxOut100 = dxOuts.dxOut100.replace(/#\d*/, '#' + amt); 
        }

        sel = e.target.id;
        printf();
    }
});

【讨论】:

  • 好的,我想我明白你做了什么。您已将 checkbox 更改事件与 dxOut100 和所有其他复选框分开。因此,提示事件中断更改事件的问题无效。但是,如果存在用户可能需要提示的不同元素怎么办?我是否需要为每个特殊情况创建一个代码块,然后再为每个特殊情况创建一个单独的代码块?
  • 对于每个逻辑应该不同的情况都有一个“代码块”听起来很合理。实际上,您也尝试过这样做,我只是让您的代码更加清晰和直接,并删除了黑客。当然,还有很大的优化空间。在答案末尾添加了一个迭代。
  • 感谢您的反馈,非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-27
  • 1970-01-01
相关资源
最近更新 更多