zoukankan      html  css  js  c++  java
  • jQuery事件处理(五)

    对原生js不熟悉看jQuery会困难很多。后续需要更多的关注下原生js

    jQuery封装之后的事件触发,其中一个分支(处理普通事件)是通过:elem.addEventListener( type, eventHandle, false );来完成的。

    通过这一句,为元素绑定一个事件监听器,并绑定eventHandler事件处理程序。

    该事件监听程序内部调用dispatch方法处理并执行用户真正绑定到该元素上的所有事件处理程序。

    相当于在所有的事件处理程序外围又包括了一个方法。

    接下来看下dispatch内部做了哪些事情:

    // 这里的event参数其实是一个普通的原生event对象,是从elem.addEventListener( type, eventHandle, false );中传给eventHandle之后又传给dispatch的。

    dispatch: function( event ) {

      // 对event进行重新封装,前面已经看过
      event = jQuery.event.fix( event );

      var i, j, ret, matched, handleObj,

        // 存放用户绑定到该元素上的所有事件处理函数
        handlerQueue = [],
        args = core_slice.call( arguments ),

        // 这里的this指的是当前元素,取出当前元素在cache中对应的events,并找到对应的事件类型的事件处理函数
        handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],

        // 到special对象中看看该事件类型是不是特殊事件
        special = jQuery.event.special[ event.type ] || {};

      // 将原event对象替换为新的event对象
      args[0] = event;

      // 将事件的代理目标指定为当前元素
      event.delegateTarget = this;

      // 不知道preDispatch是个啥东东,后面看
      if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
        return;
      }

      // 调用event的handler方法,将返回的事件处理程序组成的数组赋值给handlerQueue

      handlerQueue = jQuery.event.handlers.call( this, event, handlers );

      // 从队列中依次取出每一个事件处理程序(并且该事件没有被阻止)
      i = 0;
      while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
        event.currentTarget = matched.elem;

        j = 0;

        // 需要了解handlers方法做了什么,现在不清楚handleObj是什么
        while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {

        // Triggered event must either 1) have no namespace, or
        // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).

          // 如果该事件没有命名空间或者该事件时命名空间的一个子集,后面的内容多需要看过handlers方法
          if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {

            event.handleObj = handleObj;
            event.data = handleObj.data;

            ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
              .apply( matched.elem, args );

            if ( ret !== undefined ) {
              if ( (event.result = ret) === false ) {
                event.preventDefault();
                event.stopPropagation();
              }
            }
          }
        }
      }

    // Call the postDispatch hook for the mapped type
    if ( special.postDispatch ) {
    special.postDispatch.call( this, event );
    }

    return event.result;
    },

    (想要继续深入了解,需要画一张cache存储的events和handler的表,同时需要了解通过handler方法做了什么。才能清楚每一步的作用)

  • 相关阅读:
    webService客户端搭建(三)
    webService服务器端搭建(二)
    electron 编译 sqlite3避坑指南---尾部链接有已经编译成功的sqlite3
    解决网页中Waiting (TTFB)数据加载过慢的问题
    Node-sqlite3多字段插入数据问题
    win上使用nvm管理node版本
    centos系统设置局域网静态IP
    将win平台上的mysql数据复制到linux上报错Can't write; duplicate key in table
    win上配置nginx
    Nodejs解决所有跨域请求
  • 原文地址:https://www.cnblogs.com/charling/p/3472260.html
Copyright © 2011-2022 走看看