From 8957ff71793a25f0b9823aa9f784ace56ec6b4d4 Mon Sep 17 00:00:00 2001 From: salah elhossiny Date: Fri, 5 Jun 2020 19:57:02 +0200 Subject: [PATCH 1/3] capturing groups --- .../11-regexp-groups/article.md | 204 +++++++++--------- 1 file changed, 102 insertions(+), 102 deletions(-) diff --git a/9-regular-expressions/11-regexp-groups/article.md b/9-regular-expressions/11-regexp-groups/article.md index 6fdf727a8..97cee4ac2 100644 --- a/9-regular-expressions/11-regexp-groups/article.md +++ b/9-regular-expressions/11-regexp-groups/article.md @@ -1,31 +1,31 @@ -# Capturing groups +# التقاط المجموعات -A part of a pattern can be enclosed in parentheses `pattern:(...)`. This is called a "capturing group". +يمكن وضع جزء من النموذج بين قوسين `نمط: (...)`. وهذا ما يسمى "مجموعة أسر". -That has two effects: +هذا له تأثيران: -1. It allows to get a part of the match as a separate item in the result array. -2. If we put a quantifier after the parentheses, it applies to the parentheses as a whole. +1. يسمح بالحصول على جزء من المباراة كبند منفصل في مصفوفة النتائج. +2. إذا وضعنا كمياً بعد الأقواس ، فإنه ينطبق على الأقواس ككل. -## Examples +## الأمثلة -Let's see how parentheses work in examples. +دعونا نرى كيف تعمل الأقواس في الأمثلة. -### Example: gogogo +### مثال: gogogo -Without parentheses, the pattern `pattern:go+` means `subject:g` character, followed by `subject:o` repeated one or more times. For instance, `match:goooo` or `match:gooooooooo`. +بدون قوسين ، فإن النمط `النمط: go +` يعني `الموضوع: g` ، متبوعًا بـ` الموضوع: o` مكررًا مرة واحدة أو أكثر. على سبيل المثال ، `match: goooo` أو` match: gooooooooo`. -Parentheses group characters together, so `pattern:(go)+` means `match:go`, `match:gogo`, `match:gogogo` and so on. +تجمع الأقواس الأحرف معًا ، لذا `النمط: (go) +` يعني `match: go` و` match: gogo` و `match: gogogo` وما إلى ذلك. ```js run alert( 'Gogogo now!'.match(/(go)+/i) ); // "Gogogo" ``` -### Example: domain +### مثال: المجال -Let's make something more complex -- a regular expression to search for a website domain. +دعونا نجعل شيئًا أكثر تعقيدًا - تعبيرًا عاديًا للبحث عن نطاق موقع ويب. -For example: +فمثلا: ``` mail.com @@ -33,9 +33,9 @@ users.mail.com smith.users.mail.com ``` -As we can see, a domain consists of repeated words, a dot after each one except the last one. +كما نرى ، المجال يتكون من كلمات متكررة ، نقطة بعد كل واحدة باستثناء الأخيرة. -In regular expressions that's `pattern:(\w+\.)+\w+`: +في التعبيرات العادية هذا `نمط: (\ w + \.) + \ w +`: ```js run let regexp = /(\w+\.)+\w+/g; @@ -43,17 +43,17 @@ let regexp = /(\w+\.)+\w+/g; alert( "site.com my.site.com".match(regexp) ); // site.com,my.site.com ``` -The search works, but the pattern can't match a domain with a hyphen, e.g. `my-site.com`, because the hyphen does not belong to class `pattern:\w`. +يعمل البحث ، ولكن لا يمكن أن يتطابق النمط مع النطاق بواصلة ، على سبيل المثال `my-site.com` ، لأن الواصلة لا تنتمي إلى النمط` class: \ w`. -We can fix it by replacing `pattern:\w` with `pattern:[\w-]` in every word except the last one: `pattern:([\w-]+\.)+\w+`. +يمكننا إصلاحه عن طريق استبدال `pattern: \ w` بـ` pattern: [\ w-] `في كل كلمة باستثناء الكلمة الأخيرة:` pattern: ([\ w -] + \.) + \ w + `. -### Example: email +### مثال: البريد الإلكتروني -The previous example can be extended. We can create a regular expression for emails based on it. +يمكن توسيع المثال السابق. يمكننا إنشاء تعبير عادي للرسائل الإلكترونية بناءً عليه. -The email format is: `name@domain`. Any word can be the name, hyphens and dots are allowed. In regular expressions that's `pattern:[-.\w]+`. +تنسيق البريد الإلكتروني هو: `name @ domain`. يمكن أن تكون أي كلمة الاسم والواصلات والنقاط مسموحًا بها. في التعبيرات العادية هذا `النمط: [-. \ w] +`. -The pattern: +النمط: ```js run let regexp = /[-.\w]+@([\w-]+\.)+[\w-]+/g; @@ -61,24 +61,24 @@ let regexp = /[-.\w]+@([\w-]+\.)+[\w-]+/g; alert("my@mail.com @ his@site.com.uk".match(regexp)); // my@mail.com, his@site.com.uk ``` -That regexp is not perfect, but mostly works and helps to fix accidental mistypes. The only truly reliable check for an email can only be done by sending a letter. +هذا التعبير العادي ليس مثاليًا ، ولكنه يعمل في الغالب ويساعد على إصلاح الأخطاء العرضية. لا يمكن إجراء الاختيار الوحيد الموثوق به حقًا للبريد الإلكتروني إلا عن طريق إرسال بريد إلكتروني. -## Parentheses contents in the match +## أقواس المحتويات في المباراة -Parentheses are numbered from left to right. The search engine memorizes the content matched by each of them and allows to get it in the result. +الأقواس مرقمة من اليسار إلى اليمين. يحفظ محرك البحث المحتوى المطابق لكل منها ويسمح بالحصول عليه في النتيجة. -The method `str.match(regexp)`, if `regexp` has no flag `g`, looks for the first match and returns it as an array: +الطريقة `str.match (regexp)` ، إذا لم يكن لـ `regexp` علامة` g` ، فابحث عن المطابقة الأولى وترجعها كمصفوفة: -1. At index `0`: the full match. -2. At index `1`: the contents of the first parentheses. -3. At index `2`: the contents of the second parentheses. -4. ...and so on... +1. في الفهرس `0`: المباراة الكاملة. +2. في الفهرس `1`: محتويات الأقواس الأولى. +3. في الفهرس `2`: محتويات الأقواس الثانية. +4. ... وهكذا ... -For instance, we'd like to find HTML tags `pattern:<.*?>`, and process them. It would be convenient to have tag content (what's inside the angles), in a separate variable. +على سبيل المثال ، نود العثور على علامات HTML `pattern: <. *؟>` ، ومعالجتها. سيكون من المناسب وجود محتوى علامة (ما يوجد داخل الزوايا) ، في متغير منفصل. -Let's wrap the inner content into parentheses, like this: `pattern:<(.*?)>`. +دعونا نلف المحتوى الداخلي بين قوسين ، مثل هذا: `pattern: <(. *؟)>`. -Now we'll get both the tag as a whole `match:

` and its contents `match:h1` in the resulting array: +الآن سنحصل على كل من العلامة على أنها `مطابقة كاملة:

` ومحتوياتها `مطابقة: h1` في الصفيف الناتج: ```js run let str = '

Hello, world!

'; @@ -89,19 +89,19 @@ alert( tag[0] ); //

