У меня проблема, когда страница загружается так быстро, что jquery не завершил загрузку до того, как он будет вызван последующим скриптом. Есть ли способ проверить наличие jquery, и если он не существует, подождите немного, а затем повторите попытку?
В ответ на ответы / комментарии ниже я публикую часть разметки.
Ситуация ... главная страница asp.net и дочерняя страница.
На главной странице у меня есть ссылка на jquery. Затем на странице содержимого у меня есть ссылка на скрипт для конкретной страницы. Когда загружается скрипт для конкретной страницы, он жалуется, что «$ не определено».
Я разместил предупреждения в нескольких точках разметки, чтобы увидеть порядок, в котором срабатывают объекты, и подтвердил, что они срабатывают в следующем порядке:
- Заголовок главной страницы.
- Блок содержимого дочерней страницы 1 (находится внутри заголовка главной страницы, но после вызова скриптов главной страницы).
- Блок содержимого дочерней страницы 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();
});
});
источник
$(document).ready(function(){...});
?<script src="...">
тегами, этого не произойдет. Вы используете что-то вроде RequireJS или LABjs?$(document).ready()
или$(window).load()
? Можем ли мы увидеть пример?type="text/Scripts"
кtype="text/javascript"
, или избавиться от нее все вместе это не нужно больше, а также избавиться отlanguage="javascript
. С таким же успехом можно начать пробовать.Ответы:
редактировать
Не могли бы вы попробовать правильный тип для ваших тегов скрипта? Я вижу, вы используете
text/Scripts
mimetype, который не подходит для javascript.Использовать это:
конец править
или вы можете взглянуть на require.js, который является загрузчиком вашего кода javascript.
в зависимости от вашего проекта, это может быть немного излишним
источник
Поздно к вечеринке и аналогично вопросу Briguy37, но для справки в будущем я использую следующий метод и передаю функции, которые я хочу отложить до загрузки jQuery:
Он будет рекурсивно вызывать метод defer каждые 50 мс, пока не будет
window.jQuery
существовать, когда он завершится и вызоветmethod()
Пример с анонимной функцией:
источник
script
тега, который загружает jQuery, естьdefer
атрибут, это вызовет проблему, не загрузив его позже, несмотря на определенный в коде порядок скриптов.вы можете использовать атрибут defer для загрузки скрипта в самом конце.
но обычно загрузка вашего скрипта в правильном порядке должна помочь, поэтому обязательно поместите включение jquery перед своим собственным скриптом
Если ваш код находится на странице, а не в отдельном js-файле, вам нужно выполнить свой скрипт только после того, как документ будет готов, и инкапсуляция вашего кода, как это, тоже должно работать:
источник
Еще один способ сделать это, хотя метод отсрочки Darbio более гибкий.
источник
Самый простой и безопасный способ - использовать что-то вроде этого:
источник
Вы можете попробовать событие onload. Он возникает после загрузки всех скриптов:
Но имейте в виду, что вы можете переопределить другие скрипты, в которых используется window.onload.
источник
Я обнаружил, что предлагаемое решение работает только с учетом асинхронного кода. Вот версия, которая подойдет в любом случае:
источник
load
функцию, но потом снова ее используетеsetTimeout
.Это обычная проблема, представьте, что вы используете классный шаблонизатор PHP, поэтому у вас есть базовый макет:
И, конечно, вы где-то читали, что лучше загружать Javascript внизу страницы, чтобы ваш динамический контент не знал, кто такой jQuery (или $).
Также вы где-то читали, что полезно встроить небольшой Javascript, поэтому представьте, что вам нужен jQuery на странице, baboom, $ не определен (.. пока ^^).
Мне нравится решение, которое предоставляет Facebook
Итак, как ленивый программист (я бы сказал, хороший программист ^^), вы можете использовать эквивалент (на своей странице):
И добавьте внизу вашего макета после того, как jQuery include
источник
Вместо того, чтобы «ждать» (что обычно выполняется с помощью
setTimeout
), вы также можете использовать определение объекта jQuery в самом окне в качестве ловушки для выполнения вашего кода, который на него полагается. Это достигается с помощью определения свойства, определенного с помощьюObject.defineProperty
.источник
window.jQuery
значение, определяяjQuery
переменную в глобальной области (т.е.window
). Это вызовет функцию установки свойств для объекта окна, определенного в коде.</body>
а не раньше</head>
Использование:
Ознакомьтесь с этим для получения дополнительной информации: http://www.learningjquery.com/2006/09/introduction-document-ready
Примечание. Это должно работать, пока импорт сценария для вашей библиотеки JQuery находится выше этого вызова.
Обновить:
Если по какой-то причине ваш код не загружается синхронно (с чем
я никогда не сталкивался, но, видимо, это возможно из-за комментария ниже,этого не должно происходить), вы можете закодировать его следующим образом.источник
Я не очень люблю интервальные штучки. Когда я хочу отложить jquery или что-то еще, обычно происходит что-то вроде этого.
Начнем с:
Затем:
И наконец:
Или менее ошеломляющая версия:
А в случае async вы можете выполнять push-функции при загрузке jquery.
Альтернативно:
источник
Давайте расширим
defer()
Dario, чтобы он был более многоразовым.Что затем запускается:
источник
Я не думаю, что это твоя проблема. По умолчанию загрузка сценария выполняется синхронно, поэтому, если вы не используете
defer
атрибут или не загружаете сам jQuery через другой запрос AJAX, ваша проблема, вероятно, больше похожа на ошибку 404. Можете ли вы показать свою разметку и сообщить нам, если вы заметите что-нибудь подозрительное в firebug или веб-инспектор?источник
Проверь это:
https://jsfiddle.net/neohunter/ey2pqt5z/
Он создаст поддельный объект jQuery, который позволяет вам использовать методы onload jquery, и они будут выполнены, как только jquery будет загружен.
Это не идеально.
источник
Косвенное замечание о подходах здесь, которые нагружают
setTimeout
илиsetInterval
. В таких случаях возможно, что при повторном запуске проверки DOM уже будет загружена, иDOMContentLoaded
событие браузера будет запущено, поэтому вы не сможете надежно обнаружить это событие, используя эти подходы. Я обнаружил, что jQuery всеready
еще работает, поэтому вы можете встроить свой обычныйjQuery(document).ready(function ($) { ... }
внутри вашего
setTimeout
илиsetInterval
и все должно работать как обычно.источник