Как заставить выполнение скрипта ждать загрузки jquery - PullRequest
96 голосов
/ 20 сентября 2011

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


В ответ на ответы / комментарии ниже, я публикую некоторыеразметки.

Ситуация ... главная страница asp.net и дочерняя страница.

На главной странице у меня есть ссылка на jquery.Затем на странице содержимого у меня есть ссылка на скрипт для конкретной страницы.Когда загружается скрипт для конкретной страницы, он жалуется, что «$ не определено».

Я поместил оповещения в нескольких точках разметки, чтобы увидеть порядок запуска объектов, и подтвердил, что он срабатывает в этомзаказ:

  1. Заголовок главной страницы.
  2. Блок содержимого дочерней страницы 1 (находится внутри заголовка главной страницы, но после вызова сценариев мастер-страницы).
  3. Блок содержимого дочерней страницы 2.

Вот разметка вверху главной страницы:

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="SiteMaster" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Reporting Portal</title>
    <link href="~/Styles/site.css" rel="stylesheet" type="text/css" />
    <link href="~/Styles/red/red.css" rel="stylesheet" type="text/css" />
    <script type="text/Scripts" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> 
    <script type="text/Scripts" language="javascript" src="../Scripts/jquery.dropdownPlain.js"></script>
    <script type="text/Scripts" language="javascript" src="../Scripts/facebox.js"></script>
    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
</head>

Затем в теле главной страницы естьявляется дополнительным ContentPlaceHolder:

 <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
                </asp:ContentPlaceHolder>

На дочерней странице это выглядит так:

<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Dashboard.aspx.cs" Inherits="Data.Dashboard" %>
<%@ Register src="../userControls/ucDropdownMenu.ascx" tagname="ucDropdownMenu" tagprefix="uc1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
    <link rel="stylesheet" type="text/css" href="../Styles/paserMap.css" />
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
***CONTENT HERE***
    <script src="../Scripts/Dashboard.js" type="text/javascript"></script>
</asp:Content>

Вот содержимое файла "../Script/Dashboard.js":

    $(document).ready(function () {

    $('.tgl:first').show(); // Show the first div

    //Description: East panel parent tab navigation
    $('.tabNav label').click(function () {
        $('.tabNav li').removeClass('active')
        $(this).parent().addClass('active');

        var index = $(this).parent('li').index();
        var divToggle = $('.ui-layout-content').children('div.tgl');

        //hide all subToggle divs
        divToggle.hide();
        divToggle.eq(index).show();
    });

});

Ответы [ 14 ]

184 голосов
/ 29 июля 2013

Поздно к вечеринке, и похоже на вопрос Briguy37, но для дальнейшего использования я использую следующий метод и передаю функции, которые я хочу отложить до загрузки jQuery:

function defer(method) {
    if (window.jQuery) {
        method();
    } else {
        setTimeout(function() { defer(method) }, 50);
    }
}

Он будет рекурсивно вызывать метод defer каждые 50 мс, пока не появится window.jQuery, когда он выйдет и вызовет method()

Пример с анонимной функцией:

defer(function () {
    alert("jQuery is now loaded");
});
18 голосов
/ 20 сентября 2011

вы можете использовать атрибут defer для загрузки скрипта в самом конце.

<script type='text/javascript' src='myscript.js' defer='defer'></script>

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

Если ваш код находится на странице, а не в отдельном js-файле, поэтому вы должны выполнять свой скрипт только после того, как документ готов и инкапсулировать ваш код, как это должно работать тоже:

$(function(){
//here goes your code
});
14 голосов
/ 17 апреля 2015

Еще один способ сделать это, хотя метод отсрочки Дарбио более гибкий.

(function() {
  var nTimer = setInterval(function() {
    if (window.jQuery) {
      // Do something with jQuery
      clearInterval(nTimer);
    }
  }, 100);
})();
12 голосов
/ 20 сентября 2011

редактировать

Не могли бы вы попробовать правильный тип для ваших тегов скрипта? Я вижу, вы используете text/Scripts, который не является правильным mimetype для javascript.

Используйте это:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> 
<script type="text/javascript" src="../Scripts/jquery.dropdownPlain.js"></script>
<script type="text/javascript" src="../Scripts/facebox.js"></script>

конец редактирования

или вы можете взглянуть на require.js , который является загрузчиком для вашего кода JavaScript.

в зависимости от вашего проекта, это может быть немного излишним

11 голосов
/ 20 мая 2015

Вы можете попробовать событие загрузки. Вызывается, когда загружены все скрипты:

window.onload = function () {
   //jquery ready for use here
}

Но имейте в виду, что вы можете переопределить другие скрипты, которые использует window.onload.

10 голосов
/ 26 марта 2017

Самый простой и безопасный способ - использовать что-то вроде этого:

var waitForJQuery = setInterval(function () {
    if (typeof $ != 'undefined') {

        // place your code here.

        clearInterval(waitForJQuery);
    }
}, 10);
5 голосов
/ 18 мая 2016

Вместо «ожидания» (что обычно делается с помощью setTimeout), вы также можете использовать определение объекта jQuery в самом окне в качестве ловушки для выполнения вашего кода, который опирается на него. Это достижимо с помощью определения свойства, определенного с помощью Object.defineProperty.

(function(){
  var _jQuery;
  Object.defineProperty(window, 'jQuery', {
    get: function() { return _jQuery; },
    set: function($) {
      _jQuery = $;

      // put code or call to function that uses jQuery here

    }
  });
})();
5 голосов
/ 28 августа 2014

Это распространенная проблема, представьте, что вы используете классный движок шаблонов PHP, поэтому у вас есть базовый макет:

HEADER
BODY ==> dynamic CONTENT/PAGE
FOOTER

И, конечно, вы читаете где-то, что лучше загрузить Javascript внизу страницы, чтобы ваш динамический контент не знал, кто такой jQuery (или $).

Также вы читаете где-то, что хорошо встроить небольшой Javascript, так что представьте, что вам нужен jQuery на странице, baboom, $ не определено (.. пока что ^^).

Мне нравится решение, предоставляемое Facebook

window.fbAsyncInit = function() { alert('FB is ready !'); }

Так что, как ленивый программист (я бы сказал, хороший программист ^^), вы можете использовать эквивалент (на вашей странице):

window.jqReady = function() {}

И добавьте внизу вашего макета, после jQuery включите

if (window.hasOwnProperty('jqReady')) $(function() {window.jqReady();});
4 голосов
/ 30 ноября 2017

Я обнаружил, что предлагаемое решение работает только при работе с асинхронным кодом.Вот версия, которая будет работать в любом случае:

document.addEventListener('DOMContentLoaded', function load() {
    if (!window.jQuery) return setTimeout(load, 50);
    //your synchronous or asynchronous jQuery-related code
}, false);
4 голосов
/ 20 сентября 2011

Использование:

$(document).ready(function() {
    // put all your jQuery goodness in here.
});

Проверьте это для получения дополнительной информации: http://www.learningjquery.com/2006/09/introducing-document-ready

Примечание. Это должно работать до тех пор, пока импорт скрипта для вашей библиотеки JQuery находится над этим вызовом.

Обновление:

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

function yourFunctionToRun(){
    //Your JQuery goodness here
}

function runYourFunctionWhenJQueryIsLoaded() {
    if (window.$){
        //possibly some other JQuery checks to make sure that everything is loaded here

        yourFunctionToRun();
    } else {
        setTimeout(runYourFunctionWhenJQueryIsLoaded, 50);
    }
}

runYourFunctionWhenJQueryIsLoaded();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...