diff --git a/2-ui/2-events/03-event-delegation/1-hide-message-delegate/task.md b/2-ui/2-events/03-event-delegation/1-hide-message-delegate/task.md index 62c0a8ab0..74107b2b4 100644 --- a/2-ui/2-events/03-event-delegation/1-hide-message-delegate/task.md +++ b/2-ui/2-events/03-event-delegation/1-hide-message-delegate/task.md @@ -2,12 +2,12 @@ importance: 5 --- -# Hide messages with delegation +# إخفاء الرسائل باستخدام التفويض -There's a list of messages with removal buttons `[x]`. Make the buttons work. +هناك قائمة بالرسائل مع أزرار إزالة `[x]`. اجعل الأزرار تعمل. -Like this: +مثل هذا: [iframe src="solution" height=420] -P.S. Should be only one event listener on the container, use event delegation. +ملاحظة: يجب أن يكون هناك مستمع واحد فقط للحدث على الحاوية ، استخدم تفويض الحدث. diff --git a/2-ui/2-events/03-event-delegation/2-sliding-tree/solution.md b/2-ui/2-events/03-event-delegation/2-sliding-tree/solution.md index 09c14a08c..d4b52b21f 100644 --- a/2-ui/2-events/03-event-delegation/2-sliding-tree/solution.md +++ b/2-ui/2-events/03-event-delegation/2-sliding-tree/solution.md @@ -1,4 +1,4 @@ -The solution has two parts. +الحل له جزأين. -1. Wrap every tree node title into ``. Then we can CSS-style them on `:hover` and handle clicks exactly on text, because `` width is exactly the text width (unlike without it). -2. Set a handler to the `tree` root node and handle clicks on that `` titles. +1. قم بلف كل عنوان عقدة شجرة في ``. ثم يمكننا تصميم CSS عليها على `:hover` والتعامل مع النقرات بالضبط على النص ، لأن عرض `` هو بالضبط عرض النص (على عكس بدونه). +2. قم بتعيين معالج لعقدة الجذر `tree` وتعامل مع النقرات على تلك العناوين ``. diff --git a/2-ui/2-events/03-event-delegation/2-sliding-tree/task.md b/2-ui/2-events/03-event-delegation/2-sliding-tree/task.md index bdcf2a510..e211373a9 100644 --- a/2-ui/2-events/03-event-delegation/2-sliding-tree/task.md +++ b/2-ui/2-events/03-event-delegation/2-sliding-tree/task.md @@ -2,13 +2,13 @@ importance: 5 --- -# Tree menu +# قائمة الشجرة -Create a tree that shows/hides node children on click: +قم بإنشاء شجرة تعرض / تخفي عقد الأطفال عند النقر: [iframe border=1 src="solution"] -Requirements: +المتطلبات: -- Only one event handler (use delegation) -- A click outside the node title (on an empty space) should not do anything. +- معالج واحد فقط للحدث (استخدم التفويض) +- يجب ألا يؤدي النقر خارج عنوان العقدة (على مساحة فارغة) إلى أي شيء. diff --git a/2-ui/2-events/03-event-delegation/3-sortable-table/task.md b/2-ui/2-events/03-event-delegation/3-sortable-table/task.md index ec85a473c..b1a772307 100644 --- a/2-ui/2-events/03-event-delegation/3-sortable-table/task.md +++ b/2-ui/2-events/03-event-delegation/3-sortable-table/task.md @@ -2,42 +2,42 @@ importance: 4 --- -# Sortable table +# جدول قابل للفرز -Make the table sortable: clicks on `` elements should sort it by corresponding column. +اجعل الجدول قابلًا للفرز: يجب أن تقوم النقرات على عناصر `` بفرزه حسب العمود المقابل. -Each `` has the type in the attribute, like this: +كل `` لديه النوع في السمة ، مثل هذا: ```html *!* - - + + */!* - + - + ...
AgeNameالعمرالاسم
5Johnجون
10Annآن
``` -In the example above the first column has numbers, and the second one -- strings. The sorting function should handle sort according to the type. +في المثال أعلاه ، يحتوي العمود الأول على أرقام ، والثاني - على سلاسل. يجب أن تتعامل وظيفة الفرز مع الترتيب وفقًا للنوع. -Only `"string"` and `"number"` types should be supported. +يجب دعم أنواع `"string"` و `"number"` فقط. -The working example: +المثال العامل: [iframe border=1 src="solution" height=190] -P.S. The table can be big, with any number of rows and columns. +ملاحظة: يمكن أن يكون الجدول كبيرًا ، بأي عدد من الصفوف والأعمدة. diff --git a/2-ui/2-events/03-event-delegation/4-behavior-tooltip/task.md b/2-ui/2-events/03-event-delegation/4-behavior-tooltip/task.md index 3001b9915..f0e49e280 100644 --- a/2-ui/2-events/03-event-delegation/4-behavior-tooltip/task.md +++ b/2-ui/2-events/03-event-delegation/4-behavior-tooltip/task.md @@ -2,37 +2,37 @@ importance: 5 --- -# Tooltip behavior +# سلوك التلميح -Create JS-code for the tooltip behavior. +قم بإنشاء كود JS لسلوك التلميح. -When a mouse comes over an element with `data-tooltip`, the tooltip should appear over it, and when it's gone then hide. +عندما يأتي الماوس فوق عنصر مع `data-tooltip` ، يجب أن يظهر التلميح فوقه ، وعندما يذهب يختفي. -An example of annotated HTML: +مثال على HTML المشروح: ```html - - + + ``` -Should work like this: +يجب أن يعمل هكذا: [iframe src="solution" height=200 border=1] -In this task we assume that all elements with `data-tooltip` have only text inside. No nested tags (yet). +في هذه المهمة نفترض أن جميع العناصر مع `data-tooltip` لديها نص فقط بداخلها. لا توجد علامات متداخلة (بعد). -Details: +التفاصيل: -- The distance between the element and the tooltip should be `5px`. -- The tooltip should be centered relative to the element, if possible. -- The tooltip should not cross window edges. Normally it should be above the element, but if the element is at the page top and there's no space for the tooltip, then below it. -- The tooltip content is given in the `data-tooltip` attribute. It can be arbitrary HTML. +- يجب أن يكون المسافة بين العنصر والتلميح `5px`. +- يجب أن يكون التلميح مركزًا بالنسبة للعنصر ، إذا كان ذلك ممكنًا. +- يجب ألا يتجاوز التلميح حواف النافذة. عادةً ما يكون فوق العنصر ، ولكن إذا كان العنصر في أعلى الصفحة ولا يوجد مساحة للتلميح ، فأدناه. +- يتم إعطاء محتوى التلميح في سمة `data-tooltip`. يمكن أن يكون HTML تعسفيًا. -You'll need two events here: -- `mouseover` triggers when a pointer comes over an element. -- `mouseout` triggers when a pointer leaves an element. +ستحتاج إلى حدثين هنا: +- يُطلق الحدث `mouseover` عندما يأتي مؤشر فوق عنصر. +- يُطلق الحدث `mouseout` عندما يغادر المؤشر عنصرًا. -Please use event delegation: set up two handlers on `document` to track all "overs" and "outs" from elements with `data-tooltip` and manage tooltips from there. +يرجى استخدام تفويض الحدث: قم بإعداد معالجين على `document` لتتبع جميع "overs" و "outs" من العناصر مع `data-tooltip` وإدارة التلميحات من هناك. -After the behavior is implemented, even people unfamiliar with JavaScript can add annotated elements. +بعد تنفيذ السلوك ، يمكن حتى للأشخاص غير الملمين بـ JavaScript إضافة عناصر مُلحقة. -P.S. Only one tooltip may show up at a time. +ملاحظة: قد يظهر تلميح واحد فقط في وقت واحد. diff --git a/2-ui/2-events/03-event-delegation/article.md b/2-ui/2-events/03-event-delegation/article.md index 41df9f079..1726b228c 100644 --- a/2-ui/2-events/03-event-delegation/article.md +++ b/2-ui/2-events/03-event-delegation/article.md @@ -1,91 +1,91 @@ -# Event delegation +# تفويض الحدث -Capturing and bubbling allow us to implement one of most powerful event handling patterns called *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. +لنرى مثالًا - [رسم با-غوا](http://en.wikipedia.org/wiki/Ba_gua) يعكس الفلسفة الصينية القديمة. -Here it is: +ها هو: [iframe height=350 src="bagua" edit link] -The HTML is like this: +HTML مثل هذا: ```html - + - + - ...2 more lines of this kind... - ...2 more lines of this kind... + ...2 سطرين إضافيين من هذا النوع ... + ...2 سطرين إضافيين من هذا النوع ...
Bagua Chart: Direction, Element, Color, Meaningجدول Bagua: الاتجاه ، العنصر ، اللون ، المعنى
Northwest
Metal
Silver
Elders
الشمال الغربي
معدن
فضة
كبار السن
... ...
``` -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` لكل `
` (يمكن أن يكون كثيرًا) - سنقوم بإعداد المعالج "الشامل" على عنصر ``. -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 ` ``` -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 `
` 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 *!* - Northwest + الشمال الغربي */!* ... ` or not. +في المعالج `table.onclick` يجب أن نأخذ هذا `event.target` ونعرف ما إذا كان النقر داخل `` أم لا. -Here's the improved code: +هذه هي الشفرة المحسنة: ```js table.onclick = function(event) { @@ -99,33 +99,33 @@ 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 +## مثال التفويض: الإجراءات في الترميز -There are other uses for 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` ... كيفية مطابقتها؟ -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 ``` -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. +يرجى ملاحظة أن `this.onClick` مرتبط بـ `this` في `(*)`. هذا مهم ، لأنه وإلا فإن `this` داخله سيشير إلى عنصر DOM (`elem`) ، وليس كائن `Menu` ، ولن يكون `this[action]` هو ما نحتاجه. -So, what advantages does delegation give us here? +إذن ، ما هي المزايا التي يمنحنا التفويض هنا؟ ```compare -+ 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. -+ The HTML structure is flexible, we can add/remove buttons at any time. ++ ليس علينا كتابة الكود لتعيين معالج لكل زر. فقط قم بعمل طريقة وضعها في الترميز. ++ هيكل HTML مرن ، يمكننا إضافة / إزالة الأزرار في أي وقت. ``` -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. +يمكننا أيضًا استخدام الفئات `.action-save` و `.action-load` ، ولكن السمة `data-action` هي أفضل من الناحية الدلالية. ويمكننا استخدامه في قواعد CSS أيضًا. -## The "behavior" pattern +## نمط "السلوك" -We can also use event delegation to add "behaviors" to elements *declaratively*, with special attributes and classes. +يمكننا أيضًا استخدام تفويض الحدث لإضافة "سلوكيات" إلى العناصر *بشكل تعريفي* ، مع سمات وفئات خاصة. -The pattern has two parts: -1. We add a custom attribute to an element that describes its behavior. -2. A document-wide handler tracks events, and if an event happens on an attributed element -- performs the action. +النمط له جزأين: +1. نضيف سمة مخصصة إلى عنصر يصف سلوكه. +2. يتتبع معالج على مستوى المستند الأحداث ، وإذا حدث حدث على عنصر مسمى - يؤدي الإجراء. -### Behavior: Counter +### السلوك: العداد -For instance, here the attribute `data-counter` adds a behavior: "increase value on click" to buttons: +على سبيل المثال ، هنا تضيف السمة `data-counter` سلوكًا: "زيادة القيمة عند النقر" على الأزرار: ```html run autorun height=60 -Counter: -One more counter: +العداد: +عداد آخر: ``` -If we click a button -- its value is increased. Not buttons, but the general approach is important here. +إذا قمنا بالنقر على زر - يتم زيادة قيمته. ليس الأزرار ، ولكن النهج العام مهم هنا. -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. +يمكن أن يكون هناك العديد من السمات مع `data-counter` كما نريد. يمكننا إضافة جديدة إلى HTML في أي لحظة. باستخدام تفويض الحدث ، "قمنا بتوسيع" HTML ، وأضفنا سمة تصف سلوكًا جديدًا. -```warn header="For document-level handlers -- always `addEventListener`" -When we assign an event handler to the `document` object, we should always use `addEventListener`, not `document.on`, because the latter will cause conflicts: new handlers overwrite old ones. +```warn header="لمعالجات المستندات المستوى - دائمًا `addEventListener`" +عندما نعين معالج حدث على كائن `document` ، يجب علينا دائمًا استخدام `addEventListener` ، وليس ` - Show the subscription form + أظهر نموذج الاشتراك ``` -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`. +لنلاحظ مرة أخرى ما فعلناه. الآن ، لإضافة وظيفة التبديل إلى عنصر - لا حاجة لمعرفة JavaScript ، فقط استخدم السمة `data-toggle-id`. -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. +قد يصبح ذلك مريحًا حقًا - لا حاجة لكتابة JavaScript لكل عنصر من هذا النوع. فقط استخدم السلوك. يجعل المعالج على مستوى المستند عمله لأي عنصر في الصفحة. -We can combine multiple behaviors on a single element as well. +يمكننا دمج سلوكيات متعددة على عنصر واحد أيضًا. -The "behavior" pattern can be an alternative to mini-fragments of JavaScript. +يمكن أن يكون نمط "السلوك" بديلاً للشظايا الصغيرة من JavaScript. -## Summary +## ملخص -Event delegation is really cool! It's one of the most helpful patterns for DOM events. +تفويض الحدث رائع حقًا! إنه واحد من أكثر الأنماط المفيدة لأحداث DOM. -It's often used to add the same handling for many similar elements, but not only for that. +غالبًا ما يتم استخدامه لإضافة نفس المعالجة للعديد من العناصر المتشابهة ، ولكن ليس فقط لذلك. -The algorithm: +الخوارزمية: -1. Put a single handler on the container. -2. In the handler -- check the source element `event.target`. -3. If the event happened inside an element that interests us, then handle the event. +1. ضع معالج واحد على الحاوية. +2. في المعالج - تحقق من عنصر المصدر `event.target`. +3. إذا حدث الحدث داخل عنصر يهمنا ، فقم بمعالجة الحدث. -Benefits: +الفوائد: ```compare -+ Simplifies initialization and saves memory: no need to add many handlers. -+ Less code: when adding or removing elements, no need to add/remove handlers. -+ DOM modifications: we can mass add/remove elements with `innerHTML` and the like. ++ يبسط التهيئة ويوفر الذاكرة: لا حاجة لإضافة العديد من المعالجات. ++ أقل كود: عند إضافة أو إزالة عناصر ، لا حاجة لإضافة / إزالة المعالجات. ++ تعديلات DOM: يمكننا إضافة / إزالة عناصر بكتلة مع `innerHTML` وما شابه. ``` -The delegation has its limitations of course: +بالطبع للتفويض قيوده: ```compare -- First, the event must be bubbling. Some events do not bubble. Also, low-level handlers should not use `event.stopPropagation()`. -- 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. +- أولاً ، يجب أن يكون الحدث فقاعيًا. بعض الأحداث لا تتدفق. أيضًا ، يجب على المعالجات المنخفضة المستوى عدم استخدام `()event.stopPropagation`. +- ثانيًا ، قد يضيف التفويض حملًا على وحدة المعالجة المركزية ، لأن معالج المستوى الحاوية يتفاعل مع الأحداث في أي مكان من الحاوية ، بغض النظر عما إذا كانت تهمنا أم لا. ولكن عادة ما يكون الحمل ضئيلًا ، لذلك لا نأخذه في الاعتبار. ```