自定义Javascript库。在动态添加的html中添加事件监听。

问题描述 投票:-1回答:1

我想建立一个类似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);.

但我不知道如何实现这个监听器。

请大家帮忙。

javascript event-handling dom-events event-listener dynamic-html
1个回答
0
投票

从你的评论中,我想你要求的是一个实时的实现?

如果是这样的话,我建议你在你的对象中添加一个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>

考虑因素。

  • 你将不得不为html方法做一个类似的实现。
  • 如果你想做一个真正的实时克隆,你将不得不保留预先注册的事件定义,并注册任何与选择器相匹配的新元素(此刻,一旦一个元素与选择器相匹配并注册了事件,事件定义就会在append中被删除--为了使其通用,你将不得不标记你的绑定元素,使用数据来实现这一点)。
© www.soinside.com 2019 - 2024. All rights reserved.