Estou tendo um problema de carregamento da página tão rápido que o jquery não terminou de carregar antes de ser chamado por um script subsequente. Existe uma maneira de verificar a existência de jquery e se ele não existir, aguarde um momento e tente novamente?
Em resposta às respostas / comentários abaixo, estou postando algumas das marcações.
A situação ... masterpage asp.net e childpage.
Na masterpage, tenho uma referência a jquery. Então, na página de conteúdo, tenho uma referência ao script específico da página. Quando o script específico da página está sendo carregado, ele reclama que "$ é indefinido".
Coloquei alertas em vários pontos da marcação para ver a ordem em que as coisas estavam disparando e confirmei que ele dispara nesta ordem:
- Cabeçalho da página mestra.
- Bloco 1 de conteúdo da página filha (localizado dentro do cabeçalho da página-mestre, mas depois que os scripts da página-mestre são chamados).
- Bloco 2 do conteúdo da página filha.
Aqui está a marcação no topo da página-mestre:
<%@ 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>
Então, no corpo da página-mestre, há um ContentPlaceHolder adicional:
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
Na página filha, é assim:
<%@ 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>
Aqui está o conteúdo do arquivo "../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();
});
});
fonte
$(document).ready(function(){...});
?<script src="...">
tags simples , isso não pode acontecer. Você está usando algo como RequireJS ou LABjs?$(document).ready()
ou$(window).load()
? Podemos ver um exemplo?type="text/Scripts"
paratype="text/javascript"
, ou livre-se de tudo junto, não é mais necessário, e livre-se também dolanguage="javascript
. É melhor começar a tentar coisas.Respostas:
editar
Você poderia tentar o tipo correto para suas tags de script? Vejo que você usa
text/Scripts
, que não é o tipo MIME correto para javascript.Usa isto:
fim da edição
ou você pode dar uma olhada em require.js que é um carregador para seu código javascript.
dependendo do seu projeto, isso pode ser um pouco exagero
fonte
Atrasado para a festa, e semelhante à pergunta de Briguy37, mas para referência futura, uso o seguinte método e passo as funções que desejo adiar até que o jQuery seja carregado:
Ele irá chamar recursivamente o método defer a cada 50 ms até que
window.jQuery
exista, momento em que ele sai e chamamethod()
Um exemplo com uma função anônima:
fonte
script
tag que carrega jQuery tivesse umdefer
atributo, isso causaria o problema por não carregar até mais tarde, apesar da ordem dos scripts definida pelo código.você pode usar o atributo defer para carregar o script no final.
mas normalmente carregar seu script na ordem correta deve resolver, então certifique-se de colocar a inclusão jquery antes de seu próprio script
Se seu código estiver na página e não em um arquivo js separado, você deve executar seu script somente depois que o documento estiver pronto e encapsular seu código desta forma também deve funcionar:
fonte
Mais uma maneira de fazer isso, embora o método de adiamento de Darbio seja mais flexível.
fonte
a maneira mais fácil e segura é usar algo assim:
fonte
Você pode tentar o evento onload. Ele é gerado quando todos os scripts são carregados:
Mas tenha em mente que você pode sobrescrever outros scripts onde window.onload usando.
fonte
Descobri que a solução sugerida só funciona considerando o código assíncrono. Aqui está a versão que funcionaria em ambos os casos:
fonte
load
função, mas também a reutilizasetTimeout
.É um problema comum, imagine que você usa um mecanismo de modelagem de PHP legal, então você tem seu layout básico:
E, claro, você leu em algum lugar, é melhor carregar Javascript na parte inferior da página, para que seu conteúdo dinâmico não saiba quem é jQuery (ou o $).
Além disso, você leu em algum lugar que é bom incorporar Javascript pequeno, então imagine que você precisa do jQuery em uma página, baboom, $ não está definido (.. ainda ^^).
Eu amo a solução que o Facebook oferece
Portanto, como um programador preguiçoso (devo dizer um bom programador ^^), você pode usar um equivalente (dentro de sua página):
E adicione na parte inferior do seu layout, após jQuery incluir
fonte
Em vez de "esperar" (o que geralmente é feito usando
setTimeout
), você também pode usar a definição do objeto jQuery na própria janela como um gancho para executar seu código que depende dele. Isso é possível por meio de uma definição de propriedade, definida usandoObject.defineProperty
.fonte
window.jQuery
um valor, definindo ajQuery
variável no escopo global (ou sejawindow
). Isso irá disparar a função configuradora de propriedade no objeto de janela definido no código.</body>
vez de antes</head>
Usar:
Verifique isso para obter mais informações: http://www.learningjquery.com/2006/09/introducing-document-ready
Nota: Isso deve funcionar contanto que a importação de script para sua biblioteca JQuery esteja acima desta chamada.
Atualizar:
Se por algum motivo seu código não estiver carregando de forma síncrona (o que
eu nunca encontrei, mas aparentemente pode ser possível a partir do comentário abaixonão deve acontecer), você pode codificá-lo como o seguinte.fonte
Eu não gosto muito de coisas de intervalo. Quando eu quero adiar o jquery, ou qualquer coisa na verdade, geralmente é algo assim.
Começar com:
Então:
Então finalmente:
Ou a versão menos incompreensível:
E, no caso de assíncrono, você pode executar as funções enviadas em jquery onload.
Alternativamente:
fonte
Não acho que seja problema seu. O carregamento do script é síncrono por padrão, então, a menos que você esteja usando o
defer
atributo ou carregando o próprio jQuery por meio de outra solicitação AJAX, seu problema é provavelmente algo mais como 404. Você pode mostrar sua marcação e nos avise se encontrar algo suspeito em firebug ou inspetor da web?fonte
Vamos expandir
defer()
de Dario para ser mais reutilizável.Que é então executado:
fonte
Verifique isto:
https://jsfiddle.net/neohunter/ey2pqt5z/
Ele criará um objeto jQuery falso, que permite que você use os métodos onload do jquery, e eles serão executados assim que o jquery for carregado.
Não é perfeito.
fonte
Uma nota tangencial sobre as abordagens aqui que usam
setTimeout
ou de cargasetInterval
. Nesses casos, é possível que, quando a verificação for executada novamente, o DOM já tenha sido carregado e oDOMContentLoaded
evento do navegador tenha sido disparado, portanto, você não pode detectar esse evento de forma confiável usando essas abordagens. O que descobri é que o jQueryready
ainda funciona, então você pode incorporar seujQuery(document).ready(function ($) { ... }
dentro de seu
setTimeout
ousetInterval
e tudo deve funcionar normalmente.fonte