我可以在 Cordova 中运行 Fastclick ReactJS

IT技术 cordova reactjs fastclick.js
2021-04-10 00:34:30

fastclick是否与 ReactJS 的事件系统配合使用?当通过 Cordova 运行到 iOS 或 Android 时,它似乎并不适用。如果没有,是否有另一种方法可以获得相同的结果。我的应用程序没有双击功能,所以如果可能的话,我想全面消除这种延迟......

6个回答

编辑

Facebook 决定不添加对定义自定义事件类型的支持,并建议您使用react-tappable 之的东西,以便您可以编写类似<Tappable onTap={}>.


Facebook 正在以 的形式研究解决方案TapEventPlugin,但在他们做出某些决定之前不会提供

如果您正在阅读本文,那么您可能正在从事一个项目,该项目迫不及待地想知道如何发布它。

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

当 Facebook 解决#436#1170 时,这个 repo 将消失。

此解决方案适用于 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"));

请注意,对于注入器,您可能只需要使用onTouchTaponClick不再需要)。

所以只是为了清楚我现在应该使用 react-tap-event-plugin 还是 React-Tappable ?
2021-06-05 00:34:30
两者都有效,但 react-tappable 似乎是一个更合理的选择。没有猴子补丁。
2021-06-08 00:34:30
此解决方案是否仅适用于移动浏览器?
2021-06-11 00:34:30
仅供参考,onTouchTap 用作点击(对于非触摸屏)。
2021-06-13 00:34:30
谢谢,可能会那样做,因为 react-tap-event-plugin 似乎与 react@15.3.2 崩溃了
2021-06-17 00:34:30

我让 FastClick 在一个 Webpack 项目中与 React 一起工作。一些事情看起来很挑剔,但大部分都有效。更新:只有一个模拟点击隐藏复选框的切换开关是挑剔的——不管react如何,这都是一个问题)。这是我打开它的方法:

npm install -S fastclick

main.jsx

import FastClick from 'fastclick';

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

因此,即使您不使用 Webpack 或 Browserify,我猜只要您可以运行加载事件侦听器,就可以了。

这对我来说很完美。FWIW,在我用 webpack 构建的同构 React 应用程序中,我不得不用 new webpack.NormalModuleReplacementPlugin(/fastclick$/i, 'node-noop')
2021-05-28 00:34:30
您是否正在创建一个带有onClickprop的 React 组件,但没有将它传递给组件,无论render()返回什么,以便它最终在一个真正的 HTML 组件上结束?据我所知,onClickReact 组件上处理程序不会做任何事情,您必须将其传递给 HTML 元素。
2021-06-08 00:34:30
Soo...我刚刚发现不幸的是,这个解决方案在使用 React 的 onClick 处理程序时不能很好地发挥作用。它仅适用于您的通用 html 元素——锚点、按钮等。这是我发现的最好的:github.com/zilverline/react-tap-event-plugin
2021-06-09 00:34:30
你看到了什么行为?我对onClick处理程序没有任何问题
2021-06-13 00:34:30
@Federico 很酷,知道我是否必须使用同构会很好!
2021-06-16 00:34:30

我们最近创建了一个类似于 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)
  }
})

只需将handlerprop 作为回调传递并将您的内容包装在里面。这也适用于具有触摸和点击事件的系统(如较新的 Windows 8 笔记本电脑)。例子:

 <TouchClick handler={this.clickHandler} className='app'>
   <h1>Hello world</h1>
 </TouchClick>
我的意思是,这不是一个 wham-bam-thank-you-maam 类型的解决方案,可以立即摆脱页面上所有内容的烦人点击延迟,是吗?这就是 Fastclick 的重点
2021-06-16 00:34:30

我在使用 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,因为我不想对齐我的按钮以避免不必要的行为,但我需要一些东西来替换它,因为点击延迟感觉很糟糕。

我遇到了类似的问题,一个按钮会被立即点击,但在某些环境(android 浏览器)中会在 300 毫秒后再次点击。react touch 库中使用的点击事件插件添加了一个不错的 onTouchTap 回调,但它不适用于非触摸输入。制作一个 React 事件插件可能是要走的路。我还没有找到答案...
2021-06-06 00:34:30
@PirkkaEsko 所以 FastClick 不是onTouchEnd您所看到问题的原因
2021-06-15 00:34:30
感谢您提供信息,实际上在放弃 FastClick 之后,我仍然遇到类似的“点击注册两次”问题,尽管在应用程序的不同部分与以前不同。也还没找到解决办法...
2021-06-18 00:34:30
我在 fastclick 和 react-tap-event-plugin 中都发现了这种行为。还是没有找到好的解决办法。
2021-06-20 00:34:30
老实说,我已经不记得细节了,但我上面的评论表明 FastClick 不是根本原因,但可能与它们有关,因为行为发生了改变(删除 FastClick 后应用程序的不同部分发生了问题) .
2021-06-21 00:34:30