Почему эта переменная подсказка в моей функции jQuery работает в Chrome, но не в Firefox?

Я сталкиваюсь с этой причудой между тем, как Chrome и Firefox выполняют эту функцию, но я не могу понять, почему Firefox не будет выполняться. У меня есть флажки, для которых функция прослушивает любые изменения в любом флажке, а затем выполняет некоторый текст для отображения. Но для одного флажка я хотел бы прервать обычный текст и выполнить какое-то регулярное выражение перед его завершением. Итак, у меня есть прослушиватель событий mousedown, который пытается получить этот эффект. Мое обоснование заключается в том, что mousedown будет выполнять код до события изменения checkbox (не уверен, что это верно для всех браузеров).

Странность возникает, когда во время этой функции mousedown переменная с именем amt требует значения. Если переменная amt введена через диалоговое окно подсказки, Firefox не выполнит остальную часть функции. Если вместо этого та же самая переменная amt вводится через элемент <input>, функция работает нормально. В 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>

person user1837608    schedule 25.10.2015    source источник
comment
не имеет смысла отключать его ... предотвращает изменение. Начните с объяснения, почему вам нужно сделать отключение в первую очередь. Логику трудно понять   -  person charlietfl    schedule 25.10.2015


Ответы (1)


На самом деле код ниже подсказки выполняется, как и ожидалось. Проблема заключается в том, что подсказка предотвращает событие изменения по умолчанию для флажка. Таким образом, строка не добавляется в конец вывода.

Почему так тяжело?

Если вам нужна отдельная логика события изменения для первого флажка, просто сделайте это и переместите общий код в отдельную функцию:

Скрипка

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);
});

И более короткая версия с одним обработчиком изменений:

Скрипка

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();
    }
});
person ataman    schedule 25.10.2015
comment
Ладно, кажется, я вижу, что ты сделал. Вы разделили событие изменения checkbox для dxOut100 и всех остальных флажков. Таким образом, проблема с событием приглашения, нарушающим событие изменения, сводится на нет. Но что, если есть разные элементы, где пользователю может понадобиться подсказка? Нужно ли создавать блок кода для каждого особого случая, а затем отдельный блок, исключающий каждое особое обстоятельство? - person user1837608; 25.10.2015
comment
Наличие «блока кода» для каждого случая, когда логика должна отличаться, звучит разумно. На самом деле, вы пытались сделать то же самое, я просто сделал ваш код более понятным и понятным и удалил хаки. Конечно, есть еще много возможностей для оптимизации. Добавил еще одну итерацию в конец ответа. - person ataman; 25.10.2015
comment
Спасибо за отзыв, я ценю это. - person user1837608; 27.10.2015