jsLib: События. "Правильный" onload

24.04.2008 8 JavaScript jsLib

$e

Установка/удаление стандартных событий DOM. Используется ветвление на этапе определения для ускорения работы. Для IE чистятся установленные события при unload.

if(document.addEventListener){    /// W3C event model: FF, Op, Safari, IE7

    /**    Attach event handler.
    *    @param {HTMLElement}    el    DOM node to attach event to.
    *    @param {String}                type    Event type (without 'on' in the begining).
    *    @param {Function}            fn        Event handler.
    */
    var $e=function(el, type, fn)
    {
        el && el.addEventListener(type,fn,false);
    };

    /**    Detach event handler.
    *    @param {HTMLElement}    el    DOM node to detach event from.
    *    @param {String}                type    Event type (without 'on' in the begining).
    *    @param {Function}            fn        Event handler.
    */
    $e.del=function(el, type, fn)
    {
        el && el.removeEventListener(type,fn,false);
    };

    /**    Prevent default event action.
    *    @param {Event}    e    Target event.
    */
    $e.ret=function(e)
    {
        e && e.preventDefault();
    };

    /**    Stop event propagation (bubbling).
    *    @param {Event}    e    Target event.
    */
    $e.stop=function(e)
    {
        e && e.stopPropagation();
    };

}else{ /// IE event model: IE<7

    var $e=function(el, type, fn)
    {
        if(el){
            el.attachEvent('on'+type,fn);
            $e.handlers[$e.handlers.length]=[el,type,fn];
        }
    };

    $e.handlers=[];

    /**
    * Not optimized (full array walk).
    */
    $e.del=function(el, type, fn)
    {
        if(el){
            el.detachEvent('on'+type,fn);

            var hs=$e.handlers;
            for(var i=0,n=hs.length; i<n; i++){
                var h=hs[i];
                if(h[0]==el && h[1]==type && h[2]==fn){
                    hs.splice(i,1);
                    return;
                }
            }
        }
    };

    $e.ret=function(e)
    {
        if(e) e.returnValue=false;
    };

    $e.stop=function(e)
    {
        if(e) e.cancelBubble=true;
    };

    $e.unload=function()
    {
        var hs=$e.handlers;
        for(var i=0,n=hs.length; i<n; i++){
            var h=hs[i];
            h[0].detachEvent('on'+h[1],h[2]);
        }

        $e.handlers=[];
    };

    $e(window,'unload',$e.unload);
}

$e.onload

Хаки для эмуляции события DOMContentLoaded в неподдерживающих его браузерах.

/**
*	Register DOMContentLoaded event handler
*	@param {Function}	fn	Event handler.
*	@param {Object}	scope	Handler scope.
*/
$e.onload=(function()
{
    var created=false;	// DOMContentLoaded listener created
    var loaded=false;	// DOMContentLoaded already fired
    var timer=0;
    var handlers=[];

    var create=function()
    {
        created=true;

        // for FF/Op9
        if(document.addEventListener)
            document.addEventListener('DOMContentLoaded', load, false);

        // for IE
        if($.ie){
            document.write('<script id=__ie_onload defer src=javascript:void(0)><\/script>');
            document.getElementById('__ie_onload').onreadystatechange=function(){
                if(this.readyState=='complete')
                    load(); // call the onload handler
            };
        }

        // for Safari
        if(/WebKit/i.test(navigator.userAgent)){ // sniff
            timer=setInterval(function(){
                if(/loaded|complete/.test(document.readyState)){
                    load(); // call the onload handler
                }
            }, 10);
        }

        // for other browsers
        $e(window,'load',load);
    };

    var load=function()
    {
        if(loaded) return;
        loaded=true;

        // cleanup
        if(document.addEventListener)
            document.removeEventListener('DOMContentLoaded', load, false);
        if($.ie){
            var defer=document.getElementById('__ie_onload');
            if(defer){
                defer.onreadystatechange=null;
                defer.parentNode.removeChild(defer);
            }
        }
        if(timer) clearInterval(timer);

        // do stuff
        for(var i=0, n=handlers.length; i<n; i++)
            handlers[i][0].call(handlers[i][1]||null);

        handlers=[];
    };

    var on=function(fn,scope)
    {
        // already loaded, call immediately
        if(loaded){
            fn.call(scope||null);
            return;
        }

        if(!created)
            create();

        handlers[handlers.length]=[fn,scope];
    };

    return on;
})();

Даже не знаю что еще тут можно написать - думаю все понятно. Публикую в большей степени для того, чтобы ссылаться в использующем события коде.



Комментарии

Riim 13.04.2009 07:58

>>> Хаки для эмуляции события DOMContentLoaded в неподдерживающих его браузерах.

Давно хотел, у кого ни будь спросить: что это за браузеры такие?
Я всегда писал так: $e(window, 'load', callback), проблем пока вреде не было.

dpp 13.04.2009 09:38

Событие DOMContentLoaded происходит когда загружен HTML+js+(css).
А событие onLoad - когда загружена страница полностью т.е. HTML+js+css+img.

Представьте что у вас на странице картинок на несколько мегабайт, да еще и со сторонних доменов. Пользователь может начать кликать пока графика не загрузилась.

dpp 13.04.2009 09:44

Событие DOMContentLoaded поддерживают только Firefox,Opera, и Safari 3.1 (судя по en.wikipedia.org/wiki/DOM_Events#Other_events)

Riim 14.04.2009 11:33

Спасибо, все понятно.
Может вот здесь:
>>> <script id=__ie_onload defer src=javascript:void(0)><\/script>
стоит кавычки добавить, что бы валидатор не ругался? Хотя валидатор этого не видит даже. Но все таки вреда не будет.

Riim 19.04.2009 11:51

Наверно какую-то глупость написал, раз нет ответа. Ну что ж со всеми бывает.

br_took 19.09.2009 07:01

спасибо за статью
в конце концов использовал jQuery.ready
но без вас не смог бы даже понять свою проблему=)

starrgrim 01.02.2010 10:09

intergovernmental llc specific paper emissions due available small

darlinecow 01.02.2010 10:11

costs thermal respect emissions stories

Написать комментарий

Вы представились как:   e-mail: email (изменить)

Ссылки запрещены.


Copyright © DPP, 2008-2009