From fe977620ccc9fd7b06d95e150cbbc582468ad014 Mon Sep 17 00:00:00 2001 From: Saiful Date: Sat, 6 Mar 2021 13:22:02 +0600 Subject: [PATCH 01/10] translate styles and classes --- .../08-styles-and-classes/article.md | 183 +++++++++--------- 1 file changed, 91 insertions(+), 92 deletions(-) diff --git a/2-ui/1-document/08-styles-and-classes/article.md b/2-ui/1-document/08-styles-and-classes/article.md index 9154d43d6..c09573908 100644 --- a/2-ui/1-document/08-styles-and-classes/article.md +++ b/2-ui/1-document/08-styles-and-classes/article.md @@ -1,37 +1,37 @@ -# Styles and classes +# Styles এবং classes -Before we get into JavaScript's ways of dealing with styles and classes -- here's an important rule. Hopefully it's obvious enough, but we still have to mention it. +জাভাস্ক্রিপ্টের সাহায্যে style এবং class নিয়ে কাজ করার সময় আমাদের কিছু গুরুত্বপূর্ণ রুল জেনে রাখা উচিত। যদিও আমাদের কাছে অনেক কিছু সুস্পষ্ট, তারপরও কিছু বিষয় জেনে রাখা উচিত। -There are generally two ways to style an element: +দুইটি উপায়ে আমরা এলিমেন্টে স্ট্যাইল করতে পারি: -1. Create a class in CSS and add it: `
` -2. Write properties directly into `style`: `
`. +1. CSS ক্লাস এর মাধ্যমে: `
` +2. সরাসরি `style` প্রপার্টির মাধ্যমে : `
`। -JavaScript can modify both classes and `style` properties. +জাভাস্ক্রিপ্টের মাধ্যমে ক্লাস এবং `style` প্রপার্টিকে উভয়ভাবে আমরা পরিবর্তন করতে পারি। -We should always prefer CSS classes to `style`. The latter should only be used if classes "can't handle it". +তবে আমাদের `style` এর জন্য CSS ক্লাস ব্যবহার করাই বেশি উপযোগী। তবে যদি ক্লাসের মাধ্যমে সম্পূর্ন ব্যাপারটি কন্ট্রোল করতে না পারি তাহলে দ্বিতীয়টির মাধ্যমে করা উচিত। -For example, `style` is acceptable if we calculate coordinates of an element dynamically and want to set them from JavaScript, like this: +যেমন, আমরা জাভাস্ক্রিপ্টের মাধ্যমে ডায়নামিক্যালি কো-অর্ডিনেট ক্যালকুলেশন করে `style` এ সেট করতে পারি, এভাবে: ```js -let top = /* complex calculations */; -let left = /* complex calculations */; +let top = /* জটিল ক্যালকুলেশন */; +let left = /* জটিল ক্যালকুলেশন */; -elem.style.left = left; // e.g '123px', calculated at run-time -elem.style.top = top; // e.g '456px' +elem.style.left = left; // যেমন '123px', রানটাইমে ক্যালকুলেশন +elem.style.top = top; // যেমন '456px' ``` -For other cases, like making the text red, adding a background icon -- describe that in CSS and then add the class (JavaScript can do that). That's more flexible and easier to support. +অন্যান্য ক্ষেত্রে, যেমন টেক্সট কালার লাল, বা আইকন পরিবর্তন ইত্যাদি আমরা জাভাস্ক্রিপ্টের মাধ্যমে *CSS class* সংযুক্ত করণের দ্বারা করতে পারি। এটি আরো বেশি সহজ এবং উপযোগী। -## className and classList +## className এবং classList -Changing a class is one of the most often used actions in scripts. +জাভাস্ক্রিপ্টের মাধ্যমে আমরা প্রায়সই ক্লাসের নাম পরিবর্তন করে থাকি। -In the ancient time, there was a limitation in JavaScript: a reserved word like `"class"` could not be an object property. That limitation does not exist now, but at that time it was impossible to have a `"class"` property, like `elem.class`. +পূর্বে জাভাস্ক্রিপ্টের কিছু সীমাবদ্ধতা ছিল: `"class"` একটি রিসার্ভড ওয়ার্ড হওয়ায় এটি অবজেক্টের প্রপার্টি হতে পারত না। তবে সীমাবদ্ধতাটি এখন আর নেই, কিন্তু অই সময় `"class"` নামের প্রপার্টি অ্যাসাইন করা সম্ভব হত নাহ, যেমন `elem.class`। -So for classes the similar-looking property `"className"` was introduced: the `elem.className` corresponds to the `"class"` attribute. +ক্লাসের জন্য আমাদের অনুরূপ একটি প্রপার্টি ছিল `"className"`: `elem.className` দ্বারা `"class"` অ্যাট্রিবিউটকে নির্দেশ করে। -For instance: +উদাহরণস্বরূপ: ```html run @@ -41,19 +41,19 @@ For instance: ``` -If we assign something to `elem.className`, it replaces the whole string of classes. Sometimes that's what we need, but often we want to add/remove a single class. +যদি আমরা `elem.className` এ কিছু অ্যাসাইন করি তাহলে এটি সম্পূর্ন ক্লাস স্ট্রিংটিকে রিপ্লেস করে। মাঝে মাঝে আমাদের এটি দরকার হয়, কিন্তু বেশিরভাগ সময় আমাদের একটি সিংগেল ক্লাস সংযুক্ত/বাদ দেয়া লাগে। -There's another property for that: `elem.classList`. +এজন্য আমাদের আরেকটি প্রপার্টি আছে: `elem.classList`। -The `elem.classList` is a special object with methods to `add/remove/toggle` a single class. +`elem.classList` একটি স্পেশাল অবজেক্ট যার কিছু মেথড আছে `add/remove/toggle`। -For instance: +উদাহরণস্বরূপ: ```html run ``` -This property is rarely used, because such assignment removes all existing styles: it does not add, but replaces them. May occasionally delete something needed. But we can safely use it for new elements, when we know we won't delete an existing style. +প্রপার্টিটি কদাচিৎ ব্যবহার হয়, কেননা এর ফলে বিদ্যমান সকল স্ট্যাইল রিমুভ হয়ে যায়: এটি পুরনো স্ট্যাইল টিকে সম্পুর্ন পরিবর্তন করে দেয়, এর ফলে অনেক সময় আমাদের প্রয়োজনীয় স্ট্যাইলও ডিলিট হয়ে যায়। তবে নতুন কোন এলিমেন্টে একাধিক স্ট্যাইল সেটের জন্য এটি উপযোগী, যখন আমরা জানি প্রয়োজনীয় কোন স্ট্যাইল এখনো সেট হয়নি। -The same can be accomplished by setting an attribute: `div.setAttribute('style', 'color: red...')`. +আমরা এভাবেও করতে পারি: `div.setAttribute('style', 'color: red...')`। ```` ## Mind the units -Don't forget to add CSS units to values. +CSS ইউনিট ভ্যালু লিখতে ভুলবেন না। -For instance, we should not set `elem.style.top` to `10`, but rather to `10px`. Otherwise it wouldn't work: +উদাহরণস্বরূপ, আমাদের `elem.style.top` কে শুধুমাত্র `10` দ্বারা লিখলে হবে না, তার পরিবর্তে ইউনিট লিখা লাগবে যেমন `10px`। অন্যথায় এটি কাজ করবে না: ```html run height=100 ``` ```` -```smart header="Styles applied to `:visited` links are hidden!" -Visited links may be colored using `:visited` CSS pseudoclass. +```smart header="Styles applied to `:visited` লিংক অদৃশ্য!" +ভিজিটেড লিংক সমূহ হয়তবা CSS pseudoclass `:visited` এর জন্য একটি কালার দেখায়। -But `getComputedStyle` does not give access to that color, because otherwise an arbitrary page could find out whether the user visited a link by creating it on the page and checking the styles. +কিন্তু `getComputedStyle` এটি কোন কালারের মান রিটার্ন করে না কারণ এটির অ্যাক্সেস থাকে না, কেননা একটি স্বতন্ত্র পেজে স্ট্যাইল যাচাইয়ের মাধ্যমে সহজেই জানা যাবে কোন কোন পেজ ভিজিট করা হয়েছে। -JavaScript may not see the styles applied by `:visited`. And also, there's a limitation in CSS that forbids applying geometry-changing styles in `:visited`. That's to guarantee that there's no side way for an evil page to test if a link was visited and hence to break the privacy. +তাই জাভাস্ক্রিপ্টের মাধ্যমে `:visited` এর মান জানা সম্ভব না। এটি আমাদের গোপনীয়তার নিশ্চয়তা প্রদান করে। ``` -## Summary +## সারাংশ -To manage classes, there are two DOM properties: +ক্লাস ম্যানিপুলেসনের জন্য, দুটি DOM প্রপার্টি আছে: -- `className` -- the string value, good to manage the whole set of classes. -- `classList` -- the object with methods `add/remove/toggle/contains`, good for individual classes. +- `className` -- ক্লাস অ্যাট্রিবিউটের সকল ক্লাস স্ট্রিং হিসেবে রিটার্ন করে, এলিমেন্টের সকল ক্লাসের জন্য এটি উপযোগী। +- `classList` -- একটি অবজেক্ট যার মেথডসমূহ `add/remove/toggle/contains`, সিংগেল ক্লাসের জন্য উপযোগী। -To change the styles: +স্ট্যাইল পরিবর্তনের জন্য: -- The `style` property is an object with camelCased styles. Reading and writing to it has the same meaning as modifying individual properties in the `"style"` attribute. To see how to apply `important` and other rare stuff -- there's a list of methods at [MDN](mdn:api/CSSStyleDeclaration). +- `style` প্রপার্টি একটি অবজেক্ট যার প্রপার্টি সমূহ ক্যামেল কেসের হয়ে থাকে। প্রতিটি একক প্রপার্টি পড়তে এবং অ্যাসাইন করতে এটি উপযোগী। কিভাবে আমরা `important` এবং অন্যান্য কদাচিৎ ব্যবহৃত বিষয়গুলো ব্যবহার করতে পারি -- তা জানতে এটি দেখুন [MDN](mdn:api/CSSStyleDeclaration)। +- `style.cssText` এর সাহায্যে আমরা একাধিক `"style"` অ্যাট্রিবিউট সেট করতে পারি। -- The `style.cssText` property corresponds to the whole `"style"` attribute, the full string of styles. +কোন এলিমেন্টের প্রয়োগকৃত সর্বশেষ সকল স্ট্যাইল জানতে: -To read the resolved styles (with respect to all classes, after all CSS is applied and final values are calculated): - -- The `getComputedStyle(elem, [pseudo])` returns the style-like object with them. Read-only. +- `getComputedStyle(elem, [pseudo])` সকল প্রপার্টি রিটার্ন করবে. এটি Read-only। From e8c8c0695ce391c5d095a228f4787372ad60f9b2 Mon Sep 17 00:00:00 2001 From: Saiful Date: Sat, 6 Mar 2021 13:22:20 +0600 Subject: [PATCH 02/10] translate task --- .../2-create-notification/task.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/2-ui/1-document/08-styles-and-classes/2-create-notification/task.md b/2-ui/1-document/08-styles-and-classes/2-create-notification/task.md index 60930cb6c..6d5694d5c 100644 --- a/2-ui/1-document/08-styles-and-classes/2-create-notification/task.md +++ b/2-ui/1-document/08-styles-and-classes/2-create-notification/task.md @@ -2,14 +2,14 @@ importance: 5 --- -# Create a notification +# নোটিফিকেশন তৈরি -Write a function `showNotification(options)` that creates a notification: `
` with the given content. The notification should automatically disappear after 1.5 seconds. +`showNotification(options)` নামের একটি ফাংশন লিখুন যা একটি নোটিফিকেশন দেখাবে: `
`। নোটিফিকেশনটি ১.৫ সেকেন্ড পর অদৃশ্য হবে। -The options are: +options হবে: ```js -// shows an element with the text "Hello" near the right-top of the window +// "Hello" টেক্সট সহকারে একটি এলিমেন্ট দেখাবে window এর উপরের ডান কোণায় showNotification({ top: 10, // 10px from the top of the window (by default 0px) right: 10, // 10px from the right edge of the window (by default 0px) @@ -21,4 +21,4 @@ showNotification({ [demo src="solution"] -Use CSS positioning to show the element at given top/right coordinates. The source document has the necessary styles. +CSS পজিশনিং স্ট্যাইল ব্যবহার করুন top/right এর জন্য। From 0a71143aa7a5e25f87d95eac4db4e4b30169a6fd Mon Sep 17 00:00:00 2001 From: Saiful Date: Tue, 9 Mar 2021 13:26:26 +0600 Subject: [PATCH 03/10] translate content --- .../01-introduction-browser-events/article.md | 222 +++++++++--------- 1 file changed, 110 insertions(+), 112 deletions(-) diff --git a/2-ui/2-events/01-introduction-browser-events/article.md b/2-ui/2-events/01-introduction-browser-events/article.md index 19394e49e..018ede551 100644 --- a/2-ui/2-events/01-introduction-browser-events/article.md +++ b/2-ui/2-events/01-introduction-browser-events/article.md @@ -1,56 +1,56 @@ -# Introduction to browser events +# browser events এর সূচনা -*An event* is a signal that something has happened. All DOM nodes generate such signals (but events are not limited to DOM). +*event* হল কোন কিছু ঘটার একটি সংকেত। সকল DOM নোড এই ধরণের সংকেত জেনারেট করতে পারে(কিন্তু event শুধুমাত্র এর মধ্যই সীমাবদ্ধ না)। -Here's a list of the most useful DOM events, just to take a look at: +নিচে গুরুত্বপূর্ণ কিছু DOM ইভেন্ট নিয়ে আলোচনা করা হল: **Mouse events:** -- `click` -- when the mouse clicks on an element (touchscreen devices generate it on a tap). -- `contextmenu` -- when the mouse right-clicks on an element. -- `mouseover` / `mouseout` -- when the mouse cursor comes over / leaves an element. -- `mousedown` / `mouseup` -- when the mouse button is pressed / released over an element. -- `mousemove` -- when the mouse is moved. +- `click` -- যখন কোন এলিমেন্টে ক্লিক করা হয় (টাচস্ক্রীন ডিভাইসে ট্যাপ করলে)। +- `contextmenu` -- এলিমেন্টে মাউসের ডানের বাটনটি ক্লিক হলে। +- `mouseover` / `mouseout` -- কোন এলিমেন্টে মাউসের কার্সর আসলে অথবা এলিমেন্ট হতে ছেড়ে গেলে। +- `mousedown` / `mouseup` -- যখন কোন একটি এলিমেন্টে মাউস বাটন ক্লিক হয় বা ছাড়া হয়। +- `mousemove` -- যখন মাউস নাড়াচড়া করা হয়। **Keyboard events:** -- `keydown` and `keyup` -- when a keyboard key is pressed and released. +- `keydown` এবং `keyup` -- যখন কি-বোর্ডে কোন বাটন প্রেস হয়, এবং বাটন প্রেস সম্পন্ন হয়। **Form element events:** -- `submit` -- when the visitor submits a `
`. -- `focus` -- when the visitor focuses on an element, e.g. on an ``. +- `submit` -- যখন কোন একটি `` সাবমিট হয়। +- `focus` -- যখন কোন একটি এলিমেন্টে ফোকাস হয় যেমন, ``। **Document events:** -- `DOMContentLoaded` -- when the HTML is loaded and processed, DOM is fully built. +- `DOMContentLoaded` -- যখন DOM সম্পূর্ণ বিল্ট হয় এবং HTML লোড প্রসেসড হয়। **CSS events:** -- `transitionend` -- when a CSS-animation finishes. +- `transitionend` -- যখন একটি CSS-animation সম্পন্ন হয়। -There are many other events. We'll get into more details of particular events in next chapters. +এছাড়াও আরো অনেক ইভেন্ট আছে। পরবর্তী অধ্যায় সমূহে আমরা আরো বিস্তারিত জানব। ## Event handlers -To react on events we can assign a *handler* -- a function that runs in case of an event. +ইভেন্টগুলো কিভাবে সংগঠিত হবে তা অ্যাসাইন করা হয় *handler* দ্বারা -- এটি একটি ফাংশন। -Handlers are a way to run JavaScript code in case of user actions. +হ্যান্ডেলার হল ইউজারের চাহিদামত জাভাস্ক্রিপ্ট কোড রান করার একটি উপায়, অন্য কথায় ইভেন্ট সংগঠিত হলে যে ফাংশনটি কল হয়। -There are several ways to assign a handler. Let's see them, starting from the simplest one. +বিভিন্নভাবে আমরা হ্যান্ডেলার অ্যাসাইন করতে পারি। চলুন, সবচেয়ে সহজটি দিয়ে শুরু করি। ### HTML-attribute -A handler can be set in HTML with an attribute named `on`. +অ্যাট্রিবিউট আকারে হ্যান্ডেলার `on` সেট করা। -For instance, to assign a `click` handler for an `input`, we can use `onclick`, like here: +যেমন, `input` এ একটি `click` হ্যান্ডেলার অ্যাসাইন করতে, আমরা `onclick` ব্যবহার করতে পারি, এভাবে: ```html run ``` -On mouse click, the code inside `onclick` runs. +মাউস ক্লিক হলে, `onclick` এর মধ্যের কোড রান হবে। -Please note that inside `onclick` we use single quotes, because the attribute itself is in double quotes. If we forget that the code is inside the attribute and use double quotes inside, like this: `onclick="alert("Click!")"`, then it won't work right. +দয়া করে মনে রাখুন `onclick` এর মধ্যে আমাদের একক উদ্ধৃতি চিহ্ন *''* ব্যবহার করা লাগবে, কেননা অ্যাট্রিবিউটটি যুগল উদ্ধৃতি চিহ্ন *""* দ্বারা লিখা হয়েছে। যদি আমরা উভয়ই যুগল উদ্ধৃতি চিহ্ন ব্যবহার করি, এভাবে: `onclick="alert("Click!")"`, তাহলে এটি কাজ করবে না। -An HTML-attribute is not a convenient place to write a lot of code, so we'd better create a JavaScript function and call it there. +HTML-attribute এ অনেক কোড লিখা তেমন সুবিধাজনক না। সুতরাং আমাদের জন্য সুবিধাজনক হবে আলাদা ফাংশনে কোড লিখে তাদের কল করলে। -Here a click runs the function `countRabbits()`: +**onclick এর মাধ্যমে ফাংশন কল** `countRabbits()`: ```html autorun height=50 ``` -If the handler is assigned using an HTML-attribute then the browser reads it, creates a new function from the attribute content and writes it to the DOM property. +অ্যাট্রিবিটের সাহায্যে লিখিত হ্যান্ডেলারটি, একটি নতুন ফাংশন তৈরি করে এবং DOM প্রপার্টিতে এটি সেট করে। -So this way is actually the same as the previous one. +সুতরাং এটি পূর্ববর্তী টির মত কাজ করে। -These two code pieces work the same: +নিচের দুটি কোডের কাজ একই: -1. Only HTML: +1. শুধুমাত্র HTML: ```html autorun height=50 @@ -107,30 +107,30 @@ These two code pieces work the same: ``` -In the first example, the HTML attribute is used to initialize the `button.onclick`, while in the second example -- the script, that's all the difference. +প্রথম উদাহরণটিতে, অ্যাট্রিবিউটটি `button.onclick` ইনিশিয়ালাইজ করে, যেখানে দ্বিতীয় উদাহরণটি একটি -- স্ক্রিপ্ট, এটিই মূল পার্থক্য। -**As there's only one `onclick` property, we can't assign more than one event handler.** +**এক্ষেত্রে শুধুমাত্র একটি `onclick` প্রপার্টি থাকবে, সুতরাং আমরা একের অধিক হ্যান্ডেলার সেট করতে পারব না।** -In the example below adding a handler with JavaScript overwrites the existing handler: +নিচের উদাহরণটিতে দেখুন স্ক্রিপ্টের ফাংশনটি অ্যাট্রিবিউট হ্যান্ডেলারকে ওভাররাইট করে: ```html run height=50 autorun ``` -To remove a handler -- assign `elem.onclick = null`. + হ্যান্ডেলার রিমুভ করতে -- `elem.onclick = null`। -## Accessing the element: this +## this এর মাধ্যমে এলিমেন্টকে অ্যাক্সেস -The value of `this` inside a handler is the element. The one which has the handler on it. +হ্যান্ডেলারের মধ্যে `this` দ্বারা এলিমেন্টটিকে মির্দেশ করে। অর্থাৎ যে এলিমেন্টটি হ্যান্ডেলারে লিখা হয়েছে। -In the code below `button` shows its contents using `this.innerHTML`: +নিচের কোডটি রান হলে এটি `button` এর কন্টেন্টটি দেখাবে `this.innerHTML`: ```html height=50 autorun @@ -138,9 +138,9 @@ In the code below `button` shows its contents using `this.innerHTML`: ## Possible mistakes -If you're starting to work with events -- please note some subtleties. +যখন আমরা ইভেন্ট নিয়ে কোন কাজ করব --আমাদের কিছু ব্যপার মনে রাখতে হবে। -We can set an existing function as a handler: +আমরা কোন এক্সিটিং ফাংশনকে এভাবে হ্যান্ডেলার হিসেবে সেট করতে পারি: ```js function sayThanks() { @@ -150,93 +150,91 @@ function sayThanks() { elem.onclick = sayThanks; ``` -But be careful: the function should be assigned as `sayThanks`, not `sayThanks()`. +কিন্তু সাবধান! আমাদের ফাংশনটি এভাবে অ্যাসাইন করতে হবে `sayThanks`, `sayThanks()` কাজ করবে না। ```js -// right +// সঠিক button.onclick = sayThanks; -// wrong +// ভুল button.onclick = sayThanks(); ``` -If we add parentheses, then `sayThanks()` becomes is a function call. So the last line actually takes the *result* of the function execution, that is `undefined` (as the function returns nothing), and assigns it to `onclick`. That doesn't work. +যদি আমরা প্যারেন্টেসিস সহকারে লিখি, তাহলে `sayThanks()` একটি ফাংশন কল হবে। শেষেরটি *result*ঠিসেবে নতুন আরেকটি ফাংশন এক্সিকিউশন হিসেবে নেয়, যা `undefined`, এবং এটি `onclick` অ্যাসাইন করে। তাই এটি কাজ করবে না। -...On the other hand, in the markup we do need the parentheses: +...আবার অন্যদিকে, এলিমেন্ট হতে কল করলে প্যারেন্টেসিস সহকারে করতে হবে: ```html ``` -The difference is easy to explain. When the browser reads the attribute, it creates a handler function with body from the attribute content. - -So the markup generates this property: +এটি নিচের কোডটি দেখলে আমরা সহজেই বুঝতে পারব, ব্রাউজার অ্যাট্রিবিউট হতে কন্টেন্ট নিয়ে ফাংশনটিকে এভাবে কল করে: ```js button.onclick = function() { *!* - sayThanks(); // <-- the attribute content goes here + sayThanks(); // <-- অ্যাট্রিবিউটের কন্টেন্ট এখানে সেট হয় */!* }; ``` -**Don't use `setAttribute` for handlers.** +**হ্যান্ডেলার সেট করতে `setAttribute` ব্যবহার করবেন না** -Such a call won't work: +এটি কাজ করবে না: ```js run no-beautify -// a click on will generate errors, -// because attributes are always strings, function becomes a string +// বডিতে ক্লিক করলে ইরোর দেখাবে, +// কেননা অ্যাট্রিবিউট সমূহ সর্বদা স্ট্রিং হিসেবে সেট হয় document.body.setAttribute('onclick', function() { alert(1) }); ``` -**DOM-property case matters.** +**DOM-property এর ক্ষেত্রে কেস গুরুত্বপূর্ন** -Assign a handler to `elem.onclick`, not `elem.ONCLICK`, because DOM properties are case-sensitive. +হ্যান্ডেলার অ্যাসাইন করতে `elem.onclick` কাজ করবে, কিন্তু `elem.ONCLICK` কাজ করবে না, কেননা DOM প্রপার্টি সমূহ কেস-সেনসিটিভ। ## addEventListener -The fundamental problem of the aforementioned ways to assign handlers -- we can't assign multiple handlers to one event. +উপরোল্লিখিত নিয়ম অনুযায়ী হ্যান্ডেলার অ্যাসাইনের মূল সমস্যা হল -- আমরা একাধিক হ্যান্ডেলার অ্যাসাইন করতে পারব না। -Let's say, one part of our code wants to highlight a button on click, and another one wants to show a message on the same click. +যেমন ধরা যাক, আমরা বাটন ক্লিকে আমরা তা হাইলাইট করতে চায়, এবং তারপর ঐ ক্লিকে একটি মেসেজ দেখাব। -We'd like to assign two event handlers for that. But a new DOM property will overwrite the existing one: +আমরা এজন্য দুটি হ্যান্ডেলার অ্যাসাইন করতে চাই। কিন্তু DOM প্রপার্টি বিদ্যমান হ্যান্ডেলারকে নতুনটি দ্বারা প্রতিস্থাপন করে দেয়: ```js no-beautify input.onclick = function() { alert(1); } // ... -input.onclick = function() { alert(2); } // replaces the previous handler +input.onclick = function() { alert(2); } // পূর্ববর্তী হ্যান্ডেলারকে নতুনটি দ্বারা প্রতিস্থাপন ``` -Developers of web standards understood that long ago and suggested an alternative way of managing handlers using special methods `addEventListener` and `removeEventListener`. They are free of such a problem. +এজন্য ডেভলাপাররা এই সমস্যা সমাধানের জন্য আরো দুটি বিশেষ মেথড নিয়ে আসে `addEventListener` এবং `removeEventListener`। এদের সাহায্যে আমরা এই সমস্যার সমাধান করতে পারি। -The syntax to add a handler: +হ্যান্ডেলার অ্যাসাইনের সিনট্যাক্সটি হল: ```js element.addEventListener(event, handler, [options]); ``` `event` -: Event name, e.g. `"click"`. +: ইভেন্টের নাম, যেমন `"click"`। `handler` -: The handler function. +: হ্যান্ডেলার ফাংশন `options` -: An additional optional object with properties: - - `once`: if `true`, then the listener is automatically removed after it triggers. - - `capture`: the phase where to handle the event, to be covered later in the chapter . For historical reasons, `options` can also be `false/true`, that's the same as `{capture: false/true}`. - - `passive`: if `true`, then the handler will not call `preventDefault()`, we'll explain that later in . +: কিছু ঐচ্ছিক প্রপার্টির একটি অবজেক্ট: + - `once`: যদি `true` হয়, তাহলে এটি একবার কল হওয়ার পর স্বয়ংক্রিয়ভাবে রিমুভ হয়ে যাবে। + - `capture`: এই ব্যাপারে আমরা পরবর্তী অধ্যায়ে জানব । তবে জেনে রাখুন, `options` টি `false/true` হতে পারে, অর্থাৎ `{capture: false/true}`। + - `passive`: যদি `true` হয়, তাহলে হ্যান্ডেলার `preventDefault()` কে কল করবে না, আরো বিস্তারিত জানব এই অধ্যায়ে । -To remove the handler, use `removeEventListener`: +হ্যান্ডেলার রিমুভের জন্য, `removeEventListener`: ```js element.removeEventListener(event, handler, [options]); ``` -````warn header="Removal requires the same function" -To remove a handler we should pass exactly the same function as was assigned. +````warn header="রিমুভ করা যায় একই ফাংশনকে" +হ্যান্ডেলারকে ফাংশনকে রিমুভের জন্য অ্যাসাইকৃত ফাংশনটিই পাস করতে হবে। -This doesn't work: +এটি কাজ করবে না: ```js no-beautify elem.addEventListener( "click" , () => alert('Thanks!')); @@ -244,9 +242,9 @@ elem.addEventListener( "click" , () => alert('Thanks!')); elem.removeEventListener( "click", () => alert('Thanks!')); ``` -The handler won't be removed, because `removeEventListener` gets another function -- with the same code, but that doesn't matter, as it's a different function object. +হ্যান্ডেলার রিমুভ কাজ করবে না, কেননা `removeEventListener` ফাংশনটি একই কোডের আরেকটি ফাংশন, কিন্তু এটি কোন ব্যাপার না, কেননা এটি ভিন্ন ফাংশন অবজেক্ট। -Here's the right way: +এটি কাজ করবে: ```js function handler() { @@ -258,10 +256,10 @@ input.addEventListener("click", handler); input.removeEventListener("click", handler); ``` -Please note -- if we don't store the function in a variable, then we can't remove it. There's no way to "read back" handlers assigned by `addEventListener`. +সুতরাং আমরা বলতে পারি -- কোন ধরণের অ্যানোনিমাস ফাংশনকে আমরা রিমুভ করতে পারব না। ```` -Multiple calls to `addEventListener` allow to add multiple handlers, like this: +`addEventListener` এর মাধ্যমে একাধিক হ্যান্ডেলার কল করার উপায়টি, এমন: ```html run no-beautify @@ -283,78 +281,78 @@ Multiple calls to `addEventListener` allow to add multiple handlers, like this: ``` -As we can see in the example above, we can set handlers *both* using a DOM-property and `addEventListener`. But generally we use only one of these ways. +উপরের উদাহরণে আমরা দেখছি, আমরা DOM-property এবং `addEventListener` এর মাধ্যমে হ্যান্ডেলার অ্যাসাইন করছি। তবে সাধারণত আমরা যেকোন এক উপায়ে হ্যান্ডেলার সেট করব। -````warn header="For some events, handlers only work with `addEventListener`" -There exist events that can't be assigned via a DOM-property. Only with `addEventListener`. +````warn header="কিছু ইভেন্ট আছে শুধু `addEventListener` এর সাথে কাজ করে" +কিছু ইভেন্ট আছে যারা DOM-property এর সাথে কাজ করে না, শুধুমাত্র `addEventListener` এর মাধ্যমে কাজ করে। -For instance, the `DOMContentLoaded` event, that triggers when the document is loaded and DOM is built. +যেমন, `DOMContentLoaded` ইভেন্ট, এটি ট্রিগার হয় যখন সম্পূর্ন DOM লোড হয়ে DOM অবজেক্টটি তৈরি হয়। ```js -// will never run +// এটি রান হবে না document.onDOMContentLoaded = function() { alert("DOM built"); }; ``` ```js -// this way it works +// এটি কাজ করবে document.addEventListener("DOMContentLoaded", function() { alert("DOM built"); }); ``` -So `addEventListener` is more universal. Although, such events are an exception rather than the rule. +সুতরাং `addEventListener` আরো বেশি সুবিধাজনক। এছাড়াও, এই ধরণের ইভেন্ট সমূহ কিছু ব্যতিক্রম। ```` ## Event object -To properly handle an event we'd want to know more about what's happened. Not just a "click" or a "keydown", but what were the pointer coordinates? Which key was pressed? And so on. +ইভেন্ট নিয়ে কাজ করার সময় আমাদের অনেক ব্যাপার জানা লাগে, এটি শুধু "ক্লিক" বা "কী প্রেসে" সীমাবদ্ধ না, আমাদের জানা লাগতে পারে কোন কী প্রেস করা হয়েছে বা কোন স্থানাংকে মাউস ক্লিক হয়েছে। -When an event happens, the browser creates an *event object*, puts details into it and passes it as an argument to the handler. +যখন কোন ইভেন্ট সংগঠিত হয়, ব্রাউজার *event object* তৈরি করে, এবং সকল বিস্তারিত প্রপার্টি নিয়ে *event object* টি হ্যান্ডেলারে পাস হয়। -Here's an example of getting pointer coordinates from the event object: +এখানে কোন স্থানাংকে মাউস ক্লিক হয়েছে তার একটি উদাহরণ দেখানো হল: ```html run ``` -Some properties of `event` object: +`event` অবজেক্ট এর কিছু প্রপার্টি: `event.type` -: Event type, here it's `"click"`. +: ইভেন্ট টাইপ, এখানে এটি `"click"`। `event.currentTarget` -: Element that handled the event. That's exactly the same as `this`, unless the handler is an arrow function, or its `this` is bound to something else, then we can get the element from `event.currentTarget`. +: যে এলিমেন্টে ইভেন্টটি সংগঠিত হয়। এটি এলিমেন্টের `this` এর মত, যতক্ষন হ্যান্ডেলারটি অ্যারো ফাংশনের সাহায্যে কল করা হয়, অন্যথায় `this` অন্য কোন কনট্যাক্স কে বুঝায়। `event.clientX / event.clientY` -: Window-relative coordinates of the cursor, for pointer events. +: windows এর সাপেক্ষে কার্সরের স্থানাংক। -There are more properties. Many of them depend on the event type: keyboard events have one set of properties, pointer events - another one, we'll study them later when we come to different events in details. +এছাড়াও আরো অনেক প্রপার্টি আছে। বেশিরভাগ ইভেন্টের ধরণের উপর নির্ভর করে: কী-বোর্ড ইভেন্টের প্রপার্টি এক ধরণের, পয়েন্টার ইভেন্টের প্রপার্টি অন্য ধরণের, পরবর্তী অধ্যায় সমূহে আমরা ইভেন্টের ধরণ অনুযায়ী বিস্তারিত জানব। -````smart header="The event object is also available in HTML handlers" -If we assign a handler in HTML, we can also use the `event` object, like this: +````smart header="HTML অ্যাট্রিবিউট হ্যান্ডেলারেও ইভেন্ট অবজেক্ট অ্যাক্সেস করা যায়" +যদি আমরা HTML এ কোন হ্যান্ডেলার অ্যাসাইন করি, আমরা `event` অবজেক্টটি এভাবে ব্যবহার করতে পারি: ```html autorun height=60 ``` -That's possible because when the browser reads the attribute, it creates a handler like this: `function(event) { alert(event.type) }`. That is: its first argument is called `"event"`, and the body is taken from the attribute. +এটি সম্ভব হয় কেননা যখন ব্রাউজার অ্যাট্রিবিউট হতে হ্যান্ডেলার ফাংশনটি এভাবে তৈরি করে: `function(event) { alert(event.type) }`। সুতরাং প্রথম আর্গুমেন্টটি হয় `"event"`। ```` ## Object handlers: handleEvent -We can assign not just a function, but an object as an event handler using `addEventListener`. When an event occurs, its `handleEvent` method is called. +আমরা চাইলে `addEventListener` এ কোন অবজেক্টকেও হ্যান্ডেলার হিসেবে পাস করতে পারি। যখন কোন ইভেন্ট সংগঠিত হয়, এটি `handleEvent` মেথডকে কল করে। -For instance: +যেমন: ```html run @@ -371,9 +369,9 @@ For instance: ``` -As we can see, when `addEventListener` receives an object as the handler, it calls `obj.handleEvent(event)` in case of an event. +এক্ষেত্রে আমরা দেখছি, `addEventListener` হ্যান্ডেলার হিসেবে একটি অবজেক্ট নিচ্ছে, এবং এক্ষেত্রে এটি `obj.handleEvent(event)` কে কল করে। -We could also use a class for that: +আমরা চাইলে ES-6 class সিনট্যাক্স ব্যবহার করতে পারি: ```html run @@ -401,9 +399,9 @@ We could also use a class for that: ``` -Here the same object handles both events. Please note that we need to explicitly setup the events to listen using `addEventListener`. The `menu` object only gets `mousedown` and `mouseup` here, not any other types of events. +এখানে একটি অবজেক্টকে আমরা উভয়ই ইভেন্টের হ্যান্ডেলার হিসেবে ব্যবহার করছি। দয়া করে নোট করুন `addEventListener` এর জন্য আমাদের অবজেক্টটিকে সঠিকভাবে সেটাপ করতে হবে। এক্ষেত্রে `menu` অবজেক্টটি শুধুমাত্র `mousedown` এবং `mouseup` এর সাথে কাজ করবে, অন্যান্য ইভেন্টের জন্য এটি কাজ করবে না। -The method `handleEvent` does not have to do all the job by itself. It can call other event-specific methods instead, like this: +আমরা `handleEvent` মেথডটিকে চাইলে এভাবে ডায়নামিক্যালি ব্যবহার করতে পারি: ```html run @@ -431,22 +429,22 @@ The method `handleEvent` does not have to do all the job by itself. It can call ``` -Now event handlers are clearly separated, that may be easier to support. +এখানে আমরা হ্যান্ডেলার ফাংশনকে আলাদা করে নিলাম, কোডটি পড়তে এবং পরিবর্তন করা সহজ হবে। -## Summary +## সারাংশ -There are 3 ways to assign event handlers: +তিনভাবে আমরা ইভেন্ট হ্যান্ডেলার অ্যাসাইন করতে পারি: -1. HTML attribute: `onclick="..."`. -2. DOM property: `elem.onclick = function`. -3. Methods: `elem.addEventListener(event, handler[, phase])` to add, `removeEventListener` to remove. +1. HTML attribute: `onclick="..."`। +2. DOM property: `elem.onclick = function`। +3. মেথডের সাহায্যে: `elem.addEventListener(event, handler[, phase])` হ্যান্ডেলার সংযুক্ত করতে, `removeEventListener` হ্যান্ডেলার রিমুভ করতে। -HTML attributes are used sparingly, because JavaScript in the middle of an HTML tag looks a little bit odd and alien. Also can't write lots of code in there. +HTML attribute এর সাহায্যে ইভেন্ট খুব কম লিখা হয়, কেননা HTML এ জাভাস্ক্রিপ্ট দেখতে বিদঘুটে লাগে। এছাড়াও আমরা অনেক কোড একসাথে লিখতে পারি না। -DOM properties are ok to use, but we can't assign more than one handler of the particular event. In many cases that limitation is not pressing. +আমরা DOM প্রপার্টির সাহায্যে হ্যান্ডেলার অ্যাসাইন করতে পারি, কিন্তু এর একটি সীমাবদ্ধতা আছে, আমরা শুধুমাত্র একটি হ্যান্ডেলার অ্যাসাইন করতে পারি। -The last way is the most flexible, but it is also the longest to write. There are few events that only work with it, for instance `transitionend` and `DOMContentLoaded` (to be covered). Also `addEventListener` supports objects as event handlers. In that case the method `handleEvent` is called in case of the event. +এবং শেষেরটি ব্যবহার আমাদের জন্য সুবিধাজনক, তবে এটি অন্য দুটি থেকে দেখতে কিছুটা বড়। এছাড়াও কিছু ইভেন্ট আছে যা এটি ছাড়া অন্য কোনভাবে কাজ করবে না, যেমন `transitionend` এবং `DOMContentLoaded` (যা পরবর্তীতে আমরা দেখব)। এছাড়াও `addEventListener` হ্যান্ডেলার হিসেবে অবজেক্ট নিতে পারে। এক্ষেত্রে এটি ডায়নামিক্যালি `handleEvent` মেথড কে কল করে। -No matter how you assign the handler -- it gets an event object as the first argument. That object contains the details about what's happened. +আপনি যেভাবেই হ্যান্ডেলার অ্যাসাইন করুন না কেন -- প্রথম আর্গুমেন্টটি সর্বদা একটি *event object* হয়। যা ইভেন্ট সম্পর্কিত সকল তথ্য ধারণ করে। -We'll learn more about events in general and about different types of events in the next chapters. +এছাড়াও আমরা নির্দিষ্ট ইভেন্ট সম্পর্কিত বিস্তারিত পরবর্তী অধ্যায় সমূহে জানব। From 057b9551c15cbcdb0179591cc7edf93cca3a59d1 Mon Sep 17 00:00:00 2001 From: Saiful Date: Tue, 16 Mar 2021 19:33:37 +0600 Subject: [PATCH 04/10] wip task translation --- .../01-hide-other/solution.view/index.html | 4 ++-- .../01-introduction-browser-events/01-hide-other/task.md | 6 +++--- .../02-hide-self-onclick/solution.md | 2 +- .../02-hide-self-onclick/task.md | 2 +- .../03-which-handlers-run/solution.md | 8 ++++---- .../03-which-handlers-run/task.md | 6 ++---- 6 files changed, 13 insertions(+), 15 deletions(-) diff --git a/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html b/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html index 7228a45de..a1e90e1f6 100644 --- a/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html +++ b/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html @@ -12,8 +12,8 @@
Text
``` -The problem is that when we click on `elem`, we get two menus: the button-level and (the event bubbles up) the document-level menu. +তবে এখানে `elem` এর জন্য একটি সমস্যা দেখা যাচ্ছে, এটির জন্য দুটি অ্যালার্ট দেখায়: একটি button-level এবং অন্যটি document-level। -How to fix it? One of solutions is to think like: "When we handle right-click in the button handler, let's stop its bubbling" and use `event.stopPropagation()`: +কিভাবে এটি ফিক্স করা যায়? একটি সমাধান এভাবে হতে পারে: "যখন আমরা বাটনে ডানের বাটনে প্রেস, তখন `event.stopPropagation()` এর মাধ্যমে bubbling কে থামাতে পারি": ```html autorun height=80 no-beautify run

