検索
ホームページウェブフロントエンドjsチュートリアルjQuery コード最適化イベント delegation_jquery

jQuery は、イベントをバインドおよび委任するための .bind()、.live()、および .delegate() メソッドを提供します。この記事では、これらのメソッドの内部実装について説明し、その利点、欠点、および適用可能な状況を示します。

イベント委任

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

DOM がページ内の各要素にイベントをディスパッチすると、通常、対応する要素がイベント バブリング ステージでイベントを処理することがわかっています。 body > div > a のような構造では、a 要素をクリックすると、クリック イベントが a から div と body (つまりドキュメント オブジェクト) に発生します。したがって、a、div、body 要素で発生するクリック イベントも処理できます。イベント伝播のメカニズム (ここではバブリング) を使用することで、イベントの委任を実現できます。具体的には、イベント委任とは、イベント ターゲットがイベント自体を処理するのではなく、処理タスクをその親要素や祖先要素、さらにはルート要素 (ドキュメント) に委任することを意味します。

.bind()
複数の行と列を含むテーブルがあるとします。ユーザーが各セルをクリックすると、その内容に関連する詳細情報が表示されます。情報(ツールチップなどを介して)。これを行うには、クリック イベントを各セルにバインドします。

$("info_table td").bind("click", function(){/*詳細情報を表示*/}); >
問題は、クリック イベントがバインドされているテーブルに 10 列と 500 行がある場合、5000 個のセルを検索して走査すると、スクリプトの実行が大幅に遅くなる一方で、5000 個の td 要素と対応するイベントが保存されることです。ハンドラーも多くのメモリを消費します (全員が物理的にドアの前に立って配達を待っているのと同じです)。

前の例に基づいて、単純なフォト アルバム アプリケーションを実装する場合、各ページには 50 枚の写真 (50 セル) のサムネイルのみが表示され、ユーザーは「ページ x」(または「次のページ」) をクリックします。 ) リンクは、Ajax 経由でサーバーからさらに 50 枚の写真を動的にロードできます。この場合、 .bind() メソッドを使用した 50 個のセルのバインディング イベントが再び受け入れられるようです。

そうではありません。 .bind() メソッドを使用すると、クリック イベントは最初のページの 50 個のセルにのみバインドされ、動的に読み込まれる後続のページのセルにはこのクリック イベントがありません。つまり、 .bind() は、呼び出されたときにすでに存在する要素にイベントをバインドすることしかできず、将来追加される要素にイベントをバインドすることはできません (新入社員が速達配送を受け取ることができないのと同様)。

イベント委任は、上記の 2 つの問題を解決できます。コード固有の場合は、.bind() メソッドの代わりに jQuery 1.3 で追加された .live() メソッドを使用します:

$("#info_table td").live("click",function() {/*詳細情報を表示*/});

