From 16137e5e1a0385b351896c7d2da9d589aacce0c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michae=CC=88l=20Fortin?= Date: Mon, 3 Dec 2018 17:45:29 -0500 Subject: [PATCH 1/2] Stop propagation of events to parent elements Allows embedding impetus-enabled elements into other impetus-enabled elements, such as a small scrollable div inside a larger one, etc. --- src/Impetus.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Impetus.js b/src/Impetus.js index d0173d6..99d4148 100644 --- a/src/Impetus.js +++ b/src/Impetus.js @@ -210,6 +210,7 @@ export default class Impetus { * @param {Object} ev Normalized event */ function onDown(ev) { + ev.stopPropagation(); var event = normalizeEvent(ev); if (!pointerActive && !paused) { pointerActive = true; @@ -230,6 +231,7 @@ export default class Impetus { * @param {Object} ev Normalized event */ function onMove(ev) { + ev.stopPropagation(); ev.preventDefault(); var event = normalizeEvent(ev); @@ -246,6 +248,7 @@ export default class Impetus { * @param {Object} ev Normalized event */ function onUp(ev) { + ev.stopPropagation(); var event = normalizeEvent(ev); if (pointerActive && event.id === pointerId) { From 01165f7eb6a5f3b74187282c76ae4a596ec9a042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Fortin?= Date: Thu, 3 Jan 2019 14:00:29 -0500 Subject: [PATCH 2/2] Implement "stop propagation" in a react-compatible way --- dist/impetus.js | 12 ++++++++++++ dist/impetus.min.js | 2 +- docs/impetus.min.js | 2 +- src/Impetus.js | 15 ++++++++++++--- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/dist/impetus.js b/dist/impetus.js index 56f560d..adbbf58 100644 --- a/dist/impetus.js +++ b/dist/impetus.js @@ -229,6 +229,18 @@ * @param {Object} ev Normalized event */ function onDown(ev) { + // This allows embedding impetus-enabled elements into other impetus-enabled elements (such as a scrollable div + // within another) by making any ancestor impetus ignore the down event. Normally we would use stopPropagation to + // prevent the event from bubbling up to the ancestor impetus (which does work as expected in raw HTML). However, + // this approach does not work in React because React implements its own event system, which causes all sorts of + // issues with non-React stopPropagation as native DOM events propagate before react events are triggered and + // propagate. Instead, we simply tag the event as handled. Ancestor impetus instances then ignore the event if + // it's been marked as handled. + // https://dlinau.wordpress.com/2015/09/16/avoid-mixing-reacts-event-system-with-native-dom-event-handling/ + // https://github.com/facebook/react/issues/8693 + if (ev.handledByImpetus) return; + ev.handledByImpetus = true; + var event = normalizeEvent(ev); if (!pointerActive && !paused) { pointerActive = true; diff --git a/dist/impetus.min.js b/dist/impetus.min.js index c6325cc..8b290bc 100644 --- a/dist/impetus.min.js +++ b/dist/impetus.min.js @@ -1 +1 @@ -!function(e,t){if("function"==typeof define&&define.amd)define(["exports","module"],t);else if("undefined"!=typeof exports&&"undefined"!=typeof module)t(exports,module);else{var n={exports:{}};t(n.exports,n),e.Impetus=n.exports}}(this,function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(){var e=!1;try{var t=Object.defineProperty({},"passive",{get:function(){e=!0}});window.addEventListener("test",null,t)}catch(e){}return o=function(){return e},e}var i=.04,u=.11;window.addEventListener("touchmove",function(){});var r=function e(t){function r(){document.removeEventListener("touchmove",v,!!o()&&{passive:!1}),document.removeEventListener("touchend",m),document.removeEventListener("touchcancel",l),document.removeEventListener("mousemove",v,!!o()&&{passive:!1}),document.removeEventListener("mouseup",m)}function c(){r(),document.addEventListener("touchmove",v,!!o()&&{passive:!1}),document.addEventListener("touchend",m),document.addEventListener("touchcancel",l),document.addEventListener("mousemove",v,!!o()&&{passive:!1}),document.addEventListener("mouseup",m)}function d(){g.call(M,H,J)}function a(e){if("touchmove"===e.type||"touchstart"===e.type||"touchend"===e.type){var t=e.targetTouches[0]||e.changedTouches[0];return{x:t.clientX,y:t.clientY,id:t.identifier}}return{x:e.clientX,y:e.clientY,id:null}}function f(e){var t=a(e);Q||W||(Q=!0,Z=!1,C=t.id,V=k=t.x,j=z=t.y,$=[],h(V,j),c())}function v(e){e.preventDefault();var t=a(e);Q&&t.id===C&&(k=t.x,z=t.y,h(V,j),x())}function m(e){var t=a(e);Q&&t.id===C&&l()}function l(){Q=!1,h(V,j),E(),r()}function h(e,t){for(var n=Date.now();$.length>0&&!(n-$[0].time<=100);)$.shift();$.push({x:e,y:t,time:n})}function p(){var e=k-V,t=z-j;if(H+=e*B,J+=t*B,P){var n=w();0!==n.x&&(H-=e*y(n.x)*B),0!==n.y&&(J-=t*y(n.y)*B)}else w(!0);d(),V=k,j=z,N=!1}function y(e){return 5e-6*Math.pow(e,2)+1e-4*e+.55}function x(){N||s(p),N=!0}function w(e){var t=0,n=0;return void 0!==S&&HD&&(t=D-H),void 0!==R&&JU&&(n=U-J),e&&(0!==t&&(H=t>0?S:D),0!==n&&(J=n>0?R:U)),{x:t,y:n,inBounds:0===t&&0===n}}function E(){var e=$[0],t=$[$.length-1],n=t.x-e.x,o=t.y-e.y,i=t.time-e.time,u=i/15/B;O=n/u||0,G=o/u||0;var r=w();(Math.abs(O)>1||Math.abs(G)>1||!r.inBounds)&&(Z=!0,s(L))}function L(){if(Z){O*=X,G*=X,H+=O,J+=G;var e=w();if(Math.abs(O)>K||Math.abs(G)>K||!e.inBounds){if(P){if(0!==e.x)if(e.x*O<=0)O+=e.x*i;else{var t=e.x>0?2.5:-2.5;O=(e.x+t)*u}if(0!==e.y)if(e.y*G<=0)G+=e.y*i;else{var t=e.y>0?2.5:-2.5;G=(e.y+t)*u}}else 0!==e.x&&(H=e.x>0?S:D,O=0),0!==e.y&&(J=e.y>0?R:U,G=0);d(),s(L)}else Z=!1}}var b=t.source,M=void 0===b?document:b,g=t.update,T=t.multiplier,B=void 0===T?1:T,q=t.friction,X=void 0===q?.92:q,Y=t.initialValues,A=t.boundX,F=t.boundY,I=t.bounce,P=void 0===I||I;n(this,e);var S,D,R,U,V,j,k,z,C,O,G,H=0,J=0,K=.3*B,N=!1,Q=!1,W=!1,Z=!1,$=[];!function(){if(!(M="string"==typeof M?document.querySelector(M):M))throw new Error("IMPETUS: source not found.");if(!g)throw new Error("IMPETUS: update function not defined.");Y&&(Y[0]&&(H=Y[0]),Y[1]&&(J=Y[1]),d()),A&&(S=A[0],D=A[1]),F&&(R=F[0],U=F[1]),M.addEventListener("touchstart",f),M.addEventListener("mousedown",f)}(),this.destroy=function(){return M.removeEventListener("touchstart",f),M.removeEventListener("mousedown",f),r(),null},this.pause=function(){r(),Q=!1,W=!0},this.resume=function(){W=!1},this.setValues=function(e,t){"number"==typeof e&&(H=e),"number"==typeof t&&(J=t)},this.setMultiplier=function(e){B=e,K=.3*B},this.setBoundX=function(e){S=e[0],D=e[1]},this.setBoundY=function(e){R=e[0],U=e[1]}};t.exports=r;var s=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(e){window.setTimeout(e,1e3/60)}}()}); \ No newline at end of file +!function(e,t){if("function"==typeof define&&define.amd)define(["exports","module"],t);else if("undefined"!=typeof exports&&"undefined"!=typeof module)t(exports,module);else{var n={exports:{}};t(n.exports,n),e.Impetus=n.exports}}(this,function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(){var e=!1;try{var t=Object.defineProperty({},"passive",{get:function(){e=!0}});window.addEventListener("test",null,t)}catch(e){}return o=function(){return e},e}var i=.04,u=.11;window.addEventListener("touchmove",function(){});var r=function e(t){function r(){document.removeEventListener("touchmove",v,!!o()&&{passive:!1}),document.removeEventListener("touchend",m),document.removeEventListener("touchcancel",l),document.removeEventListener("mousemove",v,!!o()&&{passive:!1}),document.removeEventListener("mouseup",m)}function d(){r(),document.addEventListener("touchmove",v,!!o()&&{passive:!1}),document.addEventListener("touchend",m),document.addEventListener("touchcancel",l),document.addEventListener("mousemove",v,!!o()&&{passive:!1}),document.addEventListener("mouseup",m)}function c(){B.call(M,H,J)}function a(e){if("touchmove"===e.type||"touchstart"===e.type||"touchend"===e.type){var t=e.targetTouches[0]||e.changedTouches[0];return{x:t.clientX,y:t.clientY,id:t.identifier}}return{x:e.clientX,y:e.clientY,id:null}}function f(e){if(!e.handledByImpetus){e.handledByImpetus=!0;var t=a(e);Q||W||(Q=!0,Z=!1,C=t.id,V=k=t.x,j=z=t.y,$=[],h(V,j),d())}}function v(e){e.preventDefault();var t=a(e);Q&&t.id===C&&(k=t.x,z=t.y,h(V,j),x())}function m(e){var t=a(e);Q&&t.id===C&&l()}function l(){Q=!1,h(V,j),E(),r()}function h(e,t){for(var n=Date.now();$.length>0&&!(n-$[0].time<=100);)$.shift();$.push({x:e,y:t,time:n})}function p(){var e=k-V,t=z-j;if(H+=e*T,J+=t*T,P){var n=w();0!==n.x&&(H-=e*y(n.x)*T),0!==n.y&&(J-=t*y(n.y)*T)}else w(!0);c(),V=k,j=z,N=!1}function y(e){return 5e-6*Math.pow(e,2)+1e-4*e+.55}function x(){N||s(p),N=!0}function w(e){var t=0,n=0;return void 0!==S&&HD&&(t=D-H),void 0!==R&&JU&&(n=U-J),e&&(0!==t&&(H=t>0?S:D),0!==n&&(J=n>0?R:U)),{x:t,y:n,inBounds:0===t&&0===n}}function E(){var e=$[0],t=$[$.length-1],n=t.x-e.x,o=t.y-e.y,i=t.time-e.time,u=i/15/T;O=n/u||0,G=o/u||0;var r=w();(Math.abs(O)>1||Math.abs(G)>1||!r.inBounds)&&(Z=!0,s(L))}function L(){if(Z){O*=q,G*=q,H+=O,J+=G;var e=w();if(Math.abs(O)>K||Math.abs(G)>K||!e.inBounds){if(P){if(0!==e.x)if(e.x*O<=0)O+=e.x*i;else{var t=e.x>0?2.5:-2.5;O=(e.x+t)*u}if(0!==e.y)if(e.y*G<=0)G+=e.y*i;else{var t=e.y>0?2.5:-2.5;G=(e.y+t)*u}}else 0!==e.x&&(H=e.x>0?S:D,O=0),0!==e.y&&(J=e.y>0?R:U,G=0);c(),s(L)}else Z=!1}}var b=t.source,M=void 0===b?document:b,B=t.update,g=t.multiplier,T=void 0===g?1:g,I=t.friction,q=void 0===I?.92:I,X=t.initialValues,Y=t.boundX,A=t.boundY,F=t.bounce,P=void 0===F||F;n(this,e);var S,D,R,U,V,j,k,z,C,O,G,H=0,J=0,K=.3*T,N=!1,Q=!1,W=!1,Z=!1,$=[];!function(){if(!(M="string"==typeof M?document.querySelector(M):M))throw new Error("IMPETUS: source not found.");if(!B)throw new Error("IMPETUS: update function not defined.");X&&(X[0]&&(H=X[0]),X[1]&&(J=X[1]),c()),Y&&(S=Y[0],D=Y[1]),A&&(R=A[0],U=A[1]),M.addEventListener("touchstart",f),M.addEventListener("mousedown",f)}(),this.destroy=function(){return M.removeEventListener("touchstart",f),M.removeEventListener("mousedown",f),r(),null},this.pause=function(){r(),Q=!1,W=!0},this.resume=function(){W=!1},this.setValues=function(e,t){"number"==typeof e&&(H=e),"number"==typeof t&&(J=t)},this.setMultiplier=function(e){T=e,K=.3*T},this.setBoundX=function(e){S=e[0],D=e[1]},this.setBoundY=function(e){R=e[0],U=e[1]}};t.exports=r;var s=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(e){window.setTimeout(e,1e3/60)}}()}); \ No newline at end of file diff --git a/docs/impetus.min.js b/docs/impetus.min.js index c6325cc..8b290bc 100644 --- a/docs/impetus.min.js +++ b/docs/impetus.min.js @@ -1 +1 @@ -!function(e,t){if("function"==typeof define&&define.amd)define(["exports","module"],t);else if("undefined"!=typeof exports&&"undefined"!=typeof module)t(exports,module);else{var n={exports:{}};t(n.exports,n),e.Impetus=n.exports}}(this,function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(){var e=!1;try{var t=Object.defineProperty({},"passive",{get:function(){e=!0}});window.addEventListener("test",null,t)}catch(e){}return o=function(){return e},e}var i=.04,u=.11;window.addEventListener("touchmove",function(){});var r=function e(t){function r(){document.removeEventListener("touchmove",v,!!o()&&{passive:!1}),document.removeEventListener("touchend",m),document.removeEventListener("touchcancel",l),document.removeEventListener("mousemove",v,!!o()&&{passive:!1}),document.removeEventListener("mouseup",m)}function c(){r(),document.addEventListener("touchmove",v,!!o()&&{passive:!1}),document.addEventListener("touchend",m),document.addEventListener("touchcancel",l),document.addEventListener("mousemove",v,!!o()&&{passive:!1}),document.addEventListener("mouseup",m)}function d(){g.call(M,H,J)}function a(e){if("touchmove"===e.type||"touchstart"===e.type||"touchend"===e.type){var t=e.targetTouches[0]||e.changedTouches[0];return{x:t.clientX,y:t.clientY,id:t.identifier}}return{x:e.clientX,y:e.clientY,id:null}}function f(e){var t=a(e);Q||W||(Q=!0,Z=!1,C=t.id,V=k=t.x,j=z=t.y,$=[],h(V,j),c())}function v(e){e.preventDefault();var t=a(e);Q&&t.id===C&&(k=t.x,z=t.y,h(V,j),x())}function m(e){var t=a(e);Q&&t.id===C&&l()}function l(){Q=!1,h(V,j),E(),r()}function h(e,t){for(var n=Date.now();$.length>0&&!(n-$[0].time<=100);)$.shift();$.push({x:e,y:t,time:n})}function p(){var e=k-V,t=z-j;if(H+=e*B,J+=t*B,P){var n=w();0!==n.x&&(H-=e*y(n.x)*B),0!==n.y&&(J-=t*y(n.y)*B)}else w(!0);d(),V=k,j=z,N=!1}function y(e){return 5e-6*Math.pow(e,2)+1e-4*e+.55}function x(){N||s(p),N=!0}function w(e){var t=0,n=0;return void 0!==S&&HD&&(t=D-H),void 0!==R&&JU&&(n=U-J),e&&(0!==t&&(H=t>0?S:D),0!==n&&(J=n>0?R:U)),{x:t,y:n,inBounds:0===t&&0===n}}function E(){var e=$[0],t=$[$.length-1],n=t.x-e.x,o=t.y-e.y,i=t.time-e.time,u=i/15/B;O=n/u||0,G=o/u||0;var r=w();(Math.abs(O)>1||Math.abs(G)>1||!r.inBounds)&&(Z=!0,s(L))}function L(){if(Z){O*=X,G*=X,H+=O,J+=G;var e=w();if(Math.abs(O)>K||Math.abs(G)>K||!e.inBounds){if(P){if(0!==e.x)if(e.x*O<=0)O+=e.x*i;else{var t=e.x>0?2.5:-2.5;O=(e.x+t)*u}if(0!==e.y)if(e.y*G<=0)G+=e.y*i;else{var t=e.y>0?2.5:-2.5;G=(e.y+t)*u}}else 0!==e.x&&(H=e.x>0?S:D,O=0),0!==e.y&&(J=e.y>0?R:U,G=0);d(),s(L)}else Z=!1}}var b=t.source,M=void 0===b?document:b,g=t.update,T=t.multiplier,B=void 0===T?1:T,q=t.friction,X=void 0===q?.92:q,Y=t.initialValues,A=t.boundX,F=t.boundY,I=t.bounce,P=void 0===I||I;n(this,e);var S,D,R,U,V,j,k,z,C,O,G,H=0,J=0,K=.3*B,N=!1,Q=!1,W=!1,Z=!1,$=[];!function(){if(!(M="string"==typeof M?document.querySelector(M):M))throw new Error("IMPETUS: source not found.");if(!g)throw new Error("IMPETUS: update function not defined.");Y&&(Y[0]&&(H=Y[0]),Y[1]&&(J=Y[1]),d()),A&&(S=A[0],D=A[1]),F&&(R=F[0],U=F[1]),M.addEventListener("touchstart",f),M.addEventListener("mousedown",f)}(),this.destroy=function(){return M.removeEventListener("touchstart",f),M.removeEventListener("mousedown",f),r(),null},this.pause=function(){r(),Q=!1,W=!0},this.resume=function(){W=!1},this.setValues=function(e,t){"number"==typeof e&&(H=e),"number"==typeof t&&(J=t)},this.setMultiplier=function(e){B=e,K=.3*B},this.setBoundX=function(e){S=e[0],D=e[1]},this.setBoundY=function(e){R=e[0],U=e[1]}};t.exports=r;var s=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(e){window.setTimeout(e,1e3/60)}}()}); \ No newline at end of file +!function(e,t){if("function"==typeof define&&define.amd)define(["exports","module"],t);else if("undefined"!=typeof exports&&"undefined"!=typeof module)t(exports,module);else{var n={exports:{}};t(n.exports,n),e.Impetus=n.exports}}(this,function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(){var e=!1;try{var t=Object.defineProperty({},"passive",{get:function(){e=!0}});window.addEventListener("test",null,t)}catch(e){}return o=function(){return e},e}var i=.04,u=.11;window.addEventListener("touchmove",function(){});var r=function e(t){function r(){document.removeEventListener("touchmove",v,!!o()&&{passive:!1}),document.removeEventListener("touchend",m),document.removeEventListener("touchcancel",l),document.removeEventListener("mousemove",v,!!o()&&{passive:!1}),document.removeEventListener("mouseup",m)}function d(){r(),document.addEventListener("touchmove",v,!!o()&&{passive:!1}),document.addEventListener("touchend",m),document.addEventListener("touchcancel",l),document.addEventListener("mousemove",v,!!o()&&{passive:!1}),document.addEventListener("mouseup",m)}function c(){B.call(M,H,J)}function a(e){if("touchmove"===e.type||"touchstart"===e.type||"touchend"===e.type){var t=e.targetTouches[0]||e.changedTouches[0];return{x:t.clientX,y:t.clientY,id:t.identifier}}return{x:e.clientX,y:e.clientY,id:null}}function f(e){if(!e.handledByImpetus){e.handledByImpetus=!0;var t=a(e);Q||W||(Q=!0,Z=!1,C=t.id,V=k=t.x,j=z=t.y,$=[],h(V,j),d())}}function v(e){e.preventDefault();var t=a(e);Q&&t.id===C&&(k=t.x,z=t.y,h(V,j),x())}function m(e){var t=a(e);Q&&t.id===C&&l()}function l(){Q=!1,h(V,j),E(),r()}function h(e,t){for(var n=Date.now();$.length>0&&!(n-$[0].time<=100);)$.shift();$.push({x:e,y:t,time:n})}function p(){var e=k-V,t=z-j;if(H+=e*T,J+=t*T,P){var n=w();0!==n.x&&(H-=e*y(n.x)*T),0!==n.y&&(J-=t*y(n.y)*T)}else w(!0);c(),V=k,j=z,N=!1}function y(e){return 5e-6*Math.pow(e,2)+1e-4*e+.55}function x(){N||s(p),N=!0}function w(e){var t=0,n=0;return void 0!==S&&HD&&(t=D-H),void 0!==R&&JU&&(n=U-J),e&&(0!==t&&(H=t>0?S:D),0!==n&&(J=n>0?R:U)),{x:t,y:n,inBounds:0===t&&0===n}}function E(){var e=$[0],t=$[$.length-1],n=t.x-e.x,o=t.y-e.y,i=t.time-e.time,u=i/15/T;O=n/u||0,G=o/u||0;var r=w();(Math.abs(O)>1||Math.abs(G)>1||!r.inBounds)&&(Z=!0,s(L))}function L(){if(Z){O*=q,G*=q,H+=O,J+=G;var e=w();if(Math.abs(O)>K||Math.abs(G)>K||!e.inBounds){if(P){if(0!==e.x)if(e.x*O<=0)O+=e.x*i;else{var t=e.x>0?2.5:-2.5;O=(e.x+t)*u}if(0!==e.y)if(e.y*G<=0)G+=e.y*i;else{var t=e.y>0?2.5:-2.5;G=(e.y+t)*u}}else 0!==e.x&&(H=e.x>0?S:D,O=0),0!==e.y&&(J=e.y>0?R:U,G=0);c(),s(L)}else Z=!1}}var b=t.source,M=void 0===b?document:b,B=t.update,g=t.multiplier,T=void 0===g?1:g,I=t.friction,q=void 0===I?.92:I,X=t.initialValues,Y=t.boundX,A=t.boundY,F=t.bounce,P=void 0===F||F;n(this,e);var S,D,R,U,V,j,k,z,C,O,G,H=0,J=0,K=.3*T,N=!1,Q=!1,W=!1,Z=!1,$=[];!function(){if(!(M="string"==typeof M?document.querySelector(M):M))throw new Error("IMPETUS: source not found.");if(!B)throw new Error("IMPETUS: update function not defined.");X&&(X[0]&&(H=X[0]),X[1]&&(J=X[1]),c()),Y&&(S=Y[0],D=Y[1]),A&&(R=A[0],U=A[1]),M.addEventListener("touchstart",f),M.addEventListener("mousedown",f)}(),this.destroy=function(){return M.removeEventListener("touchstart",f),M.removeEventListener("mousedown",f),r(),null},this.pause=function(){r(),Q=!1,W=!0},this.resume=function(){W=!1},this.setValues=function(e,t){"number"==typeof e&&(H=e),"number"==typeof t&&(J=t)},this.setMultiplier=function(e){T=e,K=.3*T},this.setBoundX=function(e){S=e[0],D=e[1]},this.setBoundY=function(e){R=e[0],U=e[1]}};t.exports=r;var s=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(e){window.setTimeout(e,1e3/60)}}()}); \ No newline at end of file diff --git a/src/Impetus.js b/src/Impetus.js index 99d4148..bb26bbb 100644 --- a/src/Impetus.js +++ b/src/Impetus.js @@ -210,7 +210,18 @@ export default class Impetus { * @param {Object} ev Normalized event */ function onDown(ev) { - ev.stopPropagation(); + // This allows embedding impetus-enabled elements into other impetus-enabled elements (such as a scrollable div + // within another) by making any ancestor impetus ignore the down event. Normally we would use stopPropagation to + // prevent the event from bubbling up to the ancestor impetus (which does work as expected in raw HTML). However, + // this approach does not work in React because React implements its own event system, which causes all sorts of + // issues with non-React stopPropagation as native DOM events propagate before react events are triggered and + // propagate. Instead, we simply tag the event as handled. Ancestor impetus instances then ignore the event if + // it's been marked as handled. + // https://dlinau.wordpress.com/2015/09/16/avoid-mixing-reacts-event-system-with-native-dom-event-handling/ + // https://github.com/facebook/react/issues/8693 + if (ev.handledByImpetus) return; + ev.handledByImpetus = true; + var event = normalizeEvent(ev); if (!pointerActive && !paused) { pointerActive = true; @@ -231,7 +242,6 @@ export default class Impetus { * @param {Object} ev Normalized event */ function onMove(ev) { - ev.stopPropagation(); ev.preventDefault(); var event = normalizeEvent(ev); @@ -248,7 +258,6 @@ export default class Impetus { * @param {Object} ev Normalized event */ function onUp(ev) { - ev.stopPropagation(); var event = normalizeEvent(ev); if (pointerActive && event.id === pointerId) {