Pergunta

Meu site estava usando jquery.load() Para fazer a navegação em uma grande parte da página. Eu realmente aprecio a capacidade de incluir apenas uma parte específica do conteúdo carregado, aqui o div com id = "content":

$(frame_selector).load(url +" #content", function(response, status, xhr) {...});

Mas agora preciso executar scripts que fazem parte das páginas que estão sendo carregadas dinamicamente. Jquery.load() retire esses scripts, mas jquery.ajax() não. Então eu dupliquei a funcionalidade de conteúdo parcial de jquery.load Em uma chamada de Ajax como tal:

$.ajax({
  url: url,
  dataType: 'html', 
  success: function(data, textStatus, XMLHttpRequest) {
      // Only include the response within the #content id element.
      $(frame_selector).html( jQuery("<div>")
            .append(data)
            .find("#content")
      );
  }
});

O problema é que os scripts que estão sendo carregados dinamicamente da chamada do Ajax não estão funcionando de maneira confiável. Às vezes, eles não parecem ter nenhum efeito, talvez porque estejam correndo muito cedo. Os scripts estão apenas fazendo manipulação de DOM no jQuery - não confiando em imagens ou flash ou qualquer coisa que ainda não deve ser carregada. Para não ficar preso, tenho esse hacking hediondo para fazer as coisas funcionarem. Em vez do script carregado de Ajax apenas usando:

$(document).ready( function() {...} );  // unreliable

Eu adio o script 200ms antes de correr:

$(document).ready( window.setTimeout( function() {...}, 200 )); // HATE THIS

Alguém sabe como posso fazer com que esse trabalho de forma confiável sem codificar um atraso? Acho que é uma condição de corrida entre o <script> E minha lógica para carregar #content em uma nova div, mas não tenho certeza do que fazer sobre isso.

Foi útil?

Solução

Presumo que os scripts estejam manipulando os elementos DOM que você está adicionando através do AJAX.

JQuery tem um isReady propriedade que ela define quando o ready O evento foi acionado na página.

Quaisquer chamadas subsequentes para jQuery.ready(...) Vai primeiro verificar isso isReady bandeira. Se o sinalizador estiver definido como true, ele ligará para o manipulador imediatamente. Você pode ver por que isso causaria problemas em seu código.

Uma opção seria carregar a resposta em um fragmento de jQuery e analisar todos os <script /> Tags para execução mais tarde.

var ajaxResponse = $(html);
var scripts = ajaxResponse.find('script');

// Move your scripts into a new element
var tempScripts = $().append(scripts);

// Append your content, followed by your script tags
$(document).append(ajaxResponse);
$(document).append(tempScripts);

Outras dicas

@Dan tem a resposta. Ao carregar scripts via Ajax, o documento isReady é verdade. Isso significa que se esta é a tag de script solicitada pela sua solicitação AJAX:

<script type="text/javascript">
    if (jQuery.isReady) {
        $('body').append("<div id='new_content'>Document Ready</div>");
    }
    else {
        $('body').append("<div id='new_content'>Document Not Ready</div>");
    }
</script>

Em vez de analisar, utilize JSON. Uma propriedade manterá HTML. Outra propriedade manterá os scripts.

Então você pode fazer isso:

$(document).append(ajaxResponse.html);
$(document).append(ajaxResponse.script);

Além disso, se você carregar scripts com a função pronta em torno do código, ela criará um fechamento. Este fechamento durará a vida útil da página. Os vazamentos de memória serão criados toda vez que você solicitar esse script sem atualizar sua página

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top