jQuery оценивает JavaScript в строке HTML с осложнения - PullRequest
3 голосов
/ 18 апреля 2011

Это сводит меня с ума ...

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

Первоначально у меня был следующий код JavaScript, который выполнялся всякий раз, когда выполнялся запрос AJAX для нового HTML:

var $newContent = $(newHtmlContent);
loadingElement.innerHTML = $("#" + loadingElementId, $newContent).html();

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

var $newContent = $(newHtmlContent);
$(loadingElement).html($("#" + loadingElementId, $newContent).html());

Я читал, что jQuery будет оценивать любые сценарии с аргументом строки HTML функции html () - однако, похоже, проблема заключается в том, что сценарии удаляются перед этим вызовом. После просмотра firebug, похоже, происходит следующее:

$(newHtmlContent) // includes all 'script' elements
$("#" + loadingElementId, $newContent) // has no scripts
$("script", $newContent) // empty jQuery object

У кого-нибудь есть предложения? Заранее спасибо.

Ответы [ 5 ]

4 голосов
/ 18 апреля 2011

Сделал быстрый тест (скрипка) , учитывая следующую разметку в виде строки:

<div id="root">
    <div>some dynamic content</div>
    <script type="text/javascript">alert("hello");</script>
    <div class="desiredElement">after script</div>
</div>

jQuery создаст объект, подобный

> [0]: #root
> [1]: script

[0] будет содержать все html в #root, за исключением сценария, сценарии разделены на свои собственные объекты.Похоже, что это верно для всех скриптов в разметке.

Таким образом, вы можете сделать что-то вроде этого для запуска скрипта:

var $new = $(dynamicContent); // dynamicContent is string
var $desired = $new.find('.desiredElement');

$new.eq(1).appendTo('body'); // run the script
1 голос
/ 18 апреля 2011

Здесь есть длинное объяснение этой проблемы: http://forum.jquery.com/topic/jquery-removing-script-tags-from-html-string-when-using-html

Из этого обсуждения:

Если вы хотите выбрать / пройти часть строки HTML и хотите, чтобы <script> внутри строки HTML выполнялось, вам нужно вставить строку HTML в DOM перед выбором / обходом.

Похоже, проблема в том, что вы пытаетесь извлечь элементы из возвращенного HTML, не вставляя его в DOM. Два возможных решения:

  1. Вставьте весь возвращаемый HTML в DOM. Теги скрипта будут выполнены. Затем удалите части, которые вам не нужны. Это не идеально, так как может отображать нежелательный контент, если вы сначала не скроете loadingElement и не покажете, когда закончите.

  2. Извлечение URL-адресов сценариев из $(newHtmlContent), использование $.getScript() для извлечения и выполнения каждого URL-адреса, , а затем добавление полученных элементов в DOM. Это большая боль, но она должна работать нормально, и вам не нужно вставлять ненужный контент в DOM.

1 голос
/ 18 апреля 2011

редактировать Неважно;Я думаю, что вы здесь утонули.Как только вы передадите контент в jQuery, я уверен, что ваши скрипты будут удалены.Прием, описанный ниже, сработал бы, если бы «newContent» на самом деле был частью «нативной» страницы, но, поскольку он находится в этом фрагменте, созданном jQuery, слишком поздно.* это будет работать, но я признаю, что я не пробовал его с загруженным документом, как то, что у вас есть:

$('#loadingElement').html($('#' + loadingElementId, $newContent)[0].innerHTML);

Идея состоит в том, чтобы обойти jQuery при извлечении содержимого загруженной части.

0 голосов
/ 18 апреля 2011

Я думаю, что и здесь, но как насчет:

//scripts will be executed and HTML put into loadingElement
$('#loadingElement').html(newHtmlContent); 

//find the specified element under #loadingElement, get it's HTML 
//and set it as the HTML for #loadingElement
$('#loadingElement').html($('#loadingElement').find('#idToFind').html());
0 голосов
/ 18 апреля 2011

Одна вещь, которую вы могли бы попробовать, это вытащить содержащиеся <script> элементы и либо eval() их, либо добавить их в head страницы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...