Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit d262378

Browse files
fix(jqLite): allow triggerHandler() to accept custom event
In some scenarios you want to be able to specify properties on the event that is passed to the event handler. JQuery does this by overloading the first parameter (`eventName`). If it is an object with a `type` property then we assume that it must be a custom event. In this case the custom event must provide the `type` property which is the name of the event to be triggered. `triggerHandler` will continue to provide dummy default functions for `preventDefault()`, `isDefaultPrevented()` and `stopPropagation()` but you may override these with your own versions in your custom object if you wish. In addition the commit provides some performance and memory usage improvements by only creating objects and doing work that is necessary. This commit also renames the parameters inline with jQuery. Closes #8469 Closes #8505
1 parent 7729c84 commit d262378

File tree

2 files changed

+49
-13
lines changed

2 files changed

+49
-13
lines changed

src/jqLite.js

+28-12
Original file line numberDiff line numberDiff line change
@@ -952,21 +952,37 @@ forEach({
952952

953953
clone: jqLiteClone,
954954

955-
triggerHandler: function(element, eventName, eventData) {
956-
// Copy event handlers in case event handlers array is modified during execution.
957-
var eventFns = (jqLiteExpandoStore(element, 'events') || {})[eventName],
958-
eventFnsCopy = shallowCopy(eventFns || []);
955+
triggerHandler: function(element, event, extraParameters) {
959956

960-
eventData = eventData || [];
957+
var dummyEvent, eventFnsCopy, handlerArgs;
958+
var eventName = event.type || event;
959+
var eventFns = (jqLiteExpandoStore(element, 'events') || {})[eventName];
961960

962-
var event = [{
963-
preventDefault: noop,
964-
stopPropagation: noop
965-
}];
961+
if (eventFns) {
966962

967-
forEach(eventFnsCopy, function(fn) {
968-
fn.apply(element, event.concat(eventData));
969-
});
963+
// Create a dummy event to pass to the handlers
964+
dummyEvent = {
965+
preventDefault: function() { this.defaultPrevented = true; },
966+
isDefaultPrevented: function() { return this.defaultPrevented === true; },
967+
stopPropagation: noop,
968+
type: eventName,
969+
target: element
970+
};
971+
972+
// If a custom event was provided then extend our dummy event with it
973+
if (event.type) {
974+
dummyEvent = extend(dummyEvent, event);
975+
}
976+
977+
// Copy event handlers in case event handlers array is modified during execution.
978+
eventFnsCopy = shallowCopy(eventFns);
979+
handlerArgs = extraParameters ? [dummyEvent].concat(extraParameters) : [dummyEvent];
980+
981+
forEach(eventFnsCopy, function(fn) {
982+
fn.apply(element, handlerArgs);
983+
});
984+
985+
}
970986
}
971987
}, function(fn, name){
972988
/**

test/jqLiteSpec.js

+21-1
Original file line numberDiff line numberDiff line change
@@ -1647,9 +1647,11 @@ describe('jqLite', function() {
16471647
element.triggerHandler('click');
16481648
event = pokeSpy.mostRecentCall.args[0];
16491649
expect(event.preventDefault).toBeDefined();
1650+
expect(event.target).toEqual(element[0]);
1651+
expect(event.type).toEqual('click');
16501652
});
16511653

1652-
it('should pass data as an additional argument', function() {
1654+
it('should pass extra parameters as an additional argument', function() {
16531655
var element = jqLite('<a>poke</a>'),
16541656
pokeSpy = jasmine.createSpy('poke'),
16551657
data;
@@ -1680,6 +1682,24 @@ describe('jqLite', function() {
16801682
expect(clickOnceSpy).toHaveBeenCalledOnce();
16811683
expect(clickSpy.callCount).toBe(2);
16821684
});
1685+
1686+
it("should accept a custom event instead of eventName", function() {
1687+
var element = jqLite('<a>poke</a>'),
1688+
pokeSpy = jasmine.createSpy('poke'),
1689+
customEvent = {
1690+
type: 'click',
1691+
someProp: 'someValue'
1692+
},
1693+
actualEvent;
1694+
1695+
element.on('click', pokeSpy);
1696+
element.triggerHandler(customEvent);
1697+
actualEvent = pokeSpy.mostRecentCall.args[0];
1698+
expect(actualEvent.preventDefault).toBeDefined();
1699+
expect(actualEvent.someProp).toEqual('someValue');
1700+
expect(actualEvent.target).toEqual(element[0]);
1701+
expect(actualEvent.type).toEqual('click');
1702+
});
16831703
});
16841704

16851705

0 commit comments

Comments
 (0)