Чи можу я зателефонувати jquery click (), щоб перейти за посиланням <a>, якщо я вже не прив'язав обробника події до нього за допомогою прив’язки або натискання?


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 запускає дію лише натискання (називається події 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 не припускає працювати з тегами 'a', оскільки браузер не підтримує "фальшиве клацання" за допомогою JavaScript. Тобто, ви не можете "натиснути" на елемент за допомогою JavaScript. За допомогою тегів 'a' ви можете запустити його onClick подію, але посилання не змінить кольори (для відвіданого кольору посилання за замовчуванням фіолетовий у більшості браузерів). Тому не було б сенсу робити події $ (). Click подія працювати з тегами 'a', оскільки акт переходу на атрибут href не є частиною події onClick, але жорстко кодується у браузері.


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

1
Гаразд. Напевно, це було щось, що я зробив не так. Я був абсолютно впевнений у той час, коли я розмістив запитання, що це працює, але оскільки я спробував ваш приклад, моє більше не працює. Я просто повернусь до використання window.location, щоб змінити сторінку і не спробувати підробити клацання.
Mnebuerquo

Дійсно, click () не призначений для створення підроблених кліків, але іноді ми можемо використовувати його для натискання кнопок або форм з ін'єкціями javascript або просто для зручності під час створення тимчасової гарячої клавіші поверх існуючих функцій javascript.
Aero Wang

241

Інший варіант, звичайно, просто використовувати ванільний javascript:

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

1
Це не працює в Safari, і згідно з специфікаціями HTML, це потрібно лише для введення.
Джеремі Кауффман

4
Данг! Це справді працює! Але я мушу сказати, що це не зовсім "ванільний" javascript, оскільки він використовує елемент jquery, тому він є своєрідним jquery javascript .... Це працює у Firefox 24 та IE 10.
bgmCoder

@BGM, добре, але click () не є елементом jquery. Ви можете замінити його на getElementById (".."). Click ()
Пітер,

Нічого не сповна, працює як я очікував. +1 дано :). Для інших користувачів ви також можете використовувати: var lnk = document.getElementById ("a_link"); if (lnk == null) {// do some ....} else {lnk.click (); }
Ікбал

Протестований у різних браузерах, IE10 & Jquery 1.6.4 не впораються з цим.
Hannes Schneidermayer

65

Якщо ви подивитесь на код $.clickфункції, я буду робити ставку, є умовна заява, яка перевіряє, чи елемент має зареєстрованих слухачів для clickподії, перш ніж вона триває. Чому б просто не отримати hrefатрибут зі посилання та вручну змінити розташування сторінки?

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

EDIT: Ось чому він не натискає через 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 якоря (відомою браузером) та подією натискання об’єкта 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, які часто блокуються браузерами як небажані спливаючі вікна.

Цей скрипт має два різні способи: один, який намагається відкрити 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>

У вашому скрипті ви підключитесь до основного контейнера, на якому потрібно натиснути подію. Потім ви використовуєте стандартну методологію jquery, щоб знайти елемент (тип, клас, ідентифікатор) і запустити клацання. Що відбувається - jquery вводить рекурсивну функцію для запуску клацання, і ви порушуєте рекурсивну функцію, приймаючи функцію "e" і stopPropagation () і повертайте помилково, тому що ви не хочете, щоб jquery робив щось інше, крім запуску посилання.

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

Альтернативним рішенням є загортання контейнерів у елемент і розміщення як контейнери всередині замість s. Встановіть проміжки для відображення блоку відповідно до стандартів 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.