Javascript-форум (https://javascript.ru/forum/)
-   Javascript под браузер (https://javascript.ru/forum/css-html/)
-   -   Существующая переменная не существует. (https://javascript.ru/forum/css-html/29571-sushhestvuyushhaya-peremennaya-ne-sushhestvuet.html)

Maksimchik 03.07.2012 17:13

Существующая переменная не существует.
 
С помощью кода увеличиваются картинки. Это для меню. Но дело в том что код не работает. alert не выводит ничего! Через оперу посмотрел в консоль ошибок, и там:

Код:

[03.07.2012 16:10:21] JavaScript - http://localhost/index.php
Event thread: mousemove
Uncaught exception: ReferenceError: Undefined variable: menuimgs
Error thrown at unknown location in <anonymous function>(event) in http://localhost/index.php:
    /* no source available */

[03.07.2012 16:10:22] JavaScript - http://localhost/index.php
Event thread: mouseout
Uncaught exception: ReferenceError: Undefined variable: menuimgs
Error thrown at unknown location in <anonymous function>(event) in http://localhost/index.php:
    /* no source available */

Ошибка возникает в тот момент когда происходит onmousemove и onmouseout.

Код:

window.onload = function(){
	var menuimgs = document.getElementsByTagName("img");
	var links = Array();
	for(var i = 0, i2 = 0; i < menuimgs.length; i++){
		if(menuimgs.item(i).getAttribute("text") != null){
			links[i2] = menuimgs.item(i);
			menuimgs.item(i).style.width = "32px"
			menuimgs.item(i).onmouseout = "menuimgs.item(i).style.width = '32px';";
			menuimgs.item(i).onmousemove = "getLink(links,menuimgs.item(i),i2);";
			i2++;
		}
	}
}

function getLink(links,element,num){
	alert(links[num]);
	var img0 = num--, img1 = num, img2 = num++;
	if(links[img0] != null) links[img0].style.width = "48px";
	if(links[img1] != null) links[img1].style.width = "64px";
	if(links[img2] != null) links[img2].style.width = "48px";
	var infostyle = document.getElementById("getLinkInfo");
	
}

Maksimchik 03.07.2012 17:29

Я разобрался. Получается если что onmouse(move/out/...) какбы выполняют код из самого тега, и поэтому не находило переменных.

Если можно как то полегче обойти, прошу в студию. ^_^

vadim5june 03.07.2012 17:33

справа должны быть функции-а не обрашения к функциям-
function(){menuimgs.item(i).style.width = '32px';}
menuimgs.item(i).onmouseout = "menuimgs.item(i).style.width = '32px';";
menuimgs.item(i).onmousemove = "getLink(links,menuimgs.item(i),i2);";

Maksimchik 03.07.2012 17:44

Как узнать item() елемента?

vadim5june 03.07.2012 17:49

Цитата:

Сообщение от Maksimchik (Сообщение 186091)
Как узнать item() елемента?

откуда item появились?
по моему надо
menuimgs[i]

кстати зачем у Вас i2 если она меняется так же как i

melky 03.07.2012 18:42

Цитата:

Сообщение от Maksimchik
Я разобрался. Получается если что onmouse(move/out/...) какбы выполняют код из самого тега, и поэтому не находило переменных.

если таков вывод - то "нет, не разобрался".


Цитата:

Сообщение от Maksimchik
Если можно как то полегче обойти, прошу в студию. ^_^

конечно, для этого мы здесь.

window.onload = function(){  // *!*(0)*/!*
	var menuimgs = document.getElementsByTagName("img");  // *!*(1)*/!*
        /* КОД.....  */
			menuimgs.item(i).onmouseout = "menuimgs.item(i).style.width = '32px';"; // *!*(2)*/!*
        /* КОД */
}

Начну я свой ответ с того, что в JS есть области видимости. (наверняка Вы знаете, что это такое. Если нет - прошу погуглить :) ). Т.е. переменная, определённая с локальной области, будет невидима в глобальной.
Отлично. что дальше?

Как видим на строке с отметкой 0, у нас (у Вас) там имеется функция-обработчик события завершения загрузки страницы. Т.е. функция-обработчик имеет свою область видимости (Ваш К.О.)...

Копаем дальше. Отметка 1 при исполнении этой функции создаётся локальная область видимости, и в неё помещается menuimgs (очевидно).

Далее в onmouseout мы помещаем строку-функцию, которая, как ожидается, должна нормально хавать локальную область видимости. Отметка 2. А вот тут и ошибочка. Почему?

Ответ прост :

Строка эта исполняется, как код функции. Какой единственный способ так сделать? Правильно, конструктор функций new Function. А он видит только глобальную область видимости. А т.к. переменная не определена в глобальной области - её нет. Это и вызывает ошибку.
Пример кода в тему :
var foo = "foo";

(function () {
    var bar = "bar";
    try { 
        new Function("", "alert(foo + bar)")();
    } catch (e) { 
        alert(':)');
    }
})();


Как решить? подсказка : обработчики событий - это функции, а не строки :)

oneguy 03.07.2012 19:36

Цитата:

Сообщение от melky
Строка эта исполняется, как код функции. Какой единственный способ так сделать? Правильно, конструктор функций new Function. А он видит только глобальную область видимости. А т.к. переменная не определена в глобальной области - её нет. Это и вызывает ошибку.

melky, судя по вашему объяснению, вы тоже не совсем разобрались :)
Джаваскрипт не умеет преобразовывать строку в функцию. Если событию присвоить строку, то IE 9 так и записывает эту строку, но обработчик события не вызывается. FF и Chrome записывают туда null.
<!DOCTYPE html>
<html><head><title></title></head><body>
<script type="text/javascript">
  onload="alert(1);";
  alert(onload);
</script>
</body></html>

Ред: есть проблема с отображением этого кода: в IE 9 если его запускать из сообщения, то показывает "null", а когда на отдельной странице, то "alert(1);", я не знаю в чём причина, так как не разбирался, как работает эта фича просмотра на сайте.

oneguy 03.07.2012 19:45

Цитата:

Сообщение от vadim5june
откуда item появились?
по моему надо
menuimgs[i]

кстати зачем у Вас i2 если она меняется так же как i

Для получения элемента NodeList можно использовать как menuimgs[i], так и menuimgs.item(i)
i2 здесь меняется не так как i, а только когда menuimgs.item(i).getAttribute("text") != null

vadim5june 03.07.2012 20:03

Цитата:

Сообщение от oneguy (Сообщение 186105)
Для получения элемента NodeList можно использовать как menuimgs[i], так и menuimgs.item(i)
i2 здесь меняется не так как i, а только когда menuimgs.item(i).getAttribute("text") != null

Вы правы

melky 03.07.2012 20:18

Цитата:

Сообщение от oneguy (Сообщение 186104)
melky, судя по вашему объяснению, вы тоже не совсем разобрались :)
Джаваскрипт не умеет преобразовывать строку в функцию. Если событию присвоить строку, то IE 9 так и записывает эту строку, но обработчик события не вызывается. FF и Chrome записывают туда null.
<!DOCTYPE html>
<html><head><title></title></head><body>
<script type="text/javascript">
  onload="alert(1);";
  alert(onload);
</script>
</body></html>

я сначала написал про eval, но потом затёр, поэтому смысл исказился.

хм. я так раньше где-то услышал.


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