Skip to content

Commit 423b54d

Browse files
committed
remove event delegation
1 parent dcdee1c commit 423b54d

File tree

3 files changed

+28
-124
lines changed

3 files changed

+28
-124
lines changed

src/compiler.js

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -743,52 +743,6 @@ CompilerProto.parseDeps = function () {
743743
DepsParser.parse(this.computed)
744744
}
745745

746-
/**
747-
* Add an event listener to the delegator
748-
* listeners are instances of directives with `isFn:true`
749-
*/
750-
CompilerProto.addListener = function (listener) {
751-
var event = listener.arg,
752-
delegator = this.delegators[event] || this.addDelegator(event)
753-
delegator.targets.push(listener)
754-
}
755-
756-
/**
757-
* Remove an event delegation listener
758-
*/
759-
CompilerProto.removeListener = function (listener) {
760-
var targets = this.delegators[listener.arg].targets
761-
targets.splice(targets.indexOf(listener), 1)
762-
}
763-
764-
/**
765-
* Add an event delegator
766-
*/
767-
CompilerProto.addDelegator = function (event) {
768-
var delegator = this.delegators[event] = {
769-
targets: [],
770-
handler: function (e) {
771-
var target,
772-
i = delegator.targets.length,
773-
stop = e.stopPropagation
774-
// overwrite propagation control
775-
e.stopPropagation = function () {
776-
e.stopped = true
777-
stop.call(e)
778-
}
779-
while (i--) {
780-
target = delegator.targets[i]
781-
if (!e.stopped && target.handler && target.el.contains(e.target)) {
782-
target.handler(e)
783-
}
784-
}
785-
}
786-
}
787-
// useCapture:true so e.preventDefault() works
788-
this.el.addEventListener(event, delegator.handler, true)
789-
return delegator
790-
}
791-
792746
/**
793747
* Do a one-time eval of a string that potentially
794748
* includes bindings. It accepts additional raw data

src/directives/on.js

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,33 @@
1-
var utils = require('../utils'),
2-
noBubble = ['blur', 'focus', 'load']
1+
var utils = require('../utils')
32

43
module.exports = {
54

65
isFn: true,
76

87
bind: function () {
9-
// blur and focus events do not bubble
10-
// so they can't be delegated
11-
this.bubbles = noBubble.indexOf(this.arg) === -1
12-
if (this.bubbles) {
13-
this.binding.compiler.addListener(this)
14-
}
8+
this.context = this.binding.isExp
9+
? this.vm
10+
: this.binding.compiler.vm
1511
},
1612

1713
update: function (handler) {
1814
if (typeof handler !== 'function') {
1915
utils.warn('Directive "on" expects a function value.')
2016
return
2117
}
22-
var el = this.el,
23-
targetVM = this.vm,
24-
context = this.binding.isExp
25-
? targetVM
26-
: this.binding.compiler.vm,
27-
newHandler = function (e) {
28-
e.delegationTarget = el
29-
e.targetVM = targetVM
30-
context.$event = e
31-
handler.call(context, e)
32-
context.$event = null
33-
}
34-
if (!this.bubbles) {
35-
this.reset()
36-
this.el.addEventListener(this.arg, newHandler)
18+
this._unbind()
19+
var vm = this.vm,
20+
context = this.context
21+
this.handler = function (e) {
22+
e.targetVM = vm
23+
context.$event = e
24+
handler.call(context, e)
25+
context.$event = null
3726
}
38-
this.handler = newHandler
27+
this.el.addEventListener(this.arg, this.handler)
3928
},
4029

41-
reset: function () {
42-
this.el.removeEventListener(this.arg, this.handler)
43-
},
44-
4530
unbind: function () {
46-
if (this.bubbles) {
47-
this.binding.compiler.removeListener(this)
48-
} else {
49-
this.reset()
50-
}
31+
this.el.removeEventListener(this.arg, this.handler)
5132
}
5233
}

test/unit/specs/directives.js

Lines changed: 14 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ describe('Directives', function () {
417417

418418
var dir = mockDirective('on')
419419
dir.arg = 'click'
420+
dir.bind()
420421

421422
before(function () {
422423
document.body.appendChild(dir.el)
@@ -431,15 +432,18 @@ describe('Directives', function () {
431432
assert.ok(triggered)
432433
})
433434

434-
it('delegation should work', function () {
435-
var triggered = false,
436-
child = document.createElement('div')
437-
dir.el.appendChild(child)
435+
it('should remove previous handler when update() a new handler', function () {
436+
var triggered1 = false,
437+
triggered2 = false
438438
dir.update(function () {
439-
triggered = true
439+
triggered1 = true
440440
})
441-
child.dispatchEvent(mockMouseEvent('click'))
442-
assert.ok(triggered)
441+
dir.update(function () {
442+
triggered2 = true
443+
})
444+
dir.el.dispatchEvent(mockMouseEvent('click'))
445+
assert.notOk(triggered1)
446+
assert.ok(triggered2)
443447
})
444448

445449
it('should wrap the handler to supply expected args', function () {
@@ -449,27 +453,13 @@ describe('Directives', function () {
449453
dir.update(function (ev) {
450454
assert.strictEqual(this, vm, 'handler should be called on owner VM')
451455
assert.strictEqual(ev, e, 'event should be passed in')
452-
assert.strictEqual(ev.vm, dir.vm)
456+
assert.strictEqual(ev.targetVM, dir.vm)
453457
triggered = true
454458
})
455459
dir.el.dispatchEvent(e)
456460
assert.ok(triggered)
457461
})
458462

459-
it('should remove previous handler when update() a new handler', function () {
460-
var triggered1 = false,
461-
triggered2 = false
462-
dir.update(function () {
463-
triggered1 = true
464-
})
465-
dir.update(function () {
466-
triggered2 = true
467-
})
468-
dir.el.dispatchEvent(mockMouseEvent('click'))
469-
assert.notOk(triggered1)
470-
assert.ok(triggered2)
471-
})
472-
473463
it('should remove the handler in unbind()', function () {
474464
var triggered = false
475465
dir.update(function () {
@@ -480,29 +470,6 @@ describe('Directives', function () {
480470
assert.notOk(triggered)
481471
})
482472

483-
it('should not use delegation if the event is blur or focus', function () {
484-
var dir = mockDirective('on', 'input'),
485-
triggerCount = 0,
486-
handler = function () {
487-
triggerCount++
488-
}
489-
490-
document.body.appendChild(dir.el)
491-
492-
dir.arg = 'focus'
493-
dir.update(handler)
494-
dir.el.dispatchEvent(mockHTMLEvent('focus'))
495-
assert.strictEqual(triggerCount, 1)
496-
497-
dir.arg = 'blur'
498-
dir.update(handler)
499-
dir.el.dispatchEvent(mockHTMLEvent('blur'))
500-
assert.strictEqual(triggerCount, 2)
501-
502-
document.body.removeChild(dir.el)
503-
504-
})
505-
506473
after(function () {
507474
document.body.removeChild(dir.el)
508475
})
@@ -1043,6 +1010,8 @@ function mockDirective (dirName, tag, type) {
10431010
} else {
10441011
for (var key in dir) {
10451012
ret[key] = dir[key]
1013+
ret._update = dir.update
1014+
ret._unbind = dir.unbind
10461015
}
10471016
}
10481017
if (tag === 'input') ret.el.type = type || 'text'

0 commit comments

Comments
 (0)