You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 2-ui/2-events/03-event-delegation/article.md
+35-37Lines changed: 35 additions & 37 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,21 +1,19 @@
1
1
2
-
# Event delegation
2
+
# پنرن Event delegation
3
3
4
4
کپچر (capture) و bubbling ایونت ها به ما این توانایی را میدهد که از یکی از قویترین الگوهای کنترل ایونت هندلینگ یعنی *event delegation* استفاده کنیم.
5
5
6
6
ایده این است که اگر تعداد زیادی المنت داریم و میخواهیم به یک شکل آنها رو هندل کنیم به جای اینکه به تک تک آنها هندلر مجزا اختصاص دهیم، یک هندلر را برای المنت والد مشترک آنها اختصاص میدهیم.
7
7
8
8
در هندلری که اختصاص میدهیم با استفاده از `event.target` محل وقوع رویداد را متوجه میشویم و بنابراین میتوانیم آنرا هندل کنیم.
9
9
10
-
Let's see an example -- the [Ba-Gua diagram](http://en.wikipedia.org/wiki/Ba_gua) reflecting the ancient Chinese philosophy.
11
10
بیاید تا با هم یک مثال رو بررسی کنیم -- [دیاگرام Ba-Gua] (http://en.wikipedia.org/wiki/Ba_gua) که یک فلسفه چینی باستانی رو نشون میده
12
11
13
12
به این شکل :
14
13
15
14
[iframe height=350 src="bagua" edit link]
16
15
17
-
The HTML is like this:
18
-
اچتیامال به این صورت هست:
16
+
فایل HTML به اینصورت خواهد بود:
19
17
20
18
```html
21
19
<table>
@@ -47,20 +45,20 @@ let selectedTd;
47
45
48
46
*!*
49
47
table.onclick=function(event) {
50
-
let target =event.target; //where was the click?
48
+
let target =event.target; //کلیک کجا اتفاق افتاد؟
51
49
52
-
if (target.tagName!='TD') return; //not on TD? Then we're not interested
50
+
if (target.tagName!='TD') return; //المنت TD نیست؟ پس المنت موردنظر ما نیست
53
51
54
-
highlight(target); //highlight it
52
+
highlight(target); //هایلایتش کن
55
53
};
56
54
*/!*
57
55
58
56
functionhighlight(td) {
59
-
if (selectedTd) { //remove the existing highlight if any
57
+
if (selectedTd) { //اگر هایلایتی وجود دارد آنرا حذف کن
60
58
selectedTd.classList.remove('highlight');
61
59
}
62
60
selectedTd = td;
63
-
selectedTd.classList.add('highlight'); //highlight the new td
61
+
selectedTd.classList.add('highlight'); //TD جدید را هایلایت کن
1.The method `elem.closest(selector)`returns the nearest ancestor that matches the selector. In our case we look for `<td>` on the way up from the source element.
106
-
2.If`event.target`is not inside any `<td>`, then the call returns immediately, as there's nothing to do.
107
-
3.In case of nested tables, `event.target`may be a `<td>`, but lying outside of the current table. So we check if that's actually *our table's*`<td>`.
108
-
4.And, if it's so, then highlight it.
103
+
1.متد `elem.closest(selector)`نزدیکترین المنت به سلکتور را برمیگرداند. در این مسئله ما در مسیر از سورس المنت به بالا به دنبال المنت `<td>` هستیم.
104
+
2.اگر`event.target`درون هیچ `<td>` نباید آنگاه فراخوانی تابع بلافاصله برمیگردد. درست مانند آنکه چیزی برای انجام دادن وجود ندارد.
105
+
3.در مسئله جدولهای تودرتو `event.target`ممکن است یک المنت `<td>` باشد که خارج از جدول مورد نظر ما قرار گرفته است بنابراین نیاز است بررسی کنیم که المنت آیا درون جدول موردنظر ما قرار دارد یا نه.
106
+
4.و اگر چنین است آنگاه هایلایتش کن.
109
107
110
108
در نتیحه ما یک کد هایلایتر سریع و کارا داریم که عملکرد آن به تعداد سلولهای `<td>` در جدول ارتباطی ندارد.
111
109
112
-
## Delegation example: actions in markup
110
+
## مثالی از الگوی delegation: اکشنهای مارکآپ
113
111
114
112
استفادههای دیگری هم برای event delegation وجود دارد
115
113
116
114
در نظر بگیرید که میخواهیم یک منو با دکمههای "Save", "Load"، "Search" و مانند آن بسازیم آبجکتی با متدهای `save`, `load`, `search` و ... وجود دارد. چطور میتوانیم این متدهارا به دکمههای مربوطه وصل کنیم؟
117
115
118
-
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:
119
116
اولین ایدهای که به ذهن میرسد ممکن است این باشد که برای هریک از دکمهها هندلر مجزا اساین کنیم. اما راهحل بهتری هم وجود دارد. میتوانیم یک هندلر به کل منو و اتریبیوتهای `data-action` دکمهها اضافه کنیم.
120
117
121
118
```html
@@ -164,9 +161,9 @@ The first idea may be to assign a separate handler to each button. But there's a
164
161
</script>
165
162
```
166
163
167
-
Please note that `this.onClick`is bound to `this`in `(*)`. That's important, because otherwise `this`inside it would reference the DOM element (`elem`), not the `Menu`object, and `this[action]`would not be what we need.
164
+
توجه کنید که در `(*)` متد `this.onClick`به `this`متصل شده است. این مهم است زیرا در غیراینصورت `this`درون آن به المنت DOM رفرنس میدهد (`elem`) نه به آبجکت `Menu`و `this[action]`چیزی که ما میخواهیم نخواهد بود.
168
165
169
-
So, what advantages does delegation give us here?
166
+
خب، استفاده از الگوی delegation اینجا برای ما چه فایدهای دارد؟
170
167
171
168
```compare
172
169
+ We don't need to write the code to assign a handler to each button. Just make a method and put it in the markup.
@@ -175,17 +172,17 @@ So, what advantages does delegation give us here?
175
172
176
173
We could also use classes `.action-save`, `.action-load`, but an attribute `data-action` is better semantically. And we can use it in CSS rules too.
177
174
178
-
## The "behavior" pattern
175
+
## الگوی "behavior"
179
176
180
-
We can also use event delegation to add "behaviors" to elements *declaratively*, with special attributes and classes.
177
+
همچنین ما میتوانیم با استفاده از الگوی delegation با استفاده از اتریبیوتها و کلاسهای خاص رفتارهایی را به صورت *declaratively* به المنتها اضافه کنیم.
181
178
182
-
The pattern has two parts:
183
-
1.We add a custom attribute to an element that describes its behavior.
184
-
2.A document-wide handler tracks events, and if an event happens on an attributed element -- performs the action.
179
+
الگو دو قسمت دارم:
180
+
1.یک اتریبیوت شخصیسازی شده که بیانگر رفتار آن باشد را به المنت اضافه میکنیم.
181
+
2.یک هندلر به وسعت داکیومنت ایونتها را ردیابی میکند و اگر یک رویداد بر روی المنتی بااتریبوت موردنظر اتفاق آنگاه عمل خواهد کرد.
185
182
186
-
### Behavior: Counter
183
+
### رفتار شمارشگر
187
184
188
-
For instance, here the attribute `data-counter`adds a behavior: "increase value on click" to buttons:
185
+
برای مثال اینجا اتریبیوت `data-counter`رفتار "مقدار را با کلیک افزایش بده" را به دکمهها اضافه میکند.
@@ -202,19 +199,20 @@ One more counter: <input type="button" value="2" data-counter>
202
199
</script>
203
200
```
204
201
205
-
If we click a button -- its value is increased. Not buttons, but the general approach is important here.
202
+
اگر بر روی یک دکمه کلیک کنیم مقدار آن افزایش مییابد. اینجا روش کلی مهم است نه دکمه ها.
206
203
207
-
There can be as many attributes with`data-counter`as we want. We can add new ones to HTML at any moment. Using the event delegation we "extended" HTML, added an attribute that describes a new behavior.
204
+
ممکن است هر تعداد اتریبیوت با مقدار`data-counter`که بخواهیم داشته باشیم. هر زمان که بخواهیم میتوانیم یکی دیگه اضافه کنیم. با استفاده از الگوی event delegation با افزودن یک اتریبیوت که بیانگر رفتاری جدید است HTML را گسترش دادیم.
When we assign an event handler to the `document` object, we should always use `addEventListener`, not `document.on<event>`, because the latter will cause conflicts: new handlers overwrite old ones.
208
+
زمانی که یک ایونت هندلر را به آبجکت `document` اختصاص میدهیم، همواره باید از `addEventListener` استفاده کنیم، نه `document.on<event>` چون دومی موجب کانفلیکت خواهد شد: هندلرهای جدید جایگزین قدیمیها خواهند شد.
211
209
212
-
For real projects it's normal that there are many handlers on `document`set by different parts of the code.
210
+
برای پروژههای واقعی طبیعتا ممکن است هندلرهای زیادی روی `document`در قسمتهای مختلف کد تعریف شده باشد.
213
211
```
214
212
215
-
### Behavior: Toggler
213
+
### رفتار: تغییر وضعیت
216
214
217
-
One more example of behavior. A click on an element with the attribute `data-toggle-id` will show/hide the element with the given `id`:
215
+
یک مثال دیگر از این رفتار. یک کلیک بر روی المنتی با اتریبیوت `data-toggle-id` المنتی با `id` داده شده را نمایش/پنهان میکند.
218
216
219
217
```html autorun run height=60
220
218
<button *!*data-toggle-id="subscribe-mail"*/!*>
@@ -239,13 +237,13 @@ One more example of behavior. A click on an element with the attribute `data-tog
239
237
</script>
240
238
```
241
239
242
-
Let's note once again what we did. Now, to add toggling functionality to an element -- there's no need to know JavaScript, just use the attribute`data-toggle-id`.
240
+
بیاید تا یک بار دیگه به کاری که انجام دادیم توجه کنیم. حالا برای افزودن کارکرد تغییر وضعیت به یک المنت نیازی به دانستن جاوااسکریپت نداریم، تنها با استفاده از اتریبیوت`data-toggle-id` میتوان اینکار را انجام داد.
243
241
244
-
That may become really convenient -- no need to write JavaScript for every such element. Just use the behavior. The document-level handler makes it work for any element of the page.
242
+
این ممکن است خیلی کار مارا راحت کند. نیازی به نوشتن جاوااسکریپت برای هر المنت نیست. تنها با استفاده از رفتار. هندلری که به وسعت داکیومنت تعریف کردیم باعث میشود راه حل ما برای همهی المنتهای داخل صفحه کار کند.
245
243
246
-
We can combine multiple behaviors on a single element as well.
244
+
همچنین میتوانیم چندین رفتار را برای یک المنت ترکیب کنیم.
247
245
248
-
The "behavior" pattern can be an alternative to mini-fragments of JavaScript.
246
+
الگوی "رفتار" میتواند یک جایگزین برای mini fragment های جاوااسکریپت باشد.
249
247
250
248
## خلاصه
251
249
@@ -261,15 +259,15 @@ The "behavior" pattern can be an alternative to mini-fragments of JavaScript.
261
259
262
260
فواید:
263
261
264
-
```compare
262
+
```مقایسه
265
263
+ عدم نیاز به اضافه کردن تعداد زیادی هندلر باعث ذخیره حافظه و سادهسازی شروع میشود
266
264
+ کد کمتر: زمان اضافه و کم کردن المانها نیازی به تغییر در هندلرها نیست.
267
265
+ تغییرات DOM: میتواینم با استفاده از `innerHTML` و ابزارهای مشابه آن تعداد زیادی المان را کم/زیاد کنیم.
268
266
```
269
267
270
268
بدون شک این الگو هم محدودیتهای خودش را دارد:
271
269
272
-
```compare
273
-
- First, the event must be bubbling. Some events do not bubble. Also, low-level handlers should not use `event.stopPropagation()`.
274
-
- Second, the delegation may add CPU load, because the container-level handler reacts on events in any place of the container, no matter whether they interest us or not. But usually the load is negligible, so we don't take it into account.
270
+
```مقایسه
271
+
- نخست ایونت باید bubble کند. بعضی از ایونتها bubble نمیکنند. همچنین هندلرهای سطح پایین نباید از `event.stopPropagation()` استفاده کنند.
272
+
- دوم اینکه ممکن است به بار CPU اضافه کند چون هندلری که در سطح کانتینر تعریف شده است، درهرکجای کانتینر، بدون توجه به اینکه آیا مدنظر ما هستند یا نه به رویدادها واکنش نشان خواهد داد. اما این بار CPU معمولا قابل چشمپوشی است بنابراین ما آنرا به حساب نمیآوریم.
0 commit comments