diff --git a/2-ui/2-events/03-event-delegation/article.md b/2-ui/2-events/03-event-delegation/article.md index 881183740..736e3d77c 100644 --- a/2-ui/2-events/03-event-delegation/article.md +++ b/2-ui/2-events/03-event-delegation/article.md @@ -1,19 +1,19 @@ -# Event delegation +# پترن Event delegation -Capturing and bubbling allow us to implement one of the most powerful event handling patterns called *event delegation*. +گرفتن (capture) و bubbling ایونت ها به ما این توانایی را میدهد که از یکی از قویترین الگوهای ایونت هندلینگ یعنی *event delegation* استفاده کنیم. -The idea is that if we have a lot of elements handled in a similar way, then instead of assigning a handler to each of them -- we put a single handler on their common ancestor. +ایده این است که اگر تعداد زیادی المنت داریم و میخواهیم به یک شکل آنها رو هندل کنیم به جای اینکه به تک تک آنها هندلر مجزا اختصاص دهیم، یک هندلر را برای المنت والد مشترک آنها اختصاص میدهیم. -In the handler we get `event.target` to see where the event actually happened and handle it. +در هندلری که اختصاص میدهیم با استفاده از `event.target` محل وقوع رویداد را متوجه میشویم و بنابراین میتوانیم آنرا هندل کنیم. -Let's see an example -- the [Ba-Gua diagram](http://en.wikipedia.org/wiki/Ba_gua) reflecting the ancient Chinese philosophy. +بیاید تا با هم یک مثال رو بررسی کنیم -- [دیاگرام Ba-Gua] (http://en.wikipedia.org/wiki/Ba_gua) که یک فلسفه چینی باستانی رو نشون میده -Here it is: +به این شکل : [iframe height=350 src="bagua" edit link] -The HTML is like this: +فایل HTML به اینصورت خواهد بود: ```html @@ -30,45 +30,45 @@ The HTML is like this:
``` -The table has 9 cells, but there could be 99 or 9999, doesn't matter. +جدول 9 سلول دارد اما این عدد امکان دارد 99 یا 9999 باشد. مهم نیست. -**Our task is to highlight a cell `` on click.** +**ماموریت ما این است که سلول `` که روی آن کلیک شد را هایلایت کنیم** -Instead of assign an `onclick` handler to each `` (can be many) -- we'll setup the "catch-all" handler on `` element. +به جای آنکه هندلر `onclick` را به هریک از تگ های `
` اساین کنیم (که ممکن است تعداد زیادی از آنها داشته باشیم)، هندلر "catch-all" را برروی المنت `` اساین میکنیم. -It will use `event.target` to get the clicked element and highlight it. +این عمل از `event.target` برای پیدا کردن المنت کلیک شده و هایلایت آن استفاده می‌کند. -The code: +کد: ```js let selectedTd; *!* table.onclick = function(event) { - let target = event.target; // where was the click? + let target = event.target; // کلیک کجا اتفاق افتاد؟ - if (target.tagName != 'TD') return; // not on TD? Then we're not interested + if (target.tagName != 'TD') return; // المنت TD نیست؟ پس المنت موردنظر ما نیست - highlight(target); // highlight it + highlight(target); // هایلایتش کن }; */!* function highlight(td) { - if (selectedTd) { // remove the existing highlight if any + if (selectedTd) { // اگر هایلایتی وجود دارد آنرا حذف کن selectedTd.classList.remove('highlight'); } selectedTd = td; - selectedTd.classList.add('highlight'); // highlight the new td + selectedTd.classList.add('highlight'); // TD جدید را هایلایت کن } ``` -Such a code doesn't care how many cells there are in the table. We can add/remove `
` dynamically at any time and the highlighting will still work. +این کد به اینکه چند سلول داخل جدول قرار دارد اهمیتی نمیدهد. میتوانیم المنت‌های `` رو به شکل دینامیکی هر زمان که خواستیم اضافه/کم کنیم و همچنان هایلایت کار خواهد کرد. -Still, there's a drawback. +اما همچنان یک اشکال وجود دارد. -The click may occur not on the ``, but inside it. +کلیک ممکن است نه روی `` بلکه درون آن اتفاق بیفتد. -In our case if we take a look inside the HTML, we can see nested tags inside ``, like ``: +در اینصورت اگر به داخل HTML نگاهی بندازیم میتوانیم تگ های درون `` را ببینمی. مثل المنت `` ```html @@ -79,13 +79,13 @@ In our case if we take a look inside the HTML, we can see nested tags inside ` ``` -Naturally, if a click happens on that `` then it becomes the value of `event.target`. +طبیعتا زمانی که یک کلیک بر روی `` انجام میشود آنگاه مقدار `event.target` برابر آن خواهد شد. ![](bagua-bubble.svg) -In the handler `table.onclick` we should take such `event.target` and find out whether the click was inside `` or not. +در هندلر `table.onclick` ما باید مقدار `event.target` را گرفته و از این طریق مشخص کنیم که آیا کلیک درون `` اتفاق افتاده یا نه. -Here's the improved code: +کد بهبود یافته شده: ```js table.onclick = function(event) { @@ -99,27 +99,27 @@ table.onclick = function(event) { }; ``` -Explanations: -1. The method `elem.closest(selector)` returns the nearest ancestor that matches the selector. In our case we look for `` on the way up from the source element. -2. If `event.target` is not inside any ``, then the call returns immediately, as there's nothing to do. -3. In case of nested tables, `event.target` may be a ``, but lying outside of the current table. So we check if that's actually *our table's* ``. -4. And, if it's so, then highlight it. +توضیحات: +1. متد `elem.closest(selector)` نزدیک‌ترین المنت به سلکتور را برمیگرداند. در این مسئله ما در مسیر از سورس المنت به بالا به دنبال المنت `` هستیم. +2. اگر `event.target` درون هیچ `` نباشد آنگاه فراخوانی تابع بلافاصله برمیگردد. درست مانند آنکه چیزی برای انجام دادن وجود ندارد. +3. در مسئله جدول‌های تودرتو `event.target` ممکن است یک المنت `` باشد که خارج از جدول مورد نظر ما قرار گرفته است بنابراین نیاز است بررسی کنیم که المنت آیا درون جدول موردنظر ما قرار دارد یا نه. +4. و اگر چنین است آنگاه هایلایتش کن. -As the result, we have a fast, efficient highlighting code, that doesn't care about the total number of `` in the table. +در نتیحه ما یک کد هایلایتر سریع و کارا داریم که عملکرد آن به تعداد سلول‌های `` در جدول ارتباطی ندارد. -## Delegation example: actions in markup +## مثالی از الگوی delegation: اکشن‌های مارک‌آپ -There are other uses for event delegation. +استفاده‌های دیگری هم برای event delegation وجود دارد -Let's say, we want to make a menu with buttons "Save", "Load", "Search" and so on. And there's an object with methods `save`, `load`, `search`... How to match them? +در نظر بگیرید که میخواهیم یک منو با دکمه‌های "Save", "Load"، "Search" و مانند آن بسازیم آبجکتی با متدهای `save`, `load`, `search` و ... وجود دارد. چطور میتوانیم این متدهارا به دکمه‌های مربوطه وصل کنیم؟ -The first idea may be to assign a separate handler to each button. But there's a more elegant solution. We can add a handler for the whole menu and `data-action` attributes for buttons that has the method to call: +اولین ایده‌ای که به ذهن میرسد ممکن است این باشد که برای هریک از دکمه‌ها هندلر مجزا اساین کنیم. اما راه‌حل بهتری هم وجود دارد. می‌توانیم یک هندلر به کل منو و اتریبیوت‌های `data-action` دکمه‌ها اضافه کنیم. ```html ``` -The handler reads the attribute and executes the method. Take a look at the working example: +هندلر اتریبیوت را خوانده و متد را اجرا میکند. نگاهی به این مثال واقعی بیندازید: ```html autorun height=60 run untrusted