A chamada jQuery .load () não executa JavaScript no arquivo HTML carregado

83

Este parece ser um problema relacionado apenas ao Safari. Tentei 4 no Mac e 3 no Windows e ainda não estou tendo sorte.

Estou tentando carregar um arquivo HTML externo e fazer com que o JavaScript incorporado seja executado.

O código que estou tentando usar é este:

$("#myBtn").click(function() {
    $("#myDiv").load("trackingCode.html");
});

trackingCode.html se parece com isto (simples agora, mas irá expandir uma vez / se eu fizer isso funcionar):

<html>
<head>
    <title>Tracking HTML File</title>
    <script language="javascript" type="text/javascript">
        alert("outside the jQuery ready");
        $(function() {
            alert("inside the jQuery ready");
        });
    </script>
</head>

<body>
</body>
</html>

Estou vendo mensagens de alerta no IE (6 e 7) e no Firefox (2 e 3). No entanto, não consigo ver as mensagens no Safari (o último navegador com o qual preciso me preocupar - requisitos do projeto - por favor, sem guerras).

Alguma idéia de por que o Safari está ignorando o JavaScript no trackingCode.htmlarquivo?

Eventualmente, gostaria de ser capaz de passar objetos JavaScript para este trackingCode.htmlarquivo para ser usado na chamada pronta do jQuery, mas gostaria de ter certeza de que isso seja possível em todos os navegadores antes de seguir por esse caminho.

Mike
fonte

Respostas:

56

Você está carregando uma página HTML inteira em seu div, incluindo as tags html, head e body. O que acontecerá se você carregar e tiver apenas o script de abertura, o script de fechamento e o código JavaScript no HTML carregado?

Aqui está a página do driver:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>jQuery Load of Script</title>
        <script type="text/javascript" src="http://www.google.com/jsapi"></script>
        <script type="text/javascript">
            google.load("jquery", "1.3.2");
        </script>
        <script type="text/javascript">
            $(document).ready(function(){
                $("#myButton").click(function() {
                    $("#myDiv").load("trackingCode.html");
                });
             });
         </script>
    </head>
    <body>
        <button id="myButton">Click Me</button>
        <div id="myDiv"></div>
    </body>
</html>

Aqui está o conteúdo de trackingCode.html:

<script type="text/javascript">
    alert("Outside the jQuery ready");
    $(function() {
        alert("Inside the jQuery ready");
    });
 </script>

Isso funciona para mim no Safari 4.

Atualização: Adicionados DOCTYPE e namespace html para corresponder ao código em meu ambiente de teste. Testado com Firefox 3.6.13 e funciona com código de exemplo.

Tony Miller
fonte
1
Entendi, obrigado Tony! Remover as tags <html>, <head> e <body> pareceu resolver o problema.
Mike de
1
Eu estava pensando se eu deveria fazer uma chamada separada de ajax getJson () porque eu ouvi falar disso .. Mas se funcionar assim está tudo bem! Caso contrário, eu chamaria as mesmas consultas duas vezes
GorillaApe
2
Seu código não está realmente funcionando no FF (IE8 - funcionando bem). Existe uma maneira de fazer isso funcionar em todos os navegadores? Obrigado
1
@Maxim Galushka Eu ainda tinha esses arquivos na minha estação de trabalho pessoal. Sem modificação, eles produziram o comportamento correto. Estou usando o Firefox 3.6.13 no Windows 7.
Tony Miller
41
$("#images").load(location.href+" #images",function(){
    $.getScript("js/productHelper.js"); 
});
xtds
fonte
Isso funcionou para mim. Aqui está um exemplo que você pode tentar: var frmAcademicCalendar = "frmAcademicCalendar.aspx" if (window.location.href.toLowerCase (). IndexOf (frmAcademicCalendar.toLowerCase ())> = 0) {$ ("# IncludeCMSContent"). load (" example.com #externalContent", function () {$ .getScript ("example.js");}); }
Evan
25

Uma outra versão da solução de John Pick um pouco antes, funciona bem para mim:

jQuery.ajax({
   ....
   success: function(data, textStatus, jqXHR) {
       jQuery(selecteur).html(jqXHR.responseText);
       var reponse = jQuery(jqXHR.responseText);
       var reponseScript = reponse.filter("script");
       jQuery.each(reponseScript, function(idx, val) { eval(val.text); } );
   }
   ...
});
Yannick
fonte
2
Esta é a melhor solução !, eu te amo @Yannick, você fez meu dia
utiq
15

