para-bridge-demo
Version:
a bridge api for js-ios/andriod rest
140 lines (127 loc) • 4.33 kB
text/typescript
import { canUseDOM } from './dom';
const canUseEventListeners = true;
const bind = canUseEventListeners && window.addEventListener ? 'addEventListener' : 'attachEvent';
const unbind = canUseEventListeners && window.removeEventListener ? 'removeEventListener' : 'detachEvent';
const canEventHasCapture = (bind === 'addEventListener');
const prefix = bind !== 'addEventListener' ? 'on' : '';
/**
* Bind to DOM events during the bubble phase.
*
* @param {DOMEventTarget} target DOM element to register listener on.
* @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
* @param {function} callback Callback function.
* @param {Boolean} is event capture phase.
* @return {object} Object with a `remove` method.
*/
export const on = (target, eventType, eventListener, capture?) => {
if (!canUseDOM || !target) {
return;
}
if (capture === true && !canEventHasCapture) {
if (process.env.NODE_ENV !== 'production') {
console.error('Attempted to listen to events during the capture phase on a ' + 'browser that does not support the capture phase. Your application ' + 'will not receive some events.');
}
return {
off: function noop() { /** */ },
};
}
// Warning. Unable to preventDefault inside passive event listener due to target being treated as passive
// If you're call preventDefault on every touchstart then you should also have a CSS rule to disable touch scrolling like .sortable-handler { touch-action: none; }
capture = isPassiveMode() ? { passive: false, capture: false } : capture || false;
target[bind](prefix + eventType, eventListener, capture);
return {
off() {
target[unbind](prefix + eventType, eventListener, capture);
},
};
};
/**
* Unbind to DOM events during the bubble phase.
*
* @param {DOMEventTarget} target DOM element to register listener on.
* @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
* @param {function} callback Callback function.
* @param {Boolean} is event capture phase.
* @return {Function}
*/
export const off = (target, eventType, eventListener, capture?) => {
if (!canUseDOM || !canUseEventListeners || !target) {
return;
}
capture = isPassiveMode() ? { passive: false, capture: false } : capture || false;
target[unbind](prefix + eventType, eventListener, capture);
return eventListener;
};
export const one = (node, eventNames, eventListener) => {
if (!canUseDOM || !canUseEventListeners || !node) {
return;
}
const typeArray = eventNames.split(' ');
const recursiveFunction = (e) => {
e.currentTarget.removeEventListener(e.type, recursiveFunction, isPassiveMode() ? { passive: false, capture: false } : false);
return eventListener(e);
};
for (let i = typeArray.length - 1; i >= 0; i--) {
on(node, typeArray[i], recursiveFunction);
}
};
export const getEvent = (event) => {
return event || window.event;
};
export const getTarget = (event) => {
event = getEvent(event);
return event.target || event.srcElement;
};
// ref https://github.com/WICG/EventListenerOptions/pull/30
// Passive event listeners, chrome and touch events
export const isPassiveMode = () => {
let supportsPassiveOption = false;
try {
addEventListener('test', () => {/** */ }, Object.defineProperty({}, 'passive', {
get() {
supportsPassiveOption = true;
},
}));
} catch (e) { /** */ }
return supportsPassiveOption;
};
export const preventDefault = (event) => {
event = getEvent(event);
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
};
export const stopPropagation = (event) => {
event = getEvent(event);
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
};
export const getCharCode = (event) => {
event = getEvent(event);
if (typeof event.charCode === 'number') {
return event.charCode;
} else {
return event.keyCode;
}
};
export const eventsFor = {
mouse: {
start: 'mousedown',
move: 'mousemove',
end: 'mouseup',
},
touch: {
start: 'touchstart',
move: 'touchmove',
end: 'touchend',
},
};
// Default to mouse events
export const dragEventFor = (isTouchDevice) => {
return isTouchDevice ? eventsFor.touch : eventsFor.mouse;
};