Замораживание DOM для JavaScript: перезапись функций модификации DOM в качестве no-ops - PullRequest
2 голосов
/ 09 января 2009

Я пишу фрагмент кода, который требует, чтобы DOM веб-сайта оставался замороженным во время работы произвольного JavaScript. Изменение атрибутов - это хорошо, но я не могу ничего изменить в исходной структуре тегов страницы!

Я знаю, что в JavaScript есть базовое количество функций, которые могут изменять DOM:

appendChild( nodeToAppend )
cloneNode( true|false )
createElement( tagName )
createElemeentNS( namespace, tagName )
createTextNode( textString )
innerHTML
insertBefore( nodeToInsert, nodeToInsertBefore )
removeChild( nodetoRemove )
replacechild( nodeToInsert, nodeToReplace )

Моя первоначальная мысль состояла в том, чтобы просто переписать эти функции без всяких операций:

>>> document.write('<p>Changing your DOM. Mwwhaha!</p>')
>>> document.write = function() {}
>>> document.write('<p>No-op now!</p>')

Хотя это легко сделать для объекта document, функции модификации DOM можно вызывать из множества различных объектов JavaScript! Если бы я мог переписать эти функции на верхнем уровне, возможно, это сработало бы?

Обновление от sktrdie:

>>> HTMLElement.prototype.appendChild = function(){}
>>> $("a").get(0).appendChild(document.createElement("div"))
# Still works argh.
>>> HTMLAnchorElement.prototype.appendChild = function(){}
>>> $("a").get(0).appendChild(document.createElement("div"))
# No-op yeah!

Так что, похоже, я мог бы просто собрать конструкторы всех элементов DOM и запустить их, вставив no-ops, но это все еще выглядит довольно грязно ...

Как я могу защитить DOM от модификации от произвольного JavaScript?

Ответы [ 5 ]

2 голосов
/ 09 января 2009

Вы пытались HTMLElement .prototype.appendChild = function () {} переписать методы DOM на более высоком уровне?

1 голос
/ 10 января 2009

Хотя это действительно хакерский подход, единственный способ сохранить текущую структуру DOM - сохранить «снимок» DOM и периодически проверять его.

//place in anonymous function to prevent global access
(function() {
  //storing the whole DOM as objects would be ideal, but too memory intensive, so a string will have to do.
  var originalDOM = document.body.innerHTML;

  var checkDOM = function() {
    if (document.body.innerHTML != originalDOM)  document.body.innerHTML = originalDOM
    //check that the code is running
    if (arbitraryCodeIsRunning)  setTimeout("checkDOM", 100);
  }
  checkDOM();
})();

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

0 голосов
/ 09 января 2009

Нет способа сделать это. Я сделал пару тестов, и независимо от того, как я пытался переписать эти методы, они остаются. Я считаю, что они реализованы на более высоком уровне, чем доступ к исполняемому javascript, поэтому вы не можете их по-настоящему трогать.

0 голосов
/ 09 января 2009

Вы можете поместить все в тег <div> и скрыть этот тег, заменив его другим, который говорит «Загрузка ...». Затем после загрузки вы можете скрыть загрузку <div> и заменить ее оригиналом.

0 голосов
/ 09 января 2009

Не делай этого. Используйте белый список. Пожалуйста.

...