Могу ли я вызвать jquery click (), чтобы перейти по ссылке <a>, если я еще не связал с ней обработчик событий с помощью bind или click?


175

В моем JavaScript есть таймер, который должен эмулировать нажатие на ссылку, чтобы перейти на другую страницу по истечении этого времени. Для этого я использую click()функцию jQuery . Я использовал, $().trigger()а window.locationтакже, и я могу заставить его работать как задумано со всеми тремя.

Я наблюдал странное поведение click()и пытаюсь понять, что происходит и почему.

Я использую Firefox для всего, что я описываю в этом вопросе, но мне также интересно, что другие браузеры будут делать с этим.

Если я не использовал $('a').bind('click',fn)или $('a').click(fn)для установки обработчика событий, то, $('a').click()кажется, вызов вообще ничего не делает. Он не вызывает обработчик браузера по умолчанию для этого события, так как браузер не загружает новую страницу.

Однако, если я сначала установлю обработчик событий, он будет работать, как и ожидалось, даже если обработчик событий ничего не делает.

$('a').click(function(){return true;}).click();

Это загружает новую страницу, как будто я нажал на себя.

Поэтому мой вопрос двоякий: это странное поведение, потому что я где-то делаю что-то не так? и почему вызов click()ничего не делает с поведением по умолчанию, если я не создал собственный обработчик?

РЕДАКТИРОВАТЬ:

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

Таким образом, ответ заключается в том, что вы не можете «фальсифицировать» клики в браузере и что все, что делает jQuery - это вызывает ваш обработчик событий. Вы все еще можете использовать, window.locationчтобы изменить страницу, и это прекрасно работает для меня.


Ответы:


90

Интересно, что это, вероятно, «запрос функции» (т.е. ошибка) для jQuery. Событие jQuery click запускает только действие click (называемое событием onClick в DOM) для элемента, если вы связываете событие jQuery с элементом. Вы должны перейти в списки рассылки jQuery ( http://forum.jquery.com/ ) и сообщить об этом. Это может быть желаемое поведение, но я так не думаю.

РЕДАКТИРОВАТЬ:

Я провел некоторое тестирование, и то, что вы сказали, неверно, даже если вы привязали функцию к тегу «a», она все равно не приведет вас на сайт, указанный атрибутом href. Попробуйте следующий код:

<html>
<head>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
 <script>
  $(document).ready(function() {
   /* Try to dis-comment this:
   $('#a').click(function () {
    alert('jQuery.click()');
    return true;
   });
   */
  });
  function button_onClick() {
   $('#a').click();
  }
  function a_onClick() {
   alert('a_onClick');
  }
 </script>

</head>
<body>
 <input type="button" onclick="button_onClick()">
 <br>
 <a id='a' href='http://www.google.com' onClick="a_onClick()"> aaa </a>

</body>
</html> 

Он никогда не переходит на google.com, если вы не нажмете ссылку напрямую (с комментарием или без него). Также обратите внимание, что даже если вы связываете событие click со ссылкой, оно все равно не станет фиолетовым после нажатия кнопки. Он станет фиолетовым, если вы нажмете ссылку напрямую.

Я провел некоторое исследование, и кажется, что .click не должен работать с тегами «a», потому что браузер не поддерживает «поддельные клики» с javascript. Я имею в виду, вы не можете «щелкнуть» по элементу с помощью JavaScript. С помощью тегов «a» вы можете вызвать событие onClick, но ссылка не изменит цвета (на цвет посещенной ссылки по умолчанию фиолетовый цвет в большинстве браузеров). Поэтому не имеет смысла заставлять событие $ (). Click работать с тегами «a», поскольку переход к атрибуту href не является частью события onClick, а жестко запрограммирован в браузере.


7
Я попробовал ваш код, и он работает точно так, как вы сказали, но мой код работает так, как я описал выше. Я сделаю еще несколько экспериментов и посмотрю, смогу ли я собрать простой пример моих результатов, которые вы можете попробовать.
Mnebuerquo

1
Хорошо. Должно быть, я что-то не так сделал. В тот момент, когда я опубликовал свой вопрос, я был абсолютно уверен, что он работает, но поскольку я попробовал ваш пример, мой больше не работает. Я просто вернусь к использованию window.location, чтобы изменить страницу, а не пытаться подделать клик.
Mnebuerquo

Действительно, click () не предназначен для создания поддельных кликов, но иногда мы можем использовать его для нажатия кнопок или форм с помощью инъекций javascript или просто для удобства при создании временной горячей клавиши поверх существующих функций javascript.
Аэро Ван

241

Другой вариант, конечно, просто использовать ванильный JavaScript:

document.getElementById("a_link").click()

1
Это не работает в Safari, и в соответствии со спецификацией HTML это должны реализовывать только входные данные.
Джереми Кауффман

4
Dang! Это работает! Но я должен сказать, что это не совсем «ванильный» javascript, так как он использует элемент jquery, так что это своего рода ванильный javascript .... Он работает в Firefox 24 и IE 10.
bgmCoder

@BGM, хорошо, но click () не принадлежит элементу jquery. Вы можете заменить его getElementById (".."). Click ()
Питер

вау ваундер полный, работает как я и ожидал. +1 дано :). Для других пользователей вы также можете использовать: var lnk = document.getElementById ("a_link"); if (lnk == null) {// делать некоторые ....} else {lnk.click (); }
Икбал

IE10 и Jquery 1.6.4, протестированные в различных браузерах, не справляются с этой задачей.
Ханнес Шнайдермайер

65

Если вы посмотрите на код $.clickфункции, то, держу пари, есть условный оператор, который проверяет, зарегистрированы ли у элемента прослушиватели, зарегистрированные для clickсобытия, прежде чем оно продолжится. Почему бы просто не получить hrefатрибут по ссылке и вручную изменить местоположение страницы?

 window.location.href = $('a').attr('href');

РЕДАКТИРОВАТЬ: Вот почему он не щелкает через triggerфункцию, источник jQuery для версии 1.3.2:

 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
    if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
        event.result = false;

    // Trigger the native events (except for clicks on links)
    if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
        this.triggered = true;
        try {
            elem[ type ]();
        // prevent IE from throwing an error for some hidden elements
        } catch (e) {}
    }

