Wywołanie jQuery .load () nie wykonuje JavaScript w załadowanym pliku HTML

83

Wydaje się, że jest to problem związany tylko z Safari. Wypróbowałem 4 na Macu i 3 na Windowsie i nadal nie mam szczęścia.

Próbuję załadować zewnętrzny plik HTML i wykonać osadzony JavaScript.

Kod, którego próbuję użyć, jest następujący:

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

trackingCode.html wygląda następująco (teraz jest prosty, ale rozwinie się raz / jeśli to działa):

<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>

Widzę oba komunikaty ostrzegawcze w IE (6 i 7) oraz Firefox (2 i 3). Nie widzę jednak wiadomości w Safari (ostatnia przeglądarka, którą muszę się martwić - wymagania projektu - proszę o żadne wojny ognia).

Jakieś przemyślenia na temat tego, dlaczego Safari ignoruje JavaScript w trackingCode.htmlpliku?

Ostatecznie chciałbym móc przekazywać obiekty JavaScript do tego trackingCode.htmlpliku, aby były używane w wywołaniu gotowym do jQuery, ale chciałbym się upewnić, że jest to możliwe we wszystkich przeglądarkach, zanim pójdę tą drogą.

Mikrofon
źródło

Odpowiedzi:

56

Ładujesz całą stronę HTML do swojego div, w tym tagi html, head i body. Co się stanie, jeśli wykonasz ładowanie i masz tylko skrypt otwierający, skrypt zamykający i kod JavaScript w ładowanym kodzie HTML?

Oto strona sterownika:

<!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>

Oto zawartość trackingCode.html:

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

To działa dla mnie w Safari 4.

Aktualizacja: Dodano przestrzeń nazw DOCTYPE i html, aby dopasować kod w moim środowisku testowym. Testowane z przeglądarką Firefox 3.6.13 i przykładowy kod działa.

Tony Miller
źródło
1
Rozumiem, dzięki Tony! Usunięcie tagów <html>, <head> i <body> wydawało się załatwić sprawę.
Mike
1
Wędrowałem, czy powinienem wykonać oddzielne wywołanie Ajax getJson (), ponieważ słyszałem o tym .. Ale jeśli to działa tak, jest w porządku! W przeciwnym razie dwa razy bym zadzwonił do tych samych zapytań
GorillaApe
2
Twój kod faktycznie nie działa w FF (IE8 - działa dobrze). Czy istnieje sposób, aby to działało we wszystkich przeglądarkach? Dzięki
1
@Maxim Galushka Nadal miałem te pliki na mojej osobistej stacji roboczej. Bez modyfikacji powodowały prawidłowe zachowanie. Używam przeglądarki Firefox 3.6.13 w systemie Windows 7.
Tony Miller,
41
$("#images").load(location.href+" #images",function(){
    $.getScript("js/productHelper.js"); 
});
xtds
źródło
To załatwiło sprawę dla mnie. Oto przykład, który możesz wypróbować: var frmAcademicCalendar = "frmAcademicCalendar.aspx" if (window.location.href.toLowerCase (). IndexOf (frmAcademicCalendar.toLowerCase ())> = 0) {$ ("# IncludeCMSContent"). load (" example.com #externalContent", function () {$ .getScript ("example.js");}); }
Evan,
25

Inna wersja wcześniejszego rozwiązania Johna Pick'a działa dobrze:

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
źródło
2
To najlepsze rozwiązanie! Kocham Cię @Yannick, zrobiłeś mój dzień
utiq
15

Zdaję sobie sprawę, że jest to nieco starszy post, ale dla każdego, kto przychodzi na tę stronę i szuka podobnego rozwiązania ...

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

jQuery.getScript( url, [ success(data, textStatus) ] )
  • url - ciąg zawierający adres URL, do którego wysyłane jest żądanie.

  • success(data, textStatus) - Funkcja zwrotna, która jest wykonywana, jeśli żądanie się powiedzie.

$.getScript('ajax/test.js', function() {
  alert('Load was performed.');
});
ryan
źródło
11

Wydaje się, że to nie działa, jeśli ładujesz pole HTML do dynamicznie utworzonego elementu.

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

Patrzę na firebug DOM i nie ma żadnego węzła skryptu, tylko HTML i mój węzeł CSS.

Czy ktoś to spotkał?

tim
źródło
Musiałem załadować html, a następnie w wywołaniu zwrotnym użyć $ .getScript, aby uzyskać javascript.
Dex
1
Koleś! Rozwiązałeś mój problem około 8 lat wcześniej. Dzięki: D
Skorek
3

Prawie to masz. Powiedz jquery, że chcesz załadować tylko skrypt:

$("#myBtn").click(function() {
    $("#myDiv").load("trackingCode.html script");
});
John Pick
źródło
7
Ale to wydaje się ładować TYLKO i skrypt. Jak sprawić, by załadował zawartość HTML ORAZ uruchomił dowolny javascript, który może zawierać?
ThatAintWorking
2

