ホームページ ウェブフロントエンド jsチュートリアル Javascriptイベントデリゲーションの詳しい説明

Javascriptイベントデリゲーションの詳しい説明

Jul 24, 2017 pm 04:02 PM
javascript js イベント

原因:

1. これは、フロントエンドの面接によくある質問です。

2. 実際、私はまだそれを理解していません。これは準備のために書いたものです。もう 1 つは、それを知っていても理由が​​わからない他の友人に参考にするためです。

では、イベント委任とは何ですか?高度な JavaScript プログラミングの観点からは、イベント プロキシと呼ばれる名前もあります。イベント デリゲーションは、イベント バブリングを使用して、イベント ハンドラーを 1 つだけ指定することによって、特定の種類のすべてのイベントを管理します。では、これは何を意味するのでしょうか?インターネットの専門家は、イベントの委任について話すときに、基本的に同じ例を使用します。つまり、この現象を説明するために、この例が本当に適切であることがわかりました。仏陀にお供えする花をいくつか摘んでみましょう。イベントの委任の原則を詳しく見てみましょう:

月曜日に 3 人の同僚が速達で配達される予定です。速達の署名方法は 2 つあります。1 つは会社の玄関で 3 人で速達を待ってもらう方法、もう 1 つは受付担当者に代理で署名を依頼する方法です。実際、私たちは主に委託ソリューションを使用しています (会社は、速達を待っているだけでドアに立っている多くの従業員を容認しません)。フロントデスクの MM は速達を受け取ると、受取人が誰であるかを判断し、受取人の要件に従って署名し、代わりに代金を支払います。このソリューションのもう 1 つの利点は、新入社員が (人数に関係なく) 会社に来ても、フロント デスクの MM が新入社員に送られた速達便を確認し、新入社員に代わって署名することです。

ここには実際には 2 つのレベルの意味があります:

まず、フロントデスクの同僚が署名できるようになります。つまり、プログラム内の既存の dom ノードにイベントがあります。

次に、新しい従業員も署名できます。これはフロントデスク MM によって署名されています。つまり、プログラムに新しく追加された dom ノードにもイベントがあります。

イベント委任を使用する理由:

一般的に言えば、DOM にはイベント ハンドラーが必要なので、イベント ハンドラーを直接設定するだけですが、イベント ハンドラーを追加する必要がある DOM が多数ある場合はどうなるでしょうか。たとえば、100 個の li があり、各 li に同じクリック イベントがあるとします。おそらく、for ループ メソッドを使用してすべての li を走査し、それらにイベントを追加するとどうなるでしょうか。

JavaScript では、ページに追加されるイベント ハンドラーの数は、ページの全体的な実行パフォーマンスに直接関係します。これは、dom ノードと常にやり取りする必要があるため、dom へのアクセス回数が増えると、ブラウザの再描画とリフローの回数が増えると、ページ全体のインタラクティブな準備時間が長くなります。このため、イベント委任を使用する場合、DOM 操作を減らすことが重要になります。内部では、DOM との操作は 1 回だけ行う必要があるため、DOM との操作の数が大幅に削減され、パフォーマンスが向上します

各関数はオブジェクトであり、そのオブジェクトがメモリを占有します。オブジェクトの数が増えると、占有されるメモリも増えます (メモリ不足は欠陥です、笑)。イベント委任を使用すると、その親のオブジェクトに対してのみ操作できるようになります (親が 1 つだけの場合)。これにより、必要なメモリ空間が 1 つだけになり、当然のことながら大幅に節約されます。パフォーマンスが向上します。

イベント委任の原理:

イベント委任は、イベントのバブリング原理を使用して実装されます。 イベントのバブリングとは何ですか?つまり、イベントは最も深いノードから始まり、徐々に上に伝播します。たとえば、ページ上にこのようなノード ツリーがあり、div>ul>li>a; にクリック イベントを追加するとします。一番内側の a の場合、このイベントはレイヤーごとに実行されます。実行順序は a>li>ul>div です。次に、一番外側の div にクリック イベントを追加します。 、li、および内部のクリック イベントは、最も外側の div にバブルされるため、トリガーされます。これは、親に代わってイベントを実行することを委任します。

イベント委任の実装方法:

ついにこの記事の核心部分に到達しました、笑、イベント委任の方法を紹介する前に、一般的な方法の例を見てみましょう:

子ノードは同じものを実装しますfunction:

