自定义Javascript库:添加事件侦听器以动态添加html

时间:2015-10-26 06:29:43

标签: javascript javascript-events event-handling event-listener dynamic-html

我试图建立一个像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);时,它都能正常工作。

但是,假设我添加了一些像jsLib('body').append('<a id="#bar" href="#">Click</a>');

这样的HTML

然后我想提供一个api来向#bar jsLib('body').on('click', '#bar', someOtherFunc);添加事件监听器。

但我不确定如何实现这个监听器。

请帮助。

感谢。

1 个答案:

答案 0 :(得分:0)

根据您的评论,我想您要求实时实施?

如果是这种情况,我建议你向对象添加一个数据方法,记住要注册的所有事件,并在将内容附加到当前元素时从append方法注册它们。

我使用.data和.live方法扩展了您的库,并将下一个跨度的事件注册排入队列中。查看修改后的代码段并查看控制台以进行验证。

&#13;
&#13;
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>');
&#13;
<div>existing content</div>
&#13;
&#13;
&#13;

注意事项:

  • 你必须为html方法做一个类似的实现
  • 如果你想制作一个真正的实时克隆,你必须保留预先注册的事件定义并注册与选择器匹配的任何新元素(此时,一旦元素与选择器匹配并且事件被注册,事件定义被删除在追加 - 为了使它普及,你将必须标记你的绑定元素,使用数据)