Skip to content

Commit b3163e9

Browse files
committed
translate Event delegation article
1 parent 1a65e45 commit b3163e9

File tree

1 file changed

+90
-90
lines changed

1 file changed

+90
-90
lines changed
Lines changed: 90 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,91 @@
11

2-
# Event delegation
2+
# تفويض الحدث
33

4-
Capturing and bubbling allow us to implement one of most powerful event handling patterns called *event delegation*.
4+
يسمح لنا التقاط والتدفق بتنفيذ أحد أنماط معالجة الأحداث الأكثر قوة المسمى *تفويض الحدث*.
55

6-
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.
6+
الفكرة هي أنه إذا كان لدينا الكثير من العناصر المعالجة بطريقة مماثلة ، فبدلاً من تعيين معالج لكل منها - نضع معالجًا واحدًا على سلفهم المشترك.
77

8-
In the handler we get `event.target` to see where the event actually happened and handle it.
8+
في المعالج نحصل على `event.target` لمعرفة المكان الذي حدث فيه الحدث فعليًا ومعالجته.
99

10-
Let's see an example -- the [Ba-Gua diagram](http://en.wikipedia.org/wiki/Ba_gua) reflecting the ancient Chinese philosophy.
10+
لنرى مثالًا - [رسم با-غوا](http://en.wikipedia.org/wiki/Ba_gua) يعكس الفلسفة الصينية القديمة.
1111

12-
Here it is:
12+
ها هو:
1313

1414
[iframe height=350 src="bagua" edit link]
1515

16-
The HTML is like this:
16+
HTML مثل هذا:
1717

1818
```html
1919
<table>
2020
<tr>
21-
<th colspan="3"><em>Bagua</em> Chart: Direction, Element, Color, Meaning</th>
21+
<th colspan="3">جدول <em>Bagua</em>: الاتجاه ، العنصر ، اللون ، المعنى</th>
2222
</tr>
2323
<tr>
24-
<td class="nw"><strong>Northwest</strong><br>Metal<br>Silver<br>Elders</td>
24+
<td class="nw"><strong>الشمال الغربي</strong><br>معدن<br>فضة<br>كبار السن</td>
2525
<td class="n">...</td>
2626
<td class="ne">...</td>
2727
</tr>
28-
<tr>...2 more lines of this kind...</tr>
29-
<tr>...2 more lines of this kind...</tr>
28+
<tr>...2 سطرين إضافيين من هذا النوع ...</tr>
29+
<tr>...2 سطرين إضافيين من هذا النوع ...</tr>
3030
</table>
3131
```
3232

33-
The table has 9 cells, but there could be 99 or 9999, doesn't matter.
33+
الجدول يحتوي على 9 خلايا ، لكن يمكن أن يكون هناك 99 أو 9999 ، لا يهم.
3434

35-
**Our task is to highlight a cell `<td>` on click.**
35+
**مهمتنا هي تسليط الضوء على الخلية `<td>` عند النقر.**
3636

37-
Instead of assign an `onclick` handler to each `<td>` (can be many) -- we'll setup the "catch-all" handler on `<table>` element.
37+
بدلاً من تعيين معالج `onclick` لكل `<td>` (يمكن أن يكون كثيرًا) - سنقوم بإعداد المعالج "الشامل" على عنصر `<table>`.
3838

39-
It will use `event.target` to get the clicked element and highlight it.
39+
سيستخدم `event.target` للحصول على العنصر المُنقر عليه وتسليط الضوء عليه.
4040

41-
The code:
41+
الشفرة:
4242

4343
```js
4444
let selectedTd;
4545

4646
*!*
4747
table.onclick = function(event) {
48-
let target = event.target; // where was the click?
48+
let target = event.target; // أين كان النقر؟
4949

50-
if (target.tagName != 'TD') return; // not on TD? Then we're not interested
50+
if (target.tagName != 'TD') return; // ليس على TD؟ إذن لسنا مهتمين
5151

52-
highlight(target); // highlight it
52+
highlight(target); // تسليط الضوء عليه
5353
};
5454
*/!*
5555

5656
function highlight(td) {
57-
if (selectedTd) { // remove the existing highlight if any
57+
if (selectedTd) { // إزالة التسليط الحالي إن وجد
5858
selectedTd.classList.remove('highlight');
5959
}
6060
selectedTd = td;
61-
selectedTd.classList.add('highlight'); // highlight the new td
61+
selectedTd.classList.add('highlight'); // تسليط الضوء على td الجديد
6262
}
6363
```
6464

65-
Such a code doesn't care how many cells there are in the table. We can add/remove `<td>` dynamically at any time and the highlighting will still work.
65+
لا يهتم هذا الكود بعدد الخلايا الموجودة في الجدول. يمكننا إضافة / إزالة `<td>` ديناميكيًا في أي وقت وسيظل التسليط يعمل.
6666

67-
Still, there's a drawback.
67+
مع ذلك ، هناك عيب.
6868

69-
The click may occur not on the `<td>`, but inside it.
69+
قد يحدث النقر ليس على `<td>` ، ولكن داخله.
7070

71-
In our case if we take a look inside the HTML, we can see nested tags inside `<td>`, like `<strong>`:
71+
في حالتنا إذا نظرنا داخل HTML ، يمكننا رؤية علامات متداخلة داخل `<td>` ، مثل `<strong>`:
7272

7373
```html
7474
<td>
7575
*!*
76-
<strong>Northwest</strong>
76+
<strong>الشمال الغربي</strong>
7777
*/!*
7878
...
7979
</td>
8080
```
8181

82-
Naturally, if a click happens on that `<strong>` then it becomes the value of `event.target`.
82+
بطبيعة الحال ، إذا حدث نقر على هذا `<strong>` فإنه يصبح قيمة `event.target`.
8383

8484
![](bagua-bubble.svg)
8585

86-
In the handler `table.onclick` we should take such `event.target` and find out whether the click was inside `<td>` or not.
86+
في المعالج `table.onclick` يجب أن نأخذ هذا `event.target` ونعرف ما إذا كان النقر داخل `<td>` أم لا.
8787

88-
Here's the improved code:
88+
هذه هي الشفرة المحسنة:
8989

9090
```js
9191
table.onclick = function(event) {
@@ -99,33 +99,33 @@ table.onclick = function(event) {
9999
};
100100
```
101101

102-
Explanations:
103-
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.
104-
2. If `event.target` is not inside any `<td>`, then the call returns immediately, as there's nothing to do.
105-
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>`.
106-
4. And, if it's so, then highlight it.
102+
تفسيرات:
103+
1. يعيد الأسلوب `elem.closest(selector)` السلف الأقرب الذي يطابق المحدد. في حالتنا نبحث عن `<td>` في الطريق لأعلى من العنصر المصدر.
104+
2. إذا لم يكن `event.target` داخل أي `<td>` ، فإن الاستدعاء يعود فورًا ، لأنه لا يوجد شيء يمكن القيام به.
105+
3. في حالة الجداول المتداخلة ، قد يكون `event.target` هو `<td>` ، ولكن يكمن خارج الجدول الحالي. لذلك نتحقق مما إذا كان هذا هو `<td>` *لجدولنا* فعلاً.
106+
4. وإذا كان كذلك ، فتسلط الضوء عليه.
107107

108-
As the result, we have a fast, efficient highlighting code, that doesn't care about the total number of `<td>` in the table.
108+
وبالتالي ، لدينا رمز تسليط سريع وفعال ، لا يهتم بإجمالي عدد `<td>` في الجدول.
109109

110-
## Delegation example: actions in markup
110+
## مثال التفويض: الإجراءات في الترميز
111111

112-
There are other uses for event delegation.
112+
هناك استخدامات أخرى لتفويض الحدث.
113113

114-
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?
114+
لنقل ، نريد عمل قائمة بأزرار "حفظ" و "تحميل" و "بحث" وما إلى ذلك. وهناك كائن به طرق `save` و `load` و `search` ... كيفية مطابقتها؟
115115

116-
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:
116+
قد تكون الفكرة الأولى هي تعيين معالج منفصل لكل زر. لكن هناك حلاً أكثر أناقة. يمكننا إضافة معالج للقائمة بأكملها وسمات `data-action` للأزرار التي لديها الطريقة المطلوب استدعاؤها:
117117

118118
```html
119-
<button *!*data-action="save"*/!*>Click to Save</button>
119+
<button *!*data-action="save"*/!*>انقر للحفظ</button>
120120
```
121121

122-
The handler reads the attribute and executes the method. Take a look at the working example:
122+
يقرأ المعالج السمة وينفذ الطريقة. ألق نظرة على المثال العامل:
123123

124124
```html autorun height=60 run untrusted
125125
<div id="menu">
126-
<button data-action="save">Save</button>
127-
<button data-action="load">Load</button>
128-
<button data-action="search">Search</button>
126+
<button data-action="save">حفظ</button>
127+
<button data-action="load">تحميل</button>
128+
<button data-action="search">بحث</button>
129129
</div>
130130

131131
<script>
@@ -136,15 +136,15 @@ The handler reads the attribute and executes the method. Take a look at the work
136136
}
137137
138138
save() {
139-
alert('saving');
139+
alert('جاري الحفظ');
140140
}
141141
142142
load() {
143-
alert('loading');
143+
alert('جاري التحميل');
144144
}
145145
146146
search() {
147-
alert('searching');
147+
alert('جاري البحث');
148148
}
149149
150150
onClick(event) {
@@ -161,65 +161,65 @@ The handler reads the attribute and executes the method. Take a look at the work
161161
</script>
162162
```
163163

164-
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]` هو ما نحتاجه.
165165

166-
So, what advantages does delegation give us here?
166+
إذن ، ما هي المزايا التي يمنحنا التفويض هنا؟
167167

168168
```compare
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.
170-
+ The HTML structure is flexible, we can add/remove buttons at any time.
169+
+ ليس علينا كتابة الكود لتعيين معالج لكل زر. فقط قم بعمل طريقة وضعها في الترميز.
170+
+ هيكل HTML مرن ، يمكننا إضافة / إزالة الأزرار في أي وقت.
171171
```
172172

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.
173+
يمكننا أيضًا استخدام الفئات `.action-save` و `.action-load` ، ولكن السمة `data-action` هي أفضل من الناحية الدلالية. ويمكننا استخدامه في قواعد CSS أيضًا.
174174

175-
## The "behavior" pattern
175+
## نمط "السلوك"
176176

177-
We can also use event delegation to add "behaviors" to elements *declaratively*, with special attributes and classes.
177+
يمكننا أيضًا استخدام تفويض الحدث لإضافة "سلوكيات" إلى العناصر *بشكل تعريفي* ، مع سمات وفئات خاصة.
178178

179-
The pattern has two parts:
180-
1. We add a custom attribute to an element that describes its behavior.
181-
2. A document-wide handler tracks events, and if an event happens on an attributed element -- performs the action.
179+
النمط له جزأين:
180+
1. نضيف سمة مخصصة إلى عنصر يصف سلوكه.
181+
2. يتتبع معالج على مستوى المستند الأحداث ، وإذا حدث حدث على عنصر مسمى - يؤدي الإجراء.
182182

183-
### Behavior: Counter
183+
### السلوك: العداد
184184

185-
For instance, here the attribute `data-counter` adds a behavior: "increase value on click" to buttons:
185+
على سبيل المثال ، هنا تضيف السمة `data-counter` سلوكًا: "زيادة القيمة عند النقر" على الأزرار:
186186

187187
```html run autorun height=60
188-
Counter: <input type="button" value="1" data-counter>
189-
One more counter: <input type="button" value="2" data-counter>
188+
العداد: <input type="button" value="1" data-counter>
189+
عداد آخر: <input type="button" value="2" data-counter>
190190

191191
<script>
192192
document.addEventListener('click', function(event) {
193193
194-
if (event.target.dataset.counter != undefined) { // if the attribute exists...
195-
event.target.value++;
194+
if (event.target.dataset.counter != undefined) { // إذا كانت السمة موجودة ...
195+
event.target.value++;
196196
}
197197
198198
});
199199
</script>
200200
```
201201

202-
If we click a button -- its value is increased. Not buttons, but the general approach is important here.
202+
إذا قمنا بالنقر على زر - يتم زيادة قيمته. ليس الأزرار ، ولكن النهج العام مهم هنا.
203203

204-
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` كما نريد. يمكننا إضافة جديدة إلى HTML في أي لحظة. باستخدام تفويض الحدث ، "قمنا بتوسيع" HTML ، وأضفنا سمة تصف سلوكًا جديدًا.
205205

206-
```warn header="For document-level handlers -- always `addEventListener`"
207-
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.
206+
```warn header="لمعالجات المستندات المستوى - دائمًا `addEventListener`"
207+
عندما نعين معالج حدث على كائن `document` ، يجب علينا دائمًا استخدام `addEventListener` ، وليس `<document.on<event` ، لأن الأخير سيسبب تعارضات: المعالجات الجديدة تكتب فوق القديمة.
208208

209-
For real projects it's normal that there are many handlers on `document` set by different parts of the code.
209+
بالنسبة للمشاريع الحقيقية ، فمن الطبيعي أن يكون هناك العديد من المعالجات على `document` التي تم تعيينها بواسطة أجزاء مختلفة من الكود.
210210
```
211211
212-
### Behavior: Toggler
212+
### السلوك: المفتاح
213213
214-
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`:
214+
مثال آخر على السلوك. سيعرض / يخفي النقر على عنصر بسمة `data-toggle-id` العنصر بالمعرف المعطى:
215215
216216
```html autorun run height=60
217217
<button *!*data-toggle-id="subscribe-mail"*/!*>
218-
Show the subscription form
218+
أظهر نموذج الاشتراك
219219
</button>
220220
221221
<form id="subscribe-mail" hidden>
222-
Your mail: <input type="email">
222+
بريدك: <input type="email">
223223
</form>
224224
225225
<script>
@@ -236,37 +236,37 @@ One more example of behavior. A click on an element with the attribute `data-tog
236236
</script>
237237
```
238238

239-
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`.
239+
لنلاحظ مرة أخرى ما فعلناه. الآن ، لإضافة وظيفة التبديل إلى عنصر - لا حاجة لمعرفة JavaScript ، فقط استخدم السمة `data-toggle-id`.
240240

241-
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.
241+
قد يصبح ذلك مريحًا حقًا - لا حاجة لكتابة JavaScript لكل عنصر من هذا النوع. فقط استخدم السلوك. يجعل المعالج على مستوى المستند عمله لأي عنصر في الصفحة.
242242

243-
We can combine multiple behaviors on a single element as well.
243+
يمكننا دمج سلوكيات متعددة على عنصر واحد أيضًا.
244244

245-
The "behavior" pattern can be an alternative to mini-fragments of JavaScript.
245+
يمكن أن يكون نمط "السلوك" بديلاً للشظايا الصغيرة من JavaScript.
246246

247-
## Summary
247+
## ملخص
248248

249-
Event delegation is really cool! It's one of the most helpful patterns for DOM events.
249+
تفويض الحدث رائع حقًا! إنه واحد من أكثر الأنماط المفيدة لأحداث DOM.
250250

251-
It's often used to add the same handling for many similar elements, but not only for that.
251+
غالبًا ما يتم استخدامه لإضافة نفس المعالجة للعديد من العناصر المتشابهة ، ولكن ليس فقط لذلك.
252252

253-
The algorithm:
253+
الخوارزمية:
254254

255-
1. Put a single handler on the container.
256-
2. In the handler -- check the source element `event.target`.
257-
3. If the event happened inside an element that interests us, then handle the event.
255+
1. ضع معالج واحد على الحاوية.
256+
2. في المعالج - تحقق من عنصر المصدر `event.target`.
257+
3. إذا حدث الحدث داخل عنصر يهمنا ، فقم بمعالجة الحدث.
258258

259-
Benefits:
259+
الفوائد:
260260

261261
```compare
262-
+ Simplifies initialization and saves memory: no need to add many handlers.
263-
+ Less code: when adding or removing elements, no need to add/remove handlers.
264-
+ DOM modifications: we can mass add/remove elements with `innerHTML` and the like.
262+
+ يبسط التهيئة ويوفر الذاكرة: لا حاجة لإضافة العديد من المعالجات.
263+
+ أقل كود: عند إضافة أو إزالة عناصر ، لا حاجة لإضافة / إزالة المعالجات.
264+
+ تعديلات DOM: يمكننا إضافة / إزالة عناصر بكتلة مع `innerHTML` وما شابه.
265265
```
266266

267-
The delegation has its limitations of course:
267+
بالطبع للتفويض قيوده:
268268

269269
```compare
270-
- First, the event must be bubbling. Some events do not bubble. Also, low-level handlers should not use `event.stopPropagation()`.
271-
- 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+
- أولاً ، يجب أن يكون الحدث فقاعيًا. بعض الأحداث لا تتدفق. أيضًا ، يجب على المعالجات المنخفضة المستوى عدم استخدام `()event.stopPropagation`.
271+
- ثانيًا ، قد يضيف التفويض حملًا على وحدة المعالجة المركزية ، لأن معالج المستوى الحاوية يتفاعل مع الأحداث في أي مكان من الحاوية ، بغض النظر عما إذا كانت تهمنا أم لا. ولكن عادة ما يكون الحمل ضئيلًا ، لذلك لا نأخذه في الاعتبار.
272272
```

0 commit comments

Comments
 (0)