Вызов jQuery .load () не выполняет JavaScript в загруженном HTML-файле


83

Кажется, это проблема, связанная только с Safari. Я пробовал 4 на Mac и 3 на Windows, и мне все еще не повезло.

Я пытаюсь загрузить внешний файл HTML и выполнить встроенный JavaScript.

Код, который я пытаюсь использовать, таков:

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

trackingCode.html выглядит так (сейчас просто, но будет расширяться один раз / если у меня это сработает):

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

Я вижу оба предупреждающих сообщения в IE (6 и 7) и Firefox (2 и 3). Однако я не могу видеть сообщения в Safari (последний браузер, о котором я должен беспокоиться - требования проекта - пожалуйста, не пламя войн).

Есть мысли о том, почему Safari игнорирует JavaScript в trackingCode.htmlфайле?

В конце концов, я хотел бы иметь возможность передавать объекты JavaScript в этот trackingCode.htmlфайл для использования в вызове jQuery ready, но я хотел бы убедиться, что это возможно во всех браузерах, прежде чем я пойду по этому пути.

Ответы:


56

Вы загружаете в свой div целую HTML-страницу, включая теги html, head и body. Что произойдет, если вы выполните загрузку и в загружаемом HTML-коде есть только сценарий открытия, сценарий закрытия и код JavaScript?

Вот страница драйвера:

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

Вот содержимое файла trackingCode.html:

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

У меня это работает в Safari 4.

Обновление: добавлено пространство имен DOCTYPE и html для соответствия коду в моей тестовой среде. Протестировано с Firefox 3.6.13, и пример кода работает.


1
Понятно, спасибо, Тони! Удаление тегов <html>, <head> и <body>, похоже, помогло.
Майк,

1
я бродил, должен ли я сделать отдельный вызов ajax getJson (), потому что я слышал об этом .. Но если он работает так, все в порядке !! В противном случае я бы назвал те же запросы дважды
GorillaApe

2
Ваш код на самом деле не работает в FF (IE8 - работает нормально). Есть ли способ заставить это работать во всех браузерах? Спасибо

1
@Maxim Galushka Эти файлы остались на моей рабочей станции. Без модификации они показали правильное поведение. Я использую Firefox 3.6.13 в Windows 7.
Тони Миллер

41
$("#images").load(location.href+" #images",function(){
    $.getScript("js/productHelper.js"); 
});

Это помогло мне. Вот пример, который вы можете попробовать: var frmAcademicCalendar = "frmAcademicCalendar.aspx" if (window.location.href.toLowerCase (). IndexOf (frmAcademicCalendar.toLowerCase ())> = 0) {$ ("# IncludeCMSContent"). load (" example.com #externalContent", function () {$ .getScript ("example.js");}); }
Evan

25

Другая версия решения Джона Пика как раз раньше, это отлично работает для меня:

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); } );
   }
   ...
});

2
Это лучшее решение !, я люблю тебя @Yannick, ты сделал мой день
utiq

15

Я понимаю, что это что-то вроде более старого поста, но для всех, кто заходит на эту страницу в поисках аналогичного решения ...

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

jQuery.getScript( url, [ success(data, textStatus) ] )
  • url - Строка, содержащая URL-адрес, на который отправляется запрос.

  • success(data, textStatus) - Функция обратного вызова, которая выполняется, если запрос выполнен успешно.

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

11

Это не работает, если вы загружаете поле HTML в динамически создаваемый элемент.

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

Я смотрю на firebug DOM, и там вообще нет узла сценария, только HTML и мой узел CSS.

Кто-нибудь сталкивался с этим?


Мне пришлось загрузить html, а затем в обратном вызове использовать $ .getScript, чтобы получить javascript.
Dex

1
Чувак! Вы решили мою проблему лет 8 назад. Спасибо: D
Skorek

3

Вы почти получили это. Скажите jquery, что вы хотите загрузить только скрипт:

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

7
Но это похоже ТОЛЬКО для загрузки и скрипта. Как заставить его загружать html-контент И запускать любой javascript, который он может содержать?
ThatAintWorking 02


2

Проверьте это в файле trackingCode.html:

<script type="text/javascript">

    $(function() {

       show_alert();

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

    });
 </script>

1

Я столкнулся с этим, когда скрипты загружались один раз, но повторные вызовы не запускали скрипт.

Оказалось, что проблема заключается в использовании .html () для отображения индикатора ожидания и последующего связывания .load () после него.

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

Когда я делал им отдельные вызовы, мои встроенные скрипты загружались каждый раз, как и ожидалось.

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

Для дальнейшего исследования обратите внимание, что существует две версии .load ()

Простой вызов .load () (без селектора после URL) - это просто сокращение для вызова $ .ajax () с dataType: "html" и получения возвращаемого содержимого и вызова .html () для помещения этого содержимого в DOM . А в документации для dataType: «html» четко указано, что «включенные теги сценария оцениваются при вставке в DOM». http://api.jquery.com/jquery.ajax/ Итак .load () официально запускает встроенные скрипты.

У сложного вызова .load () есть селектор, например load ("page.html #content"). При таком использовании jQuery целенаправленно отфильтровывает теги сценариев, как описано в статьях вроде этой: https://forum.jquery.com/topic/the-load-function-and-script-blocks#14737000000752785 В этом случае сценарии никогда не бежать, ни разу.


1

Если вы хотите загрузить и HTML, и скрипты, вот более автоматизированный способ сделать это, используя оба $(selector).load()и jQuery.getScript(). В этом конкретном примере загружается HTML-содержимое элемента с идентификатором «toLoad» из content.html, вставляется HTML- код в элемент с идентификатором «content», а затем загружаются и запускаются все сценарии внутри элемента с идентификатором «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());
            }
        });
    }

});

Этот код находит все элементы сценария в загружаемом содержимом и просматривает каждый из этих элементов. Если у элемента есть srcатрибут, то есть это скрипт из внешнего файла, мы используем jQuery.getScriptметод выборки и запуска скрипта. Если элемент не имеет srcатрибута, то есть это встроенный скрипт, мы просто используем его evalдля запуска кода. Если он не находит элементов сценария, он вставляет только HTML в целевой элемент и не пытается загрузить какие-либо сценарии.

Я тестировал этот метод в Chrome, и он работает. Не забывайте соблюдать осторожность при использовании eval, так как он может запускать потенциально небезопасные сценарии и обычно считается вредным. Возможно, вы захотите избежать использования встроенных скриптов при использовании этого метода, чтобы избежать использования eval.


0

Что ж, у меня была та же проблема, которая, казалось, возникла только для Firefox, и я не мог использовать другую команду JQuery, кроме .load (), поскольку я изменял интерфейс для существующих файлов PHP ...

В любом случае, после использования команды .load () я встроил свой сценарий JQuery во внешний загружаемый HTML-код, и, похоже, он работал. Я не понимаю, почему JS, который я загрузил в верхней части основного документа, не работал с новым контентом ...


Легко, потому что на момент выполнения скрипта нового контента не было.
Matteo


0

Переходя к ответу @efreed ...

Я использовал .load('mypage.html #theSelectorIwanted')для вызова контента со страницы с помощью селектора, но это означает, что он не выполняет встроенные скрипты внутри.

Вместо этого я смог изменить свою разметку так, чтобы '#theSelectorIwanted'она стала собственным файлом, и я использовал

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

и он отлично запускал встроенные скрипты.

Не у всех есть такая возможность, но это был быстрый обходной путь, чтобы добраться туда, куда я хотел!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.