ここでの .live() メソッドは、クリック イベントを $(document) オブジェクトにバインドします (ただし、これはコードから反映できません。これも.live() メソッドが批判されている重要な理由 (後で詳しく説明します)、$(document) を 1 回バインドするだけで済みます (50 回どころか、5000 回も)。その後は、その後の動的処理を行うことができます。フォトセルのクリックイベント。イベントを受信すると、$(document) オブジェクトはイベント タイプとイベント ターゲットを確認し、それがクリック イベントでイベント ターゲットが td の場合、それに委任されたハンドラーが実行されます。


.live()
これまでのところ、すべてが完璧であるようです。残念ながらそうではありません。 .live() メソッドは完璧ではないため、次のような大きな欠点があります。

$() 関数は現在のページ内のすべての td 要素を検索し、jQuery オブジェクトを作成しますが、確認時には使用されません。イベント ターゲット。この td 要素のコレクションは代わりにセレクター式を使用して、event.target またはその祖先要素と比較します。そのため、この jQuery オブジェクトを生成すると、不要なオーバーヘッドが発生します。
イベントはデフォルトで $(document) 要素にバインドされます。 DOM の入れ子構造が非常に深い場合、多数の祖先要素を介したイベントのバブリングによりパフォーマンスの低下が発生します。
は直接選択された要素の後にのみ配置でき、連続した DOM トラバーサル メソッドの後には使用できません。 、$("#infotable td ").live... は機能しますが、$("#infotable").find("td").live... は機能しません。
は td 要素を収集し、jQuery オブジェクトを作成します。ですが、実際の操作は $( document) オブジェクトであり、不可解です。


解決策
不要な jQuery オブジェクトの生成を避けるために、$(document).ready ( ) メソッド外部呼び出し .live():

コードをコピー コードは次のとおりです:
(function ($){
$("#info_table td").live("click",function(){/*詳細情報を表示*/});
})(jQuery);

Here, (function($){...})(jQuery) is an "anonymous function that is executed immediately", forming a closure to prevent naming conflicts. Inside the anonymous function, the $parameter refers to the jQuery object. This anonymous function does not wait until the DOM is ready before executing. Note that when using this hack, the script must be linked and/or executed in the head element of the page. The reason for choosing this timing is that the document element is available at this time, and the entire DOM is far from being generated; if the script is placed in front of the closing body tag, it makes no sense, because the DOM is fully available at that time.

In order to avoid performance losses caused by event bubbling, jQuery supports the use of a context parameter when using the .live() method starting from 1.4:

$("td",$(" #info_table")[0]).live("click",function(){/*Show more information*/}); In this way, the "trustee" changes from the default $(document) to $(" #infotable")[0], saving the bubbling trip. However, the context parameter used with .live() must be a separate DOM element, so the context object is specified here using $("#infotable")[0], which is obtained using the array index operator. A DOM element.

.delegate()
As mentioned earlier, in order to break through the limitations of the single .bind() method and implement event delegation, jQuery 1.3 introduced the .live() method. Later, in order to solve the problem of too long "event propagation chain", jQuery 1.4 supported specifying context objects for the .live() method. In order to solve the problem of unnecessary generation of element collections, jQuery 1.4.2 simply introduced a new method.delegate().

Using .delegate(), the previous example can be written like this:

$("#info_table").delegate("td","click",function(){/*Display More information*/});
Using .delegate() has the following advantages (or solves the following problems of the .live() method):

Directly set the target element selector ("td" ), events ("click") and handlers are bound to the "dragee" $("#info_table"), no additional elements are collected, the event propagation path is shortened, and the semantics are clear;
Supports continuous DOM traversal methods Later calls support $("table").find("#info").delegate..., which supports precise control;
It can be seen that the .delegate() method is a relatively perfect solution. But when the DOM structure is simple, .live() can also be used.

Tip: When using event delegation, if other event handlers registered on the target element use .stopPropagation() to prevent event propagation, the event delegation will be invalid.

Conclusion
In the following situations, .live() or .delegate() should be used instead of .bind():

is in DOM Bind the same event to many elements;
binds events to elements that do not yet exist in the DOM;

PS: According to the release notes of jQuery 1.7 Beta 1, in order to solve the inconsistency problem caused by the coexistence of .bind(), .live() and .delegate(), jQuery 1.7 will add a For new event methods: .on() and .off():
$(elems).on(events, selector, data, fn);
$(elems).off(events, selector, fn) );
If selector is specified, it is event delegation; otherwise, it is regular binding. The correspondence between the old and new APIs is as follows:
jQuery コード最適化イベント delegation_jquery

