Событие фокуса Javascript/jQuery, которое изменяет макет, приводит к тому, что событие щелчка не срабатывает

У меня есть поле, которое, когда вы оставляете на нем фокус, меняет макет страницы. У меня также есть кнопки на странице, которые отправляют мою форму.

Если я зайду в свое поле и введу значение, а затем нажму кнопку, событие нажатия кнопки никогда не сработает. Похоже, это происходит из-за того, что макет меняется до запуска события click, что означает, что кнопка меняет местами. К тому времени, когда срабатывает событие click, оно срабатывает на пустой области, а не на кнопке.

Вот jsfiddle проблемы: http://jsfiddle.net/xM88p/

Я нашел способ решить эту проблему для IE, но после обширных исследований я не могу найти/получить доступ к тому же объекту в FF/Chrome:

//only works in IE

if(event.originalEvent.toElement){
  $("#"+event.originalEvent.toElement.id).click();
}

person codewarrior    schedule 20.08.2013    source источник
comment
В чем разница между исправлением IE и запуском клика вручную: $("#btn_test").click(); ? Я имею в виду, почему одно предпочтительнее другого? (Почему бы просто не вызвать щелчок?)   -  person cssyphus    schedule 20.08.2013
comment
На странице есть несколько кнопок и ссылок, которые могут повлиять на это, поэтому мне нужно знать идентификатор элемента, который пользователь только что щелкнул, чтобы убедиться, что я запускаю правильный.   -  person codewarrior    schedule 20.08.2013


Ответы (1)


http://jsfiddle.net/xM88p/2/

Используйте mousedown вместо click:

$("#btn_test").on('mousedown', function (event){
    alert("clicked!"); 
});

$('#test').focusout(function (event){
    $('<p>Test</p>').insertAfter(this);
});

Изменить

Хорошо, я стал немного изобретательнее с обработчиками событий. Новое решение отслеживает события mousedown/mouseup, а также положение щелчка. Он использует эти значения, чтобы проверить, должно ли нажатие мыши вызывать оповещение.

var testClicked = false;
var lastX, lastY;

$(document).on('mouseup', function (event) {
    if (testClicked === true && lastX === event.clientX && lastY === event.clientY) {
        alert("clicked!"); 
    }
    testClicked = false;
    lastX = null;
    lastY = null;
});

$("#btn_test").on('mousedown', function (event){
    testClicked = true;
    lastX = event.clientX;
    lastY = event.clientY;
});

$('#test').focusout(function (event){
    $('<p>Test</p>').insertAfter(this);
});
person Fuzzley    schedule 20.08.2013
comment
обычно мы используем mouseup, поэтому, если пользователь что-то забывает, он знает, что нужно перетащить мышь за элемент, чтобы отменить щелчок. - person pythonian29033; 20.08.2013
comment
Моя проблема похожа на питонианцев: если пользователь нажимает кнопку, но держит мышь нажатой (и решает, что больше не хочет нажимать кнопку), он должен иметь возможность перетащить мышь, не отправляя форму. - person codewarrior; 20.08.2013
comment
Это правда, но это немного частный случай. Принудительное нажатие триггера кажется худшим решением, чем просто использование мыши. - person Fuzzley; 20.08.2013
comment
Я согласен с вами, mousedown определенно кажется лучшим решением из двух. Я просто надеялся, что есть способ сохранить возможность нажимать мышь и перемещать мышь от кнопки, а не запускать отправку формы, хотя похоже, что это может быть невозможно. - person codewarrior; 20.08.2013
comment
Проблема в том, что невозможно определить, намеренно ли пользователь отодвинул мышь перед тем, как отпустить ее, или отодвинулась ли сама кнопка от мыши. Могут быть более творческие решения, но любое решение, включающее обработчики событий, должно будет устранить это несоответствие. - person Fuzzley; 20.08.2013
comment
Хорошо, я пересмотрел свое решение. Кажется, это делает то, что вы хотите, не лишая преимущества mouseup. Дайте мне знать, если это имеет какие-либо проблемы. - person Fuzzley; 20.08.2013