Rumah > hujung hadapan web > tutorial js > jQuery-1.9.1 Siri Analisis Kod Sumber (10) Pembungkusan Acara Sistem Peristiwa_jquery

jQuery-1.9.1 Siri Analisis Kod Sumber (10) Pembungkusan Acara Sistem Peristiwa_jquery

WBOY
Lepaskan: 2016-05-16 15:30:50
asal
1227 orang telah melayarinya

Dalam artikel sebelumnya, saya memperkenalkan anda kepada jQuery-1.9.1 siri analisis kod sumber (10) seni bina acara sistem acara Artikel ini terus memperkenalkan kepada anda pengetahuan yang berkaitan tentang jquery1. 9.1 siri analisis kod sumber Sila lihat di bawah untuk butiran.

Pertama sekali, anda perlu memahami bahawa peristiwa asli penyemak imbas adalah baca sahaja, yang mengehadkan operasi jQuery padanya. Contoh mudah akan membantu anda memahami mengapa jQuery mesti membina objek acara baharu.

Dalam pemprosesan perwakilan, nod a mewakilkan nod b untuk melaksanakan fungsi fn apabila a diklik. Apabila acara buih ke nod b, persekitaran konteks perlu betul semasa melaksanakan fn Nod a yang melaksanakan fn, bukan nod b. Bagaimana untuk memastikan bahawa konteks pelaksanaan fn ialah nod a: lihat pada kod sumber (bahagian merah)

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

Salin selepas log masuk

Gunakan guna untuk menggantikan konteks fungsi pelaksanaan dengan nod (matched.elem). Perkara lain ialah args[0] ialah acara objek acara. Bagaimana untuk memastikan bahawa peristiwa itu adalah peristiwa nod a? Ini ialah fungsi peristiwa atribut penting.currentTarget, jadi satu langkah dilakukan sebelum melaksanakan apply

event.currentTarget = matched.elem;
Salin selepas log masuk

Tukar secara langsung sifat Sasaran semasa objek acara, yang tidak boleh dilakukan dalam acara setempat penyemak imbas. Itulah sebabnya kami mempunyai objek acara jQuery yang dibina berdasarkan acara tempatan.

Terdapat dua jenis acara: acara tetikus dan acara papan kekunci (saya tidak tahu bila acara sentuh boleh ditambah). Lihat sifat terperinci kedua-dua

ini

 

Sebahagian daripadanya adalah khusus pelayar dan bukan piawaian W3C. jQuery membahagikan sifat acara kepada tiga bahagian

Sifat yang dikongsi oleh acara tetikus dan papan kekunci jQuery.event.props: "altKey buih boleh dibatalkan ctrlKey currentTarget eventFasa metaKey relatedTarget shiftKey sasaran timeStamp view which".split(" ")

Sifat khusus acara papan kekunci jQuery.event.keyHooks.props: "char charCode key keyCode".split(" ")

Sifat khusus acara tetikus jQuery.event.mouseHooks.props: "butang butang clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" ")

a. Bina objek acara baharu jQuery.event.fix(originalEvent)

Membina objek acara baharu selesai dalam tiga langkah

Dalam langkah pertama, gunakan event = new jQuery.Event(originalEvent) untuk membina objek acara baharu (jika anda tidak memahami peranan baharu, sila klik di sini), dan tambah isDefaultPrevented, originalEvent, taip dan timeStamp semasa mencipta acara Dan tanda acara telah diperbetulkan (penggunaan dioptimumkan untuk mengelakkan pemprosesan yang tidak perlu). Kod sumber jQuery.Event(src, props) adalah seperti berikut

jQuery.Event = function( src, props ) {
  // Allow instantiation without the 'new' keyword
  if ( !(this instanceof jQuery.Event) ) {
    return new jQuery.Event( src, props );
  }
  //src为事件对象
  if ( src && src.type ) {
    this.originalEvent = src;
    this.type = src.type;
    //事件冒泡的文档可能被标记为阻止默认事件发生;这个函数可以反应是否阻止的标志的正确值
    this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
      src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
  //src为事件类型
  } else {
    this.type = src;
  }
  //将明确提供的特征添加到事件对象上
  if ( props ) {
    jQuery.extend( this, props );
  }
  //创建一个时间戳如果传入的事件不只一个
  this.timeStamp = src && src.timeStamp || jQuery.now();
  //标记事件已经修正过
  this[ jQuery.expando ] = true;
};
Salin selepas log masuk

Objek acara yang dibina dalam langkah pertama

 

Langkah kedua ialah mengenal pasti jenis acara acara semasa, dan kemudian salin atribut yang sepadan satu demi satu daripada acara asal acara tempatan penyemak imbas

 //创建可写的事件对象副本,并格式化一些特征名称
  var i, prop, copy,
    type = event.type,
    originalEvent = event,
    fixHook = this.fixHooks[ type ];
  if ( !fixHook ) {
    this.fixHooks[ type ] = fixHook =
    //rmouseEvent=/^(?:mouse|contextmenu)|click/
    rmouseEvent.test( type ) ? this.mouseHooks :
    //rkeyEvent=/^key/
    rkeyEvent.test( type ) ? this.keyHooks :
    {};
  }
  //获得要从原生事件中拷贝过来的属性列表
  copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
  ...
  //将原生的属性都拷贝到新的事件上
  i = copy.length;
  while ( i-- ) {
    prop = copy[ i ];
    event[ prop ] = originalEvent[ prop ];
  }