ログイン後にコピー
        
  • 111
  •     
  • 222
  •     
  • 333
  •     
  • 444

関数を実装するには、li をクリックすると、123 がポップアップします:

window.onload = function(){
    var oUl = document.getElementById("ul1");
    var aLi = oUl.getElementsByTagName('li');
    for(var i=0;i<ali.length><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/001/22e3a06a99eaee066d9e0282007809c3-0.gif" class="lazy" alt="Javascriptイベントデリゲーションの詳しい説明"></ali.length>
ログイン後にコピー
Javascriptイベントデリゲーションの詳しい説明 上記のコードの意味は、多くの人が非常に単純だと思います。このように実装しました。dom がいくつあるか見てみましょう。操作するには、最初に ul を見つけてから li を移動し、次に li をクリックして、最後の操作を実行する前にターゲット li の位置を再度見つける必要があります。クリックするたびに li を見つける必要があります
次に、イベント委任を使用します。このようにするとどうなりますか?

りー

 

这里用父级ul做事件处理,当li被点击时,由于冒泡原理,事件就会冒泡到ul上,因为ul上有点击事件,所以事件就会触发,当然,这里当点击ul的时候,也是会触发的,那么问题就来了,如果我想让事件代理的效果跟直接给节点的事件效果一样怎么办,比如说只有点击li才会触发,不怕,我们有绝招:

Event对象提供了一个属性叫target,可以返回事件的目标节点,我们成为事件源,也就是说,target就可以表示为当前的事件操作的dom,但是不是真正操作dom,当然,这个是有兼容性的,标准浏览器用ev.target,IE浏览器用event.srcElement,此时只是获取了当前节点的位置,并不知道是什么节点名称,这里我们用nodeName来获取具体是什么标签名,这个返回的是一个大写的,我们需要转成小写再做比较(习惯问题):

Javascriptイベントデリゲーションの詳しい説明

window.onload = function(){
  var oUl = document.getElementById("ul1");
  oUl.onclick = function(ev){
    var ev = ev || window.event;
    var target = ev.target || ev.srcElement;
    if(target.nodeName.toLowerCase() == 'li'){
         alert(123);
         alert(target.innerHTML);
    }
  }
}

Javascriptイベントデリゲーションの詳しい説明

 

这样改下就只有点击li会触发事件了,且每次只执行一次dom操作,如果li数量很多的话,将大大减少dom的操作,优化的性能可想而知!

 

上面的例子是说li操作的是同样的效果,要是每个li被点击的效果都不一样,那么用事件委托还有用吗?

<div>
        <input>
        <input>
        <input>
        <input>
    </div>
ログイン後にコピー
Javascriptイベントデリゲーションの詳しい説明
window.onload = function(){
            var Add = document.getElementById("add");
            var Remove = document.getElementById("remove");
            var Move = document.getElementById("move");
            var Select = document.getElementById("select");
            
            Add.onclick = function(){
                alert('添加');
            };
            Remove.onclick = function(){
                alert('删除');
            };
            Move.onclick = function(){
                alert('移动');
            };
            Select.onclick = function(){
                alert('选择');
            }
            
        }
ログイン後にコピー
Javascriptイベントデリゲーションの詳しい説明

 

上面实现的效果我就不多说了,很简单,4个按钮,点击每一个做不同的操作,那么至少需要4次dom操作,如果用事件委托,能进行优化吗?

Javascriptイベントデリゲーションの詳しい説明
window.onload = function(){
            var oBox = document.getElementById("box");
            oBox.onclick = function (ev) {
                var ev = ev || window.event;
                var target = ev.target || ev.srcElement;
                if(target.nodeName.toLocaleLowerCase() == 'input'){
                    switch(target.id){
                        case 'add' :
                            alert('添加');
                            break;
                        case 'remove' :
                            alert('删除');
                            break;
                        case 'move' :
                            alert('移动');
                            break;
                        case 'select' :
                            alert('选择');
                            break;
                    }
                }
            }
            
        }
ログイン後にコピー
Javascriptイベントデリゲーションの詳しい説明

 

用事件委托就可以只用一次dom操作就能完成所有的效果,比上面的性能肯定是要好一些的 

 

 现在讲的都是document加载完成的现有dom节点下的操作,那么如果是新增的节点,新增的节点会有事件吗?也就是说,一个新员工来了,他能收到快递吗?

看一下正常的添加节点的方法:

Javascriptイベントデリゲーションの詳しい説明
<input>
    
ログイン後にコピー
            
  • 111
  •         
  • 222
  •         
  • 333
  •         
  • 444
  •     
Javascriptイベントデリゲーションの詳しい説明

 

现在是移入li,li变红,移出li,li变白,这么一个效果,然后点击按钮,可以向ul中添加一个li子节点

 

Javascriptイベントデリゲーションの詳しい説明
window.onload = function(){
            var oBtn = document.getElementById("btn");
            var oUl = document.getElementById("ul1");
            var aLi = oUl.getElementsByTagName('li');
            var num = 4;
            
            //鼠标移入变红,移出变白
            for(var i=0; i<ali.length><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/001/8e05a80ecdb75cfe19baae0423d6c017-11.gif" class="lazy" alt="Javascriptイベントデリゲーションの詳しい説明"></span></div></ali.length>
ログイン後にコピー

 

这是一般的做法,但是你会发现,新增的li是没有事件的,说明添加子节点的时候,事件没有一起添加进去,这不是我们想要的结果,那怎么做呢?一般的解决方案会是这样,将for循环用一个函数包起来,命名为mHover,如下:

Javascriptイベントデリゲーションの詳しい説明
window.onload = function(){
            var oBtn = document.getElementById("btn");
            var oUl = document.getElementById("ul1");
            var aLi = oUl.getElementsByTagName('li');
            var num = 4;
            
            function mHover () {
                //鼠标移入变红,移出变白
                for(var i=0; i<ali.length><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/001/8e05a80ecdb75cfe19baae0423d6c017-13.gif" class="lazy" alt="Javascriptイベントデリゲーションの詳しい説明"></span></div></ali.length>
ログイン後にコピー

 

虽然功能实现了,看着还挺好,但实际上无疑是又增加了一个dom操作,在优化性能方面是不可取的,那么有事件委托的方式,能做到优化吗?

Javascriptイベントデリゲーションの詳しい説明
window.onload = function(){
            var oBtn = document.getElementById("btn");
            var oUl = document.getElementById("ul1");
            var aLi = oUl.getElementsByTagName('li');
            var num = 4;
            
            //事件委托,添加的子元素也有事件
            oUl.onmouseover = function(ev){
                var ev = ev || window.event;
                var target = ev.target || ev.srcElement;
                if(target.nodeName.toLowerCase() == 'li'){
                    target.style.background = "red";
                }
                
            };
            oUl.onmouseout = function(ev){
                var ev = ev || window.event;
                var target = ev.target || ev.srcElement;
                if(target.nodeName.toLowerCase() == 'li'){
                    target.style.background = "#fff";
                }
                
            };
            
            //添加新节点
            oBtn.onclick = function(){
                num++;
                var oLi = document.createElement('li');
                oLi.innerHTML = 111*num;
                oUl.appendChild(oLi);
            };
        }
ログイン後にコピー
Javascriptイベントデリゲーションの詳しい説明

 

看,上面是用事件委托的方式,新添加的子元素是带有事件效果的,我们可以发现,当用事件委托的时候,根本就不需要去遍历元素的子节点,只需要给父级元素添加事件就好了,其他的都是在js里面的执行,这样可以大大的减少dom操作,这才是事件委托的精髓所在。

 

--------------------------------------------------华丽的分割线-------------- -----------------------------------------------------------------------------------------------------

在这里先感谢一下@苍茫大地NV 的提问,提的问题非常好!

以上がJavascriptイベントデリゲーションの詳しい説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

推奨: 優れた JS オープンソースの顔検出および認識プロジェクト 推奨: 優れた JS オープンソースの顔検出および認識プロジェクト Apr 03, 2024 am 11:55 AM

顔の検出および認識テクノロジーは、すでに比較的成熟しており、広く使用されているテクノロジーです。現在、最も広く使用されているインターネット アプリケーション言語は JS ですが、Web フロントエンドでの顔検出と認識の実装には、バックエンドの顔認識と比較して利点と欠点があります。利点としては、ネットワーク インタラクションの削減とリアルタイム認識により、ユーザーの待ち時間が大幅に短縮され、ユーザー エクスペリエンスが向上することが挙げられます。欠点としては、モデル サイズによって制限されるため、精度も制限されることが挙げられます。 js を使用して Web 上に顔検出を実装するにはどうすればよいですか? Web 上で顔認識を実装するには、JavaScript、HTML、CSS、WebRTC など、関連するプログラミング言語とテクノロジに精通している必要があります。同時に、関連するコンピューター ビジョンと人工知能テクノロジーを習得する必要もあります。 Web 側の設計により、次の点に注意してください。

PHP および JS 開発のヒント: 株価ローソク足チャートの描画方法をマスターする PHP および JS 開発のヒント: 株価ローソク足チャートの描画方法をマスターする Dec 18, 2023 pm 03:39 PM

インターネット金融の急速な発展に伴い、株式投資を選択する人がますます増えています。株式取引では、ローソク足チャートは一般的に使用されるテクニカル分析手法であり、株価の変化傾向を示し、投資家がより正確な意思決定を行うのに役立ちます。この記事では、PHP と JS の開発スキルを紹介し、株価ローソク足チャートの描画方法を読者に理解してもらい、具体的なコード例を示します。 1. 株のローソク足チャートを理解する 株のローソク足チャートの描き方を紹介する前に、まずローソク足チャートとは何かを理解する必要があります。ローソク足チャートは日本人が開発した

簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 Jan 05, 2024 pm 06:08 PM

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

jsとvueの関係 jsとvueの関係 Mar 11, 2024 pm 05:21 PM

js と vue の関係: 1. Web 開発の基礎としての JS、2. フロントエンド フレームワークとしての Vue.js の台頭、3. JS と Vue の補完関係、4. JS と Vue の実用化ビュー。

jQueryで選択要素の変更イベントバインディングを実装する方法 jQueryで選択要素の変更イベントバインディングを実装する方法 Feb 23, 2024 pm 01:12 PM

jQuery は、DOM 操作、イベント処理、アニメーション効果などを簡素化するために使用できる人気のある JavaScript ライブラリです。 Web 開発では、選択した要素のイベント バインディングを変更する必要がある状況によく遭遇します。この記事では、jQuery を使用して選択要素変更イベントをバインドする方法を紹介し、具体的なコード例を示します。まず、ラベルを使用してオプションを含むドロップダウン メニューを作成する必要があります。

JavaScript で HTTP ステータス コードを簡単に取得する方法 JavaScript で HTTP ステータス コードを簡単に取得する方法 Jan 05, 2024 pm 01:37 PM

JavaScript で HTTP ステータス コードを取得する方法の紹介: フロントエンド開発では、バックエンド インターフェイスとの対話を処理する必要があることが多く、HTTP ステータス コードはその非常に重要な部分です。 HTTP ステータス コードを理解して取得すると、インターフェイスから返されたデータをより適切に処理できるようになります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法と、具体的なコード例を紹介します。 1. HTTP ステータス コードとは何ですか? HTTP ステータス コードとは、ブラウザがサーバーへのリクエストを開始したときに、サービスが

PHP を使用してイベントベースのアプリケーションを構築する方法 PHP を使用してイベントベースのアプリケーションを構築する方法 May 04, 2024 pm 02:24 PM

PHP でイベントベースのアプリケーションを構築する方法には、EventSourceAPI を使用してイベント ソースを作成する方法と、EventSource オブジェクトを使用してクライアント側でイベントをリッスンする方法が含まれます。 Server Sent Events (SSE) を使用してイベントを送信し、XMLHttpRequest オブジェクトを使用してクライアント側でイベントをリッスンします。実際の例は、EventSource を使用して、電子商取引 Web サイトの在庫数をリアルタイムで更新することです。これは、サーバー側で在庫をランダムに変更して更新を送信することで実現され、クライアントは EventSource を通じて在庫の更新をリッスンし、それらを表示します。リアルタイム。

JSのAI時代が到来! JSのAI時代が到来! Apr 08, 2024 am 09:10 AM

JS-Torch の概要 JS-Torch は、構文が PyTorch に非常に似ている深層学習 JavaScript ライブラリです。これには、完全に機能するテンソル オブジェクト (追跡された勾配で使用可能)、深層学習レイヤーと関数、および自動微分エンジンが含まれています。 JS-Torch は JavaScript での深層学習の研究に適しており、深層学習の開発を加速するための便利なツールや機能を多数提供します。 Image PyTorch は、Meta の研究チームによって開発および保守されているオープンソースの深層学習フレームワークです。ニューラル ネットワーク モデルを構築およびトレーニングするための豊富なツールとライブラリのセットを提供します。 PyTorch は、シンプル、柔軟、そして使いやすいように設計されており、その動的な計算グラフ機能により、

See all articles