mirror of
https://github.com/videojs/video.js.git
synced 2024-12-25 02:42:10 +02:00
Added support for listening to multiple events through a types array. closes #1231
This commit is contained in:
parent
d5372545a2
commit
392cbda095
@ -12,6 +12,7 @@ CHANGELOG
|
||||
* Exported missing Player API methods (remainingTime, supportsFullScreen, enterFullWindow, exitFullWindow, preload) ([view](https://github.com/videojs/video.js/pull/1328))
|
||||
* Added a base for running saucelabs tests from grunt ([view](https://github.com/videojs/video.js/pull/1215))
|
||||
* Added additional browsers for saucelabs testing ([view](https://github.com/videojs/video.js/pull/1216))
|
||||
* Added support for listening to multiple events through a types array ([view](https://github.com/videojs/video.js/pull/1231))
|
||||
|
||||
--------------------
|
||||
|
||||
|
@ -11,11 +11,15 @@
|
||||
* and adds a generic handler to the element's event,
|
||||
* along with a unique id (guid) to the element.
|
||||
* @param {Element|Object} elem Element or object to bind listeners to
|
||||
* @param {String} type Type of event to bind to.
|
||||
* @param {String|Array} type Type of event to bind to.
|
||||
* @param {Function} fn Event listener.
|
||||
* @private
|
||||
*/
|
||||
vjs.on = function(elem, type, fn){
|
||||
if (vjs.obj.isArray(type)) {
|
||||
return _handleMultipleEvents(vjs.on, elem, type, fn);
|
||||
}
|
||||
|
||||
var data = vjs.getData(elem);
|
||||
|
||||
// We need a place to store all our handler data
|
||||
@ -64,7 +68,7 @@ vjs.on = function(elem, type, fn){
|
||||
/**
|
||||
* Removes event listeners from an element
|
||||
* @param {Element|Object} elem Object to remove listeners from
|
||||
* @param {String=} type Type of listener to remove. Don't include to remove all events from element.
|
||||
* @param {String|Array=} type Type of listener to remove. Don't include to remove all events from element.
|
||||
* @param {Function} fn Specific listener to remove. Don't incldue to remove listeners for an event type.
|
||||
* @private
|
||||
*/
|
||||
@ -77,6 +81,10 @@ vjs.off = function(elem, type, fn) {
|
||||
// If no events exist, nothing to unbind
|
||||
if (!data.handlers) { return; }
|
||||
|
||||
if (vjs.obj.isArray(type)) {
|
||||
return _handleMultipleEvents(vjs.off, elem, type, fn);
|
||||
}
|
||||
|
||||
// Utility function
|
||||
var removeType = function(t){
|
||||
data.handlers[t] = [];
|
||||
@ -337,15 +345,33 @@ vjs.trigger = function(elem, event) {
|
||||
/**
|
||||
* Trigger a listener only once for an event
|
||||
* @param {Element|Object} elem Element or object to
|
||||
* @param {String} type
|
||||
* @param {String|Array} type
|
||||
* @param {Function} fn
|
||||
* @private
|
||||
*/
|
||||
vjs.one = function(elem, type, fn) {
|
||||
if (vjs.obj.isArray(type)) {
|
||||
return _handleMultipleEvents(vjs.one, elem, type, fn);
|
||||
}
|
||||
var func = function(){
|
||||
vjs.off(elem, type, func);
|
||||
fn.apply(this, arguments);
|
||||
};
|
||||
// copy the guid to the new function so it can removed using the original function's ID
|
||||
func.guid = fn.guid = fn.guid || vjs.guid++;
|
||||
vjs.on(elem, type, func);
|
||||
};
|
||||
|
||||
/**
|
||||
* Loops through an array of event types and calls the requested method for each type.
|
||||
* @param {Function} fn The event method we want to use.
|
||||
* @param {Element|Object} elem Element or object to bind listeners to
|
||||
* @param {String} type Type of event to bind to.
|
||||
* @param {Function} callback Event listener.
|
||||
* @private
|
||||
*/
|
||||
function _handleMultipleEvents(fn, elem, type, callback) {
|
||||
vjs.arr.forEach(type, function(type) {
|
||||
fn(elem, type, callback); //Call the event method for each one of the types
|
||||
});
|
||||
}
|
||||
|
@ -843,3 +843,28 @@ vjs.findPosition = function(el) {
|
||||
top: vjs.round(top)
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Array functions container
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
vjs.arr = {};
|
||||
|
||||
/*
|
||||
* Loops through an array and runs a function for each item inside it.
|
||||
* @param {Array} array The array
|
||||
* @param {Function} callback The function to be run for each item
|
||||
* @param {*} thisArg The `this` binding of callback
|
||||
* @returns {Array} The array
|
||||
* @private
|
||||
*/
|
||||
vjs.arr.forEach = function(array, callback, thisArg) {
|
||||
if (vjs.obj.isArray(array) && callback instanceof Function) {
|
||||
for (var i = 0, len = array.length; i < len; ++i) {
|
||||
callback.call(thisArg || vjs, array[i], i, array);
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
};
|
||||
|
@ -14,6 +14,32 @@ test('should add and remove an event listener to an element', function(){
|
||||
vjs.trigger(el, 'click'); // No click should happen.
|
||||
});
|
||||
|
||||
test('should add and remove multiple event listeners to an element with a single call', function(){
|
||||
expect(6);
|
||||
|
||||
var el = document.createElement('div');
|
||||
var listener = function(){
|
||||
ok(true, 'Callback triggered');
|
||||
};
|
||||
|
||||
vjs.on(el, ['click', 'event1', 'event2'], listener);
|
||||
|
||||
vjs.trigger(el, 'click');
|
||||
vjs.trigger(el, 'click');
|
||||
vjs.off(el, 'click', listener);
|
||||
vjs.trigger(el, 'click'); // No click should happen.
|
||||
|
||||
vjs.trigger(el, 'event1');
|
||||
vjs.trigger(el, 'event1');
|
||||
vjs.off(el, 'event1', listener);
|
||||
vjs.trigger(el, 'event1'); // No event1 should happen.
|
||||
|
||||
vjs.trigger(el, 'event2');
|
||||
vjs.trigger(el, 'event2');
|
||||
vjs.off(el, 'event2', listener);
|
||||
vjs.trigger(el, 'event2'); // No event2 should happen.
|
||||
});
|
||||
|
||||
test('should remove all listeners of a type', function(){
|
||||
var el = document.createElement('div');
|
||||
var clicks = 0;
|
||||
@ -36,6 +62,30 @@ test('should remove all listeners of a type', function(){
|
||||
ok(clicks === 2, 'no click listeners fired');
|
||||
});
|
||||
|
||||
test('should remove all listeners of an array of types', function(){
|
||||
var el = document.createElement('div');
|
||||
var calls = 0;
|
||||
var listener = function(){
|
||||
calls++;
|
||||
};
|
||||
var listener2 = function(){
|
||||
calls++;
|
||||
};
|
||||
|
||||
vjs.on(el, ['click', 'event1'], listener);
|
||||
vjs.on(el, ['click', 'event1'], listener2);
|
||||
vjs.trigger(el, 'click'); // 2 calls
|
||||
vjs.trigger(el, 'event1'); // 2 calls
|
||||
|
||||
ok(calls === 4, 'both click listeners fired');
|
||||
|
||||
vjs.off(el, ['click', 'event1']);
|
||||
vjs.trigger(el, 'click'); // No click should happen.
|
||||
vjs.trigger(el, 'event1'); // No event1 should happen.
|
||||
|
||||
ok(calls === 4, 'no event listeners fired');
|
||||
});
|
||||
|
||||
test('should remove all listeners from an element', function(){
|
||||
expect(2);
|
||||
|
||||
@ -73,6 +123,23 @@ test('should listen only once', function(){
|
||||
vjs.trigger(el, 'click'); // No click should happen.
|
||||
});
|
||||
|
||||
test( 'should listen only once in multiple events from a single call', function(){
|
||||
expect(3);
|
||||
|
||||
var el = document.createElement('div');
|
||||
var listener = function(){
|
||||
ok(true, 'Callback Triggered');
|
||||
};
|
||||
|
||||
vjs.one(el, ['click', 'event1', 'event2'], listener);
|
||||
vjs.trigger(el, 'click'); // 1 click
|
||||
vjs.trigger(el, 'click'); // No click should happen.
|
||||
vjs.trigger(el, 'event1'); // event1 must be handled.
|
||||
vjs.trigger(el, 'event1'); // No event1 should be handled.
|
||||
vjs.trigger(el, 'event2'); // event2 must be handled.
|
||||
vjs.trigger(el, 'event2'); // No event2 should be handled.
|
||||
});
|
||||
|
||||
test('should stop immediate propagtion', function(){
|
||||
expect(1);
|
||||
|
||||
|
@ -332,3 +332,25 @@ test('should confirm logging functions work', function() {
|
||||
console.error = origError;
|
||||
}
|
||||
});
|
||||
|
||||
test('should loop through each element of an array', function() {
|
||||
expect(10);
|
||||
var a = [1, 2, 3];
|
||||
var sum = 0;
|
||||
var i = 0;
|
||||
var thisArg = {};
|
||||
|
||||
vjs.arr.forEach(a, function(item, iterator, array) {
|
||||
sum += item;
|
||||
deepEqual(array, a, 'The array arg should match the original array');
|
||||
equal(i++, iterator, 'The indexes should match');
|
||||
equal(this, thisArg, 'The context should equal the thisArg');
|
||||
}, thisArg);
|
||||
ok(sum, 6);
|
||||
|
||||
vjs.arr.forEach(a, function(){
|
||||
if (this !== vjs) {
|
||||
ok(false, 'default context should be vjs');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user