Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Разное поведение js при активном окне. Выполнение после загрузки страницы. (https://javascript.ru/forum/misc/44114-raznoe-povedenie-js-pri-aktivnom-okne-vypolnenie-posle-zagruzki-stranicy.html)

totalavitaminoz 07.01.2014 15:22

Разное поведение js при активном окне. Выполнение после загрузки страницы.
 
Мне нужно что бы код выполнялся после загрузки страницы. И выдавался алерт даже при активном окне.

Код:

setInterval("location.reload()", 5000);
//мой код: действия, условия, алерт


Если запустить код (в хроме через tampermonkey) и отстаться на странице, то в консоле будет выдаваться
Код:

ERROR: Execution of script 'test yandex' failed! Cannot call method 'getElementsByTagName' of null
А если перейти на другую вкладку, то будет выдаваться алерт. (как и нужно)

Пробовал сделать так:
Код:

function my(){
//
}
document.addEventListener('DOMContentLoaded', myfunc, false);

Консоль теперь выдаёт
Код:

Uncaught TypeError: Cannot call method 'getElementsByTagName' of null
либо алерт, если так же перейти на другую вкладку

на
Код:

window.onload
вобще не реагирует. консоль не ругается, алерт не появляется, вобщем, ничего не происходит.

Хотел попробовать как советуют здесь:
http://javascript.ru/blog/gordon-fre...#comment-17157

но не понял как использовать)

Erolast 07.01.2014 18:07

Не очень понял... надо, чтобы через пять секунд после загрузки страницы она обновилась? Ну, вот так:
//Вешаем окну обработчик события onload.
window.onload = function()
{
   //Запускаем таймер, по истечении которого страница должна перезагрузиться.
   setTimeout(function(){location.reload()}, 5000);
}

А алерт... Что за алерт? Куда алерт ставить? Ну и, в обработчиках событий его использовать надо очень осторожно. А лучше вообще нигде не использовать.

totalavitaminoz 07.01.2014 19:05

window.onload = function()

Вот этот код, как я понимаю, ждёт пока страницы не загрузиться полностью.
Если написать так
window.onload = function(){
   setTimeout(function(){location.reload()}, 10000);
}

alert ("blabla");

То, алерт будет показываться.
А если что-то типа
window.onload = function(){
   setTimeout(function(){location.reload()}, 10000);
}
var name = document.getElementById('name').getElementsByTagName('*')[1].innerHTML;
alert ("name");


То алерта уже не будет.

Сам же алерт я вывожу, что бы видеть обрабатывается ли код или нет.
Вместо алерта в итоге какое-либо действие: нажать копку, перейти на страницу и т.п.

Erolast 07.01.2014 19:47

Ну и не мудренно.
var name = document.getElementById('name').getElementsByTagName('*')[1].innerHTML;
- неправильный код. Выполнение скрипта останавливается на этой строке, потому-что идет попытка обращения к свойству несуществующего объекта.

.getElementsByTagName находит элементы по названию тега, то есть,
document.getElementByTagName("div")
вернет массив div'ов, дочерних элементу document - ну, то есть, со всеми div'ами на странице.
document.getElementById('name').getElementsByTagName('div')

вернет массив из div'ов, являющихся дочерними элементу с идентификатором name.
Следующий код будет пытаться вернуть массив из элементов с тегом *, дочерних элементу с идентификатором name.
document.getElementById('name').getElementsByTagName('*')

Но, так как таких тегов в природе не существует, массив окажется пустым.

P.S. Пользуйся консолью ошибок JS, есть она в любом браузере. Большинство проблем можно решить, просто взглянув на нее.
P.P.S. Для того, чтобы видеть, обрабатывается код или нет, используй лучше console.log("Текст"); - текст запишется в консоль (ну, естественно, надо включить отображение лога в ней).

totalavitaminoz 07.01.2014 20:25

Когда я запускаю этот же самый код
var name = document.getElementById('name').getElementsByTagName('*')[1].innerHTML;
alert ("name");

через консоль(вручную, после загрузки страницы), то всё обрабатывается как надо.

Т.е. мне непонятно почему этот же самый код перестаёт работать, если его подключить как userjs

Реализацию брал из этого урока http://javascript.ru/tutorial/dom/search сам ничего не придумывал

апд: изменение * на div ничего не даёт.

Erolast 07.01.2014 21:00

А, пардон, оказывается, использование
.getElementsByTagName('*')

позволяет вообще все дочерние элементы получить. Я и не знал. Тогда все верно.

Но дело в том, что на момент выполнения этой строки того самого элемента с идентификатором name просто не существует - он еще не загрузился. Нужно так:

window.onload = function(){
   setTimeout(function(){location.reload()}, 10000);
   var name = document.getElementById('name').getElementsByTagName('*')[1].innerHTML;
   alert(name);
}

totalavitaminoz 07.01.2014 21:53

Цитата:

window.onload = function(){
   setTimeout(function(){location.reload()}, 10000);
   var name = document.getElementById('name').getElementsByTagName('*')[1].innerHTML;
   alert(name);
}

Проблема остаётся той же. При использовании значений со страницы, алерт не появляется.

Если сделать так:
window.onload = function(){
   setTimeout(function(){location.reload()}, 5000);
   alert("343");
     var name = document.getElementById('name').getElementsByTagName('*')[1].innerHTML;
   alert(name);
}

То будет выводиться 343

Если так:
window.onload = function(){
   setTimeout(function(){location.reload()}, 5000);
     var name = document.getElementById('name').getElementsByTagName('*')[1].innerHTML;
   alert(name);
   alert("343");
}

То ничего выводиться не будет

Erolast 07.01.2014 22:22

Так... из-за чего JS может не выполнить строку? Из-за того, что где-то ранее скрипт был остановлен. Когда скрипт останавливается? При попытке обращения к свойству несуществующего объекта. То есть, либо у тебя нету объекта с ID name, либо он есть, но у него нету второго дочернего элемента, у которого ты пытаешься получить innerHTML (не забываем, что arr[1] - это не первый элемент массива, а второй, так как отсчет идет с нуля). Если та же строка работает в том же документе из адресной строки... вот не знаю. Скорее всего, где-то допущена какая-нибудь незначительная ошибка - кавычки поставлены не так, точка с запятой пропущена, лишняя точка с запятой вставлена. Хорошо бы увидеть полный код страницы - тогда сразу можно будет сказать, где что не так.

<html>
<head>
<script>
window.onload = function(){
   //setTimeout(function(){location.reload()}, 5000);
   var name = document.getElementById('name').getElementsByTagName('*')[1].innerHTML;
   alert(name);
}
</script>
</head>
<body>
<div id="name">
<span>Текст1</span>
<span>Текст2</span>
</div>
</body>
</html>

Erolast 07.01.2014 22:43

Ну а вообще - открой уже консоль ошибок. Если что-то не работает, в большинстве случаев можно увидеть причину в консоли ошибок.

totalavitaminoz 07.01.2014 23:20

Код работающий. Как я уже писал выше если запустить
var name = document.getElementById('name').getElementsByTagName('*')[1].innerHTML;
   alert(name);

вручную в консоле, то всё проходит гладко.

но если обернуть его
window.onload = function(){
   setTimeout(function(){location.reload()}, 10000);
   var name = document.getElementById('name').getElementsByTagName('*')[1].innerHTML;
   alert(name);
}

или хотя бы даже так:
setInterval("location.reload()", 5000);
   var name = document.getElementById('name').getElementsByTagName('*')[1].innerHTML;
   alert(name);
}

и подключать как userjs, то он перестаёт выполняться.
Причём, в хроме работает только второй вариант автообновления, а в Опере оба.

На счёт перестаёт выполняться. Выполняется в одном случае из пары десятков.
И если без window.onload я могу понять почему он выполняется не всегда, то в примере с этой функцией я теряюсь в чём может быть причина.

Консоль ошибок в хроме при использовании второго варианта (без window.onload) выдаёт вполне предсказуемое:
Цитата:

ERROR: Execution of script 'test yandex' failed! Cannot call method 'getElementsByTagName' of null
Более того, пока я писал, то мне хром выдал нужный алерт раза 3(без использования window.onload), чего не было до этого. Потом снова замолк.
После этого я снова обернул код в window.onload
window.onload = function(){
   setTimeout(function(){location.reload()}, 10000);
   var name = document.getElementById('name').getElementsByTagName('*')[1].innerHTML;
   alert(name);
}

и автообновление пропало.
То, что код подключен убедился добавив алерт после обёртки. При ручном обвнолении страницы, он выводится.
В консоли НИКАКИХ ошибок не появляется.

Я запутался.

upd:
консоль в опере, в которой нормально работает автообновление с window.onload выдаёт это
Цитата:

Error thrown at line 11, column 3 in <anonymous function: window.onload>() in test.user.js:
var name = document.getElementById('name').getElementsByTagNa me('*')[1].innerHTML;
content_script.js:64
ext_content: opera.extension.postMessage get_scripts
Uncaught exception: TypeError: Cannot convert 'document.getElementById('name')' to object


Часовой пояс GMT +3, время: 20:18.