简体   繁体   English

元素加载后,Javascript绑定元素事件

[英]Javascript bind element events as soon as element is loaded

I'm new to javascript so maby this is well-known/stupid/useless, but I want to make things happen with DOM elements as soon as they are loaded(found nothing with search on this site or google, but it is hard to explain this with few words). 我是javascript的新手,所以maby这是众所周知的/愚蠢的/没用的,但是我想让DOM元素一加载就使事情发生(在此网站或google上搜索找不到任何内容,但是很难用几句话解释一下)。 For example when a big page is loading I want to hide/add onlick events/etc. 例如,当一个大页面正在加载时,我想隐藏/添加onlick事件/等。 to elements as soon as they appear on user's screen not on $(document).ready(). 元素出现在用户的屏幕上,而不是出现在$(document).ready()上。 I wrote a simple class(just for training, closures are new for me so there may be lots of errors) that does what I want but I want to use something better for commercial use(on the site I'm helping to develop). 我写了一个简单的类(只是为了训练,闭包对我来说是新的,所以可能会有很多错误),可以满足我的要求,但我想将更好的东西用于商业用途(在我正在帮助开发的网站上)。 Here is my source code - maby it will explain what I want better then this post: I'm new to english too (: 这是我的源代码-maby它将解释我想要的更好的内容,然后,这篇文章:我也是英语新手(:

function MY_loader() {
    function container() {
        this.add_event = function(new_event,obj_selector,settings) {
            if(typeof(settings)!='object') {
                settings={};
            }
            if(typeof(settings.event_id)!='string') {
                settings.event_id=gen_new_event_id();
            }
            settings=$.extend({},default_settings,settings);
            settings.obj_selector=obj_selector;
            settings.event=new_event;
            events[settings.event_id]=settings;
        }

        this.execute_events = function(if_force) {
            if(typeof(if_force)=='undefined') {
                if_force=false;
            }
            if(html_is_loaded&&!if_force) {
                return;
            }
            var temp_obj;
            for(var event_name in events) {
                temp_obj=$(events[event_name].obj_selector);
                if(temp_obj.length || (html_is_loaded && events[event_name].if_force)) {
                    temp_obj.each(function() {
                        if(events[event_name].expect_multiple) {
                            if($(this).data('my_loader_'+events[event_name].event_id+'_executed')) {

                                return;
                            }
                        }
                        if(events[event_name].event_type!='func') {
                            $(this).bind(events[event_name].event_type+'.'+events[event_name].event_id,events[event_name].event);
                        }
                        else {
                            events[event_name].event($(this));
                        }
                        if(events[event_name].expect_multiple) {
                            alert('here');
                            $(this).data('my_loader_'+events[event_name].event_id+'_executed',1);
                        }
                    });
                       //alert(events[event_name].obj_selector+' '+events[event_name].event_type);
                    if(!events[event_name].expect_multiple) {
                        delete events[event_name];
                    }
                }
            }
            if(!html_is_loaded) {
               var cur_time=new Date().getTime();
               setTimeout('MY_loader().execute_events();',Math.max(Math.min(tick_time-(cur_time-last_tick_time),tick_time),0,min_tick_diff));
               last_tick_time=cur_time;
            }
        }

        this.html_is_loaded_set=function(if_html_is_loaded) {
            html_is_loaded=if_html_is_loaded?true:false;
        };

        this.html_is_loaded_get=function() {
            return html_is_loaded?true:false;
        };

        return this;
    }
    function instance(if_strat) {
        if(typeof(class_is_loaded)=='undefined'||!class_is_loaded) {
            load_class();
        }
        return container(if_strat);
    }

    var load_class=function() {
        this.class_is_loaded=true;
        this.events = {};
        this.allowed_event_id_chars='abcdefghijklmnopqrstuvwxyz0123456789';
        this.default_settings={
            'event_type':'click',
            'if_force':false,
            'expect_multiple':false
        };
        this.tick_time=500;
        this.min_tick_diff=100;
        this.last_tick_time=0;
        this.html_is_loaded=false;
        MY_loader().execute_events();
        $(document).ready(function(){
            MY_loader().html_is_loaded_set(true);
            MY_loader().execute_events(true);
        });
    }

    var gen_new_event_id=function() {
        for(var new_id=gen_random_id();typeof(events[new_id])!='undefined';new_id=gen_random_id());
        return new_id;
    }

    var gen_random_id=function() {
        var allowed_event_id_chars_size=allowed_event_id_chars.length;
        var new_id='';
        for(var i=0;i<10;i++) {
            new_id+=allowed_event_id_chars[get_random_int(0,allowed_event_id_chars_size-1)];
        }
        return new_id;
    }

    function get_random_int(min, max)
    {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    return new instance();
}
//Add click event to #some_selector (once and dont check after it)
MY_loader().add_event(function() {
    alert($(this).val());
}, '#some_selector');
//Hide elements as soon as they are loaded.
//We expect multiple elements with this selector, so it will
//check for this elements untill document is loaded, but this function
//will be applied only one time for each element.
MY_loader().add_event(function(obj) {
    obj.hide();
    alert('This should happen before DOM is completely loaded!');
}, '.some_other_selector',{'event_type':'func','expect_multiple':true});
//This alert should be outputted the last
$(document).ready(function(){
    alert('Document is fully loaded!');
});

Thank you all in advance! 谢谢大家!

UPD: To make this question a little bit more interesting as it seems too specic I must add: most of the browsers start page rendering before it is completely loaded(this seems to be not well-known for some reason), here are a few links: UPD:为了使这个问题变得更有趣,因为它似乎太具体了,我必须补充:大多数浏览器在页面完全加载之前就开始了页面渲染(由于某种原因,这似乎并不为人所知),这里有一些链接:

  1. http://en.wikipedia.org/wiki/Incremental_rendering http://en.wikipedia.org/wiki/Incremental_rendering
  2. When do browsers start to render partially transmitted HTML? 浏览器何时开始呈现部分传输的HTML?
  3. http://www.vbulletin.org/forum/showthread.php?t=161099 http://www.vbulletin.org/forum/showthread.php?t=161099

So, my problem should be more widely known as this incremental page loading adds lots of problems for developer: user can click on non-working buttons before page is loaded, some things that are hidden by javascript on load may show and they can be ugly, etc.(this are examples from my problem). 因此,我的问题应该更广为人知,因为这种增量页面加载给开发人员带来了很多问题:用户可以在页面加载前单击非工作按钮,加载时javascript隐藏的某些内容可能会显示出来,并且可能很丑陋等(这是我的问题的示例)。 Do other developers just ignore this problem? 其他开发人员会忽略这个问题吗? Please, correct me if I am wrong. 请改正我,如果我错了。

If your concern is that you don't want users to see the page before it is final, you can probably get away with doing the DOM modification straightaway, eg: 如果您担心您不希望用户在页面定型之前看到它,则可以直接进行DOM修改,例如:

<a href="#" id="test">Test</a>
<script type="text/javascript" src="enhancePage.js"></script>

Because the node in question exists in the DOM before the script is parsed, you can work with it. 因为有问题的节点在解析脚本之前已存在于DOM中,所以您可以使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM