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方法做了什么。才能清楚每一步的作用)

  • 相关阅读:
    JS LeetCode 1423. 可获得的最大点数简单题解
    SpringBoot 学集 (第六章) Docker
    Linux 学记 (第三章)
    Linux 学记 (第二章)
    Linux 学记 (第一章)
    SpringBoot 学集 (第五章) Web开发续
    SpringBoot 学集 (第四章)Web开发
    SpringBoot 学集 (第三章) 日志框架
    SpringBoot 学集 (第二章) 配置文件
    SpringBoot 学集 (第一章)
  • 原文地址:https://www.cnblogs.com/charling/p/3472260.html
Copyright © 2011-2022 走看看