Коли саме виконується зворотний виклик $ (документ) .ready?


74

Припустимо, що ми прикріплюємо .click()обробник до <a>тегу anchor ( ) у $(document).readyзворотному виклику. Цей обробник скасує дію за замовчуванням (слідуючи наведеній href) та покаже попередження.

Я хотів би знати, коли саме буде виконаний зворотний виклик і чи можливо для користувача натиснути на прив’язку (документ показаний у браузері), але подія ще не приєднана.

Ось різні HTML-сторінки, які містять прив'язку, але порядок включення сценаріїв різний. Яка різниця (якщо така є) між ними? Чи будуть різні браузери поводитися по-різному?

Сторінка 1:

<html>
<head>
    <title>Test 1</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
    <script type="text/javascript">
    $(function() {
        $('a').click(function() {
            alert('overriding the default action');
            return false;
        });
    });
    </script>
</head>
<body>
    <a href="http://www.google.com">Test</a>
</body>
</html>

Сторінка 2:

<html>
<head>
    <title>Test 1</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
</head>
<body>
    <a href="http://www.google.com">Test</a>
    <script type="text/javascript">
    $(function() {
        $('a').click(function() {
            alert('overriding the default action');
            return false;
        });
    });
    </script>
</body>
</html>

Сторінка 3:

<html>
<head>
    <title>Test 1</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
    <a href="http://www.google.com">Test</a>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
    <script type="text/javascript">
    $(function() {
        $('a').click(function() {
            alert('overriding the default action');
            return false;
        });
    });
    </script>
</body>
</html>

Тож чи можливо, що користувач перенаправляється на href, натискаючи на прив’язку, і ніколи не бачить сповіщення (звичайно ігноруючи випадок відключеного JavaScript)? Чи може це статися в будь-якому з прикладів, які я подав?

Все, що мені потрібно, це переконатися, що clickобробник подій приєднаний до прив’язки, перш ніж користувач матиме можливість натиснути на цей прив’язок. Я знаю, що можу надати порожнє, hrefа потім поступово покращувати його у javascript, але це більш загальне питання.

Що станеться у випадку, якщо веб-сервер швидко генерує HTML, але бібліотеці jquery потрібен час для отримання з віддаленого сервера? Чи вплине це на мій сценарій? Який порядок включення сценаріїв порівняно із завантаженням DOM? Чи можна їх робити паралельно?

Відповіді:


59

Приклад 3 матиме найбільший шанс, що користувач зможе натиснути на посилання без обробника, який ще не приєднався. Оскільки ви завантажуєте бібліотеку jQuery після надання посилання, якщо сервери Google працюють трохи повільно (або пошук DNS займає секунду або близько того), або комп'ютер користувачів повільно обробляє jQuery, посилання не матиме свого обробника клацань прикріплюється, коли користувач намагається клацнути на ньому.

Інша ситуація, коли це може статися, - якщо у вас дуже велика або повільна сторінка завантаження, і це посилання знаходиться вгорі. Тоді DOM може бути не повністю готовим, коли його частини видно. Якщо у вас виникає така проблема, найбезпечніше зробити:

  1. Завантажте jQuery в head(приклад 1 або 2)
  2. Приєднайте подію клацання відразу після <a>елемента, але не у зворотному виклику DOMReady. Таким чином він буде викликаний негайно і не буде чекати решти документа.

Після відображення елемента його можна захопити з DOM, а згодом jQuery може отримати до нього доступ:

<a href="http://www.google.com">Test</a>
<script type="text/javascript>
    // No (document).ready is needed. The element is availible
    $('a').click(function() {
        alert('overriding the default action');
        return false;
    });
</script>

Крім того, спираючись на коментар user384915, якщо дія повністю залежить від JavaScript, то навіть не відображайте його як частину HTML, додайте його після того, як jQuery буде готовий:

<script type="text/javascript">
jQuery(function($){
   $("<a />", { 
      style: "cursor: pointer", 
      click: function() {
        alert('overriding the default action');
        return false;
      },
      text: "Test"
   }).prependTo("body");
});
</script>

15

Тут у вас є кілька різних запитань

Коли саме виконується зворотний виклик $ (документ) .ready?

Він виконується, як тільки DOM повністю завантажується. НЕ, коли все (наприклад, зображення) завантажується, як .load () буде. Це (загалом) до цього, в основному це коли сторінка будується сама.

Я хотів би знати, коли саме буде виконаний зворотний виклик

Коли на неї клацають.

чи можливо для користувача натиснути на прив’язку (документ був показаний у браузері), але подія ще не вкладена.

Так, це можливо. Але якщо помістити його в .ready (), ви отримаєте найкращий шанс, що цього не буде. Є лише 2 способи зробити це, щоб бути «більш впевненим», що це не стане. Вони фактично використовують 'onclick' на посиланні самостійно і розміщують javascript безпосередньо після посилання (а не в .ready ()), що виконується відразу після створення посилання.

Крім того, немає різниці між тим, як будуть працювати 2 зразки коду, які ви надали. Однак у другому вам не потрібно поміщати код у .ready (), оскільки він існує після посилання, він завжди буде виконаний після створення посилання. Якщо ви видалите його з .ready (), це буде перший із 2-х способів, які я описав вище.

Крім того, замість того, щоб ставити 'return false;' у зворотному виклику краще використовувати .preventDefault () та .stopPropagation (), це дозволить вам вказати, якщо ви хочете запобігти дії за замовчуванням або зупинити подію, що спливає, або те й інше.


Отже, ви стверджуєте, що єдиний спосіб досягти того, що я шукаю (є гарантія того, що користувач бачить попередження перед перенаправленням) - це або використовувати, onclickабо приєднати clickобробник відразу після посилання (не використовуючи $(document).ready)?
Дарін Димитров

приклади різні, залежно від того, чи увімкнено буферизацію виводу, чи використовується фрагментоване кодування.
gblazex

Який із трьох прикладів був би найкращим з точки зору моєї цілі, якщо припустимо, що буферизація увімкнена? А як щодо фрагментованого кодування?
Дарін Димитров

2
Використання onclick було б єдиним способом бути впевненим. Використовуючи .ready (), малоймовірно, що це не відбудеться, і якщо це не відбувається насправді ТАК погано, найкраще знайти інший спосіб зробити все, що ви робите. Пам’ятайте, що не у всіх увімкнений javascript, тому дуже можливо, що хтось натискає це посилання і виконує дію за замовчуванням.
Matt Evanoff

2

Це залежить від багатьох речей. Наприклад, якщо у вас є фрагментоване кодування, можливо, користувач отримає фрагмент, але оскільки документ ще не готовий, слухач не буде приєднаний.

Подія jQuery ready - це подія DOMContentLoaded у браузерах, сумісних із W3C (стандартизована у специфікації HTML5), та деякі альтернативи цього в інших (наприклад, readystate в IE).

DOMContentLoaded (MDC)

Здійснюється в об’єкті документа сторінки, коли аналіз документа завершено. На момент запуску цієї події DOM сторінки готовий.

Оскільки це трапляється перед рендерингом, було б твердим припущенням, що зворотний виклик, виконаний після цієї події, зможе запобігти взаємодії користувача на не готовій сторінці.

Але, як зазначив у своїй статті Пітер Міко, через різницю в тому, як браузери реалізують цю подію, "потужна техніка раннього пожвавлення неможлива у чотирьох великих браузерах".

Тому я б сказав, що ви не можете покластися на 100% на подію, готову до jQuery, але в більшості випадків вона буде працювати нормально.



1

Ваш третій приклад надає найбільший шанс користувачеві клацнути без приєднання обробника заміни. Зазвичай браузер завантажує та аналізує кожен, <script>перш ніж переходити до наступного. Ви використовуєте jQuery із зовнішнього джерела (Google), яке, хоча і є надійним, може бути недоступним або повільним для завантаження. У вас є обидва <script>блоки в кінці вашого документа <body>, тому попередні ділянки сторінки, ймовірно, вже були завантажені та відображені на екрані, поки обробляються ці два останні скрипти. Хоча цей підхід пропонується представити користувачеві адаптивний досвід завантаження сторінки, він може натискати протягом цього невизначеного періоду, і, звичайно, обробник заміни ще не буде приєднаний.

Там цікава стаття YUIblog на сценарії і порядок завантаження тут .


0

Звичайно, можна "обдурити" попередження (навіть якщо Javascript увімкнено). Спробуйте перетягнути посилання в поле url, і ви побачите, що воно буде виконане без попередження. Це особливо проблематично, якщо посилання ініціює дію видалення.

Про документ. Вже зворотний виклик - у мене теж така проблема. Дозволь пояснити. Ми робимо проект, де всі форми відображаються у спливаючих вікнах (вікно jQuery). Отже, коли спливаюче вікно закрито (поки що), сторінка перезавантажується, і я мав випадки, коли мене перенаправляють на інший екран, замість того, щоб відкривати нове спливаюче вікно.

Повністю погодьтеся з користувачем384915 щодо розміщення javascript безпосередньо на події onClick або навіть краще до тегу href.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.