После вызова обработчиков (если они есть) jQuery вызывает событие на объекте. Однако он вызывает собственные обработчики для событий щелчка, только если элемент не является ссылкой. Я думаю, это было сделано целенаправленно по какой-то причине. Это должно быть верно, независимо от того, определен обработчик события или нет, поэтому я не уверен, почему в вашем случае присоединение обработчика события вызвало onClickвызов собственного обработчика. Вы должны будете сделать то, что я сделал, и пройти через выполнение, чтобы увидеть, где он вызывается.


Я, конечно, могу использовать window.location и href, как я уже упоминал в этом вопросе. Я пытаюсь понять, что происходит в jquery click (), и что вызывает результаты, которые я наблюдал.
Mnebuerquo

Я отредактировал свой ответ, чтобы показать, где в источнике jQuery он имеет дело с вызовами $ .click () для ссылок.
Райан Линч

2
window.location работает, но не публикует HTTP Referrer и ломает кнопку назад.
Погоня Зайбер

5

Обработчики щелчков на тегах привязки - это особый случай в jQuery.

Я думаю, вы можете запутаться между событием onclick привязки (известным браузеру) и событием click объекта jQuery, который оборачивает понятие DOM тега привязки.

Вы можете скачать исходный код jQuery 1.3.2 здесь .

Соответствующими разделами источника являются строки 2643-2645 (я разделил это на несколько строк, чтобы было легче понять):

// Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
if (
     (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && 
       elem["on"+type] && 
       elem["on"+type].apply( elem, data ) === false
   )
     event.result = false;

5

JS / jQuery не поддерживает стандартное поведение ссылок, «щелкаемых» программно.

Что вы можете сделать, это создать форму и отправить ее. Таким образом, вам не нужно использовать window.locationили window.open, которые часто блокируются как нежелательные всплывающие окна в браузерах.

Этот сценарий имеет 2 различных метода: один, который пытается открыть 3 новые вкладки / окна (он открывает только 1 в IE и Chrome, дополнительную информацию см. Ниже), и другой, который запускает пользовательское событие при щелчке по ссылке.

Вот как:

HTML

<html>
<head>
    <script src="jquery-1.9.1.min.js" type="text/javascript"></script>
    <script src="script.js" type="text/javascript"></script>
</head>
<body>
    <button id="testbtn">Test</button><br><br>

    <a href="https://google.nl">GOOGLE</a><br>
    <a href="http://en.wikipedia.org/wiki/Main_Page">WIKI</a><br>
    <a href="https://stackoverflow.com/">SO</a>
</body>
</html>

jQuery (script.js)

$(function()
{ 
    // Try to open all 3 links by pressing the button
    // - Firefox opens all 3 links
    // - Chrome only opens 1 of them without popup warning
    // - IE only opens 1 of them WITH popup warning
    $("#testbtn").on("click", function()
    {
        $("a").each(function()
        {
            var form = $("<form></form>");
            form.attr(
            {
                id     : "formform",
                action : $(this).attr("href"),
                method : "GET",
                // Open in new window/tab
                target : "_blank"
            });

            $("body").append(form);
            $("#formform").submit();
            $("#formform").remove();
        });
    });

    // Or click the link and fire a custom event 
    // (open your own window without following the link itself)
    $("a").on("click", function()
    {
        var form = $("<form></form>");
        form.attr(
        {
            id     : "formform",
            // The location given in the link itself
            action : $(this).attr("href"), 
            method : "GET",
            // Open in new window/tab
            target : "_blank"              
        });

        $("body").append(form);
        $("#formform").submit();
        $("#formform").remove();

        // Prevent the link from opening normally
        return false;
    });

});

Что он делает для каждого элемента ссылки:

  1. Создать форму
  2. Придай ему атрибуты
  3. Добавьте его в DOM, чтобы его можно было отправить
  4. Отправить это
  5. Удалите форму из DOM, удалив все следы * Вставьте злой смех *

Теперь у вас есть новая вкладка / окно загрузки "https://google.nl"(или любой URL, который вы хотите, просто замените его). К сожалению, когда вы пытаетесь открыть более одного окна таким образом, вы получаете Popup blockedпанель сообщений при попытке открыть второе (первое все еще открыто).


Более подробную информацию о том, как я получил этот метод можно найти здесь:

Открытие нового окна / вкладки без использования window.openилиwindow.location.href


3

Запустите элемент гиперссылки, который находится внутри элемента, который вы хотите подключить jquery .click ()

<div class="TopicControl">
    <div class="articleImage">
       <a href=""><img src="" alt=""></a>
    </div>
</div>

В вашем скрипте вы подключаетесь к основному контейнеру, на котором вы хотите событие click. Затем вы используете стандартную методологию jquery, чтобы найти элемент (тип, класс, id) и выполнить щелчок. Происходит следующее: jquery вводит рекурсивную функцию для запуска клика, и вы прерываете рекурсивную функцию, беря событие 'e' и функцию stopPropagation (), и возвращаете false, потому что вы не хотите, чтобы jquery делал что-то еще, кроме запуска ссылки.

$('.TopicControl').click(function (event) {
         $(this).find('a').click();
        event.stopPropagation();
        return false;
     });

Альтернативное решение состоит в том, чтобы обернуть контейнеры в элемент и поместить внутри себя контейнеры вместо контейнеров. Установите промежутки для отображения блока в соответствии со стандартами W3C.


3

Вы можете использовать jQuery для выбора объекта jQuery для этого элемента. Затем получите базовый элемент DOM и вызовите его click()метод.

по идентификатору

$("#my-link").each(function (index) { $(this).get(0).click() });

или используйте jQuery, чтобы щелкнуть по группе ссылок по классу CSS

$(".my-link-class").each(function (index) { $(this).get(0).click() });

2

Это ничего не делает, потому что никакие события не были связаны с событием. Если я правильно помню, jQuery поддерживает свой собственный список обработчиков событий, которые связаны с NodeLists для производительности и других целей.


2

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

// For modren Browsers
$(ele).trigger("click");

// Relaying on Paul Irish's conditional class names http://bit.ly/HWIpAp (via HTML5 Boilerplate http://bit.ly/HUzi3I) where each IE version gets a class of its Version
$("html.ie7").length && (function(){
    var eleOnClickattr = $(ele).attr("onclick") 
    eval(eleOnClickattr);
  })()

1

Чтобы открыть гиперссылку в той же вкладке, используйте:

$(document).on('click', "a.classname", function() {
    var form = $("<form></form>");
    form.attr(
    {
        id     : "formid",
        action : $(this).attr("href"),
        method : "GET",
    });

    $("body").append(form);
    $("#formid").submit();
    $("#formid").remove();
    return false;
});
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.