Как удалить все скрипты на странице, даже те, которые привязаны к событиям и таймерам?

#javascript

#javascript

Вопрос:

Я экспериментирую с JavaScript и, похоже, не могу понять простое поведение. Что я хочу сделать, так это отключить абсолютно любой JS, который был до следующего фрагмента кода:

 void (function(){
    (function prepare(name){ 
        var elements = document.getElementsByTagName(name);
        for(var i = elements.length; i--;)
            elements[i].parentNode.removeChild(elements[i]);
        return prepare;
    }('script'));
}());
  

ОБРАТИТЕ ВНИМАНИЕ Марселя Корпела: отступ вставлен для удобства чтения, но вы должны вставить это в виде одной строки кода в адресной строке.

Следующий код теоретически должен отключить все JS на странице, верно? Чтобы протестировать его, вы можете выполнить его через javascript: [..] , когда страница полностью загружена. FireBug HTML покажет, что все скрипты удалены. Однако в коде были такие вещи, как setTimeout , setInterval привязка определенных действий, события нажатия и т.д. И они все еще работают даже после выполнения кода.

Есть ли способ полностью удалить все это после выполнения скрипта?

Комментарии:

1. Все предыдущие скрипты выполняются до того, как ваш скрипт удалит их <script/> теги. Удаление тегов не выгружает выполняемый код и не удаляет прослушиватели событий, определенные выполняемым кодом. Вы можете предотвратить всплывающее окно событий, настроив свои собственные прослушиватели событий.

Ответ №1:

К сожалению, таймауты (как в setTimeout ) и интервалы ( setInterval ) непрозрачны. Это означает, что нет способа отменить время ожидания / интервал выполнения без знания его дескриптора. То же самое относится и к прослушивателям событий, приемник событий объекта DOM недоступен, поэтому нет способа, removeEventListener не зная, как addEventListener был вызван.

Единственный способ, которым я могу разобраться, — это пользовательский javascript в Opera, где вы можете подключать перечисленные выше функции и отслеживать тайм-ауты / интервалы / прослушиватели.

Комментарии:

1. Вы можете отменить все тайм-ауты без идентификаторов, но это перебор. Каждый тайм-аут или интервал возвращает большее целое число, чем любой предыдущий существующий таймер, и целое число — это значение, переданное при вызове clearTimeout (ссылка). Вы можете захватить следующее целое число, создав фиктивный тайм-аут и зациклив clearTimeout (целое число—) на ноль. Грубым его делает то, что некоторые браузеры начинают серию с необычайно большого целого числа.

2. @kennebec, да, это можно использовать, однако последовательность не гарантируется, смотрите официальную спецификацию: whatwg.org/specs/web-apps/current-work/multipage /…

Ответ №2:

После оценки скрипта вы не можете удалить JavaScript таким образом. Если вы знаете, какой объект необходимо удалить, вы можете использовать метод грубой силы:

 for (var key in window) {
    window[key] = undefined;
}
  

но это не удаляет события.

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

Современную систему событий отключить немного сложнее:

 document.body.innerHTML = document.body.innerHTML  '';
  

Но в этом решении возможны некоторые утечки памяти.

Ответ №3:

Я скомпилировал ответы в комментариях и придумал эту функцию…

 function KILL(){
 document.body.style='';
 document.body.innerHTML = 'KILLED';

 a=setTimeout(function(){},1)
 for (var i = a; i >= 0; i--) {
  clearTimeout(i);
  clearInterval(i);
 }

 for (var key in window) {
  if(key != 'location' amp;amp; key != 'KILL'){
     window[key] = undefined;
  }
 }
 return 0;
}
  

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

Комментарии:

1. Я думаю, что outerHTML может быть лучшим способом очистить тег body, поскольку он очистит любые атрибуты в теге document.body.outerHTML = '<body>KILLED</body>';