react touch事件

前一篇文章提到前端框架React.js在IOS手机上onClick属性失效
其实理论上触屏设备都应该出问题,可能是由于android还是支持click,但click并不好,有300ms的延时,最好还是用touch方法

知乎上有两种办法

  • 在组件中的componentDidMount方法中,为该div绑定事件,在回调函数中写入想要实现的逻辑。选取dom的方法,可以用原生js或jquery,也可以用react中的ref实现。

  • 为“按钮”这个div 的样式 加入cursor:pointer这一条属性,在ios设备上就正常了。(这个我试过,可行)

这两种方法都不完美,前者写的不够优雅,好的react项目中是基本不对dom进行操作的;后者虽然只加了一行代码,但对日后维护增加了不确定性,特别是对于移动端的页面,cursor属性在不明真相的人看起来会觉得你写的莫名其妙,很可能误删,造成不必要的麻烦。

最好的办法–touch

React event列表

触摸事件

为了使触摸事件生效,在渲染所有组件之前调用

React.initializeTouchEvents(true)。

事件名:

onTouchCancel onTouchEnd onTouchMove onTouchStart

属性:

boolean altKey
DOMTouchList changedTouches
boolean ctrlKey
function getModifierState(key)
boolean metaKey
boolean shiftKey
DOMTouchList targetTouches
DOMTouchList touches

一个参考代码

var IndexPage = (function(A){
    var Person = React.createClass({
        handleClick: function () {
            window.location.href = "#" + this.props.id ;
        },
        render: function () {
            var link = "tel:" + this.props.tel;
            return (
                <A.ListItem className="Person" onClick={this.handleClick} onTouchStart={this.handleClick}>
                    <A.Icon icon="user" className="person-icon" />
                    {this.props.name}
                    <A.Badge amStyle="success" radius className="person-phone">
                        <a href={link}>
                            <A.Icon icon="phone" />
                        </a>
                    </A.Badge>
                </A.ListItem>
            );
        }
    });

    return React.createClass({
        initializeTouchEvents: function () {
            return (true);
        },
        getInitialState: function () {
            return {
                persons: []
            };
        },
        componentDidMount: function () {
            $.getJSON('/js/data.json').then(function (data) {
                if(this.isMounted()){
                    this.setState({
                        persons:data
                    });
                }
            }.bind(this));
        },
        render: function () {
            var items = this.state.persons.map(function (t) {
                return <Person {...t} />;
            });
            return (
                <div>
                    <A.Header title="通讯录3"/>
                    <A.List className="person-list">
                        {items}
                    </A.List>
                </div>
            );
        }
    });
})(AMUIReact);