Подтвердить что ты не робот

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? Кто-нибудь лучше знает, как это сделать?

4b9b3361

Ответ 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>