Penjelasan terperinci tentang penulisan acara tersuai dalam pengetahuan JavaScript_Basic

WBOY
Lepaskan: 2016-05-16 09:00:02
asal
2200 orang telah melayarinya

Kami boleh menyesuaikan acara untuk mencapai pembangunan yang lebih fleksibel Acara boleh menjadi alat yang sangat berkuasa apabila digunakan dengan betul Pembangunan berasaskan acara mempunyai banyak kelebihan (diterangkan kemudian).

Fungsi yang berkaitan dengan acara tersuai termasuk Acara, CustomEvent dan dispatchEvent.

Untuk menyesuaikan acara secara langsung, gunakan pembina Acara:

var event = new Event('build');

// Listen for the event.
elem.addEventListener('build', function (e) { ... }, false);

// Dispatch the event.
elem.dispatchEvent(event);

Salin selepas log masuk

CustomEvent boleh mencipta acara yang lebih disesuaikan dan juga boleh melampirkan beberapa data Penggunaan khusus adalah seperti berikut:

var myEvent = new CustomEvent(eventname, options);
Salin selepas log masuk

di mana pilihan boleh:

{
  detail: {
    ...
  },
  bubbles: true,
  cancelable: false
}
Salin selepas log masuk

Butiran boleh menyimpan beberapa maklumat permulaan dan boleh dipanggil apabila dicetuskan. Sifat lain menentukan sama ada acara itu mempunyai fungsi menggelegak dan sebagainya.

Acara terbina dalam akan dicetuskan oleh penyemak imbas berdasarkan operasi tertentu, manakala acara tersuai perlu dicetuskan secara manual. Fungsi dispatchEvent digunakan untuk mencetuskan acara:

element.dispatchEvent(customEvent);
Salin selepas log masuk

Kod di atas menunjukkan bahawa acara customEvent dicetuskan pada elemen. Digunakan bersama:

// add an appropriate event listener
obj.addEventListener("cat", function(e) { process(e.detail) });

// create and dispatch the event
var event = new CustomEvent("cat", {"detail":{"hazcheeseburger":true}});
obj.dispatchEvent(event);

Salin selepas log masuk

Menggunakan acara tersuai memerlukan perhatian kepada isu keserasian, tetapi menggunakan jQuery adalah lebih mudah:

// 绑定自定义事件
$(element).on('myCustomEvent', function(){});

// 触发事件
$(element).trigger('myCustomEvent');
此外,你还可以在触发自定义事件时传递更多参数信息:

$( "p" ).on( "myCustomEvent", function( event, myName ) {
 $( this ).text( myName + ", hi there!" );
});
$( "button" ).click(function () {
 $( "p" ).trigger( "myCustomEvent", [ "John" ] );
});

Salin selepas log masuk

Acara tersuai JavaScript ialah acara tersuai yang berbeza daripada acara standard seperti klik, serahkan, dsb. Sebelum menerangkan faedah acara tersuai, mari lihat contoh acara tersuai:

<div id="testBox"></div>

// 创建事件
var evt = document.createEvent('Event');
// 定义事件类型
evt.initEvent('customEvent', true, true);
// 在元素上监听事件
var obj = document.getElementById('testBox');
obj.addEventListener('customEvent', function(){
  console.log('customEvent 事件触发了');
}, false);

Salin selepas log masuk

Untuk kesan tertentu, anda boleh melihat Demo Enter obj.dispatchEvent(evt) dalam konsol Anda boleh melihat bahawa "acara customEvent dicetuskan" adalah output dalam konsol, menunjukkan bahawa acara tersuai berjaya dicetuskan.

Dalam proses ini, kaedah createEvent mencipta evt acara kosong, dan kemudian menggunakan kaedah initEvent untuk mentakrifkan jenis acara sebagai acara tersuai yang dipersetujui, kemudian memantau elemen yang sepadan dan kemudian menggunakan dispatchEvent untuk mencetuskan acara.

Ya, mekanisme acara tersuai adalah sama seperti acara biasa - dengar acara, tulis operasi panggil balik dan laksanakan panggilan balik selepas acara dicetuskan. Tetapi perbezaannya ialah peristiwa tersuai dikawal sepenuhnya oleh kami apabila ia dicetuskan, yang bermaksud sejenis penyahgandingan JavaScript dicapai. Kami secara fleksibel boleh mengawal berbilang operasi berkaitan tetapi kompleks secara logik menggunakan mekanisme acara tersuai.

Sudah tentu, anda mungkin meneka bahawa kod di atas tidak berkuat kuasa dalam versi IE yang lebih rendah Malah, createEvent() tidak disokong dalam IE8 dan versi IE yang lebih rendah, tetapi terdapat kaedah fireEvent() peribadi IE. . , tetapi malangnya, fireEvent hanya menyokong pencetus peristiwa standard. Oleh itu, kami hanya boleh menggunakan kaedah khas dan mudah untuk mencetuskan acara tersuai.

// type 为自定义事件,如 type = 'customEvent',callback 为开发者实际定义的回调函数
obj[type] = 0;
obj[type]++;
 
obj.attachEvent('onpropertychange', function(event){
  if( event.propertyName == type ){
    callback.call(obj);
  }
});
Salin selepas log masuk

Prinsip kaedah ini sebenarnya adalah untuk menambah atribut tersuai pada DOM dan pada masa yang sama mendengar peristiwa propertychange elemen Apabila nilai sifat DOM berubah, panggilan balik propertychange akan dicetuskan. dan kemudian peristiwa itu akan dinilai dalam panggilan balik sama ada atribut yang diubah ialah atribut tersuai kami, jika ya, panggilan balik sebenarnya ditakrifkan oleh pembangun akan dilaksanakan. Ini meniru mekanisme acara tersuai.

