From af4b6b23c546ad2a97a21cb9535aea5d5568182d Mon Sep 17 00:00:00 2001 From: Joseph Cheung Date: Wed, 14 Nov 2018 10:32:37 +0800 Subject: [PATCH 1/2] finished --- lib/index.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/lib/index.js b/lib/index.js index 8d2deb0..c0a1e31 100644 --- a/lib/index.js +++ b/lib/index.js @@ -3,14 +3,39 @@ class Delegator { constructor (selector/* root选择器 */) { // TODO + this.root = doc.querySelector(selector); + this.delegatedListeners = {}; + this.cache = {}; + } + + cachedQuerySelector(selector) { + selector = selector.replace(/^\s+(.*?)\s+$/g, '$1'); + if (this.cache[selector]) return this.cache[selector]; + var item = doc.querySelector(selector); + this.cache[selector] = item; + return item; } on (event/* 绑定事件 */, selector/* 触发事件节点对应选择器 */, fn/* 出发函数 */) { // TODO + var item = this.cachedQuerySelector(selector); + if (!this.delegatedListeners[event]) this.delegatedListeners[event] = []; + let delegated = fn.bind(item); + this.delegatedListeners[event].push({ + target: item, + event: delegated + }) + item.addEventListener(event, delegated); + return this } destroy () { // TODO + Object.keys(this.delegatedListeners).forEach(eventNm => { + this.delegatedListeners[eventNm].forEach(item => { + item.target.removeEventListener(eventNm, item.event); + }) + }) } } From 3fa29a7beb3bc9911d584d926236f367f14d3eb6 Mon Sep 17 00:00:00 2001 From: Joseph Cheung Date: Wed, 14 Nov 2018 22:57:45 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E8=BF=99=E4=B8=8B=E6=98=AF=E4=BB=A3?= =?UTF-8?q?=E7=90=86=E4=BA=86=E5=8F=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/index.js | 50 +++++++++++++++++++++++++++++++------------------ lib/polyfill.js | 14 ++++++++++++++ 2 files changed, 46 insertions(+), 18 deletions(-) create mode 100644 lib/polyfill.js diff --git a/lib/index.js b/lib/index.js index c0a1e31..870c36b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -5,36 +5,50 @@ // TODO this.root = doc.querySelector(selector); this.delegatedListeners = {}; - this.cache = {}; } - cachedQuerySelector(selector) { - selector = selector.replace(/^\s+(.*?)\s+$/g, '$1'); - if (this.cache[selector]) return this.cache[selector]; - var item = doc.querySelector(selector); - this.cache[selector] = item; - return item; + delegator (eventNm) { + return (e, ...args) => { + var event = e || window.event; + // console.log(e); + var i = 0, len = event.path.length; + while (i < len) { + var target = event.path[i]; + this.delegatedListeners[eventNm].listeners.forEach(item => { + if (target.matches(item.selector)) { + item.fn.call(target, e, ...args); + } + }) + if (target === this.root) return + i++; + } + } } on (event/* 绑定事件 */, selector/* 触发事件节点对应选择器 */, fn/* 出发函数 */) { - // TODO - var item = this.cachedQuerySelector(selector); - if (!this.delegatedListeners[event]) this.delegatedListeners[event] = []; - let delegated = fn.bind(item); - this.delegatedListeners[event].push({ - target: item, - event: delegated + // 字符串处理selector + selector = selector.replace(/^\s+(.*?)\s+$/g, '$1'); + + if (!this.delegatedListeners[event]) { + let delegator = this.delegator(event); + this.delegatedListeners[event] = { + delegator, + listeners: [] + } + this.root.addEventListener(event, delegator); + }; + this.delegatedListeners[event].listeners.push({ + selector, + fn }) - item.addEventListener(event, delegated); + return this } destroy () { // TODO Object.keys(this.delegatedListeners).forEach(eventNm => { - this.delegatedListeners[eventNm].forEach(item => { - item.target.removeEventListener(eventNm, item.event); - }) + this.root.removeEventListener(eventNm, this.delegatedListeners[eventNm].delegator); }) } } diff --git a/lib/polyfill.js b/lib/polyfill.js new file mode 100644 index 0000000..3cc5a48 --- /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