cordova reactjs fastclick.js

¿Puedo hacer Fastclick ReactJS en Cordova?



fastclick.js (6)

¿ fastclick funciona con el sistema de eventos de ReactJS? No parece estar tomando cuando se ejecuta a través de Córdova en iOS o Android. Si no, ¿hay otra forma de obtener los mismos resultados? Mi aplicación no tiene funcionalidad de doble toque, así que me gustaría eliminar esa demora en todos los ámbitos, si es posible ...


Conseguí FastClick para trabajar con React, en un proyecto de Webpack. Algunas cosas parecen melindrosas, pero sobre todo funciona. ( Actualización : solo un conmutador que simulaba clics en una casilla oculta era meticuloso, eso sería un problema independientemente de Reaccionar). Así es como lo encendí:

npm install -S fastclick

En main.jsx :

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

Así que incluso si no estás usando Webpack o Browserify, supongo que siempre que puedas ejecutar el detector de eventos de carga, estarás bien.


Parecía estar funcionando bien en mi aplicación Cordova, pero hay un problema importante que me topé.

Cuando se hace clic en un elemento usando React + FastClick, y la vista renderizada siguiente contiene un elemento seleccionable en la misma posición, un evento onTouchEnd también se registra en el segundo elemento.

Me deshice de FastClick porque no quiero alinear mis botones para evitar comportamientos no deseados, pero necesito algo para reemplazarlo, ya que el retraso en los clics es bastante malo.


Recientemente creamos un componente React que es similar al FastClick, excepto que es mucho más simple y requiere una devolución de llamada manual. Es bastante corto, así que lo publicaré aquí:

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) } })

Simplemente pase handler prop como devolución de llamada y envuelva su contenido en su interior. Esto también funciona para los sistemas que tienen eventos de tocar y hacer clic (como las computadoras portátiles más nuevas de Windows 8). Ejemplo:

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


También puede usar react-fastclick ( https://github.com/JakeSidSmith/react-fastclick ) desde npm:

npm i react-fastclick --save

¡Al usarlo no tienes que cambiar tu código y funciona muy bien! Solo debes solicitarlo una vez.

require(''react-fastclick'');


Tuve problemas con el método de David, así que como alternativa a FastClick, implementé un mixin usando HammerJs para el evento. Un poco más de código para configurar el evento, pero funciona bien.

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(); } } });

Esto se puede usar de la siguiente manera:

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"/> ); } });


Editar

Facebook decidió no agregar soporte para definir tipos de eventos personalizados y recomendarle que use algo como react-tappable para que pueda escribir algo como <Tappable onTap={}> .

Facebook está trabajando en una solución en forma de TapEventPlugin , pero no estará disponible hasta que tomen algunas decisiones .

Si estás leyendo esto, probablemente estés trabajando en un proyecto que no puede esperar hasta que descubran cómo quieren publicarlo.

Este informe es para ti: https://github.com/zilverline/react-tap-event-plugin

Cuando Facebook resuelva # 436 y #1170 , este repositorio desaparecerá.

Esta solución funciona para React 0.14.x y 15.x.

npm i -S react-tap-event-plugin

Ejemplo de uso:

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"));

Tenga en cuenta que con el inyector, es probable que necesite usar solo en onTouchTap (y no en onClick más).