Как я могу программно вызвать событие onclick() из тега привязки, сохраняя при этом ссылку «this» в функции onclick?

StackOverflow https://stackoverflow.com/questions/906486

  •  05-09-2019
  •  | 
  •  

Вопрос

Следующее не работает...(по крайней мере, не в Firefox: document.getElementById('linkid').click() это не функция)

<script type="text/javascript">
    function doOnClick() {
        document.getElementById('linkid').click();
        //Should alert('/testlocation');
    }
</script>
<a id="linkid" href="/testlocation" onclick="alert(this.href);">Testlink</a>
Это было полезно?

Решение

Вам нужно apply обработчик событий в контексте этого элемента:

var elem = document.getElementById("linkid");
if (typeof elem.onclick == "function") {
    elem.onclick.apply(elem);
}

В противном случае this будет ссылаться на контекст, в котором выполняется приведенный выше код.

Другие советы

Лучший способ решить эту проблему — использовать Vanilla JS, но если вы уже используете jQuery, есть очень простое решение:

<script type="text/javascript">
    function doOnClick() {
        $('#linkid').click();
    }
</script>
<a id="linkid" href="/testlocation" onclick="alert(this.href);">Testlink</a>

Протестировано в IE8-10, Chrome, Firefox.

Чтобы вызвать событие, вы в основном просто вызываете обработчик события для этого элемент.Небольшое изменение вашего кода.

var a = document.getElementById("element");
var evnt = a["onclick"];

if (typeof(evnt) == "function") {
    evnt.call(a);
}
$("#linkid").trigger("click");

Конечно, ОП аналогичным образом заявил, что это не сработало, но для меня это сработало.Судя по заметкам в моем источнике, кажется, что это было реализовано примерно в то же время или после публикации ОП.Возможно, сейчас это более стандартно.

document.getElementsByName('MyElementsName')[0].click();

В моем случае у моей кнопки не было идентификатора.Если у вашего элемента есть идентификатор, желательно использовать следующий (непроверенный).

document.getElementById('MyElementsId').click();

Изначально я попробовал этот метод, и он не сработал.После поиска в Google я вернулся и понял, что мой элемент был по имени и не имел идентификатора.Дважды проверьте, что вы вызываете правильный атрибут.

Источник: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click

Взгляните на метод handleEvent.
https://developer.mozilla.org/en-US/docs/Web/API/EventListener

«Сырой» Javascript:

function MyObj() {
   this.abc = "ABC";
}
MyObj.prototype.handleEvent = function(e) {
   console.log("caught event: "+e.type);
   console.log(this.abc);
}

var myObj = new MyObj();

document.querySelector("#myElement").addEventListener('click', myObj);

Теперь нажмите на свой элемент (с идентификатором «myElement»), и он должен напечатать в консоли следующее:

пойманное событие:щелкнуть
АВС

Это позволяет вам использовать метод объекта в качестве обработчика событий и иметь доступ ко всем свойствам объекта в этом методе.

Ты не мочь просто передайте метод объекта непосредственно в addEventListener (например: element.addEventListener('click',myObj.myMethod);) и ожидайте myMethod действовать так, как будто меня обычно вызывали на объект.Я предполагаю, что любая функция, переданная в addEventListener, каким-то образом копируется, а не на нее ссылаются.Например, если вы передадите ссылку на функцию прослушивателя событий в addEventListener (в виде переменной), а затем отключите эту ссылку, прослушиватель событий все равно будет выполняться при перехвате событий.

Другой (менее элегантный) обходной путь для передачи метода в качестве прослушивателя событий и по-прежнему this и при этом иметь доступ к свойствам объекта в прослушивателе событий будет примерно так:

// see above for definition of MyObj

var myObj = new MyObj();

document.querySelector("#myElement").addEventListener('click', myObj.handleEvent.bind(myObj));

Если вы используете это исключительно для ссылки на функцию в атрибуте onclick, это кажется очень плохой идеей.В целом встроенные события — плохая идея.

Я бы предложил следующее:

function addEvent(elm, evType, fn, useCapture) {
    if (elm.addEventListener) {
        elm.addEventListener(evType, fn, useCapture);
        return true;
    }
    else if (elm.attachEvent) {
        var r = elm.attachEvent('on' + evType, fn);
        return r;
    }
    else {
        elm['on' + evType] = fn;
    }
}

handler = function(){
   showHref(el);
}

showHref = function(el) {
   alert(el.href);
}

var el = document.getElementById('linkid');

addEvent(el, 'click', handler);

Если вы хотите вызвать ту же функцию из другого кода JavaScript, имитация щелчка для вызова функции — не лучший способ.Учитывать:

function doOnClick() {
   showHref(document.getElementById('linkid'));
}

Тема старая, но вопрос по-прежнему актуален, так что...

(1) Пример в вашем вопросе сейчас ДЕЛАЕТ работать в Фаерфоксе.Однако помимо вызова обработчика событий (который отображает предупреждение), он ТАКЖЕ нажимает на ссылку, вызывая навигацию (после отклонения оповещения).

(2) Чтобы ТОЛЬКО вызовите обработчик событий (без запуска навигации), просто замените:

document.getElementById('linkid').click();

с

document.getElementById('linkid').onclick();

В общем, я бы рекомендовал не вызывать обработчики событий «вручную».

  • Непонятно, что выполняется из-за нескольких зарегистрированных слушателей
  • Опасность попадания в рекурсивный и бесконечный цикл событий (нажмите A) триггера Click B, триггера Click A и т.д.)
  • Избыточные обновления DOM
  • Трудно отличить фактические изменения в представлении, вызванные пользователем, от изменений, внесенных в виде кода инициализации (который следует запускать только один раз).

Лучше выяснить, что именно вы хотите, чтобы произошло, поместить это в функцию и вызвать ее вручную И зарегистрировать как прослушиватель событий.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top