Advertisement
Guest User

Untitled

a guest
Apr 19th, 2019
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.96 KB | None | 0 0
  1. function addSimultaneousEventListeners(eventNames, callback, options) {
  2. const defaultOptions = {
  3. inOrder: true, // the events should be fired in the order specified in eventNames array or not
  4. tolerance: 500, // the tolerance time between the first and the last event in milliseconds,
  5. // you can rarely fire two events at the exact moment
  6. }
  7. // merge default options with user options
  8. const mergedOptions = {
  9. ...defaultOptions,
  10. ...options
  11. };
  12. const inOrder = mergedOptions.inOrder;
  13. const tolerance = mergedOptions.tolerance;
  14.  
  15. eventNames = Object.freeze(eventNames); // make array immutable
  16. let eventList = [];
  17. eventNames.forEach((eventName) => {
  18. document.addEventListener(eventName, listener);
  19. })
  20.  
  21. function listener(e) {
  22. eventList.push(e);
  23. // trim eventList size
  24. if (eventList.length > eventNames.length) {
  25. eventList = eventList.slice(eventList.length - eventNames.length);
  26. }
  27. // console.log("eventList: " + eventList.reduce((string, event) => {
  28. // return string + event.type + "@" + Math.round(event.timeStamp) + ", ";
  29. // }, ""));
  30. const eventStack = eventNames.slice(); // copy array
  31. if (eventList.length === eventNames.length) {
  32. const firstEvent = eventList[0];
  33. for (let i = 0; i < eventList.length; i++) {
  34. const currentEvent = eventList[i];
  35. let currentEventName;
  36. if (inOrder) {
  37. currentEventName = eventNames[i];
  38. } else {
  39. const eventIndex = eventStack.indexOf(currentEvent.type);
  40. if (eventIndex >= 0) {
  41. currentEventName = currentEvent.type;
  42. eventStack.splice(eventIndex, 1);
  43. } else {
  44. return; // not the right events fired
  45. }
  46. }
  47. if (currentEvent.type !== currentEventName || !approximatelyEqual(firstEvent.timeStamp, currentEvent.timeStamp)) {
  48. return; // not the right event type or both events are NOT fired at the same time
  49. }
  50. }
  51. // eventList will be in order when inOrder is true
  52. // otherwise it will be the order the user fired them
  53. // you should always test for event types
  54. callback(eventList);
  55. }
  56. }
  57.  
  58. // test if a and b are equal within the tolerance range
  59. function approximatelyEqual(a, b) {
  60. return (Math.abs(a - b) <= tolerance);
  61. }
  62. }
  63. // Demo: detect keydown, click, and contextmenu fire at about the same time in that order
  64. addSimultaneousEventListeners(["keydown", "click", "contextmenu"], // events registered
  65. (eventList) => { // listener
  66. console.log("you pressed a key, left clicked, and right clicked the document!");
  67. console.log("eventList: ", eventList);
  68. },
  69. { // options
  70. inOrder: true
  71. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement