Skip to content

Commit 835dd0e

Browse files
author
Evan You
committed
fix #161 event propagation control
1 parent d06892b commit 835dd0e

File tree

2 files changed

+67
-19
lines changed

2 files changed

+67
-19
lines changed

src/compiler.js

+29-19
Original file line numberDiff line numberDiff line change
@@ -727,29 +727,12 @@ CompilerProto.parseDeps = function () {
727727
}
728728

729729
/**
730-
* Add an event delegation listener
730+
* Add an event listener to the delegator
731731
* listeners are instances of directives with `isFn:true`
732732
*/
733733
CompilerProto.addListener = function (listener) {
734734
var event = listener.arg,
735-
delegator = this.delegators[event]
736-
if (!delegator) {
737-
// initialize a delegator
738-
delegator = this.delegators[event] = {
739-
targets: [],
740-
handler: function (e) {
741-
var i = delegator.targets.length,
742-
target
743-
while (i--) {
744-
target = delegator.targets[i]
745-
if (target.el.contains(e.target) && target.handler) {
746-
target.handler(e)
747-
}
748-
}
749-
}
750-
}
751-
this.el.addEventListener(event, delegator.handler)
752-
}
735+
delegator = this.delegators[event] || this.addDelegator(event)
753736
delegator.targets.push(listener)
754737
}
755738

@@ -761,6 +744,33 @@ CompilerProto.removeListener = function (listener) {
761744
targets.splice(targets.indexOf(listener), 1)
762745
}
763746

747+
/**
748+
* Add an event delegator
749+
*/
750+
CompilerProto.addDelegator = function (event) {
751+
var delegator = this.delegators[event] = {
752+
targets: [],
753+
handler: function (e) {
754+
var target,
755+
i = delegator.targets.length,
756+
stop = e.stopPropagation
757+
// overwrite propagation control
758+
e.stopPropagation = function () {
759+
e.stopped = true
760+
stop.call(e)
761+
}
762+
while (i--) {
763+
target = delegator.targets[i]
764+
if (!e.stopped && target.handler && target.el.contains(e.target)) {
765+
target.handler(e)
766+
}
767+
}
768+
}
769+
}
770+
this.el.addEventListener(event, delegator.handler)
771+
return delegator
772+
}
773+
764774
/**
765775
* Do a one-time eval of a string that potentially
766776
* includes bindings. It accepts additional raw data

test/unit/specs/misc.js

+38
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,42 @@ describe('Misc Features', function () {
130130
})
131131
})
132132

133+
describe('event delegation', function () {
134+
135+
var inCalled = 0,
136+
outCalled = 0,
137+
innerHandler = function () {}
138+
var v = new Vue({
139+
template: '<div v-on="click:out"><div class="inner" v-on="click:in"></div></div>',
140+
methods: {
141+
'in': function (e) {
142+
inCalled++
143+
innerHandler(e)
144+
},
145+
out: function () {
146+
outCalled++
147+
}
148+
}
149+
})
150+
v.$appendTo('#test')
151+
152+
it('should work', function () {
153+
var e = mockMouseEvent('click')
154+
v.$el.querySelector('.inner').dispatchEvent(e)
155+
assert.strictEqual(inCalled, 1)
156+
assert.strictEqual(outCalled, 1)
157+
})
158+
159+
it('should allow stopPropagation()', function () {
160+
innerHandler = function (e) {
161+
e.stopPropagation()
162+
}
163+
var e = mockMouseEvent('click')
164+
v.$el.querySelector('.inner').dispatchEvent(e)
165+
assert.strictEqual(inCalled, 2)
166+
assert.strictEqual(outCalled, 1)
167+
})
168+
169+
})
170+
133171
})

0 commit comments

Comments
 (0)