alert( tag[1] ); // h1 ``` -### Nested groups +### المجموعات المتداخلة -Parentheses can be nested. In this case the numbering also goes from left to right. +يمكن أن تتداخل الأقواس. في هذه الحالة ، ينتقل الترقيم أيضًا من اليسار إلى اليمين. -For instance, when searching a tag in `subject:` we may be interested in: +على سبيل المثال ، عند البحث عن علامة في `الموضوع: ` قد نكون مهتمين بما يلي: -1. The tag content as a whole: `match:span class="my"`. -2. The tag name: `match:span`. -3. The tag attributes: `match:class="my"`. +1. محتوى العلامة ككل: `match: span class =" my "`. +2. اسم العلامة: `match: span`. +3. سمات العلامة: `match: class =" my "`. -Let's add parentheses for them: `pattern:<(([a-z]+)\s*([^>]*))>`. +دعونا نضيف أقواسًا لهم: `pattern: <(([a-z] +) \ s * ([^>] *))>`. -Here's how they are numbered (left to right, by the opening paren): +إليك كيفية ترقيمها (من اليسار إلى اليمين ، عن طريق قوس الافتتاح): ![](regexp-nested-groups-pattern.svg) @@ -119,23 +119,23 @@ alert(result[2]); // span alert(result[3]); // class="my" ``` -The zero index of `result` always holds the full match. +دائمًا ما يحمل الفهرس الصفري "النتيجة" المطابقة الكاملة. -Then groups, numbered from left to right by an opening paren. The first group is returned as `result[1]`. Here it encloses the whole tag content. +ثم المجموعات ، مرقمة من اليسار إلى اليمين بواسطة قوس افتتاح. تم إرجاع المجموعة الأولى على أنها `نتيجة [1]`. هنا يرفق محتوى العلامة بالكامل. -Then in `result[2]` goes the group from the second opening paren `pattern:([a-z]+)` - tag name, then in `result[3]` the tag: `pattern:([^>]*)`. +ثم في `النتيجة [2]` تنتقل المجموعة من نمط `` الفتح الثاني '': ([az] +) `- اسم العلامة ، ثم في` النتيجة [3] `العلامة:` النمط: ([^>] * ) `. -The contents of every group in the string: +محتويات كل مجموعة في السلسلة: ![](regexp-nested-groups-matches.svg) -### Optional groups +### المجموعات الاختيارية -Even if a group is optional and doesn't exist in the match (e.g. has the quantifier `pattern:(...)?`), the corresponding `result` array item is present and equals `undefined`. +حتى إذا كانت المجموعة اختيارية ولا وجود لها في المطابقة (على سبيل المثال ، تحتوي على النموذج `المُحدِّد الكمي: (...)؟`) ، فإن عنصر صفيف `النتيجة` المطابق موجود ويساوي` غير معرّف`. -For instance, let's consider the regexp `pattern:a(z)?(c)?`. It looks for `"a"` optionally followed by `"z"` optionally followed by `"c"`. +على سبيل المثال ، دعنا نفكر في regexp `pattern: a (z)؟ (c)؟`. تبحث عن "" "متبوعًا اختياريًا بـ" "z" "متبوعًا اختياريًا بـ" "c" ". -If we run it on the string with a single letter `subject:a`, then the result is: +إذا قمنا بتشغيله على السلسلة بحرف واحد `subject: a` ، فإن النتيجة هي: ```js run let match = 'a'.match(/a(z)?(c)?/); @@ -146,9 +146,9 @@ alert( match[1] ); // undefined alert( match[2] ); // undefined ``` -The array has the length of `3`, but all groups are empty. +الصفيف له طول `3` ، لكن كل المجموعات فارغة. -And here's a more complex match for the string `subject:ac`: +وإليك مطابقة أكثر تعقيدًا للسلسلة `subject: ac`: ```js run let match = 'ac'.match(/a(z)?(c)?/) @@ -159,19 +159,19 @@ alert( match[1] ); // undefined, because there's nothing for (z)? alert( match[2] ); // c ``` -The array length is permanent: `3`. But there's nothing for the group `pattern:(z)?`, so the result is `["ac", undefined, "c"]`. +طول الصفيف دائم: `3`. ولكن لا يوجد شيء للمجموعة 'pattern: (z)؟ `، لذا فإن النتيجة هي" ["ac"، undefined، "c"] `. -## Searching for all matches with groups: matchAll +## البحث عن جميع التطابقات مع المجموعات: matchAll -```warn header="`matchAll` is a new method, polyfill may be needed" -The method `matchAll` is not supported in old browsers. +`` `warn header =" "matchAll` هي طريقة جديدة ، قد تكون هناك حاجة إلى تعبئة متعددة" +الطريقة `matchAll` غير مدعومة في المتصفحات القديمة. -A polyfill may be required, such as . -``` +قد تكون هناك حاجة إلى تعبئة متعددة ، مثل . +`` -When we search for all matches (flag `pattern:g`), the `match` method does not return contents for groups. +عندما نبحث عن جميع التطابقات (الإبلاغ عن `pattern: g`) ، لا تُرجع طريقة` match` محتويات المجموعات. -For example, let's find all tags in a string: +على سبيل المثال ، دعنا نجد كل العلامات في سلسلة: ```js run let str = '

'; @@ -181,19 +181,19 @@ let tags = str.match(/<(.*?)>/g); alert( tags ); //

,

``` -The result is an array of matches, but without details about each of them. But in practice we usually need contents of capturing groups in the result. +والنتيجة هي مجموعة من التطابقات ، ولكن بدون تفاصيل حول كل منها. ولكن في الممارسة العملية ، نحتاج عادةً إلى محتويات مجموعات الالتقاط في النتيجة. -To get them, we should search using the method `str.matchAll(regexp)`. +للحصول عليها ، يجب البحث باستخدام الطريقة `str.matchAll (regexp)`. -It was added to JavaScript language long after `match`, as its "new and improved version". +تمت إضافتها إلى لغة جافا سكريبت بعد فترة طويلة من "التطابق" ، باعتبارها "نسختها الجديدة والمحسنة". -Just like `match`, it looks for matches, but there are 3 differences: +تمامًا مثل `match` ، فإنه يبحث عن المباريات ، ولكن هناك 3 اختلافات: -1. It returns not an array, but an iterable object. -2. When the flag `pattern:g` is present, it returns every match as an array with groups. -3. If there are no matches, it returns not `null`, but an empty iterable object. +1. لا تقوم بإرجاع صفيف ، ولكن كائن قابل للتكرار. +2. عند وجود العلامة "pattern: g" ، فإنها تُرجع كل مطابقة كمصفوفة بمجموعات. +3. في حالة عدم وجود تطابقات ، فإنها لا تُرجع "قيمة خالية" ، بل تُرجع كائنًا فارغًا قابلًا للتكرار. -For instance: +على سبيل المثال: ```js run let results = '

'.matchAll(/<(.*?)>/gi); @@ -209,9 +209,9 @@ alert(results[0]); //

,h1 (1st tag) alert(results[1]); //

,h2 (2nd tag) ``` -As we can see, the first difference is very important, as demonstrated in the line `(*)`. We can't get the match as `results[0]`, because that object isn't pseudoarray. We can turn it into a real `Array` using `Array.from`. There are more details about pseudoarrays and iterables in the article . +كما نرى ، فإن الفرق الأول مهم للغاية ، كما هو موضح في السطر `(*)`. لا يمكننا الحصول على المطابقة كـ "النتائج [0]` ، لأن هذا الكائن ليس كاذبًا. يمكننا تحويلها إلى `Array` حقيقي باستخدام` Array.from`. هناك المزيد من التفاصيل حول المصفوفات الكاذبة والقابلة للتكرار في المقالة . -There's no need in `Array.from` if we're looping over results: +ليست هناك حاجة في `Array.from` إذا كنا نراجع النتائج: ```js run let results = '

'.matchAll(/<(.*?)>/gi); @@ -223,13 +223,13 @@ for(let result of results) { } ``` -...Or using destructuring: +... أو باستخدام الـ `destructuring`: ```js let [tag1, tag2] = '

'.matchAll(/<(.*?)>/gi); ``` -Every match, returned by `matchAll`, has the same format as returned by `match` without flag `pattern:g`: it's an array with additional properties `index` (match index in the string) and `input` (source string): +كل مطابقة ، يتم إرجاعها بواسطة `matchAll` ، لها نفس التنسيق الذي تم إرجاعه بواسطة` مطابقة` بدون نمط `العلامة: g`: إنها مصفوفة ذات خصائص إضافية` فهرس` (فهرس المطابقة في السلسلة) و `الإدخال` (سلسلة المصدر ): ```js run let results = '

