Разница между .click() и нажатием кнопки? (JavaScript/JQuery)
Я пытаюсь понять эту странную проблему, с которой я столкнулся, и основной причиной является различие между живым кликом и запуском .click()
.
Я не буду вдаваться в подробности проблемы, но в основном, когда вы нажимаете кнопку ввода, она отлично работает (имеет событие onclick
). Но если я вызываю .click()
из другого места (вместо физического нажатия кнопки), он не работает должным образом.
Мой вопрос - есть ли способ действительно воспроизвести фактический клик на кнопке?
ИЗМЕНИТЬ
Проблема: я открываю новое окно (aspx page), которое загружает встроенный PDF файл. Если я на самом деле нажимаю на ссылку, окно открывается нормально и загрузка PDF. Если я использую .click()
, откроется окно, и мне будет предложено загрузить PDF файл. Я прошел через настройки Adobe Reader, настройки браузера и параметры реестра в подсказке - я понимаю, что это могут быть факторы к большой картине, но прямо сейчас меня беспокоит, почему поведение между щелчком мыши и .click() делает что-то совсем другое.
Ответы
Ответ 1
Я использую эту функцию, чтобы действительно имитировать щелчок мышью:
function clickLink(link) {
var cancelled = false;
if (document.createEvent) {
var event = document.createEvent("MouseEvents");
event.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0,
false, false, false, false,
0, null);
cancelled = !link.dispatchEvent(event);
}
else if (link.fireEvent) {
cancelled = !link.fireEvent("onclick");
}
}
Ответ 2
Прежде чем читать ниже, в котором обсуждается, как обойти проблему, позвольте мне более подробно ответить, почему у вас возникла проблема:
Современные браузеры выполняют разные действия для ссылок, основанных на таких вещах, как кнопка мыши, с которой вы нажали, поддерживали ли вы Shift/Ctrl/Alt и т.д. Например, в Chrome, если вы кликнете на ссылку вместо щелчка левой кнопкой мыши, браузер автоматически откроет окно на новой вкладке.
Когда вы используете .click()
, jQuery должен делать предположения о "способе", в котором вы нажали, - и вы получаете поведение по умолчанию - что в вашем случае не является правильным поведением. Чтобы устранить проблему, вам необходимо указать "правильные" настройки в браузере в форме MouseEvents
.
Теперь, на короткое обсуждение путей его исправления:
Когда вы используете событие jQuery .click()
без параметров, это фактически не "подделка щелчка" на рассматриваемом элементе. Вместо этого, согласно документации jQuery на http://api.jquery.com/click/:
... когда .click()
вызывается без аргументов, это ярлык для .trigger("click")
Это означает, что когда вы запускаете $('#div1').click()
- если нет реального обработчика jQuery для события 'click'
, вы получите обработку по умолчанию. Итак, рассмотрим эти два случая:
Случай 1:
<a id='myLink' href='/some/link/'>Click me!</a>
<script type='text/javascript'>
$('#myLink').click();
</script>
В этом первом сценарии вызов .click()
ничего не делает, потому что для него нет обработчика. Событие запускается, но нет ничего, чтобы поймать его и ответить - поэтому используется обработка по умолчанию тега a
, и пользователь переходит к /some/link/
- и поскольку вы не указали, какую кнопку мыши или какие-либо другие параметры - он действительно по умолчанию.
Случай 2:
<a id='myLink' href='/some/link/'>Click me!</a>
<script type='text/javascript'>
$('#myLink').bind('click', function (ev) {
ev.preventDefault();
ev.stopPropagation();
alert('you clicked me!');
}).click();
</script>
В этом случае, поскольку обработчик click
был создан, когда пользователь щелкает ссылку - вызовы ev.preventDefault()
и ev.stopPropagation()
перестанут обрабатывать по умолчанию, и предупреждение будет запущено.
Однако на данный момент у вас есть объект ev
, который представляет MouseEvents
- и вы можете изменить настройки, если хотите. Например, вы можете сделать следующее:
ev.altKey = true; // Held Alt
ev.button = 1; // Middle Mouse Button
Эти настройки изменят метод обработки по умолчанию.
Альтернативное, не-jQuery решение
Вы также можете по-настоящему имитировать щелчок на кнопке, адаптировав следующий код.
function fakeClick(event, anchorObj) {
if (anchorObj.click) {
anchorObj.click()
} else if(document.createEvent) {
if(event.target !== anchorObj) {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
var allowDefault = anchorObj.dispatchEvent(evt);
// you can check allowDefault for false to see if
// any handler called evt.preventDefault().
// Firefox will *not* redirect to anchorObj.href
// for you. However every other browser will.
}
}
}
(Для более полной реализации см. исходный пост: Как я могу имитировать щелчок на якорный тег? - и посмотреть на выбранный ответ)
Это фактически подтолкнет браузер к тому, что вы нажмете мышь на якорь /span/etc, создав событие с нуля так же, как и обработчики по умолчанию браузера, за исключением того, что вы можете переопределить некоторые параметры. Однако я не предлагаю этот подход, поскольку он намного более подвержен взлому кросс-браузерного приложения, и вам нужно выяснить, на что все параметры сопоставляются.
Ответ 3
$('img').click(function(event){
console.log(event.hasOwnProperty('originalEvent')); // output : true
});
$('img').trigger("click",function(event){
console.log(event.hasOwnProperty('originalEvent')); // output : false
});