Right-click for the document menu

@@ -174,9 +173,9 @@ How to fix it? One of solutions is to think like: "When we handle right-click in ``` -Now the button-level menu works as intended. But the price is high. We forever deny access to information about right-clicks for any outer code, including counters that gather statistics and so on. That's quite unwise. +এখন এটি শুধুমাত্র button-level এর জন্য কাজ করছে। তবে এর জন্য আমাদের চরম মূল্য দেয়া লাগতে পারে। এর জন্য আমাদের অন্যান্য লেভেলের ইভেন্ট গুলো আর কাজ করবে না, সুতরা এভাবে করা বোকামি। -An alternative solution would be to check in the `document` handler if the default action was prevented? If it is so, then the event was handled, and we don't need to react on it. +তবে আমাদের কাছে একটি বিকল্প ব্যবস্থা আছে যার মাধ্যমে আমরা এটি সমাধান করতে পারি। আমরা `document` হ্যান্ডেলারে যাচাই করব আমাদের ইভেন্ট কি `defaultPrevented` হয়েছে কিনা? যদি হয়ে থাকে, তাহলে ইভেন্ট টি আগে সংগঠিত হয়েছে, এর ফলে document-level এ কোন কিছু আর ঘটবে না। ```html autorun height=80 no-beautify run @@ -200,45 +199,44 @@ An alternative solution would be to check in the `document` handler if the defau ``` -Now everything also works correctly. If we have nested elements, and each of them has a context menu of its own, that would also work. Just make sure to check for `event.defaultPrevented` in each `contextmenu` handler. +উপরের কোডটি নির্ভুল্ভাবে কাজ করবে। যদি আমাদের নেস্টেড এলিমেন্ট থাকে এবং প্রতিটির নিজস্ব কনট্যাক্স মেন্যু থাকে, তাও কাজ করবে। তবে আমাদের শুধু নিশ্চিত হতে হবে যেন প্রতিটি `contextmenu` হ্যান্ডালারে যেন `event.defaultPrevented` যাচায় করা হয়। -```smart header="event.stopPropagation() and event.preventDefault()" -As we can clearly see, `event.stopPropagation()` and `event.preventDefault()` (also known as `return false`) are two different things. They are not related to each other. +```smart header="event.stopPropagation() এবং event.preventDefault()" +আমাদের কাছে এখন পরিষ্কার, `event.stopPropagation()` এবং `event.preventDefault()` (`return false`) দুটি ভিন্ন মেথড যাদের ব্যবহার আলাদা। ``` -```smart header="Nested context menus architecture" -There are also alternative ways to implement nested context menus. One of them is to have a single global object with a handler for `document.oncontextmenu`, and also methods that allow us to store other handlers in it. +```smart header="নেস্টেড কনট্যাক্স মেন্যু আর্কিটেকচার" +নেস্টেড কনট্যাক্স মেন্যু লিখার বিকল্প উপায়ও আছে। এদের মধ্যে একটি হল `document.oncontextmenu` এর জন্য একটি একক গ্লোবাল অবজেক্ট এবং চাইল্ড এলিমেন্ট প্রত্যেকের জন্য আলাদা আলাদা হ্যান্ডেলার ব্যবহার। -The object will catch any right-click, look through stored handlers and run the appropriate one. +প্রতিবার *right-click* এর জন্য অবজেক্টটি কল হবে এবং এলিমেন্ট অনুযায়ী নির্দিষ্ট হ্যান্ডেলার কল হবে। -But then each piece of code that wants a context menu should know about that object and use its help instead of the own `contextmenu` handler. ``` -## Summary +## সারাংশ -There are many default browser actions: +ব্রাউজারের কিছু নির্দিষ্ট ডিফল্ট অ্যাকশন আছে: -- `mousedown` -- starts the selection (move the mouse to select). -- `click` on `` -- checks/unchecks the `input`. -- `submit` -- clicking an `` or hitting `key:Enter` inside a form field causes this event to happen, and the browser submits the form after it. -- `keydown` -- pressing a key may lead to adding a character into a field, or other actions. -- `contextmenu` -- the event happens on a right-click, the action is to show the browser context menu. -- ...there are more... +- `mousedown` -- সিলেকশন (মাউস মুভ করলে কোন কিছু সিলেক্ট হবে)। +- `click` `` -- ক্লিকে `input` এর checks/unchecks হয়। +- `submit` -- form এর মধ্যে `` এ ক্লিকে বা `key:Enter` প্রেসে ইভেন্টটি সংগঠিত হয়, এবং এর পরে ফর্মটি সাবমিট হয়। +- `keydown` -- কী-বোর্ডে কোন বাটনে ক্লিক হলে ক্যারাক্টার অ্যাড হবে অথবা অন্য কোন অ্যাকশন সংগঠিত হবে। +- `contextmenu` -- মাউসের right-click এ ইভেন্টটি সংগঠিত হয়, এবং এটি ব্রাউজারের context menu দেখায়। +- ...এবং আরো অনেক... -All the default actions can be prevented if we want to handle the event exclusively by JavaScript. +ব্রাউজারের সকল ডিফল্ট অ্যাকশন আমরা জাভাস্ক্রিপ্টের মাধ্যমে রোধ করতে পারি। -To prevent a default action -- use either `event.preventDefault()` or `return false`. The second method works only for handlers assigned with `on`. +সকল ডিফল্ট অ্যাকশন রোধ করতে `event.preventDefault()` বা `return false` ব্যবহার করতে পারি। দ্বিতীয়টি শুধুমাত্র `on` এর সাথেই কাজ করে। -The `passive: true` option of `addEventListener` tells the browser that the action is not going to be prevented. That's useful for some mobile events, like `touchstart` and `touchmove`, to tell the browser that it should not wait for all handlers to finish before scrolling. +`addEventListener` এ `passive: true` অপশনটি দ্বারা বুঝায় ইভেন্টটি কোনখানে রোধ হবে না। কিছু টাচস্ক্রিন ইভেন্টের জন্য এটি ব্যবহার সুবিধাজনক, যেমন `touchstart` এবং `touchmove`, যা ব্রাউজারকে নির্দেশ করে হ্যান্ডেলারের কারণে স্ক্রলিংয়ে কোন বাধাপ্রাপ্ত হবে না। -If the default action was prevented, the value of `event.defaultPrevented` becomes `true`, otherwise it's `false`. +যদি ডিফল্ট অ্যাকশন বাধাপ্রাপ্ত হয়, তাহলে `event.defaultPrevented` এর ভ্যালু `true` হবে, অন্যথায় `false`। ```warn header="Stay semantic, don't abuse" -Technically, by preventing default actions and adding JavaScript we can customize the behavior of any elements. For instance, we can make a link `` work like a button, and a button ` @@ -138,9 +138,9 @@ HTML-attribute এ অনেক কোড লিখা তেমন সুবি ## Possible mistakes -যখন আমরা ইভেন্ট নিয়ে কোন কাজ করব --আমাদের কিছু ব্যপার মনে রাখতে হবে। +If you're starting to work with events -- please note some subtleties. -আমরা কোন এক্সিটিং ফাংশনকে এভাবে হ্যান্ডেলার হিসেবে সেট করতে পারি: +We can set an existing function as a handler: ```js function sayThanks() { @@ -150,91 +150,93 @@ function sayThanks() { elem.onclick = sayThanks; ``` -কিন্তু সাবধান! আমাদের ফাংশনটি এভাবে অ্যাসাইন করতে হবে `sayThanks`, `sayThanks()` কাজ করবে না। +But be careful: the function should be assigned as `sayThanks`, not `sayThanks()`. ```js -// সঠিক +// right button.onclick = sayThanks; -// ভুল +// wrong button.onclick = sayThanks(); ``` -যদি আমরা প্যারেন্টেসিস সহকারে লিখি, তাহলে `sayThanks()` একটি ফাংশন কল হবে। শেষেরটি *result*ঠিসেবে নতুন আরেকটি ফাংশন এক্সিকিউশন হিসেবে নেয়, যা `undefined`, এবং এটি `onclick` অ্যাসাইন করে। তাই এটি কাজ করবে না। +If we add parentheses, then `sayThanks()` becomes is a function call. So the last line actually takes the *result* of the function execution, that is `undefined` (as the function returns nothing), and assigns it to `onclick`. That doesn't work. -...আবার অন্যদিকে, এলিমেন্ট হতে কল করলে প্যারেন্টেসিস সহকারে করতে হবে: +...On the other hand, in the markup we do need the parentheses: ```html ``` -এটি নিচের কোডটি দেখলে আমরা সহজেই বুঝতে পারব, ব্রাউজার অ্যাট্রিবিউট হতে কন্টেন্ট নিয়ে ফাংশনটিকে এভাবে কল করে: +The difference is easy to explain. When the browser reads the attribute, it creates a handler function with body from the attribute content. + +So the markup generates this property: ```js button.onclick = function() { *!* - sayThanks(); // <-- অ্যাট্রিবিউটের কন্টেন্ট এখানে সেট হয় + sayThanks(); // <-- the attribute content goes here */!* }; ``` -**হ্যান্ডেলার সেট করতে `setAttribute` ব্যবহার করবেন না** +**Don't use `setAttribute` for handlers.** -এটি কাজ করবে না: +Such a call won't work: ```js run no-beautify -// বডিতে ক্লিক করলে ইরোর দেখাবে, -// কেননা অ্যাট্রিবিউট সমূহ সর্বদা স্ট্রিং হিসেবে সেট হয় +// a click on will generate errors, +// because attributes are always strings, function becomes a string document.body.setAttribute('onclick', function() { alert(1) }); ``` -**DOM-property এর ক্ষেত্রে কেস গুরুত্বপূর্ন** +**DOM-property case matters.** -হ্যান্ডেলার অ্যাসাইন করতে `elem.onclick` কাজ করবে, কিন্তু `elem.ONCLICK` কাজ করবে না, কেননা DOM প্রপার্টি সমূহ কেস-সেনসিটিভ। +Assign a handler to `elem.onclick`, not `elem.ONCLICK`, because DOM properties are case-sensitive. ## addEventListener -উপরোল্লিখিত নিয়ম অনুযায়ী হ্যান্ডেলার অ্যাসাইনের মূল সমস্যা হল -- আমরা একাধিক হ্যান্ডেলার অ্যাসাইন করতে পারব না। +The fundamental problem of the aforementioned ways to assign handlers -- we can't assign multiple handlers to one event. -যেমন ধরা যাক, আমরা বাটন ক্লিকে আমরা তা হাইলাইট করতে চায়, এবং তারপর ঐ ক্লিকে একটি মেসেজ দেখাব। +Let's say, one part of our code wants to highlight a button on click, and another one wants to show a message on the same click. -আমরা এজন্য দুটি হ্যান্ডেলার অ্যাসাইন করতে চাই। কিন্তু DOM প্রপার্টি বিদ্যমান হ্যান্ডেলারকে নতুনটি দ্বারা প্রতিস্থাপন করে দেয়: +We'd like to assign two event handlers for that. But a new DOM property will overwrite the existing one: ```js no-beautify input.onclick = function() { alert(1); } // ... -input.onclick = function() { alert(2); } // পূর্ববর্তী হ্যান্ডেলারকে নতুনটি দ্বারা প্রতিস্থাপন +input.onclick = function() { alert(2); } // replaces the previous handler ``` -এজন্য ডেভলাপাররা এই সমস্যা সমাধানের জন্য আরো দুটি বিশেষ মেথড নিয়ে আসে `addEventListener` এবং `removeEventListener`। এদের সাহায্যে আমরা এই সমস্যার সমাধান করতে পারি। +Developers of web standards understood that long ago and suggested an alternative way of managing handlers using special methods `addEventListener` and `removeEventListener`. They are free of such a problem. -হ্যান্ডেলার অ্যাসাইনের সিনট্যাক্সটি হল: +The syntax to add a handler: ```js element.addEventListener(event, handler, [options]); ``` `event` -: ইভেন্টের নাম, যেমন `"click"`। +: Event name, e.g. `"click"`. `handler` -: হ্যান্ডেলার ফাংশন +: The handler function. `options` -: কিছু ঐচ্ছিক প্রপার্টির একটি অবজেক্ট: - - `once`: যদি `true` হয়, তাহলে এটি একবার কল হওয়ার পর স্বয়ংক্রিয়ভাবে রিমুভ হয়ে যাবে। - - `capture`: এই ব্যাপারে আমরা পরবর্তী অধ্যায়ে জানব । তবে জেনে রাখুন, `options` টি `false/true` হতে পারে, অর্থাৎ `{capture: false/true}`। - - `passive`: যদি `true` হয়, তাহলে হ্যান্ডেলার `preventDefault()` কে কল করবে না, আরো বিস্তারিত জানব এই অধ্যায়ে । +: An additional optional object with properties: + - `once`: if `true`, then the listener is automatically removed after it triggers. + - `capture`: the phase where to handle the event, to be covered later in the chapter . For historical reasons, `options` can also be `false/true`, that's the same as `{capture: false/true}`. + - `passive`: if `true`, then the handler will not call `preventDefault()`, we'll explain that later in . -হ্যান্ডেলার রিমুভের জন্য, `removeEventListener`: +To remove the handler, use `removeEventListener`: ```js element.removeEventListener(event, handler, [options]); ``` -````warn header="রিমুভ করা যায় একই ফাংশনকে" -হ্যান্ডেলারকে ফাংশনকে রিমুভের জন্য অ্যাসাইকৃত ফাংশনটিই পাস করতে হবে। +````warn header="Removal requires the same function" +To remove a handler we should pass exactly the same function as was assigned. -এটি কাজ করবে না: +This doesn't work: ```js no-beautify elem.addEventListener( "click" , () => alert('Thanks!')); @@ -242,9 +244,9 @@ elem.addEventListener( "click" , () => alert('Thanks!')); elem.removeEventListener( "click", () => alert('Thanks!')); ``` -হ্যান্ডেলার রিমুভ কাজ করবে না, কেননা `removeEventListener` ফাংশনটি একই কোডের আরেকটি ফাংশন, কিন্তু এটি কোন ব্যাপার না, কেননা এটি ভিন্ন ফাংশন অবজেক্ট। +The handler won't be removed, because `removeEventListener` gets another function -- with the same code, but that doesn't matter, as it's a different function object. -এটি কাজ করবে: +Here's the right way: ```js function handler() { @@ -256,10 +258,10 @@ input.addEventListener("click", handler); input.removeEventListener("click", handler); ``` -সুতরাং আমরা বলতে পারি -- কোন ধরণের অ্যানোনিমাস ফাংশনকে আমরা রিমুভ করতে পারব না। +Please note -- if we don't store the function in a variable, then we can't remove it. There's no way to "read back" handlers assigned by `addEventListener`. ```` -`addEventListener` এর মাধ্যমে একাধিক হ্যান্ডেলার কল করার উপায়টি, এমন: +Multiple calls to `addEventListener` allow to add multiple handlers, like this: ```html run no-beautify @@ -281,78 +283,78 @@ input.removeEventListener("click", handler); ``` -উপরের উদাহরণে আমরা দেখছি, আমরা DOM-property এবং `addEventListener` এর মাধ্যমে হ্যান্ডেলার অ্যাসাইন করছি। তবে সাধারণত আমরা যেকোন এক উপায়ে হ্যান্ডেলার সেট করব। +As we can see in the example above, we can set handlers *both* using a DOM-property and `addEventListener`. But generally we use only one of these ways. -````warn header="কিছু ইভেন্ট আছে শুধু `addEventListener` এর সাথে কাজ করে" -কিছু ইভেন্ট আছে যারা DOM-property এর সাথে কাজ করে না, শুধুমাত্র `addEventListener` এর মাধ্যমে কাজ করে। +````warn header="For some events, handlers only work with `addEventListener`" +There exist events that can't be assigned via a DOM-property. Only with `addEventListener`. -যেমন, `DOMContentLoaded` ইভেন্ট, এটি ট্রিগার হয় যখন সম্পূর্ন DOM লোড হয়ে DOM অবজেক্টটি তৈরি হয়। +For instance, the `DOMContentLoaded` event, that triggers when the document is loaded and DOM is built. ```js -// এটি রান হবে না +// will never run document.onDOMContentLoaded = function() { alert("DOM built"); }; ``` ```js -// এটি কাজ করবে +// this way it works document.addEventListener("DOMContentLoaded", function() { alert("DOM built"); }); ``` -সুতরাং `addEventListener` আরো বেশি সুবিধাজনক। এছাড়াও, এই ধরণের ইভেন্ট সমূহ কিছু ব্যতিক্রম। +So `addEventListener` is more universal. Although, such events are an exception rather than the rule. ```` ## Event object -ইভেন্ট নিয়ে কাজ করার সময় আমাদের অনেক ব্যাপার জানা লাগে, এটি শুধু "ক্লিক" বা "কী প্রেসে" সীমাবদ্ধ না, আমাদের জানা লাগতে পারে কোন কী প্রেস করা হয়েছে বা কোন স্থানাংকে মাউস ক্লিক হয়েছে। +To properly handle an event we'd want to know more about what's happened. Not just a "click" or a "keydown", but what were the pointer coordinates? Which key was pressed? And so on. -যখন কোন ইভেন্ট সংগঠিত হয়, ব্রাউজার *event object* তৈরি করে, এবং সকল বিস্তারিত প্রপার্টি নিয়ে *event object* টি হ্যান্ডেলারে পাস হয়। +When an event happens, the browser creates an *event object*, puts details into it and passes it as an argument to the handler. -এখানে কোন স্থানাংকে মাউস ক্লিক হয়েছে তার একটি উদাহরণ দেখানো হল: +Here's an example of getting pointer coordinates from the event object: ```html run ``` -`event` অবজেক্ট এর কিছু প্রপার্টি: +Some properties of `event` object: `event.type` -: ইভেন্ট টাইপ, এখানে এটি `"click"`। +: Event type, here it's `"click"`. `event.currentTarget` -: যে এলিমেন্টে ইভেন্টটি সংগঠিত হয়। এটি এলিমেন্টের `this` এর মত, যতক্ষন হ্যান্ডেলারটি অ্যারো ফাংশনের সাহায্যে কল করা হয়, অন্যথায় `this` অন্য কোন কনট্যাক্স কে বুঝায়। +: Element that handled the event. That's exactly the same as `this`, unless the handler is an arrow function, or its `this` is bound to something else, then we can get the element from `event.currentTarget`. `event.clientX / event.clientY` -: windows এর সাপেক্ষে কার্সরের স্থানাংক। +: Window-relative coordinates of the cursor, for pointer events. -এছাড়াও আরো অনেক প্রপার্টি আছে। বেশিরভাগ ইভেন্টের ধরণের উপর নির্ভর করে: কী-বোর্ড ইভেন্টের প্রপার্টি এক ধরণের, পয়েন্টার ইভেন্টের প্রপার্টি অন্য ধরণের, পরবর্তী অধ্যায় সমূহে আমরা ইভেন্টের ধরণ অনুযায়ী বিস্তারিত জানব। +There are more properties. Many of them depend on the event type: keyboard events have one set of properties, pointer events - another one, we'll study them later when we come to different events in details. -````smart header="HTML অ্যাট্রিবিউট হ্যান্ডেলারেও ইভেন্ট অবজেক্ট অ্যাক্সেস করা যায়" -যদি আমরা HTML এ কোন হ্যান্ডেলার অ্যাসাইন করি, আমরা `event` অবজেক্টটি এভাবে ব্যবহার করতে পারি: +````smart header="The event object is also available in HTML handlers" +If we assign a handler in HTML, we can also use the `event` object, like this: ```html autorun height=60 ``` -এটি সম্ভব হয় কেননা যখন ব্রাউজার অ্যাট্রিবিউট হতে হ্যান্ডেলার ফাংশনটি এভাবে তৈরি করে: `function(event) { alert(event.type) }`। সুতরাং প্রথম আর্গুমেন্টটি হয় `"event"`। +That's possible because when the browser reads the attribute, it creates a handler like this: `function(event) { alert(event.type) }`. That is: its first argument is called `"event"`, and the body is taken from the attribute. ```` ## Object handlers: handleEvent -আমরা চাইলে `addEventListener` এ কোন অবজেক্টকেও হ্যান্ডেলার হিসেবে পাস করতে পারি। যখন কোন ইভেন্ট সংগঠিত হয়, এটি `handleEvent` মেথডকে কল করে। +We can assign not just a function, but an object as an event handler using `addEventListener`. When an event occurs, its `handleEvent` method is called. -যেমন: +For instance: ```html run @@ -369,9 +371,9 @@ document.addEventListener("DOMContentLoaded", function() { ``` -এক্ষেত্রে আমরা দেখছি, `addEventListener` হ্যান্ডেলার হিসেবে একটি অবজেক্ট নিচ্ছে, এবং এক্ষেত্রে এটি `obj.handleEvent(event)` কে কল করে। +As we can see, when `addEventListener` receives an object as the handler, it calls `obj.handleEvent(event)` in case of an event. -আমরা চাইলে ES-6 class সিনট্যাক্স ব্যবহার করতে পারি: +We could also use a class for that: ```html run @@ -399,9 +401,9 @@ document.addEventListener("DOMContentLoaded", function() { ``` -এখানে একটি অবজেক্টকে আমরা উভয়ই ইভেন্টের হ্যান্ডেলার হিসেবে ব্যবহার করছি। দয়া করে নোট করুন `addEventListener` এর জন্য আমাদের অবজেক্টটিকে সঠিকভাবে সেটাপ করতে হবে। এক্ষেত্রে `menu` অবজেক্টটি শুধুমাত্র `mousedown` এবং `mouseup` এর সাথে কাজ করবে, অন্যান্য ইভেন্টের জন্য এটি কাজ করবে না। +Here the same object handles both events. Please note that we need to explicitly setup the events to listen using `addEventListener`. The `menu` object only gets `mousedown` and `mouseup` here, not any other types of events. -আমরা `handleEvent` মেথডটিকে চাইলে এভাবে ডায়নামিক্যালি ব্যবহার করতে পারি: +The method `handleEvent` does not have to do all the job by itself. It can call other event-specific methods instead, like this: ```html run @@ -429,22 +431,22 @@ document.addEventListener("DOMContentLoaded", function() { ``` -এখানে আমরা হ্যান্ডেলার ফাংশনকে আলাদা করে নিলাম, কোডটি পড়তে এবং পরিবর্তন করা সহজ হবে। +Now event handlers are clearly separated, that may be easier to support. -## সারাংশ +## Summary -তিনভাবে আমরা ইভেন্ট হ্যান্ডেলার অ্যাসাইন করতে পারি: +There are 3 ways to assign event handlers: -1. HTML attribute: `onclick="..."`। -2. DOM property: `elem.onclick = function`। -3. মেথডের সাহায্যে: `elem.addEventListener(event, handler[, phase])` হ্যান্ডেলার সংযুক্ত করতে, `removeEventListener` হ্যান্ডেলার রিমুভ করতে। +1. HTML attribute: `onclick="..."`. +2. DOM property: `elem.onclick = function`. +3. Methods: `elem.addEventListener(event, handler[, phase])` to add, `removeEventListener` to remove. -HTML attribute এর সাহায্যে ইভেন্ট খুব কম লিখা হয়, কেননা HTML এ জাভাস্ক্রিপ্ট দেখতে বিদঘুটে লাগে। এছাড়াও আমরা অনেক কোড একসাথে লিখতে পারি না। +HTML attributes are used sparingly, because JavaScript in the middle of an HTML tag looks a little bit odd and alien. Also can't write lots of code in there. -আমরা DOM প্রপার্টির সাহায্যে হ্যান্ডেলার অ্যাসাইন করতে পারি, কিন্তু এর একটি সীমাবদ্ধতা আছে, আমরা শুধুমাত্র একটি হ্যান্ডেলার অ্যাসাইন করতে পারি। +DOM properties are ok to use, but we can't assign more than one handler of the particular event. In many cases that limitation is not pressing. -এবং শেষেরটি ব্যবহার আমাদের জন্য সুবিধাজনক, তবে এটি অন্য দুটি থেকে দেখতে কিছুটা বড়। এছাড়াও কিছু ইভেন্ট আছে যা এটি ছাড়া অন্য কোনভাবে কাজ করবে না, যেমন `transitionend` এবং `DOMContentLoaded` (যা পরবর্তীতে আমরা দেখব)। এছাড়াও `addEventListener` হ্যান্ডেলার হিসেবে অবজেক্ট নিতে পারে। এক্ষেত্রে এটি ডায়নামিক্যালি `handleEvent` মেথড কে কল করে। +The last way is the most flexible, but it is also the longest to write. There are few events that only work with it, for instance `transitionend` and `DOMContentLoaded` (to be covered). Also `addEventListener` supports objects as event handlers. In that case the method `handleEvent` is called in case of the event. -আপনি যেভাবেই হ্যান্ডেলার অ্যাসাইন করুন না কেন -- প্রথম আর্গুমেন্টটি সর্বদা একটি *event object* হয়। যা ইভেন্ট সম্পর্কিত সকল তথ্য ধারণ করে। +No matter how you assign the handler -- it gets an event object as the first argument. That object contains the details about what's happened. -এছাড়াও আমরা নির্দিষ্ট ইভেন্ট সম্পর্কিত বিস্তারিত পরবর্তী অধ্যায় সমূহে জানব। +We'll learn more about events in general and about different types of events in the next chapters. From 7832646c706e187d08eee9b8980c8be6a62d6cb5 Mon Sep 17 00:00:00 2001 From: Saiful Date: Tue, 27 Apr 2021 05:18:31 +0600 Subject: [PATCH 07/10] more fixed --- .../01-hide-other/solution.view/index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html b/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html index c7c2977fa..712a28495 100644 --- a/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html +++ b/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html @@ -19,4 +19,5 @@ } - + + \ No newline at end of file From 4665d687474b9f1940c29bf28d90409bda0eadc3 Mon Sep 17 00:00:00 2001 From: Saiful Date: Tue, 27 Apr 2021 05:19:55 +0600 Subject: [PATCH 08/10] tick --- .../01-hide-other/solution.view/index.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html b/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html index 712a28495..fd7add18c 100644 --- a/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html +++ b/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html @@ -14,10 +14,9 @@ - \ No newline at end of file From dff330be15c6540b27dfa357af58ee8579ebd8b6 Mon Sep 17 00:00:00 2001 From: Mohammad Saiful Islam Date: Tue, 27 Apr 2021 05:21:21 +0600 Subject: [PATCH 09/10] Delete index.html wrong file --- .../01-hide-other/solution.view/index.html | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html diff --git a/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html b/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html deleted file mode 100644 index fd7add18c..000000000 --- a/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - -
Text
- - - - \ No newline at end of file From 18cac00933c25dcf3b90f353def1ce8b194b75c6 Mon Sep 17 00:00:00 2001 From: Saiful Date: Tue, 27 Apr 2021 05:24:41 +0600 Subject: [PATCH 10/10] fixed --- .../01-hide-other/solution.view/index.html | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html diff --git a/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html b/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html new file mode 100644 index 000000000..7228a45de --- /dev/null +++ b/2-ui/2-events/01-introduction-browser-events/01-hide-other/solution.view/index.html @@ -0,0 +1,22 @@ + + + + + + + + + + + +
Text
+ + + +