我想建立一个类似jQuery的Javascript库,只是为了多学习Javascript。到目前为止,我已经开发了这个。
window.jsLib = function (selector) {
var about = {
Version: 0.1
};
if (selector) {
if (window === this) {
return new jsLib(selector);
}
if (typeof selector === 'string') {
var nodes = document.querySelectorAll(selector);
for (var i = 0; i < nodes.length; i++) {
this[i] = nodes[i];
}
this.length = nodes.length;
} else if (typeof selector === 'object') {
this[0] = selector;
this.length = 1;
}
return this;
} else {
return about;
}
};
而对于方法,我已经开发了一些类似的方法。
jsLib.fn = jsLib.prototype = {
css: function (key, value) {
if (value !== undefined) {
for (var i = 0; i < this.length; i++) {
this[i].style[key] = value;
}
return this;
} else {
for (var i = 0; i < this.length; i++) {
return this[i].style[key];
}
}
},
html: function (value) {
if (value !== undefined) {
for (var i = 0; i < this.length; i++) {
this[i].innerHTML = value;
}
return this;
} else {
for (var i = 0; i < this.length; i++) {
return this[i].innerHTML;
}
}
},
on: function (type, callback) {
console.log(window.event);
for (var i = 0; i < this.length; i++) {
this[i].addEventListener(type, callback, false);
}
return this;
},
trigger: function (type) {
var event = new Event(type);
for (var i = 0; i < this.length; i++) {
this[i].dispatchEvent(event);
}
return this;
},
append: function(value) {
var old = this.html();
this.html(old + '' + value);
return this;
}
};
你可能已经注意到,我定义了一个方法。on
像jQuery一样。
每当我在调用像 jsLib('div#foo').on('click', someFunc);
,它工作得很好。
但是,假设我添加了一些html,如 jsLib('body').append('<a id="#bar" href="#">Click</a>');
然后我想提供一个API来添加事件监听器到 #bar
喜欢 jsLib('body').on('click', '#bar', someOtherFunc);
.
但我不知道如何实现这个监听器。
请大家帮忙。
从你的评论中,我想你要求的是一个实时的实现?
如果是这样的话,我建议你在你的对象中添加一个data方法,记住所有要注册的事件,并在append方法中注册它们,当内容被添加到当前元素时。
我用.data和.live方法扩展了你的库,并为下一个要添加到body中的span排队注册事件。请看修改后的代码片段,并查看控制台进行验证。
window.jsLib = function (selector) {
var about = {
Version: 0.1
};
if (selector) {
if (window === this) {
return new jsLib(selector);
}
if (typeof selector === 'string') {
var nodes = document.querySelectorAll(selector);
for (var i = 0; i < nodes.length; i++) {
this[i] = nodes[i];
}
this.length = nodes.length;
this._selector = selector;
} else if (typeof selector === 'object') {
this[0] = selector;
this.length = 1;
}
return this;
} else {
return about;
}
};
jsLib.fn = jsLib.prototype = {
css: function (key, value) {
if (value !== undefined) {
for (var i = 0; i < this.length; i++) {
this[i].style[key] = value;
}
return this;
} else {
for (var i = 0; i < this.length; i++) {
return this[i].style[key];
}
}
},
html: function (value) {
if (value !== undefined) {
for (var i = 0; i < this.length; i++) {
this[i].innerHTML = value;
}
return this;
} else {
for (var i = 0; i < this.length; i++) {
return this[i].innerHTML;
}
}
},
on: function (type, callback) {
for (var i = 0; i < this.length; i++) {
this[i].addEventListener(type, callback, false);
}
return this;
},
trigger: function (type) {
var event = new Event(type);
for (var i = 0; i < this.length; i++) {
this[i].dispatchEvent(event);
}
return this;
},
append: function(value) {
var old = this.html(),
pendingEvents = this.data('jsLib_Future_Events') || [],
registered = {};
this.html(old + '' + value);
// Attach pending events to newly added childs (if any match found)
pendingEvents.forEach(function (evConf, i) {
[].slice.call(jsLib(this._selector + ' ' + evConf.selector), 0).forEach(function (el) {
jsLib(el).on(evConf.type, evConf.callback);
registered[i] = true;
});
}.bind(this));
// Clear list of pending requests of any registered events
this.data('sLib_Future_Events', pendingEvents.filter(function (evConf, i) { return !!registered[i]; }));
return this;
},
_data: {},
data: function (key, value) {
if (arguments.length > 1) this._data[key] = arguments[1]; // Setter
return key ? this._data[key] : this._data; // Getter of key or all
},
live: function (type, selector, callback) {
this.data('jsLib_Future_Events', (this.data('jsLib_Future_Events') || []).concat({type: type, selector: selector, callback: callback}));
return this;
}
};
jsLib('body').live('click', 'span', function () { console.debug('event triggered on appendend content after live registration of event handle'); });
jsLib('body').append('<br><span>dynamic content</span>');
<div>existing content</div>
考虑因素。