fastclick是否适用于ReactJS的事件系统?当通过Cordova运行到iOS或Android时,似乎没有采取任何措施。如果没有,是否有另一种获得相同结果的方法。我的应用没有双击功能,所以如果可能的话,我想全面消除这种延迟...
答案 0 :(得分:28)
修改强>
Facebook决定not add support for defining custom event types并建议您使用类似react-tappable 的内容,以便您可以撰写<Tappable onTap={}>
之类的内容。
Facebook以 TapEventPlugin
的形式开发解决方案,但won't be made available until they make some decisions。
如果您正在阅读本文,那么您可能正在开展一个项目,该项目不能等到他们想知道如何发布它。
这个回购是给你的: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
)。
答案 1 :(得分:17)
我在一个Webpack项目中使用FastClick与React一起工作。有些事情看起来很挑剔,但它主要起作用。 (更新:只有模拟隐藏复选框点击的切换开关很挑剔 - 无论React如何都会出现问题)。这是我打开它的方式:
npm install -S fastclick
在main.jsx
:
import FastClick from 'fastclick';
window.addEventListener('load', () => {
FastClick.attach(document.body);
});
所以,即使你没有使用Webpack或Browserify,我猜也只要你能运行加载事件监听器,你就可以了。
答案 2 :(得分:5)
我们最近创建了一个类似于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
道具作为回调传递并将内容包装在内。这也适用于同时具有触摸和点击事件的系统(如较新的Windows 8笔记本电脑)。例如:
<TouchClick handler={this.clickHandler} className='app'>
<h1>Hello world</h1>
</TouchClick>
答案 3 :(得分:3)
我在使用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"/>
);
}
});
答案 4 :(得分:2)
我的Cordova应用程序似乎工作正常,但我遇到了一个重大问题。
使用React + FastClick单击元素,并且下一个渲染视图包含位于相同位置的可单击元素时,onTouchEnd事件也会在第二个元素中注册。
我放弃了FastClick,因为我不想对齐我的按钮以避免不必要的行为,但我需要更换它,因为点击延迟感觉非常糟糕。
答案 5 :(得分:2)
您也可以使用npm:{/ p>中的react-fastclick
(https://github.com/JakeSidSmith/react-fastclick)
npm i react-fastclick --save
使用它,您不必更改任何代码,它的工作非常好!你只需要一次。
require('react-fastclick');