Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Проблемы с вызовом функции (https://javascript.ru/forum/events/4287-problemy-s-vyzovom-funkcii.html)

pismenov 09.07.2009 10:24

Проблемы с вызовом функции
 
Привет всем... Изучаю потихоньку javascript. Не могу понять почему не работает данный код:
<html>
<head>
</head>
<body>
<img id="myimg" src="kia_spectra_1.jpg">
<img id="myimg2" src="top-left.jpg">
<script type="text/javascript" src="wz_tooltip.js"></script>
<script type="text/javascript">
var stroka = 'myimg,myimg2';
var arr = stroka.split(",");
for (i=0; i<arr.length; i++)
{
var img = new Array();
var e = new Array();
var str = new Array();
img[i] = document.getElementById(arr[i]);
e[i] = img[i].getAttribute("src");
str[i] = '<img src="'+ e[i] +'" width="100">';
img[i].addEventListener('mouseover',function (e) {Tip(str[i]).call;},false);
img[i].addEventListener('mouseout',function (e) { UnTip().call; },false);
}
</script>
</body>
</html>

В скрипте wz_tooltip.js(http://www.walterzorn.com) описаны функции Tip(string) и UnTip().
Tip() плавно выводит окно с переданной строкой или рисунком, переданном в виде <img src="xxx" width="yyy">. UnTip() прекращает вывод. В данном случае выводится только последняя картинка... Где загвоздка?

B~Vladi 09.07.2009 10:50

addEventListener - для ИЕ нужет attachEvent
...

B~Vladi 09.07.2009 10:53

И ещё совет: предпочтительнее использовать только одинарные кавычки в коде;)

pismenov 09.07.2009 11:06

Я смотрел здесь http://javascript.ru/tutorial/events...deventlistener.
Ни mozilla ни opera
addEventListener(img[i],'mouseover',function (e) {Tip(str[i]).call;},false);
не воспринимают(

B~Vladi 09.07.2009 11:37

Цитата:

Сообщение от pismenov
img[i].addEventListener('mouseover',function (e) {Tip(str[i]).call;},false);

Насколько я понимаю, у вас при вызове обработчика str[i] - undefined.

Лучше поступить так:
// Создадим в цикле для каждого img свойство str, которое сохранит строку
img[i].str = '<img src="'+ e[i] +'" width="100">';
// и определим обработчик
img[i].addEventListener('mouseover',getStr,false);

// Создадим ф-цию, которая будет возвращать нам эту строку и вызывать твою ф-цию (вне цикла)
function getStr(evt){
	evt=evt||event;
	var target=evt.target||evt.srcElement;
	Tip(target.str).call;
}

Теперь массив str не нужен - удаляем соответствующие строки.

И ещё...
Tip(target.str).call - уверены, что вызывать нужно так?!

B~Vladi 09.07.2009 11:37

Цитата:

Сообщение от pismenov
не воспринимают

Воспринимают:)

B~Vladi 09.07.2009 11:51

А можно всё это дело апптимизировать:
var stroka = 'myimg,myimg2';
var arr = stroka.split(",");
var img = new Array();

for (var i=0; i<arr.length; i++){
    img[i] = document.getElementById(arr[i]);
    img[i].addEventListener('mouseover',getStr,false);
    img[i].addEventListener('mouseover',function(){UnTip().call;},false);
}

function getStr(evt){
    evt=evt||event;
    var img=evt.target||evt.srcElement;
    Tip('<img src="'+ img.getAttribute('src') +'" width="100">').call;
}

`p r o x y 09.07.2009 12:00

если не ошибаюсь, вот такой кросс-браузерный вариант:

if(div.addEventListener){// not ie:
	div.addEventListener('mouseover', function(){ /*..*/ }, false);
	div.addEventListener('mouseout', function(){ /*..*/ }, false);
}else{// ie:
	div.attachEvent('onmouseover', function(){ /*..*/ });
	div.attachEvent('onmouseout', function(){ /*..*/ });
}

pismenov 09.07.2009 12:08

Спасибо большое! Помогло! Теперь работает во всех браузерах.
Реализовал вот так:
<html>
<head>
</head>
<body>
<img id="myimg" src="kia_spectra_1.jpg">
<img id="myimg2" src="top-left.jpg">
<script type="text/javascript" src="wz_tooltip.js"></script>
<script type="text/javascript">
var stroka = 'myimg,myimg2';
var arr = stroka.split(",");
for (i=0; i<arr.length; i++)
{
var img = new Array();
var e = new Array();
img[i] = document.getElementById(arr[i]);
e[i] = img[i].getAttribute("src");
img[i].str = '<img src="'+ e[i] +'" width="100">';
if (img[i].addEventListener)
{
img[i].addEventListener('mouseover',getStr,false);
img[i].addEventListener('mouseout',getStrUn,false);
}
else
{
img[i].attachEvent('onmouseover',getStr);
img[i].attachEvent('onmouseout',getStrUn);
}
}
function getStr(evt){
    evt=evt||event;
    var target=evt.target||evt.srcElement;
    Tip(target.str);
}
function getStrUn(evt){
    evt=evt||event;
    var target=evt.target||evt.srcElement;
    UnTip();
}
</script>
</body>
</html>

Ну не работает у меня
addEventListener(img[i],'mouseover',function (e) {Tip(str[i]).call;},false);
Firefox/3.5, Opera 9.63.
А можно поподробнее про эти строки:
function getStr(evt){
    evt=evt||event;
    var img=evt.target||evt.srcElement;
}
?

`p r o x y 09.07.2009 12:12

Цитата:

А можно поподробнее про эти строки:
в статьях

B~Vladi 09.07.2009 12:16

Цитата:

Сообщение от pismenov
Ну не работает у меня

Возможно не работает из-за Tip(str[i]).call
Цитата:

Сообщение от pismenov
А можно поподробнее про эти строки:

function getStr(evt){ // в функцию передаётся событие evt для мозиллы
    evt=evt||event; // Для кросс-браузерности. В ИЕ, Опера событие берётся из window.event, а в мозилле оно передаётся в функцию
    var img=evt.target||evt.srcElement; // target-свойство события, которое возвращает элемент, который это событие сгенерировал. Для ИЕ это srcElement.
}

pismenov 09.07.2009 12:18

Спасибо всем, буду разбираться.

B~Vladi 09.07.2009 12:23

Переписывай так:

var stroka = 'myimg,myimg2';
var arr = stroka.split(",");
var img = new Array();
for (var i=0; i<arr.length; i++){
img[i] = document.getElementById(arr[i]);
xAddEvt(img[i],'mouseover',getStr);
xAddEvt(img[i],'mouseout',UnTip);
}
function getStr(evt){
    evt=evt||event;
    var img=evt.target||evt.srcElement;
    Tip('<img src="'+ img.getAttribute('src') +'" width="100">');
}
function xAddEvt(e,eventType,eventListener){
	if(e.addEventListener)e.addEventListener(eventType,eventListener,false);
	else if(e.attachEvent)e.attachEvent('on'+eventType,eventListener);
}


Цитата:

Сообщение от pismenov
Ну не работает у меня

Сори, чёт я перепутал... Твой вариант правельный.

pismenov 09.07.2009 16:10

Не могу понять в чем дело. Вообщем в Opera и IE данный код работает, в mozilla ни в какую!
<html>
<head>
</head>
<body>
<img id="myimg" src="kia_spectra_1.jpg">
<img id="myimg2" src="top-left.jpg">
<img id="myimg3" src="apache_pb2.gif">
<script type="text/javascript" src="wz_tooltip.js"></script>
<script type="text/javascript">
var xmlHttp = false;
function createRequest() {
try {
  xmlHttp = new XMLHttpRequest();
} catch (e) {
  try {
    xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e2) {
    try {
          xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
   catch (e3) {
    xmlHttp = null;
   }
  }
 }
if (xmlHttp == null)
alert("Ошибка создания xmlHttp объекта!");
}
function getRequest() {
createRequest();
var e = 'tooltip.php';
xmlHttp.open("GET",e,true);
xmlHttp.onreadystatechange = updatePage;
xmlHttp.send(null);
}
function updatePage() {
  if (xmlHttp.readyState == 4) {
    var response = xmlHttp.responseText;
    var stroka = response;
	var arr = stroka.split(",");
for (i=0; i<arr.length; i++)
{
var img = new Array();
var e = new Array();
img[i] = document.getElementById(arr[i]);
if (img[i])
{
e[i] = img[i].getAttribute("src");
img[i].str = '<img src="'+ e[i] +'" width="100">';
if (img[i].addEventListener)
{
alert('firefox or opera');
img[i].addEventListener('mouseover',getStr,false);
img[i].addEventListener('mouseout',getStrUn,false);
}
else
{
img[i].attachEvent('onmouseover',getStr);
img[i].attachEvent('onmouseout',getStrUn);
}
}
}
function getStr(evt){
    evt=evt||event;
    var target=evt.target||evt.srcElement;
    Tip(target.str);
}
function getStrUn(evt){
    evt=evt||event;
    var target=evt.target||evt.srcElement;
    UnTip();
}
  }
}
getRequest();
</script>
</body>
</html>

Смысл в том, чтобы послать запрос серверному скрипту, получить от него данные из базы, в данном случае id элементов и по этим id применить функции Tip и UnTip на события onmouseover(out) для img. Mozilla ничего не делает, в консоли ошибок нет.
Запрос от сервера приходит, проверял alert(). Если вставить alert после
if (img[i].addEventListener)
{
, то Mozilla выводит сообщение один раз, а Opera 3 раза(в таблице три записи).

pismenov 09.07.2009 16:11

Методом тыка удалось выяснить что в mozilla второй раз цикл не выполняется... FireBugом посмотрел - ошибок нема... Что за аномалия?

pismenov 09.07.2009 16:50

Проблему решил. Проверку состояния
if (xmlHttp.readyState == 4) {

закрыл за циклом. Всем большое спасибо.

B~Vladi 09.07.2009 16:53

Присмотрись-ка... Это твой код, но немножко переработан:

function getStr(evt){
	evt=evt||event;
	var img=evt.target||evt.srcElement;
	Tip('<img src="'+ img.getAttribute('src') +'" width="100">');
}
function xAddEvt(e,eventType,eventListener){
	if(e.addEventListener)e.addEventListener(eventType,eventListener,false);
	else if(e.attachEvent)e.attachEvent('on'+eventType,eventListener);
}
function getRequest() {
	var xmlHttp=window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject('Microsoft.XMLHTTP');
	xmlHttp.onreadystatechange=function(){if(xmlHttp.readyState==4)updatePage(xmlHttp.responseText);}
	xmlHttp.open('GET','tooltip.php',true);
	xmlHttp.send(null);
}
function updatePage(stroka){
	var arr = stroka.split(',');
	for (var i=0; i<arr.length; i++){
		var img = document.getElementById(arr[i]);
		xAddEvt(img,'mouseover',getStr);
		xAddEvt(img,'mouseout',UnTip);
	}
}
getRequest();


Чувствуешь разницу в размере?! Давай пиши грамотно.
Здесь вроде ошибок нет... не тестил если чесно... Попробуй его.

Riim 10.07.2009 03:07

B~Vladi,
расскажи, зачем нужна переменная img в getStr, если она используются один раз. Что толку от такой "оптимизации", если после компрессора будет тоже самое.

pismenov 10.07.2009 06:21

B~Vladi, спасибо за помощь!

B~Vladi 10.07.2009 11:02

Цитата:

Сообщение от Riim
расскажи, зачем нужна переменная img в getStr, если она используются один раз.

Чтобы человек понял что к чему.
Цитата:

Сообщение от Riim
Что толку от такой "оптимизации", если после компрессора будет тоже самое.

Не то же самое. В его коде было много лишних строк/переменных/действий. Оптимизация делалась не для урезания байтов, а для правильной работы скрипта.
А это
Цитата:

Сообщение от B~Vladi
Чувствуешь разницу в размере?!

просто как "из этого вытекающее".


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