(Note: This article is compiled based on the relevant chapters of "JQuery Basics Tutorial (3rd Edition)", and also refers to

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
如何做好Java代码的重构如何做好Java代码的重构Jun 15, 2023 pm 09:17 PM

作为世界上最流行的编程语言之一,Java已成为许多企业和开发者的首选语言。然而,代码的重构对于保持代码质量以及开发效率至关重要。Java代码由于其复杂性,随着时间的推移可能会变得越来越难以维护。本文将讨论如何进行Java代码的重构,以提高代码质量和可维护性。了解重构的原则Java代码重构的目的在于改进代码的结构、可读性和可维护性,而不是简单的“改变代码”。因

Java Spring Boot Security性能优化:让你的系统飞起来Java Spring Boot Security性能优化:让你的系统飞起来Feb 19, 2024 pm 05:27 PM

一、代码优化避免使用过多的安全注解:在Controller和Service中,尽量减少使用@PreAuthorize和@PostAuthorize等注解,这些注解会增加代码的执行时间。优化查询语句:使用springDataJPA时,优化查询语句可以减少数据库的查询时间,从而提高系统性能。缓存安全信息:将一些常用的安全信息缓存起来,可以减少数据库的访问次数,提高系统的响应速度。二、数据库优化使用索引:在经常被查询的表上创建索引,可以显著提高数据库的查询速度。定期清理日志和临时表:定期清理日志和临时

程序性能优化有哪些常见的方法?程序性能优化有哪些常见的方法?May 09, 2024 am 09:57 AM

程序性能优化方法包括:算法优化:选择时间复杂度更低的算法,减少循环和条件语句。数据结构选择:根据数据访问模式选择合适的数据结构,如查找树和哈希表。内存优化:避免创建不必要对象,释放不再使用的内存,使用内存池技术。线程优化:识别可并行化任务,优化线程同步机制。数据库优化:创建索引加快数据检索,优化查询语句,使用缓存或NoSQL数据库提升性能。

PHP高并发处理中的代码优化技巧PHP高并发处理中的代码优化技巧Aug 11, 2023 pm 12:57 PM

PHP高并发处理中的代码优化技巧随着互联网的快速发展,高并发处理已经成为了web应用程序开发中的重要问题。在PHP开发中,如何优化代码以应对高并发请求成为了程序员需要解决的一个难题。本文将介绍一些PHP高并发处理中的代码优化技巧,并加上代码示例进行说明。合理利用缓存对于高并发的情况,频繁访问数据库会导致系统负载过大,并且访问数据库的速度相对较慢。因此,我们可

Go语言中的该如何进行代码重构Go语言中的该如何进行代码重构Jun 02, 2023 am 08:31 AM

随着软件开发的不断深入和代码的不断积累,代码重构已经成为了现代软件开发过程中不可避免的一部分。它是一种对系统的既定代码进行修改,以改善其结构、性能、可读性或其他相关方面的过程。在本文中,我们将探讨如何在Go语言中进行代码重构。定义好重构的目标在开始代码重构之前,我们应该制定一个清晰的重构目标。我们需要问自己一些问题,比如这段代码存在哪些问题?我们要通过重构

如何进行C++代码的重构?如何进行C++代码的重构?Nov 04, 2023 pm 04:40 PM

C++是一种非常强大、灵活且广泛使用的编程语言,但是随着项目的不断发展和代码的持续相对重用,会存在代码质量的下降、可读性的下降等问题。这时候就需要对代码进行重构,以达到更好的代码质量和更高的可维护性。本文将介绍如何进行C++代码的重构。定义目标在开始重构代码之前,你需要明确需要完成的目标。例如,你可能想改善代码的可读性、减少代码的重复、提高代码的性能等等。无

Python 性能优化实战:从基础到进阶Python 性能优化实战:从基础到进阶Feb 20, 2024 pm 12:00 PM

基础优化使用正确的Python版本:较新版本的python通常性能更高,提供更好的内存管理和内置优化。选择合适的库:使用专门构建的库而不是从头开始编写代码,可以节省时间并提高性能。减少循环次数:如果可能,避免使用嵌套循环。使用列表推导和生成器表达式是更有效的替代方案。数据结构优化选择正确的容器:列表适用于随机访问,字典适用于快速键值查找,元组适用于不可变数据。使用预分配内存:通过预分配数组或列表的大小,可以减少内存分配和碎片整理的开销。利用Numpy和Pandas:对于科学计算和数据分析,Num

代码优化在Java框架性能优化中的关键技巧代码优化在Java框架性能优化中的关键技巧Jun 03, 2024 pm 01:16 PM

在Java框架性能优化中,代码优化至关重要,包括:1.减少对象创建;2.使用合适的数据结构;3.避免阻塞I/O;4.优化字符串操作;5.避免反射。通过遵循这些技巧,可以提高框架性能,例如优化Hibernate查询以减少数据库调用次数。

See all articles

ホット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ヘンタイを無料で生成します。

ホットツール

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター