事件系统

小程序有两种绑定事件的方式。

  • bindtap 绑定一个会冒泡的 tap 事件
  • catchtap 绑定一个不会冒泡的 tap 事件
  1. <view bindtap="eventName" />

nanachi 为了大家方便,还是换回大家熟悉的风格,但不能冒泡的限制还没有搞定,因此也是两种绑定风格。

  • onClick 绑定一个会冒泡的 click 事件, 小程序上会自动转换成tap 事件
  • catchClick 绑定一个不会冒泡的 click 事件, 小程序上会自动转换成tap 事件
  1. <div onClick={this.clickHandle.bind(this, 111)} />

我们的转译器会扫描所有on/catch开头的属性, 进行事件绑定,因此如果你直接用bindTap、bindChange的方式来编写,会导致错误。

  1. //转译器中的相关源码
  2. if (/^(?:on|catch)[A-Z]/.test(attrName) &&!/[A-Z]/.test(nodeName) ) {
  3. //内置标签的nodeName都是小写的,如果它的某个属性以on/catch开头,我们会认为它可能是事件
  4. var prefix = attrName.charAt(0) == 'o' ? 'on' : 'catch';
  5. var eventName = attrName.replace(prefix, '');
  6. var otherEventName = utils.getEventName(
  7. eventName,
  8. nodeName,
  9. buildType
  10. //....
  11. }

事件对象

由于小程序存在千差万别的差别,它的事件对象没有像PC有那么多属性与方法,最大的区别是没有stopPropagationpreventDefault

但娜娜奇会帮你抹平了 PC 与小程序的差异, 为它添加上伪装的 stopPropagationpreventDefault() 方法。

注意 stopPropagation() 是没有效果的,你想并且冒泡还需要用 catchClick 的方式来绑定事件。

如果 你想它转译成H5,那么catchXXX的回调内部需要大家执行 e.stopPropagation()

小程序事件对象的属性如下:

  1. {
  2. target,//里面有dataset
  3. pageX,
  4. pageY,
  5. value, //不一定有,但input, change事件有
  6. timeStamp,
  7. type,
  8. stopPropagation,
  9. preventDefault,
  10. //还可能有其他属性,不同的事件类型会产生额外的属性
  11. }

在一些小程序平台中,事件对象有detail这个对象,但建议不要使用它,因为当你想跨平台到webview/H5/快应用时,是没有这个对象的。并且我们也会将这个detail的属性下放到event上。

  1. //创建事件对象
  2. function createEvent(e, target) {
  3. let event = Object.assign({}, e);
  4. if (e.detail) {
  5. Object.assign(event, e.detail);
  6. }
  7. //需要重写的属性或方法
  8. event.stopPropagation = function () {
  9. // eslint-disable-next-line
  10. console.warn("小程序不支持这方法,请使用catchXXX");
  11. };
  12. event.nativeEvent = e;
  13. event.preventDefault = returnFalse;
  14. event.target = target;
  15. event.timeStamp = Date.now();
  16. let touch = e.touches && e.touches[0];
  17. if (touch) {
  18. event.pageX = touch.pageX;
  19. event.pageY = touch.pageY;
  20. }
  21. return event;
  22. }

比如说微信小程序的onGetUserInfo方法

  1. onGetUserInfo: function(e){
  2. console.log(e.userInfo)
  3. }

事件回调

事件回调本身必须定义在类的原型里,不能在视图中使用 this.props.onClick ,只能this.onClick

注意事项

定义了事件的标签,可能会自动添加data-beacon-uid, data-instance-uid这些属性,注意不要与它们冲突

2018.11.14起 定义了事件的标签, 只会添加上data-beacon-uid属性,后面三者不再添加,从而减少视图的体积input标签 统一使用onChange事件,不要用onInputdiv标签 统一使用onClick事件,不要用onTap