Salin selepas log masuk

Langkah ketiga ialah pemprosesan keserasian atribut berkaitan

 // IE<9修正target特征值
  if ( !event.target ) {
    event.target = originalEvent.srcElement || document;
  }
  // Chrome 23+, Safari&#63;,Target特征值不能是文本节点
  if ( event.target.nodeType === 3 ) {
    event.target = event.target.parentNode;
  }
  // IE<9,对于鼠标/键盘事件, 如果metaKey没有定义则设置metaKey==false
  event.metaKey = !!event.metaKey;
  //调用hooks的filter
  return fixHook.filter &#63; fixHook.filter( event, originalEvent ) : event;
Salin selepas log masuk

Barisan terakhir kod melakukan pemprosesan penyesuaian yang serasi untuk acara tetikus dan acara papan kekunci.

fixHook.filter mungkin jQuery.event.keyHooks.filter

keyHooks.filter: function( event, original ) {
  //给键盘事件添加which特征值
  if ( event.which == null ) {
    event.which = original.charCode != null &#63; original.charCode : original.keyCode;
  }
  return event;
}
Salin selepas log masuk

atau jQuery.event.mouseHooks.filter ini

mouseHooks.filter: function( event, original ) {
  var body, eventDoc, doc,
  button = original.button,
  fromElement = original.fromElement;
  //如果事件pageX/Y特征不见了,用可用的clientX/Y来计算出来
  if ( event.pageX == null && original.clientX != null ) {
    eventDoc = event.target.ownerDocument || document;
    doc = eventDoc.documentElement;
    body = eventDoc.body;
    event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
    event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
  }
  //如果必要的话添加relatedTarget特征
  if ( !event.relatedTarget && fromElement ) {
    event.relatedTarget = fromElement === event.target &#63; original.toElement : fromElement;
  }
  //添加点击事件which特征值: 1 === left; 2 === middle; 3 === right
  //备注:button不标准,因此不要是使用
  if ( !event.which && button !== undefined ) {
    event.which = ( button & 1 &#63; 1 : ( button & 2 &#63; 3 : ( button & 4 &#63; 2 : 0 ) ) );
  }
  return event;
}
Salin selepas log masuk

Objek acara terkini yang dilengkapkan adalah seperti berikut (mengambil acara tetikus sebagai contoh)

 

Acara asal disimpan dalam OriginalEvent, sasaran menyimpan nod sasaran (nod yang diwakilkan, sumber acara) dan maklumat lain dilangkau

b. Kaedah acara lebihan

Apabila membina acara objek acara baru = new jQuery.Event(originalEvent), acara akan mewarisi kaedah dalam jQuery.event.prototype. Mari kita lihat kaedahnya

 

Kami sebelum ini menganalisis peranan kaedah stopPropagation terlampau beban dalam jQuery.event.prototype: selain memanggil kaedah objek acara untuk mengelakkan menggelegak, terdapat juga peranan apabila nod yang diwakilkan mempunyai berbilang acara yang diwakilkan menunggu untuk diproses. , salah satu acara yang memanggil event.stopPropagation() akan menghalang pelaksanaan pemprosesan acara berikutnya. Klik di sini untuk mencari kata kunci untuk melihat

Fungsi preventDefault juga mempunyai kesan yang sama. Kod ini telah ditambahkan pada fungsi preventDefault

this.isPropagationStopped = returnTrue;
Salin selepas log masuk

在触发事件trigger函数和模拟冒泡simulate函数中都会根据isPropagationStopped()判断是否要执行DOM节点的默认操作。源码如下

isImmediatePropagationStopped是stopPropagation特殊用法,isImmediatePropagationStopped会直接阻止掉当前的处理和后面等待执行的事件处理,而stopPropagation会执行完当前的处理,然后阻止后面等待执行的事件处理。

源码如下

// jQuery.Event基于DOM事件所指定的ECMAScript语言绑定
// http://www.w.org/TR//WD-DOM-Level--Events-/ecma-script-binding.html
jQuery.Event.prototype = {
  isDefaultPrevented: returnFalse,
  isPropagationStopped: returnFalse,
  isImmediatePropagationStopped: returnFalse,
  preventDefault: function() {
    var e = this.originalEvent;
    this.isDefaultPrevented = returnTrue;
    if ( !e ) {return; }
    if ( e.preventDefault ) {
      e.preventDefault();
    //IE支持
    } else {
      e.returnValue = false;
    }
  },
  stopPropagation: function() {
    var e = this.originalEvent;
    this.isPropagationStopped = returnTrue;
    if ( !e ) {return; }
    if ( e.stopPropagation ) {
      e.stopPropagation();
    }
    // IE支持
    e.cancelBubble = true;
  },
  stopImmediatePropagation: function() {
    this.isImmediatePropagationStopped = returnTrue;
    this.stopPropagation();
  }
}
Salin selepas log masuk

以上就是本文给大家介绍的jQuery-1.9.1源码分析系列(十)事件系统之事件包装,希望大家喜欢。

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan