Ich habe ein Problem, bei dem die Seite so schnell geladen wird, dass jquery noch nicht vollständig geladen wurde, bevor sie von einem nachfolgenden Skript aufgerufen wird. Gibt es eine Möglichkeit, die Existenz von jquery zu überprüfen, und wenn es nicht existiert, warten Sie einen Moment und versuchen Sie es dann erneut?
Als Antwort auf die Antworten / Kommentare unten poste ich einige der Markups.
Die Situation ... asp.net Masterseite und Kinderseite.
Auf der Masterseite habe ich einen Verweis auf jquery. Dann habe ich auf der Inhaltsseite einen Verweis auf das seitenspezifische Skript. Wenn das seitenspezifische Skript geladen wird, wird beschwert, dass "$ undefiniert ist".
Ich habe an mehreren Stellen im Markup Warnungen eingefügt, um die Reihenfolge zu sehen, in der die Dinge ausgelöst wurden, und habe bestätigt, dass sie in dieser Reihenfolge ausgelöst werden:
- Masterseitenkopf.
- Untergeordneter Seiteninhaltsblock 1 (befindet sich im Kopf der Masterseite, aber nachdem die Masterseiten-Skripte aufgerufen wurden).
- Untergeordneter Seiteninhaltsblock 2.
Hier ist das Markup oben auf der Masterseite:
<%@ 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>
Im Hauptteil der Masterseite befindet sich dann ein zusätzlicher ContentPlaceHolder:
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
Auf der untergeordneten Seite sieht es so aus:
<%@ 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>
Hier ist der Inhalt der Datei "../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();
});
});
quelle
$(document).ready(function(){...});
?<script src="...">
Tags laden , kann dies nicht passieren. Verwenden Sie so etwas wie RequireJS oder LABjs?$(document).ready()
oder aus$(window).load()
? Könnten wir ein Beispiel sehen?type="text/Scripts"
zutype="text/javascript"
, oder loszuwerden, alles zusammen ist es nicht mehr nötig, bekommen auch die loszuwerdenlanguage="javascript
. Könnte auch anfangen, Dinge auszuprobieren.Antworten:
bearbeiten
Könnten Sie den richtigen Typ für Ihre Skript-Tags ausprobieren? Ich sehe, dass Sie verwenden
text/Scripts
, was nicht der richtige Mimetyp für Javascript ist.Benutze das:
Ende bearbeiten
Oder schauen Sie sich require.js an , einen Loader für Ihren Javascript-Code.
Abhängig von Ihrem Projekt kann dies jedoch etwas übertrieben sein
quelle
Spät zur Party und ähnlich wie Briguy37s Frage, aber zum späteren Nachschlagen verwende ich die folgende Methode und übergebe die Funktionen, die ich verschieben möchte, bis jQuery geladen ist:
Die Defer-Methode wird alle 50 ms rekursiv aufgerufen, bis sie
window.jQuery
existiert. Zu diesem Zeitpunkt wird sie beendet und aufgerufenmethod()
Ein Beispiel mit einer anonymen Funktion:
quelle
script
Tag, das jQuery lädt, eindefer
Attribut hätte, es das Problem verursachen würde, indem es trotz der vom Code definierten Reihenfolge der Skripte erst später geladen wird.Sie können das Attribut defer verwenden, um das Skript am Ende zu laden.
Normalerweise sollte das Laden Ihres Skripts in der richtigen Reihenfolge den Trick tun. Stellen Sie daher sicher, dass Sie die jquery-Aufnahme vor Ihrem eigenen Skript platzieren
Wenn sich Ihr Code auf der Seite und nicht in einer separaten js-Datei befindet, müssen Sie Ihr Skript erst ausführen, nachdem das Dokument fertig ist und die Kapselung Ihres Codes wie folgt funktioniert:
quelle
Ein weiterer Weg, dies zu tun, obwohl Darbios Aufschubmethode flexibler ist.
quelle
Der einfachste und sicherste Weg ist, so etwas zu verwenden:
quelle
Sie können das Onload-Ereignis ausprobieren. Es wird ausgelöst, wenn alle Skripte geladen wurden:
Beachten Sie jedoch, dass Sie möglicherweise andere Skripts überschreiben, in denen window.onload verwendet wird.
quelle
Ich habe festgestellt, dass die vorgeschlagene Lösung nur unter Berücksichtigung von asynchronem Code funktioniert. Hier ist die Version, die in beiden Fällen funktionieren würde:
quelle
load
Funktion übergeben, aber dann auch wiederverwendensetTimeout
.Stellen Sie sich vor, Sie verwenden eine coole PHP-Template-Engine, damit Sie Ihr Basislayout haben:
Und natürlich lesen Sie irgendwo, dass es besser ist, Javascript am Ende der Seite zu laden, damit Ihr dynamischer Inhalt nicht weiß, wer jQuery (oder das $) ist.
Außerdem liest du irgendwo, wo es gut ist, kleines Javascript zu integrieren. Stell dir also vor, du brauchst jQuery auf einer Seite, baboom, $ ist nicht definiert (.. noch ^^).
Ich liebe die Lösung, die Facebook bietet
Als fauler Programmierer (ich sollte sagen ein guter Programmierer ^^) können Sie also ein Äquivalent (innerhalb Ihrer Seite) verwenden:
Und fügen Sie am Ende Ihres Layouts hinzu, nachdem Sie jQuery eingeschlossen haben
quelle
Anstatt zu warten (was normalerweise mit verwendet wird
setTimeout
), können Sie auch die Definition des jQuery-Objekts im Fenster selbst als Hook verwenden, um Ihren darauf basierenden Code auszuführen. Dies ist durch eine Eigenschaftsdefinition erreichbar, die mit definiert wirdObject.defineProperty
.quelle
window.jQuery
ein Wert, indem diejQuery
Variable im globalen Bereich (dhwindow
) definiert wird. Dadurch wird die Eigenschaft zum Einstellen von Eigenschaften für das im Code definierte Fensterobjekt ausgelöst.</body>
statt vorher zu setzen</head>
Verwenden:
Weitere Informationen finden Sie hier: http://www.learningjquery.com/2006/09/introducing-document-ready
Hinweis: Dies sollte funktionieren, solange der Skriptimport für Ihre JQuery-Bibliothek über diesem Aufruf liegt.
Aktualisieren:
Wenn Ihr Code aus irgendeinem Grund nicht synchron geladen wird (was
ich noch nie erlebt habe, aber anscheinend aus dem folgenden Kommentar möglich seinsollte, sollte dies nicht passieren), können Sie ihn wie folgt codieren.quelle
Ich mag die Intervall-Dinger nicht besonders. Wenn ich jquery oder irgendetwas anderes aufschieben möchte, geht es normalerweise so.
Beginnen mit:
Dann:
Dann endlich:
Oder die weniger umwerfende Version:
Und im Falle von Async können Sie die Push-Funktionen bei jquery onload ausführen.
Alternative:
quelle
Ich denke nicht, dass das dein Problem ist. Das Laden von Skripten ist standardmäßig synchron.
defer
Wenn Sie also nicht das Attribut verwenden oder jQuery selbst über eine andere AJAX-Anforderung laden, ähnelt Ihr Problem wahrscheinlich eher einem 404. Können Sie Ihr Markup anzeigen und uns mitteilen, wenn Sie etwas Verdächtiges sehen Firebug oder Web Inspector?quelle
Lassen Sie uns
defer()
von Dario aus erweitern , um wiederverwendbarer zu werden.Welches wird dann ausgeführt:
quelle
Überprüfen Sie dies:
https://jsfiddle.net/neohunter/ey2pqt5z/
Es wird ein gefälschtes jQuery-Objekt erstellt, mit dem Sie die Onload-Methoden von jquery verwenden können. Diese werden ausgeführt, sobald jquery geladen wird.
Es ist nicht perfekt.
quelle
Eine tangentiale Anmerkung zu den Ansätzen hier, die Last verwenden
setTimeout
odersetInterval
. In diesen Fällen ist es möglich, dass bei erneuter Ausführung Ihrer Prüfung das DOM bereits geladen wurde und dasDOMContentLoaded
Ereignis des Browsers ausgelöst wurde, sodass Sie dieses Ereignis mit diesen Ansätzen nicht zuverlässig erkennen können. Was ich gefunden habe ist, dass jQuery immerready
noch funktioniert, so dass Sie Ihr übliches einbetten könnenjQuery(document).ready(function ($) { ... }
in deinem
setTimeout
odersetInterval
und alles sollte wie gewohnt funktionieren.quelle