Przetestuj z tym w trackingCode.html:

<script type="text/javascript">

    $(function() {

       show_alert();

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

    });
 </script>
Aamir
źródło
1

Natknąłem się na to, w którym skrypty ładowały się raz, ale powtarzanie wywołań nie powodowało uruchomienia skryptu.

Okazało się, że wystąpił problem z używaniem .html () do wyświetlenia wskaźnika oczekiwania, a następnie połączeniem .load () po nim.

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

Kiedy wykonywałem oddzielne wywołania, moje wbudowane skrypty ładowały się za każdym razem zgodnie z oczekiwaniami.

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

Aby uzyskać dalsze badania, zwróć uwagę, że istnieją dwie wersje .load ()

Proste wywołanie .load () (bez selektora po adresie url) jest po prostu skrótem do wywołania $ .ajax () z dataType: "html" i pobrania zwracanej zawartości i wywołania .html () w celu umieszczenia tej zawartości w DOM . Dokumentacja dotycząca dataType: „html” wyraźnie stwierdza, że ​​„dołączone tagi skryptów są oceniane po wstawieniu do DOM”. http://api.jquery.com/jquery.ajax/ So .load () oficjalnie uruchamia skrypty wbudowane.

Złożone wywołanie .load () ma selektor, taki jak load ("page.html #content"). Gdy jest używany w ten sposób, jQuery celowo odfiltrowuje tagi skryptów, jak omówiono w artykułach takich jak ten: https://forum.jquery.com/topic/the-load-function-and-script-blocks#14737000000752785 W tym przypadku skrypty nigdy uciekaj, ani razu.

efreed
źródło
1

Jeśli chcesz załadować zarówno kod HTML, jak i skrypty, oto bardziej zautomatyzowany sposób, korzystając z obu $(selector).load()i jQuery.getScript(). Ten konkretny przykład ładuje zawartość HTML elementu o identyfikatorze „toLoad” z content.html, wstawia kod HTML do elementu o identyfikatorze „content”, a następnie ładuje i uruchamia wszystkie skrypty w elemencie o identyfikatorze „toLoad”.

$("#content").load("content.html #toLoad", function(data) {
    var scripts = $(data).find("script");

    if (scripts.length) {
        $(scripts).each(function() {
            if ($(this).attr("src")) {
                $.getScript($(this).attr("src"));
            }
            else {
                eval($(this).html());
            }
        });
    }

});

Ten kod znajduje wszystkie elementy skryptu w ładowanej treści i przechodzi przez każdy z tych elementów. Jeśli element posiada srcatrybut, czyli jest to skrypt z zewnętrznego pliku, używamy jQuery.getScriptmetody pobierania i uruchamiania skryptu. Jeśli element nie ma srcatrybutu, co oznacza, że ​​jest to skrypt wbudowany, po prostu używamy go evaldo uruchamiania kodu. Jeśli nie znajdzie żadnych elementów skryptu, wstawia wyłącznie kod HTML do elementu docelowego i nie próbuje załadować żadnych skryptów.

Przetestowałem tę metodę w Chrome i działa. Pamiętaj, aby zachować ostrożność podczas używania eval, ponieważ może uruchamiać potencjalnie niebezpieczne skrypty i jest ogólnie uważany za szkodliwy. Możesz chcieć uniknąć używania wbudowanych skryptów podczas korzystania z tej metody, aby uniknąć konieczności używania eval.

Cannicide
źródło
0

Cóż, miałem ten sam problem, który wydawał się występować tylko w Firefoksie, i nie mogłem użyć innego polecenia JQuery oprócz .load (), ponieważ modyfikowałem front-end na istniejących plikach PHP ...

W każdym razie po użyciu polecenia .load () osadziłem mój skrypt JQuery w zewnętrznym ładowanym kodzie HTML i wydawało się, że działa. Nie rozumiem, dlaczego JS, który załadowałem na górze głównego dokumentu, nie działał dla nowej zawartości, jednak ...

Victor G. Reano
źródło
Łatwe, ponieważ nowej treści nie było w momencie wykonywania skryptu.
Matteo
0

Udało mi się rozwiązać ten problem, zmieniając $(document).ready()na window.onLoad().

Casey Dwayne
źródło
0

Tacking do @efreed answer ...

Używałem .load('mypage.html #theSelectorIwanted')do wywoływania treści ze strony za pomocą selektora, ale oznacza to, że nie wykonuje skryptów wbudowanych w środku.

Zamiast tego mogłem zmienić moje znaczniki, aby '#theSelectorIwanted'stały się własnym plikiem i użyłem

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

i działał dobrze wbudowane skrypty.

Nie każdy ma tę opcję, ale było to szybkie obejście, aby dostać się tam, gdzie chciałem!

RCNeil
źródło