JavaScript - контроль точки вставки для document.write
Я хотел бы создать страницу с третьей стороной script, которая включает document.write
после полной загрузки DOM.
Моя страница не XHTML. Моя проблема в том, что document.write перезаписывает мою собственную страницу. (это то, что он делает после загрузки DOM).
Я попытался переопределить функцию document.write(аналогично http://ejohn.org/blog/xhtml-documentwrite-and-adsense/), но это не касается случаев, когда документ .write содержит частичные теги.
Пример, который нарушил бы приведенный выше код:
document.write("<"+"div");
document.write(">"+"Done here<"+"/");
document.write("div>");
Есть ли способ изменить точку ввода document.write через JavaScript? Кто-нибудь лучше знает, как это сделать?
Ответы
Ответ 1
Если вы имеете дело со сторонними скриптами, просто заменить document.write, чтобы захватить вывод и вставить его в нужное место, недостаточно, так как они могут изменить script, а затем ваш сайт сломается.
writeCapture.js делает то, что вам нужно (полное раскрытие: я автор). Он в основном перезаписывает теги script, так что каждый из них захватывает свой собственный вывод document.write
и помещает его в нужное место. Использование (с использованием jQuery) было бы чем-то вроде:
$(document.body).writeCapture().append('<script type="text/javascript" src="http://3rdparty.com/foo.js"></script>');
Здесь я предполагаю, что вы хотите добавить конец тела. Все селектора jQuery и методы манипуляции будут работать с плагином, поэтому вы можете вводить его в любом месте и, тем не менее, хотите. Он также может использоваться без jQuery, если это проблема.
Ответ 2
Можно переопределить метод document.write. Таким образом, вы можете буферизовать строки, отправленные на document.write, и выводить буфер везде, где хотите. Однако изменение a script от синхронного к асинхронному может привести к ошибкам, если не обрабатываться правильно. Вот пример:
Упрощенная замена document.write
(function() {
// WARNING: This is just a simplified example
// to illustrate a problem.
// Do NOT use this code!
var buffer = [];
document.write = function(str) {
// Every time document.write is called push
// the data into buffer. document.write can
// be called from anywhere, so we also need
// a mechanism for multiple positions if
// that needed.
buffer.push(str);
};
function flushBuffer() {
// Join everything in the buffer to one string and put
// inside the element we want the output.
var output = buffer.join('');
document.getElementById("ad-position-1").innerHTML = output;
}
// Inject the thid-party script dynamically and
// call flushBuffer when the script is loaded
// (and executed).
var script = document.createElement("script");
script.onload = flushBuffer;
script.src = "http://someadserver.com/example.js";
})();
Содержимое http://someadserver.com/example.js
var flashAdObject = "<object>...</object>";
document.write("<div id='example'></div>");
// Since we buffer the data the getElementById will fail
var example = document.getElementById("example");
example.innerHTML = flashAdObject; // ReferenceError: example is not defined
Я документировал различные проблемы, с которыми я столкнулся при написании и использовании моей замены document.write: https://github.com/gregersrygg/crapLoader/wiki/What-to-think-about-when-replacing-document.write
Но опасность использования замены document.write - это все неизвестные проблемы, которые могут возникнуть. Некоторые даже не могут обойтись.
document.write("<scr"+"ipt src='http://someadserver.com/adLib.js'></scr"+"ipt>");
adLib.doSomething(); // ReferenceError: adLib is not defined
К счастью, я не сталкивался с вышеупомянутой проблемой в дикой природе, но это не гарантирует, что этого не произойдет;)
По-прежнему хотите попробовать? Попробуйте crapLoader (мой) или writeCapture
Вы также можете проверить дружественные iframes. В основном он создает одинаковый домен iframe и загружает все там, а не в вашем документе. К сожалению, я еще не нашел хороших библиотек для обработки.
Ответ 3
Оригинальный ответ перед редактированием:
В основном проблема document.write
заключается в том, что она не работает в документах XHTML. Наиболее широкое решение тогда (как это может показаться суровым) - не использовать XHTML/xml для вашей страницы. Из-за IE + XHTML и проблема с mimetype, Google Adsense нарушает (может быть, хорошо:), и общий переход к HTML5 я не Думаю, это так плохо, как кажется.
Однако, если вы действительно хотите использовать XHTML для своей страницы, то John script, с которым вы связаны, - это лучшее, что у вас есть на данный момент. Просто понюхайте IE на сервере. Если запрос из IE, ничего не делайте (и не выполняйте mimetype application/xhtml+xml
!). В противном случае переместите его на <head>
вашей страницы, и вы отправитесь на гонки.
Перечитав свой вопрос, есть ли у вас конкретная проблема с Джоном script? Известно, что он не работает в Safari 2.0, но об этом.
Ответ 4
Вам может быть интересна библиотека Javascript, которую я разработал, которая позволяет загружать сторонние скрипты, используя document.write после window.onload. Внутри библиотека переопределяет document.write, динамически добавляет элементы DOM, запускает любые включенные скрипты, которые также могут использовать document.write.
В отличие от решения Джона Ресига (который был частью вдохновения для моего собственного кода), модуль, который я разработал, поддерживает частичную запись, такую как пример, который вы передаете с помощью div:
document.write("<"+"div");
document.write(">"+"Done here<"+"/");
document.write("div>");
Моя библиотека будет ждать окончания script до разбора и рендеринга разметки. В приведенном выше примере он будет выполняться один раз с полной строкой "<div>Done here</div>"
вместо трех раз с частичной разметкой.
Я установил демо, в котором я загружаю 3 Google Ads, виджет Amazon, а также динамику Google Analytics.
Ответ 5
FWIW, я нашел postscribe, чтобы быть лучшим вариантом в наши дни - он обрабатывает обманчивый модуль рендеринга рекламы, как шарм позволяя нашей странице загружаться без блокировки.
Ответ 6
Чтобы изменить содержимое страницы после рендеринга DOM, вам нужно либо использовать библиотеку javascript для добавления HTML или текста в определенные моменты (jQuery, mootools, prototype,...) или просто использовать innerHTML свойство каждого элемента DOM изменить/добавить текст к нему. Это работает crossbrowser и не требует каких-либо библиотек.
Ответ 7
Есть лучшие способы сделать это.
2 пути
1) Добавить
<html><head>
<script>
window.onload = function () {
var el = document.createTextNode('hello world');
document.body.appendChild(el);
}
</script></head><body></body></html>
2) InnerHTML
<html><head><script>
window.onload = function () {
document.body.innerHTML = 'hello world';
}
</script></head><body></body></html>