Untuk menjadikan mekanisme acara tersuai bekerjasama dengan pemantauan dan simulasi mencetuskan acara standard, mekanisme acara lengkap diberikan di sini Mekanisme ini menyokong pemantauan, penyingkiran pemantauan dan operasi pencetus simulasi bagi acara standard dan acara tersuai. Perlu diingatkan bahawa untuk menjadikan logik kod lebih jelas, adalah dipersetujui bahawa acara tersuai diawali dengan 'tersuai' (contohnya: customTest, customAlert).

/**
 * @description 包含事件监听、移除和模拟事件触发的事件机制,支持链式调用
 *
 */
 
(function( window, undefined ){
 
var Ev = window.Ev = window.$ = function(element){
 
  return new Ev.fn.init(element);
};
 
// Ev 对象构建
 
Ev.fn = Ev.prototype = {
 
  init: function(element){
 
    this.element = (element && element.nodeType == 1)&#63; element: document;
  },
 
  /**
   * 添加事件监听
   * 
   * @param {String} type 监听的事件类型
   * @param {Function} callback 回调函数
   */
 
  add: function(type, callback){
 
    var _that = this;
     
    if(_that.element.addEventListener){
       
      /**
       * @supported For Modern Browers and IE9+
       */
       
      _that.element.addEventListener(type, callback, false);
       
    } else if(_that.element.attachEvent){
       
      /**
       * @supported For IE5+
       */
 
      // 自定义事件处理
      if( type.indexOf('custom') != -1 ){
 
        if( isNaN( _that.element[type] ) ){
 
          _that.element[type] = 0;
 
        } 
 
        var fnEv = function(event){
 
          event = event &#63; event : window.event
           
          if( event.propertyName == type ){
            callback.call(_that.element);
          }
        };
 
        _that.element.attachEvent('onpropertychange', fnEv);
 
        // 在元素上存储绑定的 propertychange 的回调,方便移除事件绑定
        if( !_that.element['callback' + callback] ){
     
          _that.element['callback' + callback] = fnEv;
 
        }
    
      // 标准事件处理
      } else {
    
        _that.element.attachEvent('on' + type, callback);
      }
       
    } else {
       
      /**
       * @supported For Others
       */
       
      _that.element['on' + type] = callback;
 
    }
 
    return _that;
  },
 
  /**
   * 移除事件监听
   * 
   * @param {String} type 监听的事件类型
   * @param {Function} callback 回调函数
   */
   
  remove: function(type, callback){
 
    var _that = this;
     
    if(_that.element.removeEventListener){
       
      /**
       * @supported For Modern Browers and IE9+
       */
       
      _that.element.removeEventListener(type, callback, false);
       
    } else if(_that.element.detachEvent){
       
      /**
       * @supported For IE5+
       */
       
      // 自定义事件处理
      if( type.indexOf('custom') != -1 ){
 
        // 移除对相应的自定义属性的监听
        _that.element.detachEvent('onpropertychange', _that.element['callback' + callback]);
 
        // 删除储存在 DOM 上的自定义事件的回调
        _that.element['callback' + callback] = null;
      
      // 标准事件的处理
      } else {
      
        _that.element.detachEvent('on' + type, callback);
      
      }
 
    } else {
       
      /**
       * @supported For Others
       */
       
      _that.element['on' + type] = null;
       
    }
 
    return _that;
 
  },
   
  /**
   * 模拟触发事件
   * @param {String} type 模拟触发事件的事件类型
   * @return {Object} 返回当前的 Kjs 对象
   */
   
  trigger: function(type){
 
    var _that = this;
     
    try {
        // 现代浏览器
      if(_that.element.dispatchEvent){
        // 创建事件
        var evt = document.createEvent('Event');
        // 定义事件的类型
        evt.initEvent(type, true, true);
        // 触发事件
        _that.element.dispatchEvent(evt);
      // IE
      } else if(_that.element.fireEvent){
         
        if( type.indexOf('custom') != -1 ){
 
          _that.element[type]++;
 
        } else {
 
          _that.element.fireEvent('on' + type);
        }
    
      }
 
    } catch(e){
 
    };
 
    return _that;
       
  }
}
 
Ev.fn.init.prototype = Ev.fn;
 
})( window );
测试用例1(自定义事件测试)

// 测试用例1(自定义事件测试)
// 引入事件机制
// ...
// 捕捉 DOM
var testBox = document.getElementById('testbox');
// 回调函数1
function triggerEvent(){
    console.log('触发了一次自定义事件 customConsole');
}
// 回调函数2
function triggerAgain(){
    console.log('再一次触发了自定义事件 customConsole');
}
// 封装
testBox = $(testBox);
// 同时绑定两个回调函数,支持链式调用
testBox.add('customConsole', triggerEvent).add('customConsole', triggerAgain);

Salin selepas log masuk

Kod lengkap ada dalam Demo.

Selepas membuka Demo, panggil testBox.trigger('customConsole') dalam konsol untuk mencetuskan acara tersuai sendiri Anda boleh melihat bahawa konsol mengeluarkan dua gesaan Kemudian masukkan testBox.remove('customConsole', triggerAgain). untuk mengalih keluar pasangan. Untuk pendengar yang terakhir, gunakan testBox.trigger('customConsole') untuk mencetuskan acara tersuai Anda boleh melihat bahawa konsol hanya mengeluarkan gesaan, iaitu, pendengar terakhir berjaya dialih keluar. semua fungsi mekanisme acara berfungsi dengan normal.

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