Dalam JavaScript, Ejen dan Perwakilan sering muncul.
Jadi dalam keadaan apa ia digunakan? Apakah prinsipnya?
Di sini kami memperkenalkan penggunaan dan prinsip perwakilan javascript, serta antara muka perwakilan dalam Dojo, jQuery dan rangka kerja lain.
Proksi Acara JavaScript
Proksi acara ialah ciri yang sangat berguna dan menarik dalam dunia JS. Apabila kita perlu menambah acara pada banyak elemen, kita boleh mencetuskan fungsi pengendali dengan menambahkan acara pada nod induknya dan mewakilkan acara tersebut kepada nod induk.
Ini terutamanya disebabkan oleh mekanisme menggelegak acara penyemak imbas Mari berikan contoh khusus untuk menerangkan cara menggunakan ciri ini.
Contoh ini diambil terutamanya daripada artikel berkaitan David Walsh (Cara Perwakilan Acara JavaScript Berfungsi).
Andaikan terdapat nod induk UL, yang mengandungi banyak nod anak Li:
<ul id="list"> <li id="li-1">Li 1</li> <li id="li-2">Li 2</li> <li id="li-3">Li 3</li> <li id="li-4">Li 4</li> <li id="li-5">Li 5</li> </ul>
Apabila tetikus kami bergerak ke atas Li, kami perlu mendapatkan maklumat berkaitan Li ini dan muncul tetingkap terapung untuk memaparkan maklumat terperinci, atau apabila Li diklik, peristiwa pemprosesan yang sepadan perlu dicetuskan.
Cara penulisan biasa kami ialah menambahkan beberapa pendengar acara seperti onMouseOver atau onClick pada setiap Li.
function addListenersLi(liElement) { liElement.onclick = function clickHandler() { //TODO }; liElement.onmouseover = function mouseOverHandler() { //TODO } } window.onload = function() { var ulElement = document.getElementById("list"); var liElements = ulElement.getElementByTagName("Li"); for (var i = liElements.length - 1; i >= 0; i--) { addListenersLi(liElements[i]); } }
Jika sub-elemen Li dalam UL ini kerap ditambah atau dipadamkan, kita perlu memanggil kaedah addListenersLi setiap kali Li ditambahkan untuk menambah pengendali acara bagi setiap nod Li.
Ini akan menjadikan proses penambahan atau pemadaman rumit dan kemungkinan ralat.
Penyelesaian kepada masalah adalah dengan menggunakan mekanisme proksi acara Apabila acara dilemparkan ke nod induk atas, kami menentukan dan mendapatkan sumber peristiwa Li dengan menyemak objek sasaran (sasaran) acara.
Kod berikut boleh mencapai kesan yang diingini:
/ 获取父节点,并为它添加一个click事件 document.getElementById("list").addEventListener("click",function(e) { // 检查事件源e.targe是否为Li if(e.target && e.target.nodeName.toUpperCase == "LI") { // //TODO console.log("List item ",e.target.id," was clicked!"); } });
Tambahkan acara klik pada nod induk Apabila nod anak diklik, acara klik akan muncul daripada nod anak. Selepas nod induk menangkap peristiwa, ia menentukan sama ada ia adalah nod yang perlu kita proses dengan menilai e.target.nodeName. Dan dapatkan nod Li yang diklik melalui e.target. Dengan cara ini, maklumat yang sepadan boleh diperoleh dan diproses.
Acara menggelegak dan mengabadikan
Mekanisme menggelegak peristiwa penyemak imbas Pengeluar penyemak imbas yang berbeza mempunyai mekanisme pemprosesan yang berbeza untuk menangkap dan memproses peristiwa Di sini kami memperkenalkan peristiwa standard yang ditakrifkan oleh W3C untuk DOM2.0.
Model DOM2.0 membahagikan proses pemprosesan acara kepada tiga peringkat:
1. Fasa tangkapan acara,
2. Peringkat sasaran acara,
3. Peringkat menggelegak acara.
Seperti yang ditunjukkan di bawah:
Tangkapan peristiwa: Apabila elemen mencetuskan peristiwa (seperti onclick), dokumen objek peringkat atas akan mengeluarkan aliran peristiwa, yang akan mengalir ke nod elemen sasaran bersama-sama dengan nod pepohon DOM sehingga ia mencapai elemen sasaran di mana peristiwa itu sebenarnya berlaku. Semasa proses ini, fungsi mendengar acara yang sepadan tidak akan dicetuskan.
Sasaran acara: Selepas mencapai elemen sasaran, laksanakan fungsi pemprosesan yang sepadan bagi acara elemen sasaran. Jika tiada fungsi mendengar terikat, ia tidak akan dilaksanakan.
Acara menggelegak: bermula dari elemen sasaran dan merambat ke elemen peringkat atas. Jika terdapat nod yang terikat pada fungsi pemprosesan acara yang sepadan dalam perjalanan, fungsi ini akan dicetuskan sekaligus. Jika anda ingin menghalang peristiwa daripada menggelegak, anda boleh menggunakan e.stopPropagation() (Firefox) atau e.cancelBubble=true (IE) untuk mengelakkan peristiwa menggelegak.
mewakilkan fungsi dalam jQuery dan Dojo
Mari kita lihat cara menggunakan antara muka proksi acara yang disediakan dalam Dojo dan jQuery.
jQuery:
$("#list").delegate("li", "click", function(){ // "$(this)" is the node that was clicked console.log("you clicked a link!",$(this)); });
Kaedah perwakilan jQuery memerlukan tiga parameter, pemilih, nama masa dan pengendali acara.
Dojo serupa dengan jQuery, satu-satunya perbezaan adalah dalam gaya pengaturcaraan:
require(["dojo/query","dojox/NodeList/delegate"], function(query,delegate){ query("#list").delegate("li","onclick",function(event) { // "this.node" is the node that was clicked console.log("you clicked a link!",this); }); })
Modul perwakilan Dojo ada dalam dojox.NodeList Ia menyediakan antara muka yang sama seperti jQuery dan parameter yang sama.
Melalui delegasi, anda boleh menyedari beberapa faedah menggunakan delegasi acara untuk pembangunan:
1. Terdapat lebih sedikit fungsi pengurusan. Tidak perlu menambah fungsi pendengar untuk setiap elemen. Untuk elemen anak yang serupa di bawah nod induk yang sama, peristiwa boleh dikendalikan dengan mewakilkannya kepada fungsi mendengar elemen induk.
2. Anda boleh menambah dan mengubah suai elemen secara dinamik dengan mudah, dan tidak perlu mengubah suai pengikatan peristiwa kerana perubahan dalam elemen.
3. Terdapat lebih sedikit sambungan antara JavaScript dan nod DOM, yang mengurangkan kebarangkalian kebocoran memori yang disebabkan oleh rujukan bulat.
Menggunakan proksi dalam pengaturcaraan JavaScript
Pengenalan di atas adalah menggunakan mekanisme menggelegak penyemak imbas untuk menambah proksi acara pada elemen DOM semasa memproses acara DOM. Malah, dalam pengaturcaraan JS tulen, kami juga boleh menggunakan model pengaturcaraan ini untuk mencipta objek proksi untuk mengendalikan objek sasaran.
var delegate = function(client, clientMethod) { return function() { return clientMethod.apply(client, arguments); } } var Apple= function() { var _color = "red"; return { getColor: function() { console.log("Color: " + _color); }, setColor: function(color) { _color = color; } }; }; var a = new Apple(); var b = new Apple(); a.getColor(); a.setColor("green"); a.getColor(); //调用代理 var d = delegate(a, a.setColor); d("blue"); //执行代理 a.getColor(); //b.getColor();
Dalam contoh di atas, pengubahsuaian a dilakukan dengan memanggil fungsi proksi d yang dicipta oleh fungsi delegate().
Walaupun kaedah ini menggunakan aplikasi (panggilan juga boleh digunakan) untuk merealisasikan pemindahan objek panggilan, ia menyembunyikan objek tertentu daripada mod pengaturcaraan dan boleh melindungi objek ini daripada diakses dan diubah suai secara santai.
Konsep delegasi digunakan dalam banyak rangka kerja untuk menentukan skop kaedah yang dijalankan.
Yang biasa termasuk dojo.hitch(skop, kaedah) dan createDelegate(obj, args) ExtJS.
Di atas adalah keseluruhan kandungan artikel ini saya harap ia akan membantu semua orang dalam mempelajari pengaturcaraan javascript.