#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>';