我可以Fastclick在cordova运行的ReactJS

快速使用ReactJS的事件系统吗? 当通过cordova运行到iOS或Android时似乎并没有采取。 如果没有,是否有另一种获得相同结果的方法。 我的应用程序没有双击function,所以如果可能的话,我想要删除整个板上的延迟…

编辑

Facebook决定不添加对定义自定义事件types的支持,并build议您使用react-tappable之类的东西,这样您可以编写像<Tappable onTap={}>


Facebook正在以TapEventPlugin的forms开发一个解决scheme,但在做出一些决定之前 , 它将不可用 。

如果你正在阅读这篇文章,你可能正在研究一个不能等到他们想要发布它的项目。

这个回购是给你的: https : //github.com/zilverline/react-tap-event-plugin

当Facebook解决#436和#1170时 ,这个回购将消失。

此解决scheme适用于React 0.14.x和15.x.

 npm i -S react-tap-event-plugin 

使用示例:

 var React = require("react"); var ReactDOM = require("react-dom"); injectTapEventPlugin = require("react-tap-event-plugin"); injectTapEventPlugin(); var Main = React.createClass({ render: function() { return ( <a href="#" onTouchTap={this.handleTouchTap} onClick={this.handleClick}> Tap Me </a> ); }, handleClick: function(e) { console.log("click", e); }, handleTouchTap: function(e) { console.log("touchTap", e); } }); ReactDOM.render(<Main />, document.getElementById("container")); 

请注意,使用注入器,您可能只需要使用onTouchTap (而不是onClick )。

在一个Webpack项目中,我使FastClick与React一起工作。 一些事情看起来很挑剔,但主要是有效的。 ( 更新 :只有一个切换开关,模拟点击隐藏的checkbox是挑剔 – 这将是一个问题,无论反应)。 以下是我如何打开它:

npm install -S fastclick

main.jsx

 import FastClick from 'fastclick'; window.addEventListener('load', () => { FastClick.attach(document.body); }); 

所以,即使你不使用Webpack或者Browserify,只要你可以运行load事件监听器,你就会好的。

我们最近创build了一个类似于fastclick的React组件,只是它更简单,需要手动callback。 这很短,所以我会在这里发布:

 React.initializeTouchEvents(true) var TouchClick = React.createClass({ defaults: { touched: false, touchdown: false, coords: { x:0, y:0 }, evObj: {} }, getInitialState: function() { return this.defaults }, handler: function() { typeof this.props.handler == 'function' && this.props.handler.apply(this, arguments) }, getCoords: function(e) { if ( e.touches && e.touches.length ) { var touch = e.touches[0] return { x: touch.pageX, y: touch.pageY } } }, onTouchStart: function(e) { this.setState({ touched: true, touchdown: true, coords: this.getCoords(e), evObj: e }) }, onTouchMove: function(e) { var coords = this.getCoords(e) var distance = Math.max( Math.abs(this.state.coords.x - coords.x), Math.abs(this.state.coords.y - coords.y) ) if ( distance > 6 ) this.setState({ touchdown: false }) }, onTouchEnd: function() { if(this.state.touchdown) this.handler.call(this, this.state.evObj) setTimeout(function() { if ( this.isMounted() ) this.setState(this.defaults) }.bind(this), 4) }, onClick: function() { if ( this.state.touched ) return false this.setState(this.defaults) this.handler.apply(this, arguments) }, render: function() { var classNames = ['touchclick'] this.props.className && classNames.push(this.props.className) this.state.touchdown && classNames.push('touchdown') return React.DOM[this.props.nodeName || 'button']({ className: classNames.join(' '), onTouchStart: this.onTouchStart, onTouchMove: this.onTouchMove, onTouchEnd: this.onTouchEnd, onClick: this.onClick }, this.props.children) } }) 

只要传递handler道具作为callback,并包装你的内容。 这也适用于既有触摸又有点击事件的系统(如较新的Windows 8笔记本电脑)。 例:

  <TouchClick handler={this.clickHandler} className='app'> <h1>Hello world</h1> </TouchClick> 

我有使用David的方法的问题,所以作为FastClick的替代品,我使用HammerJs为事件实现了一个mixin。 多一点的代码来设置事件,但工作正常。

 var HammerClickMixin = React.createClass({ componentWillMount: function() { this.listeneres = []; }, addTapEvent: function(element,callback) { var mc = new Hammer.Manager(element); mc.add(new Hammer.Tap({ event: 'doubletap', taps: 2 })); mc.add(new Hammer.Tap({ event: 'tap', taps: 1 })); mc.on('tap',callback); this.listeneres.push(mc); }, addDoubleTap : function(element,callback){ var mc = new Hammer.Manager(element); mc.add(new Hammer.Tap({ event: 'doubletap', taps: 2 })); mc.on('doubletap',callback); this.listeneres.push(mc); }, componentWillUnmount: function() { for(var i= 0; i < this.listeneres.length; i++){ this.listeneres[i].destroy(); } } }); 

这可以按照以下方式使用:

  var Component = React.createClass({ mixins: [HammerClickMixin], componentDidMount: function () { this.addTapEvent(this.refs.elementToClick.getDOMNode(),function(){ //Handle fast hammer tap! }); }, render: function () { return ( <div ref="elementToClick"/> ); } }); 

在我的cordova应用程序似乎工作正常,但有一个重大问题,我遇到了。

当使用React + FastClick单击一个元素,并且下一个呈现的视图在同一位置包含一个可点击的元素时,onTouchEnd事件也被注册在第二个元素中。

我放弃了FastClick,因为我不想alignmentbutton,以避免不必要的行为,但我需要一些东西来替代它,因为点击延迟感觉很糟糕。

您也可以使用npm中的react-fastclickhttps://github.com/JakeSidSmith/react-fastclick

 npm i react-fastclick --save 

使用它,你不必改变你的任何代码,它真的很好! 你只需要一次。

 require('react-fastclick');