From 5015bf49bdc819921bc00212135cc215f478ca7a Mon Sep 17 00:00:00 2001 From: "Chen Xudong(uidp5344)" Date: Thu, 15 Nov 2018 14:16:49 +0800 Subject: [PATCH 1/2] exercise20 test passed --- lib/index.js | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/lib/index.js b/lib/index.js index 8d2deb0..e7524f1 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,18 +1,47 @@ !function (root, doc) { class Delegator { - constructor (selector/* root选择器 */) { + constructor(selector/* root选择器 */) { // TODO + this.root = document.querySelector(selector); + /** + * 用于存储事件列表 + * [{ eventName: event,selector: selector,fn: fn}] + */ + this.events = []; + // 监听是否有新节点插入,如果有新节点插入,那么为新节点注册事件(如果有需要的话) + this.root.addEventListener('DOMNodeInserted', (e) => { + this.events.forEach(event => { + let eles = document.querySelectorAll(event.selector); + eles.forEach((ele) => { + if (e.target == ele) { + e.target.addEventListener(event.eventName, event.fn) + } + }); + }); + }, false); } - on (event/* 绑定事件 */, selector/* 触发事件节点对应选择器 */, fn/* 出发函数 */) { + on(event/* 绑定事件 */, selector/* 触发事件节点对应选择器 */, fn/* 出发函数 */) { // TODO + let e = { + eventName: event, + selector: selector, + fn: fn + } + this.events.includes(e) ? null : this.events.push(e); + let eles = document.querySelectorAll(selector); + eles.forEach((ele) => { + ele.addEventListener(event, fn) + }); + return this; } - destroy () { + destroy() { // TODO + this.events = []; } } - root.Delegator = Delegator -}(window, document) \ No newline at end of file +}(window, document) + From 4ef6b784ca067fc02766027ed6d502cef6eeb557 Mon Sep 17 00:00:00 2001 From: SimpleCodeCX <248200851@qq.com> Date: Sun, 25 Nov 2018 23:41:43 +0800 Subject: [PATCH 2/2] complete with real delegator --- lib/index.js | 62 ++++++++++++++++++++++++++++++------------------- lib/polyfill.js | 14 +++++++++++ 2 files changed, 52 insertions(+), 24 deletions(-) create mode 100644 lib/polyfill.js diff --git a/lib/index.js b/lib/index.js index e7524f1..5882118 100644 --- a/lib/index.js +++ b/lib/index.js @@ -3,45 +3,59 @@ class Delegator { constructor(selector/* root选择器 */) { // TODO - this.root = document.querySelector(selector); + this.root = doc.querySelector(selector); /** - * 用于存储事件列表 - * [{ eventName: event,selector: selector,fn: fn}] + * 每一种事件类型定义一个委托,并以事件类型命名,比如click + * delegators={ + * 'click':{ + * delegator:delegatorFun, + * listeners:[] + * } + * } */ - this.events = []; - // 监听是否有新节点插入,如果有新节点插入,那么为新节点注册事件(如果有需要的话) - this.root.addEventListener('DOMNodeInserted', (e) => { - this.events.forEach(event => { - let eles = document.querySelectorAll(event.selector); - eles.forEach((ele) => { - if (e.target == ele) { - e.target.addEventListener(event.eventName, event.fn) + this.delegators = {}; + } + + createDelegator(eventName) { + return (e) => { + let event = e || window.event; + for (let i = 0, len = event.path.length; i < len; i++) { + let target = event.path[i]; + this.delegators[eventName].listeners.forEach((item) => { + if (target.matches(item.selector)) { + item.fn.call(target, event); } }); - }); - }, false); + if (target === this.root) return; + } + }; } on(event/* 绑定事件 */, selector/* 触发事件节点对应选择器 */, fn/* 出发函数 */) { // TODO - let e = { - eventName: event, - selector: selector, - fn: fn + if (!this.delegators[event]) { + let delegator = this.createDelegator(event); + this.delegators[event] = { + delegator: delegator, + listeners: [] + }; + // console.log(this.delegators[event].delegator); + this.root.addEventListener(event, this.delegators[event].delegator); } - this.events.includes(e) ? null : this.events.push(e); - let eles = document.querySelectorAll(selector); - eles.forEach((ele) => { - ele.addEventListener(event, fn) + this.delegators[event].listeners.push({ + selector, + fn }); return this; } destroy() { // TODO - this.events = []; + Object.keys(this.delegators).forEach(event => { + this.root.removeEventListener(event, this.delegators[event].delegator); + }); } } - root.Delegator = Delegator -}(window, document) + root.Delegator = Delegator +}(window, document) \ No newline at end of file diff --git a/lib/polyfill.js b/lib/polyfill.js new file mode 100644 index 0000000..2e3e67a --- /dev/null +++ b/lib/polyfill.js @@ -0,0 +1,14 @@ +if (!Element.prototype.matches) { + Element.prototype.matches = + Element.prototype.matchesSelector || + Element.prototype.mozMatchesSelector || + Element.prototype.msMatchesSelector || + Element.prototype.oMatchesSelector || + Element.prototype.webkitMatchesSelector || + function (s) { + var matches = (this.document || this.ownerDocument).querySelectorAll(s), + i = matches.length; + while (--i >= 0 && matches.item(i) !== this) { } + return i > -1; + }; +} \ No newline at end of file