Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > window.onload events


Автор: pho3nix 13.6.2007, 10:39
Хочу сделать обработку событий отдельно от html кода.
Вместо:
Код

<div id="left" onmouseover="fun1();" onmouseout="fun2();"></div>
<div id="right" onmouseover="fun1();" onmouseout="fun2();"></div>

получить:
Код

<div id="left"></div>
<div id="right"></div>

а обработку событий вынести в js-файл.

Сделал следующим образом:
Код

window.onload = function () { 
    check();
}

function check() {
    var el = document.getElementsByTagName('li');
    for (i=0;i<el.length;i++) {
        el[i].onmouseover = showBg;
        el[i].onmouseout = hideBg;
    }

    function showBg(e) {
        evt = e || window.event;
        tgt = evt.target || evt.srcElement;
        tmp = tgt;
        if (!tgt.id) {
            tmp = tgt.parentNode;
        }
        tmp.style.backgroundImage = 'url(images/menu_bg.jpg)';
        tmp.style.backgroundPosition = 'right bottom';
        tmp.style.backgroundRepeat = 'no-repeat';
                cleanup(tmp);
    }

    function hideBg(e) {
        evt = e || window.event;
        tgt = evt.target || evt.srcElement;
        tmp = tgt;
        if (!tgt.id) {
            tmp = tgt.parentNode
        }        
        tmp.style.background = 'none';
                cleanup(tmp);
    }

    function cleanup(tmp) {
        if (tmp.removeEventListener)
        {
            tmp.removeEventListener('onmouseout', hideBg, false);
            tmp.removeEventListener('onmouseover', showBg, false);
        }
        else 
        {
            tmp.detachEvent('onmouseout', hideBg);
            tmp.detachEvent('onmouseover', showBg);        
        }
}


Код

            <ul>
                <li id="l1"><img src="images/in_yan.jpg" alt="Главная" /><a href="#">Главная</a></li>
                <li id="l2"><img src="images/in_yan.jpg" alt="Главная" /><a href="#">Главная</a></li>
                <li id="l3"><img src="images/in_yan.jpg" alt="Главная" /><a href="#">Главная</a></li>
                <li id="l4"><img src="images/in_yan.jpg" alt="Главная" /><a href="#">Главная</a></li>
                <li id="l5"><img src="images/in_yan.jpg" alt="Главная" /><a href="#">Главная</a></li>
            </ul>

В принципе работает, утечки памяти не наблюдается ни в одном из трёх браузеров. Но почему-то код мне кажется немного индусским. И в Opera 9 после первого наведения на li-элемент курсор впадает в вечный wait, не обращая внимания на переопределение стиля или клавишу Esc.
Направьте на путь истинный ;)

Автор: vasac 13.6.2007, 11:42
Объясните, зачем вы после срабатывания обработчика удаляете все обработчики?
Почему установив по старинке el.onmouseover = '...', удаляете через removeEventListener.
Так же в removeEventListener имена событий указываются без "on"

Автор: lexxICON 13.6.2007, 12:01
pho3nix, вот вариант
Код

<html>
  <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
   
   <style type="text/css">
       .showBg { 
           background: url(images/menu_bg.jpg) right bottom no-repeat;
       }
   </style>
   <script type="text/javascript">

    document.onmouseover = function () { 
    
        var f = arguments.callee, e = arguments[0] || window.event, t = e.target || e.srcElement;
        
        if (f.last && t !== f.last) { 
            f.last.className = "";
            f.last = null;
        }
        
        if (t.nodeName === "LI") { 
            t.className = "showBg";
            f.last = t;
        } else if (t.parentNode.nodeName === "LI") { 
            t.parentNode.className = "showBg";
            f.last = t.parentNode;
        }
    }
   </script>
  </head>
  <body >
    <ul>
        <li><img src="images/in_yan.jpg" alt="Главная" /><a href="#">Главная</a></li>
        <li><img src="images/in_yan.jpg" alt="Главная" /><a href="#">Главная</a></li>
        <li><img src="images/in_yan.jpg" alt="Главная" /><a href="#">Главная</a></li>
        <li><img src="images/in_yan.jpg" alt="Главная" /><a href="#">Главная</a></li>
        <li><img src="images/in_yan.jpg" alt="Главная" /><a href="#">Главная</a></li>
    </ul>
  </body>
 </html>



Автор: pho3nix 13.6.2007, 12:19
Цитата(vasac @ 13.6.2007,  11:42)
Объясните, зачем вы после срабатывания обработчика удаляете все обработчики?
Почему установив по старинке el.onmouseover = '...', удаляете через removeEventListener.

Без удаления событий шла утечка памяти. Повозил мышкой по меню - сотню килобайт накрутил. Другого способа в голову не пришло/в гугле не нашёл.
Буду весьма благодарен за совет или за ссылку на правильную организацию моей задачи.
Цитата

Так же в removeEventListener имена событий указываются без "on"

Тем не менее, такая конструкция отключает утечку памяти.

Автор: vasac 13.6.2007, 16:33
Там не должно быть утечек памяти?
Вы уверены, что это не просто некоторое повышение деятельности системы в ответ на ваш провод мышкой?
В случае десяти проводов по меню 1М исчезает?

Автор: pho3nix 13.6.2007, 17:28
Цитата(vasac @ 13.6.2007,  16:33)
Там не должно быть утечек памяти?
Вы уверены, что это не просто некоторое повышение деятельности системы в ответ на ваш провод мышкой?
В случае десяти проводов по меню 1М исчезает?

На повышение деятельности системы не похоже, т.к. водил не один десяток раз. 1М не набирал, но 2-4 сотни килобайт набиралось. На сколько я заметил, основное повышение использования оперативной памяти происходило во время переходом курсором мыши от <a> к <li> и обратно. 
В принципе это не критично, но смотря глобальными мерками - нужно стремиться к идеальности ;)
Только почему в моём примере так брыкается Опера?

lexxICON, спасибо, дома попробую.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)