Подгрузка скриптов с document.write()

1st July 2005 - 05:02

(навеяно ru_javascript) При необходимости подгрузить внешний *.js со всякими document.write() можно попробовать пойти таким путём:

<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
          "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>doc.wr()</title>
<script type="text/javascript"><!--//--><![CDATA[//><!--
  function addJS(src) {
    var s = d.createElement('script');
    s.onload = pushHTML();
    s.setAttribute('type','text/javascript');
    s.setAttribute('src',src);
    d.documentElement.firstChild.appendChild(s);
  }
  function pushHTML() {
    window.setTimeout(function() {
      d.body.innerHTML += buffer;
      buffer = '';
    }, 0);
  }
  window.onload = function () {
    window.d = document;
    window.buffer = '';
    d.write = d.writeln = function(s){buffer+=s;}
    d.open = d.close = function(){}
    addJS('test.js');
    //addJS('test.js');
  }
//--><!]]></script>
</head><body>
  <p>first test +++ first test</p>
</body></html>

test.js, использовавшийся для проверки:

document.open();
document.write('<p>second test');
document.write(' +++ ');
document.write('second test</p>');
document.writeln('<p><em>third test<\/em></p>');
document.write(' +++ ');
document.write(' <strong>third test<\/strong> ');
document.close();

Несмотря на то, что там стоят всякие доктайпы, работать это будет лишь в text/html. Если же отсылать документ как application/xhtml+xml, то необходимо изменить text/javascript на application/x-javascript, убрать firstChild из d.documentElement.firstChild.appendChild и смотреть только в Gecko. Но это ещё большее извращение, хотя бы потому, что на выходе из window.buffer должен идти лишь xhtml, т.е. файл test2.js

document.write('<p>Hi!');

испортит всю гордость за валидность и соответствие-чему-то-там. Этот случай можно если не обойти, то хотя бы отлавливать, возвращая, например, текст «error while parsing», однако, это просто глупо.

Categories: dHtml | comments: (6)

Комментарии

1. Slach 1st July 2005 - 10:15

БОЛЬШОЕ Человеческое спасибо =)

хотя в данном случае вместо
addJS(http://www.googleadservices.com/pagead/conversion.js)
пришлось сделать просто ссылку на 1 пиксельную картинку…

var google_img = new Image();
google_img.src='http://www.googleadservices.com/pagead/conversion/' + google_conversion_id + '/?value=' + google_conversion_value + '&label=' + google_conversion_label + '&script=0&random=' + (new Date()).getTime();

2. Van 1st July 2005 - 10:49

Ну типа trackback

Mash:

Ну, если это похвала библиотеке Дмитрия Котерова, то я могу только присоединиться. Другое дело, что если для каких-то вещей эта библиотека избыточна, то зачем ей пользоваться? В данном конкретном случае всё решается чуть проще, да и задача несколько иная.

А по поводу сравнения того же самого JSHR с XHR… Оно не уместно в тех случаях, когда нужен POST, да и по другим параметрам тоже проигрывает. С другой стороны, есть и весомые положительные моменты. В этой области у всех способов есть те или иные недостатки; задача кодера — выбрать из них наиболее подходящий для решения какой-то конкретной задачи, взвесив все «за» и «против»; как всегда. ;)

3. Splurov 1st July 2005 - 13:34

где вычитал про application/x-javascript?

Mash:

Не помню. М.б. здесь.

4. G100m 1st July 2005 - 14:27

Фу, какая бяка. Вот это прекрастно отрабатывает:

if (ie) {
var script = document.createElement('script');
script.defer = true;
script.src = 'mainTree3.js';
document.getElementsByTagName('head')[0].appendChild(script);
} else {
if (dom) {
window.location.href = url;
}
}

Mash:

Очень в тему; особенно про window.location.

+ defer именно в этом конкретном случае может сбить buffer… хотя нет, вроде нормально будет работать. It all depends.

5. Van 2nd July 2005 - 00:14

Да, пожалуй немного погорячился с выводами.
Просто немного покоробили document.write в подгружаемом js. Как-то оно эстетичней HTML уже и подгружать имхо..

6. Mix 2nd July 2005 - 09:12

>>s.onload = pushHTML(src);
Эээ. А можно объяснить для тех кто на бронепоезде?
Я всегда считал, что обработчик события должен содержать указатель на функцию. Однако если тут заменить эту строку на
s.onload = function(){pushHTML(src)}, то ничего работать не будет.
Да и зачем передавать параметр src?

Mash:

>> Да и зачем передавать параметр src?

Я в одной из редакций игрался с buffer, но потом понял, что это лишнее, а удалить забыл; сейчас поправлю. Приз за внимательность. ;)

>> s.onload = function(){pushHTML(src)}

В Gecko работает, в Opera сейчас посмотреть нет возможности; влезаю на бронепоезд, присоединяясь к тем, кто не понимает, почему сие не работает в IE. Наверняка существует какое-то научное объяснение, но всех тонкостей JS не знаю, да и голова после Груши работать отказывается, пока ничего сказать не могу.

Комментарии временно отключены.