'.matchAll(/<(.*?)>/gi); @@ -242,23 +242,23 @@ alert( tag1.index ); // 0 alert( tag1.input ); //

``` -```smart header="Why is a result of `matchAll` an iterable object, not an array?" -Why is the method designed like that? The reason is simple - for the optimization. +```smart header="لماذا نتيجة" matchAll "كائن قابل للتكرار وليس مصفوفة؟" +لماذا تم تصميم الطريقة بهذه الطريقة؟ والسبب بسيط - للتحسين. -The call to `matchAll` does not perform the search. Instead, it returns an iterable object, without the results initially. The search is performed each time we iterate over it, e.g. in the loop. +استدعاء "matchAll" لا يجري البحث. بدلاً من ذلك ، تقوم بإرجاع كائن قابل للتكرار ، بدون النتائج في البداية. يتم إجراء البحث في كل مرة نكرر فيها ذلك ، على سبيل المثال في الحلقة. -So, there will be found as many results as needed, not more. +لذلك ، سيتم العثور على العديد من النتائج حسب الحاجة ، وليس أكثر. -E.g. there are potentially 100 matches in the text, but in a `for..of` loop we found 5 of them, then decided it's enough and make a `break`. Then the engine won't spend time finding other 95 matches. -``` +على سبيل المثال من المحتمل أن يكون هناك 100 تطابق في النص ، ولكن في حلقة "for..of` وجدنا 5 منها ، ثم قررنا أنها كافية وقمنا بعمل" استراحة ". ثم لن يقضي المحرك وقتًا في العثور على 95 مباراة أخرى. +`` -## Named groups +## المجموعات المسماة -Remembering groups by their numbers is hard. For simple patterns it's doable, but for more complex ones counting parentheses is inconvenient. We have a much better option: give names to parentheses. +من الصعب تذكر المجموعات بأرقامها. بالنسبة للأنماط البسيطة ، يمكن القيام بذلك ، ولكن بالنسبة للأنماط الأكثر تعقيدًا ، يعد حساب الأقواس غير مريح. لدينا خيار أفضل بكثير: إعطاء أسماء للأقواس. -That's done by putting `pattern:?` immediately after the opening paren. +يتم ذلك عن طريق وضع "pattern :؟ ` بعد علامة الافتتاح مباشرة. -For example, let's look for a date in the format "year-month-day": +على سبيل المثال ، دعنا نبحث عن تاريخ بتنسيق "عام-شهر-يوم": ```js run *!* @@ -273,11 +273,11 @@ alert(groups.month); // 04 alert(groups.day); // 30 ``` -As you can see, the groups reside in the `.groups` property of the match. +كما ترى ، المجموعات موجودة في خاصية ".groups" للمباراة. -To look for all dates, we can add flag `pattern:g`. +للبحث عن جميع التواريخ ، يمكننا إضافة العلم `pattern: g`. -We'll also need `matchAll` to obtain full matches, together with groups: +سنحتاج أيضًا إلى "matchAll" للحصول على تطابقات كاملة ، جنبًا إلى جنب مع المجموعات: ```js run let dateRegexp = /(?[0-9]{4})-(?[0-9]{2})-(?[0-9]{2})/g; @@ -295,11 +295,11 @@ for(let result of results) { } ``` -## Capturing groups in replacement +## الاستيلاء على المجموعات في الاستبدال -Method `str.replace(regexp, replacement)` that replaces all matches with `regexp` in `str` allows to use parentheses contents in the `replacement` string. That's done using `pattern:$n`, where `pattern:n` is the group number. +تسمح الطريقة `str.replace (regexp ، الاستبدال)` التي تستبدل جميع التطابقات بـ `regexp` في` str` باستخدام محتويات الأقواس في سلسلة `replace`. يتم ذلك باستخدام `pattern: $ n` ، حيث` pattern: n` هو رقم المجموعة. -For example, +فمثلا، ```js run let str = "John Bull"; @@ -308,9 +308,9 @@ let regexp = /(\w+) (\w+)/; alert( str.replace(regexp, '$2, $1') ); // Bull, John ``` -For named parentheses the reference will be `pattern:$`. +بالنسبة للأقواس المسماة ، سيكون المرجع `pattern: $ `. -For example, let's reformat dates from "year-month-day" to "day.month.year": +على سبيل المثال ، دعنا نعيد تنسيق التواريخ من "year-month-day" إلى "day.month.year": ```js run let regexp = /(?[0-9]{4})-(?[0-9]{2})-(?[0-9]{2})/g; @@ -321,15 +321,15 @@ alert( str.replace(regexp, '$.$.$') ); // 30.10.2019, 01.01.2020 ``` -## Non-capturing groups with ?: +## المجموعات غير الملتقطة مع؟: -Sometimes we need parentheses to correctly apply a quantifier, but we don't want their contents in results. +في بعض الأحيان نحتاج إلى قوسين لتطبيق مُحدِّد الكمية بشكل صحيح ، لكننا لا نريد محتوياتها في النتائج. -A group may be excluded by adding `pattern:?:` in the beginning. +يمكن استبعاد مجموعة بإضافة "pattern:؟:" في البداية. -For instance, if we want to find `pattern:(go)+`, but don't want the parentheses contents (`go`) as a separate array item, we can write: `pattern:(?:go)+`. +على سبيل المثال ، إذا أردنا العثور على "pattern: (go) +` ، لكننا لا نريد محتويات الأقواس (`go`) كعنصر صفيف منفصل ، فيمكننا كتابة:` pattern :( ؟: go) + ` . -In the example below we only get the name `match:John` as a separate member of the match: +في المثال أدناه ، نحصل فقط على الاسم `match: John` كعضو منفصل في المباراة: ```js run let str = "Gogogo John!"; @@ -346,19 +346,19 @@ alert( result[1] ); // John alert( result.length ); // 2 (no more items in the array) ``` -## Summary +## الملخص -Parentheses group together a part of the regular expression, so that the quantifier applies to it as a whole. +تجمع الأقواس معًا جزءًا من التعبير العادي ، بحيث ينطبق المقياس عليه ككل. -Parentheses groups are numbered left-to-right, and can optionally be named with `(?...)`. +يتم ترقيم مجموعات الأقواس من اليسار إلى اليمين ، ويمكن اختياريًا تسميتها بـ `(؟ ...)`. -The content, matched by a group, can be obtained in the results: +يمكن الحصول على المحتوى المطابق لمجموعة ما في النتائج: -- The method `str.match` returns capturing groups only without flag `pattern:g`. -- The method `str.matchAll` always returns capturing groups. +- تُظهر الطريقة `str.match` مجموعات الالتقاط فقط بدون وضع علامة على" النموذج: g`. +- الطريقة `str.matchAll` تُرجع دائمًا مجموعات الالتقاط. -If the parentheses have no name, then their contents is available in the match array by its number. Named parentheses are also available in the property `groups`. +إذا لم يكن للأقواس اسم ، فإن محتوياتها متاحة في مصفوفة المطابقة برقمها. الأقواس المسموعة متاحة أيضًا في خاصية "المجموعات". -We can also use parentheses contents in the replacement string in `str.replace`: by the number `$n` or the name `$`. +يمكننا أيضًا استخدام محتويات الأقواس في سلسلة الاستبدال في `str.replace`: بالرقم` $ n` أو بالاسم `$ `. -A group may be excluded from numbering by adding `pattern:?:` in its start. That's used when we need to apply a quantifier to the whole group, but don't want it as a separate item in the results array. We also can't reference such parentheses in the replacement string. +يمكن استبعاد مجموعة من الترقيم عن طريق إضافة "pattern:؟:" في بدايتها. يُستخدم هذا عندما نحتاج إلى تطبيق مُحدِّد الكمية على المجموعة بأكملها ، ولكن لا نريدها كبند منفصل في صفيف النتائج. لا يمكننا أيضًا الإشارة إلى هذه الأقواس في سلسلة الاستبدال. \ No newline at end of file From 1639232f1465afb342c159efb9d7cd857ea63e25 Mon Sep 17 00:00:00 2001 From: salah elhossiny Date: Fri, 5 Jun 2020 23:13:45 +0200 Subject: [PATCH 2/3] =?UTF-8?q?=1B[200~=20Window=20sizes=20and=20scrolling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../10-size-and-scroll-window/article.md | 139 +++++++++--------- 1 file changed, 69 insertions(+), 70 deletions(-) diff --git a/2-ui/1-document/10-size-and-scroll-window/article.md b/2-ui/1-document/10-size-and-scroll-window/article.md index 10898dbf7..fcdc20b79 100644 --- a/2-ui/1-document/10-size-and-scroll-window/article.md +++ b/2-ui/1-document/10-size-and-scroll-window/article.md @@ -1,50 +1,50 @@ -# Window sizes and scrolling +# أحجام النوافذ والتمرير -How do we find the width and height of the browser window? How do we get the full width and height of the document, including the scrolled out part? How do we scroll the page using JavaScript? +كيف نجد عرض وارتفاع نافذة المتصفح؟ كيف نحصل على العرض والارتفاع الكاملين للوثيقة ، بما في ذلك الجزء المسحوب؟ كيف ننتقل الصفحة باستخدام جافا سكريبت؟ -For most such requests, we can use the root document element `document.documentElement`, that corresponds to the `` tag. But there are additional methods and peculiarities important enough to consider. +بالنسبة لمعظم هذه الطلبات ، يمكننا استخدام عنصر المستند الجذر `document.documentElement` ، الذي يتوافق مع العلامة` `. ولكن هناك طرق وخصائص إضافية مهمة بما يكفي للنظر فيها. -## Width/height of the window +## عرض / ارتفاع النافذة -To get window width and height we can use `clientWidth/clientHeight` of `document.documentElement`: +للحصول على عرض النافذة وارتفاعها ، يمكننا استخدام `clientWidth / clientHeight` من` document.documentElement`: ![](document-client-width-height.svg) ```online -For instance, this button shows the height of your window: +على سبيل المثال ، يعرض هذا الزر ارتفاع النافذة: ``` -````warn header="Not `window.innerWidth/Height`" -Browsers also support properties `window.innerWidth/innerHeight`. They look like what we want. So why not to use them instead? +````warn header="ليس `window.innerWidth / Height`" +كما تدعم المستعرضات الخصائص `window.innerWidth / innerHeight`. يبدون مثل ما نريد. فلماذا لا تستخدمها بدلاً من ذلك؟ -If there exists a scrollbar, and it occupies some space, `clientWidth/clientHeight` provide the width/height without it (subtract it). In other words, they return width/height of the visible part of the document, available for the content. +إذا كان هناك شريط تمرير ، ويحتل بعض المساحة ، يوفر `clientWidth / clientHeight` العرض / الارتفاع بدونه (اطرحه). بمعنى آخر ، تقوم بإرجاع عرض / ارتفاع الجزء المرئي من المستند المتاح للمحتوى. -...And `window.innerWidth/innerHeight` include the scrollbar. +... و `window.innerWidth / innerHeight` تتضمن شريط التمرير. -If there's a scrollbar, and it occupies some space, then these two lines show different values: +إذا كان هناك شريط تمرير ، ويشغل بعض المساحة ، فإن هذين الخطين يعرضان قيمًا مختلفة: ```js run alert( window.innerWidth ); // full window width alert( document.documentElement.clientWidth ); // window width minus the scrollbar ``` -In most cases we need the *available* window width: to draw or position something. That is: inside scrollbars if there are any. So we should use `documentElement.clientHeight/Width`. -```` +في معظم الحالات ، نحتاج إلى عرض النافذة * المتوفرة *: لرسم شيء ما أو وضعه. هذا هو: داخل أشرطة التمرير إذا كان هناك أي. لذا يجب علينا استخدام `documentElement.clientHeight / Width`. +`` `` -```warn header="`DOCTYPE` is important" -Please note: top-level geometry properties may work a little bit differently when there's no `` in HTML. Odd things are possible. +`` `warn header =" "DOCTYPE` مهم" +يرجى ملاحظة: قد تعمل خصائص الهندسة عالية المستوى بشكل مختلف قليلاً عندما لا يكون هناك `في HTML. الأشياء الغريبة ممكنة. -In modern HTML we should always write `DOCTYPE`. -``` +في HTML الحديثة يجب أن نكتب دائمًا "DOCTYPE". +`` -## Width/height of the document +## عرض / ارتفاع الوثيقة -Theoretically, as the root document element is `document.documentElement`, and it encloses all the content, we could measure document full size as `document.documentElement.scrollWidth/scrollHeight`. +نظريًا ، نظرًا لأن عنصر المستند الجذر هو `document.documentElement` ، ويشتمل على كل المحتوى ، يمكننا قياس حجم المستند بالكامل على أنه` document.documentElement.scrollWidth / ScrollHeight`. -But on that element, for the whole page, these properties do not work as intended. In Chrome/Safari/Opera if there's no scroll, then `documentElement.scrollHeight` may be even less than `documentElement.clientHeight`! Sounds like a nonsense, weird, right? +ولكن في هذا العنصر ، بالنسبة للصفحة بأكملها ، لا تعمل هذه الخصائص على النحو المنشود. في Chrome / Safari / Opera إذا لم يكن هناك تمرير ، فقد يكون `documentElement.scrollHeight` أقل من` documentElement.clientHeight`! يبدو هراء ، غريب ، أليس كذلك؟ -To reliably obtain the full document height, we should take the maximum of these properties: +للحصول على ارتفاع المستند بشكل موثوق ، يجب أن نأخذ الحد الأقصى من هذه الخصائص: ```js run let scrollHeight = Math.max( @@ -56,101 +56,100 @@ let scrollHeight = Math.max( alert('Full document height, with scrolled out part: ' + scrollHeight); ``` -Why so? Better don't ask. These inconsistencies come from ancient times, not a "smart" logic. +لما ذلك؟ من الأفضل ألا تسأل. هذه التناقضات تأتي من العصور القديمة ، وليس منطق "ذكي". -## Get the current scroll [#page-scroll] +## احصل على التمرير الحالي [# page-roll] -DOM elements have their current scroll state in `elem.scrollLeft/scrollTop`. +عناصر DOM لها حالة التمرير الحالية في `elem.scrollLeft / rollTop`. -For document scroll `document.documentElement.scrollLeft/Top` works in most browsers, except older WebKit-based ones, like Safari (bug [5991](https://bugs.webkit.org/show_bug.cgi?id=5991)), where we should use `document.body` instead of `document.documentElement`. +بالنسبة إلى تمرير المستند ، يعمل المستند document.documentElement.scrollLeft / Top` في معظم المتصفحات ، باستثناء المتصفحات القديمة التي تستند إلى WebKit ، مثل Safari (الخطأ [5991] (https://bugs.webkit.org/show_bug.cgi؟id=5991) ) ، حيث يجب أن نستخدم `document.body` بدلاً من` document.documentElement`. -Luckily, we don't have to remember these peculiarities at all, because the scroll is available in the special properties `window.pageXOffset/pageYOffset`: +لحسن الحظ ، ليس علينا أن نتذكر هذه الخصائص على الإطلاق ، لأن التمرير متاح في الخصائص الخاصة `window.pageXOffset/pageYOffset`: ```js run alert('Current scroll from the top: ' + window.pageYOffset); alert('Current scroll from the left: ' + window.pageXOffset); ``` -These properties are read-only. - -## Scrolling: scrollTo, scrollBy, scrollIntoView [#window-scroll] +هذه الخصائص للقراءة فقط. -```warn -To scroll the page from JavaScript, its DOM must be fully built. +## التمرير: التمرير إلى التمرير التمرير التمرير العرضي [# window-تمرير] -For instance, if we try to scroll the page from the script in ``, it won't work. -``` +احذر +لتمرير الصفحة من JavaScript ، يجب بناء DOM بالكامل. -Regular elements can be scrolled by changing `scrollTop/scrollLeft`. +على سبيل المثال ، إذا حاولنا تمرير الصفحة من البرنامج النصي في `` ، فلن تعمل. +`` -We can do the same for the page using `document.documentElement.scrollTop/Left` (except Safari, where `document.body.scrollTop/Left` should be used instead). +يمكن تمرير العناصر العادية عن طريق تغيير `التمرير / التمرير لليسار`. -Alternatively, there's a simpler, universal solution: special methods [window.scrollBy(x,y)](mdn:api/Window/scrollBy) and [window.scrollTo(pageX,pageY)](mdn:api/Window/scrollTo). +يمكننا فعل الشيء نفسه للصفحة باستخدام `document.documentElement.scrollTop / Left` (باستثناء Safari ، حيث يجب استخدام` document.body.scrollTop / Left` بدلاً من ذلك). -- The method `scrollBy(x,y)` scrolls the page *relative to its current position*. For instance, `scrollBy(0,10)` scrolls the page `10px` down. +بدلاً من ذلك ، هناك حل أبسط وعالمي: طرق خاصة [window.scrollBy (x، y)] (mdn: api / Window / rollBy) و [window.scrollTo (pageX، pageY)] (mdn: api / Window / rollTo) . - ```online - The button below demonstrates this: +- طريقة `التمرير (x، y) 'تقوم بتمرير الصفحة * بالنسبة إلى موقعها الحالي *. على سبيل المثال ، يؤدي `التمرير (0،10)` إلى تمرير الصفحة `10 بكسل` لأسفل. - - ``` -- The method `scrollTo(pageX,pageY)` scrolls the page *to absolute coordinates*, so that the top-left corner of the visible part has coordinates `(pageX, pageY)` relative to the document's top-left corner. It's like setting `scrollLeft/scrollTop`. + `` online + يوضح الزر أدناه هذا: - To scroll to the very beginning, we can use `scrollTo(0,0)`. + + `` +- طريقة `التمرير (pageX ، pageY)` تقوم بتمرير الصفحة * إلى إحداثيات مطلقة * ، بحيث يكون للزاوية العلوية اليسرى للجزء المرئي إحداثيات `((pageX ، pageY)` بالنسبة إلى الزاوية العلوية اليسرى للمستند. الأمر أشبه بإعداد `التمرير الأيسر / التمرير العلوي`. + للتمرير إلى البداية ، يمكننا استخدام `التمرير (0،0)`. ```online ``` -These methods work for all browsers the same way. +تعمل هذه الطرق لجميع المتصفحات بنفس الطريقة. ## scrollIntoView -For completeness, let's cover one more method: [elem.scrollIntoView(top)](mdn:api/Element/scrollIntoView). +للاستكمال ، دعنا نغطي طريقة أخرى: [elem.scrollIntoView (top)] (mdn: api / Element / rollIntoView). -The call to `elem.scrollIntoView(top)` scrolls the page to make `elem` visible. It has one argument: +يؤدي استدعاء `elem.scrollIntoView (أعلى)` إلى تمرير الصفحة لإظهار `elem`. لها حجة واحدة: -- if `top=true` (that's the default), then the page will be scrolled to make `elem` appear on the top of the window. The upper edge of the element is aligned with the window top. -- if `top=false`, then the page scrolls to make `elem` appear at the bottom. The bottom edge of the element is aligned with the window bottom. +- إذا كان `top = true` (هذا هو الافتراضي) ، فسيتم تمرير الصفحة لإظهار` elem` في أعلى النافذة. يتم محاذاة الحافة العلوية للعنصر مع أعلى النافذة. +- إذا كان `top = false` ، فتمرر الصفحة لتظهر` elem` في الأسفل. يتم محاذاة الحافة السفلية للعنصر مع أسفل النافذة. ```online -The button below scrolls the page to make itself show at the window top: +يمرر الزر أدناه الصفحة لإظهار نفسها في أعلى النافذة: - + -And this button scrolls the page to show it at the bottom: +وهذا الزر يقوم بتمرير الصفحة لإظهارها في الأسفل: ``` -## Forbid the scrolling +## منع التمرير -Sometimes we need to make the document "unscrollable". For instance, when we need to cover it with a large message requiring immediate attention, and we want the visitor to interact with that message, not with the document. +نحتاج أحيانًا إلى جعل المستند "غير قابل للتمرير". على سبيل المثال ، عندما نحتاج إلى تغطيتها برسالة كبيرة تتطلب اهتمامًا فوريًا ، ونريد من الزائر أن يتفاعل مع هذه الرسالة ، وليس مع المستند. -To make the document unscrollable, it's enough to set `document.body.style.overflow = "hidden"`. The page will freeze on its current scroll. +لجعل المستند غير قابل للتمرير ، يكفي تعيين `document.body.style.overflow =" hidden "`. سيتم تجميد الصفحة في التمرير الحالي. ```online -Try it: +جربها: -The first button freezes the scroll, the second one resumes it. -``` +يجمد الزر الأول التمرير ، ويستأنفه الزر الثاني. +`` -We can use the same technique to "freeze" the scroll for other elements, not just for `document.body`. +يمكننا استخدام نفس التقنية "لتجميد" التمرير للعناصر الأخرى ، وليس فقط لـ `المستند. -The drawback of the method is that the scrollbar disappears. If it occupied some space, then that space is now free, and the content "jumps" to fill it. +عيب الطريقة هو اختفاء شريط التمرير. إذا كانت تحتل بعض المساحة ، فإن هذه المساحة الآن خالية ، ويزداد المحتوى لملئها. -That looks a bit odd, but can be worked around if we compare `clientWidth` before and after the freeze, and if it increased (the scrollbar disappeared) then add `padding` to `document.body` in place of the scrollbar, to keep the content width the same. +يبدو هذا غريبًا بعض الشيء ، ولكن يمكن التعامل معه إذا قارنا `ClientWidth` قبل التجميد وبعده ، وإذا زاد (اختفى شريط التمرير) ، فأضف` padding` إلى `document.body` بدلاً من شريط التمرير ، إلى حافظ على عرض المحتوى كما هو. -## Summary +## الملخص -Geometry: +الهندسة: -- Width/height of the visible part of the document (content area width/height): `document.documentElement.clientWidth/Height` -- Width/height of the whole document, with the scrolled out part: +- عرض / ارتفاع الجزء المرئي من المستند (عرض / ارتفاع منطقة المحتوى): `document.documentElement.clientWidth / Height` +- عرض / ارتفاع الوثيقة بأكملها ، مع الجزء الممرر: ```js let scrollHeight = Math.max( @@ -160,11 +159,11 @@ Geometry: ); ``` -Scrolling: +التمرير: -- Read the current scroll: `window.pageYOffset/pageXOffset`. -- Change the current scroll: +- قراءة التمرير الحالي: `window.pageYOffset / pageXOffset`. +- تغيير التمرير الحالي: - - `window.scrollTo(pageX,pageY)` -- absolute coordinates, - - `window.scrollBy(x,y)` -- scroll relative the current place, - - `elem.scrollIntoView(top)` -- scroll to make `elem` visible (align with the top/bottom of the window). + - `window.scrollTo (pageX ، pageY)` - الإحداثيات المطلقة ، + - `window.scrollBy (x، y)` - انتقل نسبيًا إلى المكان الحالي ، + - `elem.scrollIntoView (أعلى)` - قم بالتمرير لجعل `elem` مرئيًا (محاذاة مع الجزء العلوي / السفلي من النافذة). From 539870b80bf70c99b1ed93255ba1c603e6a4dccb Mon Sep 17 00:00:00 2001 From: salah elhossiny Date: Sat, 6 Jun 2020 10:15:06 +0200 Subject: [PATCH 3/3] window size and scroll --- 2-ui/1-document/09-size-and-scroll/article.md | 198 +++++++++--------- 1 file changed, 100 insertions(+), 98 deletions(-) diff --git a/2-ui/1-document/09-size-and-scroll/article.md b/2-ui/1-document/09-size-and-scroll/article.md index 024e9a4d9..9d706c5bf 100644 --- a/2-ui/1-document/09-size-and-scroll/article.md +++ b/2-ui/1-document/09-size-and-scroll/article.md @@ -1,12 +1,12 @@ -# Element size and scrolling +# حجم العنصر والتمرير -There are many JavaScript properties that allow us to read information about element width, height and other geometry features. +هناك العديد من خصائص JavaScript التي تسمح لنا بقراءة معلومات حول عرض العنصر وارتفاعه وميزات الهندسة الأخرى. -We often need them when moving or positioning elements in JavaScript. +غالبًا ما نحتاج إليها عند تحريك العناصر أو وضعها في JavaScript. -## Sample element +## عنصر العينة -As a sample element to demonstrate properties we'll use the one given below: +كعنصر عينة لإثبات الخصائص ، سنستخدم الخاصية الواردة أدناه: ```html no-beautify
@@ -23,49 +23,49 @@ As a sample element to demonstrate properties we'll use the one given below: ``` -It has the border, padding and scrolling. The full set of features. There are no margins, as they are not the part of the element itself, and there are no special properties for them. +لديها الحدود والحشو والتمرير. مجموعة كاملة من الميزات. لا توجد هوامش ، لأنها ليست جزءًا من العنصر نفسه ، ولا توجد خصائص خاصة لهم. -The element looks like this: +يبدو العنصر كما يلي: ![](metric-css.svg) You can [open the document in the sandbox](sandbox:metric). ```smart header="Mind the scrollbar" -The picture above demonstrates the most complex case when the element has a scrollbar. Some browsers (not all) reserve the space for it by taking it from the content (labeled as "content width" above). +توضح الصورة أعلاه الحالة الأكثر تعقيدًا عندما يكون للعنصر شريط تمرير. تحتفظ بعض المتصفحات (وليس كلها) بالفضاء الخاص بها من خلال أخذها من المحتوى (المسمى "عرض المحتوى" أعلاه). -So, without scrollbar the content width would be `300px`, but if the scrollbar is `16px` wide (the width may vary between devices and browsers) then only `300 - 16 = 284px` remains, and we should take it into account. That's why examples from this chapter assume that there's a scrollbar. Without it, some calculations are simpler. +لذلك ، بدون شريط التمرير ، سيكون عرض المحتوى `300 بكسل` ، ولكن إذا كان شريط التمرير بعرض` 16 بكسل` (قد يختلف العرض بين الأجهزة والمتصفحات) ، فعندئذٍ يبقى `300 - 16 = 284 بكسل` فقط ، ويجب أن نأخذه في الاعتبار . لهذا السبب تفترض أمثلة من هذا الفصل وجود شريط تمرير. بدونه ، بعض الحسابات أبسط. ``` -```smart header="The `padding-bottom` area may be filled with text" -Usually paddings are shown empty on our illustrations, but if there's a lot of text in the element and it overflows, then browsers show the "overflowing" text at `padding-bottom`, that's normal. +```smart header="The `padding-bottom` aقد تكون مليئة بالنص " +عادةً ما يتم عرض الحشو فارغة على الرسوم التوضيحية الخاصة بنا ، ولكن إذا كان هناك الكثير من النص في العنصر وتجاوزه ، فإن المتصفحات تعرض النص "الفائض" في "الحشو السفلي" ، فهذا أمر طبيعي. ``` -## Geometry +## الهندسة -Here's the overall picture with geometry properties: +فيما يلي الصورة العامة بخصائص الهندسة: -![](metric-all.svg) +! [] (metric-all.svg) -Values of these properties are technically numbers, but these numbers are "of pixels", so these are pixel measurements. +قيم هذه الخصائص هي أرقام تقنيًا ، لكن هذه الأرقام هي "بكسل" ، لذا فهي قياسات بكسل. -Let's start exploring the properties starting from the outside of the element. +لنبدأ في استكشاف الخصائص بدءًا من خارج العنصر. ## offsetParent, offsetLeft/Top -These properties are rarely needed, but still they are the "most outer" geometry properties, so we'll start with them. +نادرًا ما تكون هذه الخصائص مطلوبة ، لكنها لا تزال هي الخصائص الهندسية "الخارجية" ، لذلك سنبدأ بها. -The `offsetParent` is the nearest ancestor that the browser uses for calculating coordinates during rendering. +يعد "offsetParent" أقرب سلف يستخدمه المتصفح لحساب الإحداثيات أثناء العرض. -That's the nearest ancestor that is one of the following: +هذا هو أقرب سلف وهو واحد مما يلي: -1. CSS-positioned (`position` is `absolute`, `relative`, `fixed` or `sticky`), or -2. ``, ``, or ``, or +1- وضع CSS ("الموضع" هو "مطلق" ، "قريب" ، "ثابت" أو "ثابت") ، أو +2. `
` أو `` أو `` أو 3. ``. -Properties `offsetLeft/offsetTop` provide x/y coordinates relative to `offsetParent` upper-left corner. +توفر الخصائص `offsetLeft / offsetTop` إحداثيات س / ص نسبة إلى` `offsetParent` الزاوية العلوية اليسرى. -In the example below the inner `
` has `
` as `offsetParent` and `offsetLeft/offsetTop` shifts from its upper-left corner (`180`): +في المثال أدناه ، يحتوي `
` الداخلي على `
` كـ `offsetParent` و` offsetLeft / offsetTop` من الزاوية العلوية اليسرى (`180`): ```html run height=10
@@ -82,33 +82,33 @@ In the example below the inner `
` has `
` as `offsetParent` and `offse ![](metric-offset-parent.svg) -There are several occasions when `offsetParent` is `null`: +هناك عدة مناسبات عندما يكون "offsetParent" "فارغًا": -1. For not shown elements (`display:none` or not in the document). -2. For `` and ``. -3. For elements with `position:fixed`. +1. للعناصر غير المعروضة (`display: none` أو not in the document). +2. بالنسبة لـ "` و "`. +3- للعناصر ذات "الموضع: ثابت". ## offsetWidth/Height -Now let's move on to the element itself. +الآن دعنا ننتقل إلى العنصر نفسه. -These two properties are the simplest ones. They provide the "outer" width/height of the element. Or, in other words, its full size including borders. +هاتان الخاصيتان هما الأبسط. توفر العرض / الارتفاع "الخارجي" للعنصر. أو بعبارة أخرى حجمها الكامل بما في ذلك الحدود. ![](metric-offset-width-height.svg) -For our sample element: +لعنصر العينة لدينا: -- `offsetWidth = 390` -- the outer width, can be calculated as inner CSS-width (`300px`) plus paddings (`2 * 20px`) and borders (`2 * 25px`). -- `offsetHeight = 290` -- the outer height. +- `offsetWidth = 390` - العرض الخارجي ، يمكن حسابه على أنه عرض CSS داخلي (` 300 بكسل`) بالإضافة إلى حشوات (`2 * 20 بكسل`) وحدود (` 2 * 25 بكسل`). +- `offsetHeight = 290` - الارتفاع الخارجي. -````smart header="Geometry properties are zero/null for elements that are not displayed" -Geometry properties are calculated only for displayed elements. +````smart header="خصائص الهندسة هي صفر / قيمة للعناصر التي لا يتم عرضها" +يتم حساب خصائص الهندسة فقط للعناصر المعروضة. -If an element (or any of its ancestors) has `display:none` or is not in the document, then all geometry properties are zero (or `null` for `offsetParent`). +إذا كان أحد العناصر (أو أي من أسلافه) يحتوي على "عرض: لا شيء" أو غير موجود في المستند ، فإن جميع الخصائص الهندسية تكون صفرية (أو "خالية" لـ "offsetParent"). -For example, `offsetParent` is `null`, and `offsetWidth`, `offsetHeight` are `0` when we created an element, but haven't inserted it into the document yet, or it (or it's ancestor) has `display:none`. +على سبيل المثال ، `offsetParent` هي` null` ، و `offsetWidth` ،` offsetHeight` هي `0` عندما أنشأنا عنصرًا ، ولكننا لم نقم بإدراجه في المستند حتى الآن ، أو (أو أصله) يحتوي على` عرض : لا شيء. -We can use this to check if an element is hidden, like this: +يمكننا استخدام هذا للتحقق مما إذا كان العنصر مخفيًا ، مثل هذا: ```js function isHidden(elem) { @@ -116,68 +116,69 @@ function isHidden(elem) { } ``` -Please note that such `isHidden` returns `true` for elements that are on-screen, but have zero sizes (like an empty `
`). +يرجى ملاحظة أن مثل `isHidden` يعرض` true` للعناصر التي تظهر على الشاشة ، ولكن بدون أحجام (مثل `
` فارغ). ```` ## clientTop/Left -Inside the element we have the borders. +داخل العنصر لدينا الحدود. -To measure them, there are properties `clientTop` and `clientLeft`. +لقياسها ، هناك خصائص `clientTop` و` clientLeft`. -In our example: +في مثالنا: - `clientLeft = 25` -- left border width - `clientTop = 25` -- top border width ![](metric-client-left-top.svg) -...But to be precise -- these properties are not border width/height, but rather relative coordinates of the inner side from the outer side. +ولكن على وجه الدقة - هذه الخصائص ليست عرض / ارتفاع الحد ، بل هي إحداثيات نسبية للجانب الداخلي من الجانب الخارجي. -What's the difference? +ماهو الفرق؟ -It becomes visible when the document is right-to-left (the operating system is in Arabic or Hebrew languages). The scrollbar is then not on the right, but on the left, and then `clientLeft` also includes the scrollbar width. +تصبح مرئية عندما يكون المستند من اليمين إلى اليسار (نظام التشغيل باللغة العربية أو العبرية). شريط التمرير ليس بعد ذلك على اليمين ، ولكن على اليسار ، ثم يتضمن "clientLeft" أيضًا عرض شريط التمرير. -In that case, `clientLeft` would be not `25`, but with the scrollbar width `25 + 16 = 41`. +في هذه الحالة ، لن يكون "clientLeft" `25` ، ولكن بعرض شريط التمرير` 25 + 16 = 41`. -Here's the example in hebrew: +هذا هو المثال بالعبرية: ![](metric-client-left-top-rtl.svg) ## clientWidth/Height -These properties provide the size of the area inside the element borders. +توفر هذه الخصائص حجم المنطقة داخل حدود العنصر. -They include the content width together with paddings, but without the scrollbar: +تتضمن عرض المحتوى مع الحشو ، لكن بدون شريط التمرير: -![](metric-client-width-height.svg) +! [] (metric-client-width-height.svg) -On the picture above let's first consider `clientHeight`. +في الصورة أعلاه ، لنفكر أولاً في "clientHeight". -There's no horizontal scrollbar, so it's exactly the sum of what's inside the borders: CSS-height `200px` plus top and bottom paddings (`2 * 20px`) total `240px`. +لا يوجد شريط تمرير أفقي ، لذلك فهو بالضبط مجموع ما يوجد داخل الحدود: ارتفاع CSS `200 بكسل` بالإضافة إلى حشوات علوية وسفلية (` 2 * 20 بكسل`) إجمالي `240 بكسل`. -Now `clientWidth` -- here the content width is not `300px`, but `284px`, because `16px` are occupied by the scrollbar. So the sum is `284px` plus left and right paddings, total `324px`. +الآن "clientWidth" - هنا ليس عرض المحتوى "300 بكسل" ، ولكن "284 بكسل" ، لأن "16 بكسل" مشغول بشريط التمرير. لذلك يكون المجموع `284 بكسل` بالإضافة إلى حشوات اليسار واليمين ، إجمالي` 324 بكسل`. + +** إذا لم تكن هناك حشوات ، فإن "clientWidth / Height" هي بالضبط منطقة المحتوى ، داخل الحدود وشريط التمرير (إن وجد). ** -**If there are no paddings, then `clientWidth/Height` is exactly the content area, inside the borders and the scrollbar (if any).** ![](metric-client-width-nopadding.svg) -So when there's no padding we can use `clientWidth/clientHeight` to get the content area size. +لذلك عندما لا يكون هناك أي مساحة ، يمكننا استخدام `clientWidth / clientHeight` للحصول على حجم منطقة المحتوى. ## scrollWidth/Height -These properties are like `clientWidth/clientHeight`, but they also include the scrolled out (hidden) parts: +هذه الخصائص مثل `clientWidth / clientHeight` ، ولكنها تشمل أيضًا الأجزاء التي تم تمريرها (المخفية): -![](metric-scroll-width-height.svg) +! [] (metric-roll-width-height.svg) -On the picture above: +في الصورة أعلاه: -- `scrollHeight = 723` -- is the full inner height of the content area including the scrolled out parts. -- `scrollWidth = 324` -- is the full inner width, here we have no horizontal scroll, so it equals `clientWidth`. +- `التمرير = 723` - الارتفاع الداخلي الكامل لمنطقة المحتوى بما في ذلك الأجزاء التي تم تمريرها. +- `التمرير العرضي = 324` - هو العرض الداخلي الكامل ، وهنا ليس لدينا تمرير أفقي ، لذا فهو يساوي` clientWidth`. -We can use these properties to expand the element wide to its full width/height. +يمكننا استخدام هذه الخصائص لتوسيع العنصر إلى عرضه / ارتفاعه الكامل. -Like this: +مثله: ```js // expand the element to the full content height @@ -185,7 +186,7 @@ element.style.height = `${element.scrollHeight}px`; ``` ```online -Click the button to expand the element: +انقر فوق الزر لمد العنصر:
text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text
@@ -194,33 +195,34 @@ Click the button to expand the element: ## scrollLeft/scrollTop -Properties `scrollLeft/scrollTop` are the width/height of the hidden, scrolled out part of the element. +الخصائص `التمرير لليسار / التمرير العلوي` هي عرض / ارتفاع الجزء المخفي من العنصر. -On the picture below we can see `scrollHeight` and `scrollTop` for a block with a vertical scroll. +في الصورة أدناه ، يمكننا رؤية "التمرير" و "التمرير العلوي" للكتلة ذات التمرير العمودي. -![](metric-scroll-top.svg) +! [] (metric-تمرير-top.svg) -In other words, `scrollTop` is "how much is scrolled up". +وبعبارة أخرى ، فإن "rollTop" هو "مقدار التمرير". -````smart header="`scrollLeft/scrollTop` can be modified" -Most of the geometry properties here are read-only, but `scrollLeft/scrollTop` can be changed, and the browser will scroll the element. +`` `` smart header = "يمكن تعديل" التمرير لليسار / التمرير العلوي " +معظم الخصائص الهندسية هنا للقراءة فقط ، ولكن يمكن تغيير `التمرير لليسار / التمرير العلوي` ، وسوف يقوم المتصفح بتمرير العنصر. + +`` عبر الإنترنت +إذا قمت بالنقر فوق العنصر أدناه ، فسيتم تنفيذ الرمز `elem.scrollTop + = 10`. هذا يجعل محتوى العنصر بالتمرير `10px` للأسفل. -```online -If you click the element below, the code `elem.scrollTop += 10` executes. That makes the element content scroll `10px` down.
Click
Me
1
2
3
4
5
6
7
8
9
``` -Setting `scrollTop` to `0` or `Infinity` will make the element scroll to the very top/bottom respectively. -```` +يؤدي تعيين "التمرير" إلى "0" أو "إنفينيتي" إلى جعل العنصر ينتقل إلى الأعلى / الأسفل على التوالي. +`` `` -## Don't take width/height from CSS +## لا تأخذ العرض / الارتفاع من CSS -We've just covered geometry properties of DOM elements, that can be used to get widths, heights and calculate distances. +لقد غطينا للتو الخصائص الهندسية لعناصر DOM ، والتي يمكن استخدامها للحصول على العرض والارتفاعات وحساب المسافات. -But as we know from the chapter , we can read CSS-height and width using `getComputedStyle`. +ولكن كما نعلم من الفصل ، يمكننا قراءة ارتفاع وعرض CSS باستخدام `getComputedStyle`. -So why not to read the width of an element with `getComputedStyle`, like this? +فلماذا لا تقرأ عرض عنصر باستخدام `getComputedStyle` ، مثل هذا؟ ```js run let elem = document.body; @@ -228,10 +230,10 @@ let elem = document.body; alert( getComputedStyle(elem).width ); // show CSS width for elem ``` -Why should we use geometry properties instead? There are two reasons: +لماذا يجب أن نستخدم الخصائص الهندسية بدلاً من ذلك؟ هناك سببان: -1. First, CSS `width/height` depend on another property: `box-sizing` that defines "what is" CSS width and height. A change in `box-sizing` for CSS purposes may break such JavaScript. -2. Second, CSS `width/height` may be `auto`, for instance for an inline element: +1. أولاً ، يعتمد "عرض / ارتفاع" CSS على خاصية أخرى: "تحجيم المربع" الذي يحدد "ما هو" عرض وارتفاع CSS. قد يؤدي التغيير في "تحجيم المربع" لأغراض CSS إلى كسر جافا سكريبت. +2. ثانيًا ، قد يكون "عرض / ارتفاع" CSS "تلقائي" ، على سبيل المثال لعنصر مضمن: ```html run Hello! @@ -243,34 +245,34 @@ Why should we use geometry properties instead? There are two reasons: ``` - From the CSS standpoint, `width:auto` is perfectly normal, but in JavaScript we need an exact size in `px` that we can use in calculations. So here CSS width is useless. + من وجهة نظر CSS ، يعد `العرض: تلقائي` أمرًا طبيعيًا تمامًا ، ولكن في جافا سكريبت نحتاج إلى حجم دقيق في` بكسل` يمكننا استخدامه في العمليات الحسابية. حتى هنا عرض CSS عديم الفائدة. -And there's one more reason: a scrollbar. Sometimes the code that works fine without a scrollbar becomes buggy with it, because a scrollbar takes the space from the content in some browsers. So the real width available for the content is *less* than CSS width. And `clientWidth/clientHeight` take that into account. +وهناك سبب آخر: شريط التمرير. في بعض الأحيان ، تصبح الشفرة التي تعمل بشكل جيد بدون شريط تمرير عربات التي تجرها الدواب ، لأن شريط التمرير يأخذ المساحة من المحتوى في بعض المتصفحات. لذا فإن العرض الحقيقي المتاح للمحتوى هو * أقل * من عرض CSS. و "clientWidth / clientHeight" يأخذ ذلك في الاعتبار. -...But with `getComputedStyle(elem).width` the situation is different. Some browsers (e.g. Chrome) return the real inner width, minus the scrollbar, and some of them (e.g. Firefox) -- CSS width (ignore the scrollbar). Such cross-browser differences is the reason not to use `getComputedStyle`, but rather rely on geometry properties. +... ولكن مع "getComputedStyle (elem) .width" ، الوضع مختلف. تعرض بعض المتصفحات (مثل Chrome) العرض الداخلي الحقيقي مطروحًا منه شريط التمرير ، وبعضها (مثل Firefox) - عرض CSS (تجاهل شريط التمرير). هذه الاختلافات بين المتصفحات هي السبب في عدم استخدام `getComputedStyle` ، بل الاعتماد على الخصائص الهندسية. ```online -If your browser reserves the space for a scrollbar (most browsers for Windows do), then you can test it below. +إذا كان المستعرض الخاص بك يحتفظ بمساحة شريط التمرير (معظم المستعرضات لنظام Windows) ، فيمكنك اختباره أدناه. -[iframe src="cssWidthScroll" link border=1] +[iframe src = "cssWidthScroll" حدود الرابط = 1] -The element with text has CSS `width:300px`. +يحتوي العنصر الذي يحتوي على نص على CSS `width: 300px`. -On a Desktop Windows OS, Firefox, Chrome, Edge all reserve the space for the scrollbar. But Firefox shows `300px`, while Chrome and Edge show less. That's because Firefox returns the CSS width and other browsers return the "real" width. -``` +على نظام التشغيل Windows Desktop و Firefox و Chrome و Edge ، كلهم ​​يحجزون مساحة شريط التمرير. لكن Firefox يُظهر `300 بكسل` ، بينما يُظهر Chrome و Edge أقل. ذلك لأن Firefox يعرض عرض CSS وتعرض المستعرضات الأخرى العرض "الحقيقي". +`` -Please note that the described difference is only about reading `getComputedStyle(...).width` from JavaScript, visually everything is correct. +يرجى ملاحظة أن الفرق الموضح هو فقط حول قراءة `getComputedStyle (...). width` من JavaScript ، كل شيء بصريًا صحيح. -## Summary +## الملخص -Elements have the following geometry properties: +العناصر لها خصائص الهندسة التالية: -- `offsetParent` -- is the nearest positioned ancestor or `td`, `th`, `table`, `body`. -- `offsetLeft/offsetTop` -- coordinates relative to the upper-left edge of `offsetParent`. -- `offsetWidth/offsetHeight` -- "outer" width/height of an element including borders. -- `clientLeft/clientTop` -- the distances from the upper-left outer corner to the upper-left inner (content + padding) corner. For left-to-right OS they are always the widths of left/top borders. For right-to-left OS the vertical scrollbar is on the left so `clientLeft` includes its width too. -- `clientWidth/clientHeight` -- the width/height of the content including paddings, but without the scrollbar. -- `scrollWidth/scrollHeight` -- the width/height of the content, just like `clientWidth/clientHeight`, but also include scrolled-out, invisible part of the element. -- `scrollLeft/scrollTop` -- width/height of the scrolled out upper part of the element, starting from its upper-left corner. +- `offsetParent` - أقرب سلف تم وضعه أو` td` أو `th` أو` table` أو `body`. +- `offsetLeft / offsetTop` - الإحداثيات المتعلقة بالحافة العلوية اليسرى لـ` offsetParent`. +- "offsetWidth / offsetHeight" - العرض / الارتفاع "الخارجي" للعنصر بما في ذلك الحدود. +- `clientLeft / clientTop` - المسافات من الزاوية الخارجية العلوية اليسرى إلى الزاوية الداخلية العلوية اليسرى (المحتوى + المساحة). بالنسبة لنظام التشغيل من اليسار إلى اليمين ، تكون دائمًا عروض الحدود اليسرى / العلوية. بالنسبة لنظام التشغيل من اليمين إلى اليسار ، يكون شريط التمرير الرأسي على اليسار بحيث يتضمن "clientLeft" عرضه أيضًا. +- "clientWidth / clientHeight" - عرض / ارتفاع المحتوى بما في ذلك البطانات ، ولكن بدون شريط التمرير. +- "التمرير / التمرير" - عرض / ارتفاع المحتوى ، مثل "clientWidth / clientHeight" ، ولكن يشمل أيضًا الجزء غير المرئي من العنصر. +- `التمرير لليسار / التمرير العلوي` - عرض / ارتفاع الجزء العلوي الذي تم تمريره للخارج من العنصر ، بدءًا من الزاوية العلوية اليسرى. -All properties are read-only except `scrollLeft/scrollTop` that make the browser scroll the element if changed. +جميع الخصائص للقراءة فقط باستثناء `التمرير الأيسر / التمرير العلوي` والتي تجعل المتصفح يقوم بتمرير العنصر إذا تم تغييره. \ No newline at end of file