Sei que este é um post mais antigo, mas para quem vem a esta página em busca de uma solução semelhante ...

http://api.jquery.com/jQuery.getScript/

jQuery.getScript( url, [ success(data, textStatus) ] )
  • url - Uma string contendo o URL para o qual a solicitação é enviada.

  • success(data, textStatus) - Uma função de retorno de chamada que é executada se a solicitação for bem-sucedida.

$.getScript('ajax/test.js', function() {
  alert('Load was performed.');
});
Ryan
fonte
11

Isso não parece funcionar se você estiver carregando o campo HTML em um elemento criado dinamicamente.

$('body').append('<div id="loader"></div>');
$('#loader').load('htmlwithscript.htm');

Eu olho para o Firebug DOM e não há nenhum nó de script, apenas o nó HTML e meu CSS.

Alguém já encontrou isso?

tim
fonte
Tive que carregar o html, então no callback, usar $ .getScript para pegar o javascript.
Dex
1
Cara! Você resolveu meu problema cerca de 8 anos antes. Obrigado: D
Skorek
3

Você quase conseguiu. Diga ao jquery que você deseja carregar apenas o script:

$("#myBtn").click(function() {
    $("#myDiv").load("trackingCode.html script");
});
John Pick
fonte
7
Mas isso parece carregar SÓ e o script. Como você faz para carregar o conteúdo html E executar qualquer javascript que ele possa conter?
ThatAintWorking
2

Teste com trackingCode.html:

<script type="text/javascript">

    $(function() {

       show_alert();

       function show_alert() {
           alert("Inside the jQuery ready");
       }

    });
 </script>
Aamir
fonte
1

Eu encontrei isso onde os scripts carregariam uma vez, mas as chamadas repetidas não executariam o script.

Acabou sendo um problema usar .html () para exibir um indicador de espera e, em seguida, encadear .load () depois dele.

// Processes scripts as expected once per page load, but not for repeat calls
$("#id").html("<img src=wait.gif>").load("page.html");

Quando fiz chamadas separadas, meus scripts embutidos carregaram sempre conforme o esperado.

// Without chaining html and load together, scripts are processed as expected every time
$("#id").html("<img src=wait.gif>");
$("#id").load("page.html");

Para pesquisas futuras, observe que existem duas versões de .load ()

Uma chamada .load () simples (sem um seletor após o url) é simplesmente uma abreviação para chamar $ .ajax () com dataType: "html" e pegar o conteúdo de retorno e chamar .html () para colocar esse conteúdo no DOM . E a documentação para dataType: "html" afirma claramente "as tags de script incluídas são avaliadas quando inseridas no DOM." http://api.jquery.com/jquery.ajax/ Então .load () executa oficialmente scripts embutidos.

Uma chamada .load () complexa tem um seletor como load ("page.html #content"). Quando usado dessa forma, o jQuery filtra propositadamente as tags de script, conforme discutido em artigos como este: https://forum.jquery.com/topic/the-load-function-and-script-blocks#14737000000752785 Neste caso, os scripts nunca correr, nem mesmo uma vez.

efreed
fonte
0

Bem, eu tive o mesmo problema que parecia acontecer apenas com o Firefox, e não pude usar outro comando JQuery exceto para .load (), pois estava modificando o front-end em arquivos PHP existentes ...

De qualquer forma, depois de usar o comando .load (), embuti meu script JQuery no HTML externo que estava sendo carregado e pareceu funcionar. Não entendo por que o JS que carreguei na parte superior do documento principal não funcionou com o novo conteúdo ...

Victor G. Reano
fonte
Fácil, porque o novo conteúdo não estava lá quando o script foi executado.
Matteo
0

Consegui corrigir esse problema mudando $(document).ready()para window.onLoad().

Casey Dwayne
fonte
0

Seguindo a resposta @efreed ...

Eu estava usando .load('mypage.html #theSelectorIwanted')para chamar o conteúdo de uma página pelo seletor, mas isso significa que ele não executa os scripts embutidos dentro.

Em vez disso, consegui alterar minha marcação para que '#theSelectorIwanted'se tornasse seu próprio arquivo e usei

load('theSelectorIwanted.html`, function() {}); 

e executou perfeitamente os scripts embutidos.

Nem todo mundo tem essa opção, mas essa foi uma solução rápida para chegar onde eu queria!

RCNeil
fonte