我是新来的JavaScript所以maby这是众所周知的/愚蠢的/无用的,但我想让事情发生与DOM元素一旦加载(什么都没发现搜索本网站或谷歌,但很难用几句话来解释这一点)。例如,当一个大页面加载时,我想隐藏/添加onlick事件/等。元素一旦出现在用户的屏幕上,不在$(document).ready()上。我写了一个简单的类(仅用于培训,闭包对我来说是新的,所以可能会有很多错误),但我希望使用更好的商业用途(在我正在帮助开发的站点上)。下面是我的源代码 - 莫比它会解释什么,我想要更好的,然后这个帖子:我是新来的英语水平(:一旦元素被加载,Javascript绑定元素事件
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='abcdefghijklmnopqrstuvwxyz';
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!');
});
谢谢大家提前
UPD:为了使这个问题!更有趣一点,因为它看起来太具体了,我必须补充一点:大多数浏览器在完全加载之前就开始页面渲染(这似乎因为某些原因而不是众所周知的),下面是几个链接:
- http://en.wikipedia.org/wiki/Incremental_rendering
- When do browsers start to render partially transmitted HTML?
- http://www.vbulletin.org/forum/showthread.php?t=161099
所以,我的问题应该得到更广泛的,因为这增加的页面加载增加了许多针对开发商的问题:用户可以点击非工作按钮之前加载页面时,有些事情是隐藏的JavaScript负载可能会显示,他们可以是丑陋的,等等(这是我的问题的例子)。其他开发者是否忽略了这个问题?请纠正我,如果我错了。
你是否正在使用一些在构建DOM之前实际呈现页面的浏览器?我不知道有这样的浏览器。 – kinakuta
@kinakuta:几乎所有的浏览器都是这样:例如firefox(100%测试)。阅读评论:http://php.net/manual/ru/function.flush.php,但这不是唯一的情况下(甚至启用gzip)。 – XzKto
您可能已经知道这一点,但document.ready()与body onload不同。 onload等待加载所有资源(images/css/etc),但document.ready()不加载。除非你有一个巨大的DOM结构,否则用户在.ready()触发之前可以选择任何东西似乎不太可能。 –