Очень интересное поведение при загрузке jQuery, ошибка или решение? - PullRequest
1 голос
/ 30 ноября 2009

Недавно я пытался найти ошибку в некоторых скриптах и ​​обнаружил это очень интересное поведение при загрузке страницы с помощью jQuery.

Файл № 1: Test1.htm

<div id="test"></div>

<script type="text/javascript">
$(document).ready(function(){
 $('#test').load('test2.htm #content',function(){
  alert('done loading!');
 })
})
</script>

Файл № 2: Test2.htm

<div id="content">
howdy

<script type="text/javascript">
$(document).ready(function(){
 alert('hello #1');
})
</script>
<SCRIPT type="text/javascript">
$(document).ready(function(){
 alert('hello #2');
})
</SCRIPT>

</div>

Теперь, когда я запускаю Test1.htm, я получаю следующее:

  • Привет # 2 оповещение
  • Привет из test2.htm отображает
  • оповещение о завершении загрузки

Как вы можете видеть, единственное отличие состоит в том, что тег script находится в верхнем регистре для предупреждения hello # 2. Скрипт для показа приветствия # 1 никогда не срабатывает ...

До сих пор я тестировал это в Firefox 3.55, IE 8.0.6001.18702 и Chrome 3.0.195.33 с похожими результатами.

Раньше я хотел извлечь javascript из загруженного контента, аналогично этому ТАКому вопросу . Итак, мой вопрос, это ошибка или решение?


Обновление: как указано ниже в Jitter, то же самое происходит, если Test2.htm имеет скрипт вне загружаемого мной контента.

<div id="content">
howdy from test2.htm
</div>

<script type="text/javascript">
$(document).ready(function(){
 alert('hello #1');
})
</script>
<SCRIPT type="text/javascript">
$(document).ready(function(){
 alert('hello #2');
})
</SCRIPT>

Ответы [ 2 ]

9 голосов
/ 30 ноября 2009

На самом деле это похоже на ошибку в jQuery. Вы должны опубликовать сообщение об ошибке. Хорошая находка между прочим.

В jQuery 1.3.2 строка 3270-3272 у нас

// inject the contents of the document in, removing the scripts
// to avoid any 'Permission Denied' errors in IE
.append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))

Очевидно, что регистр без учета регистра i в этом регулярном выражении отсутствует. Таким образом, каждый тег <script>...</script>, который не является строчными, как <SCRIPT>, <Script>, <scriPt>, ... не удаляется jQuery, как предполагалось.

Таким образом, строка 3272 должна выглядеть как

.append(res.responseText.replace(/<script(.|\s)*?\/script>/gi, ""))

Кроме того, эта ошибка вызывается только использованием селектора в URL-адресе загрузки test2.htm #content. Если оставить его и использовать

$('#test').load('test2.htm',function(){....});

и test2.htm выглядят так, как показано ниже, они также будут запускать три оповещения (независимо от того, как вы пишете скрипт-тег). Так что это тоже ошибка в угловом случае.

howdy

<SCRIPT type="text/javascript">
$(document).ready(function(){
 alert('hello #1');
});
</SCRIPT>
<script type="text/javascript">
$(document).ready(function(){
 alert('hello #2');
})
</script>
2 голосов
/ 30 ноября 2009

Внедрение элементов скрипта через HTML очень сложно сделать надежным кросс-браузерным, и, следовательно, ломается различными способами в jQuery. Он делает некоторые вещи, чтобы обойти известные проблемы с браузером, но в итоге может только усугубить ситуацию.

Исправив ошибку джиттера (+1), вы обнаружите, что скрипты вообще не вставляются, чтобы попытаться избежать подобных проблем. Даже с исправлением эта строка является мерзким и хрупким кодом, пытающимся обработать HTML с помощью регулярных выражений, и потерпит неудачу, если строка /script> включена в блок сценария (что вполне допустимо). И потерпит неудачу за </script >. И так далее.

Так что сделайте себе одолжение и оставьте <script> содержимого HTML, которое вы собираетесь загружать динамически. Всегда передавайте содержимое скрипта для выполнения отдельно от HTML.

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