fastclick是否适用于ReactJS的事件系统?在通过Cordova进入iOS或Android时似乎没有采取任何措施.如果没有,是否有另一种获得相同结果的方法.我的应用程序没有双击功能,所以如果可能的话,我想全面消除这种延迟......
我在一个Webpack项目中使FastClick与React一起工作.有些事情看起来很挑剔,但它主要起作用.(更新:只有一个模拟隐藏复选框点击的切换开关很挑剔 - 无论React如何都会出现问题).这是我打开它的方式:
npm install -S fastclick
在main.jsx
:
import FastClick from 'fastclick'; window.addEventListener('load', () => { FastClick.attach(document.body); });
所以即使你没有使用Webpack或Browserify,我猜你只要你可以运行load事件监听器,你就没事了.
编辑
Facebook决定不添加对定义自定义事件类型的支持,并建议你使用像react-tappable这样的东西,这样你就可以写出像<Tappable onTap={}>
.
Facebook正在以一种形式开发解决方案TapEventPlugin
,但在做出 决定之前不会提供.
如果您正在阅读本文,那么您可能正在开展一个项目,该项目不能等到他们想知道如何发布它.
这个回购是给你的:https://github.com/zilverline/react-tap-event-plugin
当Facebook解决#436和#1170时,这个回购将会消失.
此解决方案适用于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
再使用).
我们最近创建了一个类似于fastclick的React组件,除了它更简单并且需要手动回调.它很短,所以我会在这里发布:
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
prop作为回调并将您的内容包装在里面.这也适用于同时具有触摸和点击事件的系统(如较新的Windows 8笔记本电脑).例:
<TouchClick handler={this.clickHandler} className='app'>
<h1>Hello world</h1>
</TouchClick>