Merge pull request #1496 from microsoft/update-translations

🌐 Update translations via Co-op Translator
pull/1497/head
Lee Stott 4 months ago committed by GitHub
commit 274ce79d3d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,21 +1,21 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "c63675cfaf1d223b37bb9fecbfe7c252",
"translation_date": "2025-08-25T23:08:09+00:00",
"original_hash": "2dcbb9259dee4f20a4f08d9a1aa2bd4c",
"translation_date": "2025-08-28T23:06:45+00:00",
"source_file": "1-getting-started-lessons/1-intro-to-programming-languages/README.md",
"language_code": "bn"
}
-->
# প্রোগ্রামিং ভাষা এবং টুলস অফ দ্য ট্রেডের পরিচিতি
# প্রোগ্রামিং ভাষা এবং প্রয়োজনীয় সরঞ্জাম সম্পর্কে পরিচিতি
এই পাঠে প্রোগ্রামিং ভাষার মৌলিক বিষয়গুলো আলোচনা করা হয়েছে। এখানে আলোচিত বিষয়গুলো আজকের আধুনিক প্রোগ্রামিং ভাষার জন্য প্রযোজ্য। 'টুলস অফ দ্য ট্রেড' অংশে, আপনি ডেভেলপার হিসেবে সহায়ক কিছু সফটওয়্যার সম্পর্কে জানতে পারবেন
এই পাঠে প্রোগ্রামিং ভাষার মৌলিক বিষয়গুলো আলোচনা করা হয়েছে। এখানে আলোচিত বিষয়গুলো আজকের আধুনিক প্রোগ্রামিং ভাষার জন্য প্রযোজ্য। 'প্রয়োজনীয় সরঞ্জাম' অংশে, আপনি এমন কিছু সফটওয়্যার সম্পর্কে জানবেন যা একজন ডেভেলপার হিসেবে আপনার কাজে সাহায্য করবে
![Intro Programming](../../../../translated_images/webdev101-programming.d6e3f98e61ac4bff0b27dcbf1c3f16c8ed46984866f2d29988929678b0058fde.bn.png)
> স্কেচনোট: [Tomomi Imura](https://twitter.com/girlie_mac)
## প্রি-লেকচার কুইজ
[প্রি-লেকচার কুইজ](https://forms.office.com/r/dru4TE0U9n?origin=lprLink)
## প্রাক-পাঠ কুইজ
[প্রাক-পাঠ কুইজ](https://forms.office.com/r/dru4TE0U9n?origin=lprLink)
## পরিচিতি
@ -23,26 +23,26 @@ CO_OP_TRANSLATOR_METADATA:
- প্রোগ্রামিং কী?
- প্রোগ্রামিং ভাষার প্রকারভেদ
- প্রোগ্রামের মৌলিক উপাদান
- পেশাদার ডেভেলপারের জন্য সহায়ক সফটওয়্যার এবং টুলস
- একটি প্রোগ্রামের মৌলিক উপাদান
- পেশাদার ডেভেলপারের জন্য প্রয়োজনীয় সফটওয়্যার এবং সরঞ্জাম
> আপনি এই পাঠটি [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101/introduction-programming/?WT.mc_id=academic-77807-sagibbon) এ নিতে পারেন!
## প্রোগ্রামিং কী?
প্রোগ্রামিং (কোডিং নামেও পরিচিত) হলো একটি ডিভাইস যেমন কম্পিউটার বা মোবাইল ডিভাইসের জন্য নির্দেশনা লেখার প্রক্রিয়া। আমরা এই নির্দেশনা একটি প্রোগ্রামিং ভাষার মাধ্যমে লিখি, যা পরে ডিভাইস দ্বারা ব্যাখ্যা করা হয়। এই নির্দেশনার সেটগুলো বিভিন্ন নামে পরিচিত হতে পারে, যেমন *প্রোগ্রাম*, *কম্পিউটার প্রোগ্রাম*, *অ্যাপ্লিকেশন (অ্যাপ)* এবং *এক্সিকিউটেবল*
প্রোগ্রামিং (যা কোডিং নামেও পরিচিত) হলো একটি ডিভাইস যেমন কম্পিউটার বা মোবাইল ডিভাইসের জন্য নির্দেশনা লেখার প্রক্রিয়া। আমরা এই নির্দেশনাগুলো প্রোগ্রামিং ভাষার মাধ্যমে লিখি, যা পরে ডিভাইস দ্বারা ব্যাখ্যা করা হয়। এই নির্দেশনার সেটগুলো বিভিন্ন নামে পরিচিত হতে পারে, যেমন *প্রোগ্রাম*, *কম্পিউটার প্রোগ্রাম*, *অ্যাপ্লিকেশন (অ্যাপ)* এবং *এক্সিকিউটেবল*
একটি *প্রোগ্রাম* হলো কোড দিয়ে তৈরি যেকোনো কিছু; ওয়েবসাইট, গেমস এবং ফোন অ্যাপগুলো প্রোগ্রাম। যদিও কোড না লিখেও প্রোগ্রাম তৈরি করা সম্ভব, কিন্তু এর অন্তর্নিহিত লজিক ডিভাইস দ্বারা ব্যাখ্যা করা হয় এবং সেই লজিক সম্ভবত কোড দিয়ে লেখা হয়েছে। একটি প্রোগ্রাম যখন *চালানো* বা *এক্সিকিউট* করা হয়, তখন এটি নির্দেশনা সম্পাদন করে। আপনি যে ডিভাইস দিয়ে এই পাঠটি পড়ছেন, সেটি একটি প্রোগ্রাম চালাচ্ছে যা এটি আপনার স্ক্রিনে দেখাচ্ছে।
একটি *প্রোগ্রাম* হলো কোড দিয়ে তৈরি যেকোনো কিছু; ওয়েবসাইট, গেমস এবং ফোন অ্যাপগুলো প্রোগ্রাম। যদিও কোড না লিখেও প্রোগ্রাম তৈরি করা সম্ভব, তবে এর অন্তর্নিহিত লজিক ডিভাইস দ্বারা ব্যাখ্যা করা হয় এবং সেই লজিক সম্ভবত কোড দিয়ে লেখা হয়েছে। একটি প্রোগ্রাম যখন *চালানো* বা *এক্সিকিউট* করা হয়, তখন এটি নির্দেশনাগুলো সম্পন্ন করে। আপনি যে ডিভাইস দিয়ে এই পাঠটি পড়ছেন, সেটি একটি প্রোগ্রাম চালাচ্ছে যা এটি আপনার স্ক্রিনে দেখাচ্ছে।
✅ একটু গবেষণা করুন: কে বিশ্বের প্রথম কম্পিউটার প্রোগ্রামার হিসেবে বিবেচিত?
## প্রোগ্রামিং ভাষা
প্রোগ্রামিং ভাষা ডেভেলপারদের ডিভাইসের জন্য নির্দেশনা লেখার সুযোগ দেয়। ডিভাইস শুধুমাত্র বাইনারি (১ এবং ) বুঝতে পারে, এবং *বেশিরভাগ* ডেভেলপারের জন্য এটি খুবই অকার্যকর যোগাযোগের মাধ্যম। প্রোগ্রামিং ভাষা হলো মানুষের এবং কম্পিউটারের মধ্যে যোগাযোগের মাধ্যম।
প্রোগ্রামিং ভাষা ডেভেলপারদের ডিভাইসের জন্য নির্দেশনা লেখার সুযোগ দেয়। ডিভাইসগুলো শুধুমাত্র বাইনারি (১ এবং ) বুঝতে পারে, এবং *অধিকাংশ* ডেভেলপারের জন্য এটি খুবই অকার্যকর যোগাযোগের মাধ্যম। প্রোগ্রামিং ভাষা হলো মানুষের এবং কম্পিউটারের মধ্যে যোগাযোগের মাধ্যম।
প্রোগ্রামিং ভাষাগুলো বিভিন্ন ফরম্যাটে আসে এবং বিভিন্ন উদ্দেশ্যে ব্যবহার করা হয়। যেমন, জাভাস্ক্রিপ্ট প্রধানত ওয়েব অ্যাপ্লিকেশনের জন্য ব্যবহৃত হয়, আর Bash প্রধানত অপারেটিং সিস্টেমের জন্য ব্যবহৃত হয়।
প্রোগ্রামিং ভাষাগুলো বিভিন্ন ফরম্যাটে আসে এবং বিভিন্ন উদ্দেশ্যে ব্যবহার করা হয়। উদাহরণস্বরূপ, জাভাস্ক্রিপ্ট প্রধানত ওয়েব অ্যাপ্লিকেশনের জন্য ব্যবহৃত হয়, যেখানে Bash প্রধানত অপারেটিং সিস্টেমের জন্য ব্যবহৃত হয়।
*লো লেভেল ভাষা* সাধারণত *হাই লেভেল ভাষা* তুলনায় ডিভাইসের জন্য নির্দেশনা ব্যাখ্যা করতে কম ধাপ প্রয়োজন হয়। তবে, হাই লেভেল ভাষার জনপ্রিয়তার কারণ হলো এর পাঠযোগ্যতা এবং সাপোর্ট। জাভাস্ক্রিপ্ট একটি হাই লেভেল ভাষা হিসেবে বিবেচিত।
*লো লেভেল ভাষা* সাধারণত *হাই লেভেল ভাষা* তুলনায় ডিভাইসের জন্য নির্দেশনা ব্যাখ্যা করতে কম ধাপ প্রয়োজন হয়। তবে, হাই লেভেল ভাষার জনপ্রিয়তার কারণ হলো এর পাঠযোগ্যতা এবং সাপোর্ট। জাভাস্ক্রিপ্ট একটি হাই লেভেল ভাষা হিসেবে বিবেচিত।
নিম্নলিখিত কোডটি জাভাস্ক্রিপ্ট (হাই লেভেল ভাষা) এবং ARM অ্যাসেম্বলি কোড (লো লেভেল ভাষা) এর মধ্যে পার্থক্য দেখায়।
@ -83,39 +83,39 @@ back add r0,r1
end
```
বিশ্বাস করুন বা না করুন, *দুি কই একই কাজ করছে*: ১০ পর্যন্ত একটি ফিবোনাচ্চি সিকোয়েন্স প্রিন্ট করছে।
বিশ্বাস করুন বা না করুন, *দুটোই একই কাজ করছে*: ১০ পর্যন্ত একটি ফিবোনাচি সিকোয়েন্স প্রিন্ট করছে।
✅ ফিবোনাচ্চি সিকোয়েন্স [সংজ্ঞায়িত](https://en.wikipedia.org/wiki/Fibonacci_number) হয় এমন একটি সংখ্যার সেট হিসেবে, যেখানে প্রতিটি সংখ্যা পূর্ববর্তী দুটি সংখ্যার যোগফল। এটি এবং ১ থেকে শুরু হয়। প্রথম ১০টি ফিবোনাচ্চি সংখ্যা হলো , ১, ১, ২, ৩, ৫, ৮, ১৩, ২১ এবং ৩৪।
✅ ফিবোনাচি সিকোয়েন্স [সংজ্ঞায়িত](https://en.wikipedia.org/wiki/Fibonacci_number) হয় এমন একটি সংখ্যার সেট হিসেবে, যেখানে প্রতিটি সংখ্যা পূর্ববর্তী দুটি সংখ্যার যোগফল। এটি এবং ১ থেকে শুরু হয়। প্রথম ১০টি ফিবোনাচি সংখ্যাগুলো হলো , ১, ১, ২, ৩, ৫, ৮, ১৩, ২১ এবং ৩৪।
## প্রোগ্রামের উপাদান
## একটি প্রোগ্রামের উপাদান
একটি প্রোগ্রামের একক নির্দেশনাকে *স্টেটমেন্ট* বলা হয় এবং সাধারণত একটি চরিত্র বা লাইন স্পেসিং থাকে যা নির্দেশনার শেষ বা *টার্মিনেশন* চিহ্নিত করে। একটি প্রোগ্রাম কীভাবে শেষ হয় তা প্রতিটি ভাষার জন্য ভিন্ন।
একটি প্রোগ্রামের একক নির্দেশনাকে *স্টেটমেন্ট* বলা হয় এবং সাধারণত একটি চিহ্ন বা লাইন স্পেসিং থাকে যা নির্দেশনার শেষ বা *টার্মিনেশন* চিহ্নিত করে। একটি প্রোগ্রাম কীভাবে শেষ হয় তা প্রতিটি ভাষার ক্ষেত্রে ভিন্ন।
প্রোগ্রামের স্টেটমেন্টগুলো ব্যবহারকারীর দেওয়া ডেটা বা অন্য কোথাও থেকে প্রাপ্ত ডেটার উপর নির্ভর করতে পারে নির্দেশনা সম্পাদনের জন্য। ডেটা প্রোগ্রামের আচরণ পরিবর্তন করতে পারে, তাই প্রোগ্রামিং ভাষাগুলো ডেটা সাময়িকভাবে সংরক্ষণ করার একটি উপায় নিয়ে আসে, যা পরে ব্যবহার করা যায়। এগুলোকে *ভেরিয়েবল* বলা হয়। ভেরিয়েবল হলো স্টেটমেন্ট যা ডিভাইসকে তার মেমোরিতে ডেটা সংরক্ষণ করতে নির্দেশ দেয়। প্রোগ্রামের ভেরিয়েবলগুলো অ্যালজেব্রার ভেরিয়েবলের মতো, যেখানে তাদের একটি অনন্য নাম থাকে এবং তাদের মান সময়ের সাথে পরিবর্তিত হতে পারে।
প্রোগ্রামের স্টেটমেন্টগুলো ব্যবহারকারীর দেওয়া ডেটা বা অন্য কোথাও থেকে প্রাপ্ত ডেটার উপর নির্ভর করতে পারে নির্দেশনা সম্পন্ন করার জন্য। ডেটা প্রোগ্রামের আচরণ পরিবর্তন করতে পারে, তাই প্রোগ্রামিং ভাষাগুলো ডেটা সাময়িকভাবে সংরক্ষণ করার একটি উপায় নিয়ে আসে যাতে এটি পরে ব্যবহার করা যায়। এগুলোকে *ভেরিয়েবল* বলা হয়। ভেরিয়েবল হলো স্টেটমেন্ট যা ডিভাইসকে তার মেমোরিতে ডেটা সংরক্ষণ করতে নির্দেশ দেয়। প্রোগ্রামের ভেরিয়েবলগুলো অ্যালজেব্রার ভেরিয়েবলের মতো, যেখানে তাদের একটি ইউনিক নাম থাকে এবং তাদের মান সময়ের সাথে পরিবর্তিত হতে পারে।
কিছু স্টেটমেন্ট ডিভাইস দ্বারা সম্পাদিত নাও হতে পারে। এটি সাধারণত ডেভেলপার দ্বারা পরিকল্পিতভাবে লেখা হয় বা দুর্ঘটনাক্রমে ঘটে যখন একটি অপ্রত্যাশিত ত্রুটি দেখা দেয়। এই ধরনের নিয়ন্ত্রণ একটি অ্যাপ্লিকেশনকে আরও শক্তিশালী এবং রক্ষণাবেক্ষণযোগ্য করে তোলে। সাধারণত, এই নিয়ন্ত্রণের পরিবর্তন ঘটে যখন নির্দিষ্ট শর্ত পূরণ হয়। আধুনিক প্রোগ্রামিংয়ে একটি সাধারণ স্টেটমেন্ট যা প্রোগ্রাম কীভাবে চলবে তা নিয়ন্ত্রণ করে, সেটি হলো `if..else` স্টেটমেন্ট।
কিছু স্টেটমেন্ট ডিভাইস দ্বারা সম্পন্ন না হওয়ার সম্ভাবনা থাকে। এটি সাধারণত ডেভেলপার দ্বারা পরিকল্পিতভাবে লেখা হয় অথবা দুর্ঘটনাক্রমে যখন একটি অপ্রত্যাশিত ত্রুটি ঘটে। এই ধরনের নিয়ন্ত্রণ একটি অ্যাপ্লিকেশনকে আরও শক্তিশালী এবং রক্ষণাবেক্ষণযোগ্য করে তোলে। সাধারণত, এই নিয়ন্ত্রণের পরিবর্তন তখন ঘটে যখন নির্দিষ্ট শর্ত পূরণ হয়। আধুনিক প্রোগ্রামিংয়ে একটি সাধারণ স্টেটমেন্ট যা প্রোগ্রামের চলার পদ্ধতি নিয়ন্ত্রণ করে তা হলো `if..else` স্টেটমেন্ট।
✅ আপনি এই ধরনের স্টেটমেন্ট সম্পর্কে পরবর্তী পাঠে আরও শিখবেন।
## টুলস অফ দ্য ট্রেড
## প্রয়োজনীয় সরঞ্জাম
[![Tools of the Trade](https://img.youtube.com/vi/69WJeXGBdxg/0.jpg)](https://youtube.com/watch?v=69WJeXGBdxg "Tools of the Trade")
> 🎥 উপরের ছবিতে ক্লিক করুন টুলিং সম্পর্কিত একটি ভিডিও দেখার জন্য
> 🎥 উপরের ছবিতে ক্লিক করুন টুলিং সম্পর্ক একটি ভিডিও দেখার জন্য
এই অংশে, আপনি কিছু সফটওয়্যার সম্পর্কে জানবেন যা আপনার পেশাদার ডেভেলপমেন্ট যাত্রা শুরু করার সময় খুবই সহায়ক হতে পারে।
এই অংশে, আপনি কিছু সফটওয়্যার সম্পর্কে জানবেন যা আপনার পেশাদার ডেভেলপমেন্ট যাত্রা শুরু করার সময় খুবই উপকারী হতে পারে।
একটি **ডেভেলপমেন্ট এনভায়রনমেন্ট** হলো টুলস এবং ফিচারের একটি অনন্য সেট যা ডেভেলপাররা সফটওয়্যার লেখার সময় প্রায়ই ব্যবহার করে। এই টুলগুলো ডেভেলপারের নির্দিষ্ট প্রয়োজন অনুযায়ী কাস্টমাইজ করা হয়েছে এবং সময়ের সাথে পরিবর্তিত হতে পারে যদি ডেভেলপার কাজের অগ্রাধিকার পরিবর্তন করে, ব্যক্তিগত প্রকল্পে কাজ করে, বা ভিন্ন প্রোগ্রামিং ভাষা ব্যবহার করে। ডেভেলপমেন্ট এনভায়রনমেন্টগুলো ডেভেলপারদের মতোই অনন্য।
একটি **ডেভেলপমেন্ট এনভায়রনমেন্ট** হলো একটি অনন্য সরঞ্জাম এবং বৈশিষ্ট্যের সেট যা একজন ডেভেলপার সফটওয়্যার লেখার সময় প্রায়ই ব্যবহার করেন। এই সরঞ্জামগুলো ডেভেলপারের নির্দিষ্ট প্রয়োজন অনুযায়ী কাস্টমাইজ করা হয়েছে এবং সময়ের সাথে পরিবর্তিত হতে পারে যদি সেই ডেভেলপার কাজের অগ্রাধিকার পরিবর্তন করে, ব্যক্তিগত প্রকল্পে কাজ করেন, বা অন্য প্রোগ্রামিং ভাষা ব্যবহার করে। ডেভেলপমেন্ট এনভায়রনমেন্টগুলো ডেভেলপারদের মতোই অনন্য।
### এডিটর
সফটওয়্যার ডেভেলপমেন্টের জন্য সবচেয়ে গুরুত্বপূর্ণ টুলগুলোর একটি হলো এডিটর। এডিটর হলো যেখানে আপনি আপনার কোড লিখেন এবং কখনও কখনও যেখানে আপনি আপনার কোড চালান।
সফটওয়্যার ডেভেলপমেন্টের জন্য সবচেয়ে গুরুত্বপূর্ণ সরঞ্জামগুলোর একটি হলো এডিটর। এডিটর হলো যেখানে আপনি আপনার কোড লিখেন এবং কখনও কখনও যেখানে আপনি আপনার কোড চালান।
ডেভেলপাররা এডিটরের উপর নির্ভর করেন আরও কিছু কারণে:
ডেভেলপাররা এডিটর ব্যবহার করেন আরও কিছু অতিরিক্ত কারণে:
- *ডিবাগিং* কোডের ত্রুটি এবং ভুলগুলো খুঁজে বের করতে সাহায্য করে, লাইন বাই লাইন কোড পরীক্ষা করে। কিছু এডিটরে ডিবাগিং সুবিধা থাকে; এগুলো নির্দিষ্ট প্রোগ্রামিং ভাষার জন্য কাস্টমাইজ এবং যোগ করা যায়।
- *ডিবাগিং* কোডের ত্রুটি এবং ভুল খুঁজে বের করতে সাহায্য করে, লাইন বাই লাইন কোড পরীক্ষা করে। কিছু এডিটরে ডিবাগিং সুবিধা থাকে; এগুলো নির্দিষ্ট প্রোগ্রামিং ভাষার জন্য কাস্টমাইজ এবং যোগ করা যায়।
- *সিনট্যাক্স হাইলাইটিং* কোডে রঙ এবং টেক্সট ফরম্যাটিং যোগ করে, যা পড়া সহজ করে। বেশিরভাগ এডিটর কাস্টমাইজড সিনট্যাক্স হাইলাইটিংয়ের অনুমতি দেয়।
- *এক্সটেনশন এবং ইন্টিগ্রেশন* হলো ডেভেলপারদের জন্য বিশেষায়িত টুল। এই টুলগুলো বেস এডিটরে অন্তর্ভুক্ত ছিল না। উদাহরণস্বরূপ, অনেক ডেভেলপার তাদের কোড ডকুমেন্ট করে ব্যাখ্যা করার জ্য যে এটি কীভাবে কাজ করে। তারা ডকুমেন্টেশনে টাইপো খুঁজে বের করতে সাহায্য করার জন্য একটি স্পেল চেক এক্সটেনশন ইনস্টল করতে পারে। বেশিরভাগ এক্সটেনশন নির্দিষ্ট এডিটরের জন্য ব্যবহারের উদ্দেশ্যে তৈরি করা হয়েছে এবং বেশিরভাগ এডিটর এক্সটেনশন খুঁজে বের করার একটি উপায় নিয়ে আসে।
- *এক্সটেনশন এবং ইন্টিগ্রেশন* হলো ডেভেলপারদের জন্য বিশেষায়িত সরঞ্জাম, যা ডেভেলপারদের দ্বারা তৈরি। এই সরঞ্জামগুলো বেস এডিটরে অন্তর্ভুক্ত ছিল না। উদাহরণস্বরূপ, অনেক ডেভেলপার তাদের কোড ডকুমেন্ট করেন এটি কীভাবে কাজ করে তা ব্যাখ্যা করার জন্য। তারা ডকুমেন্টেশনে টাইপো খুঁজে বের করতে একটি স্পেল চেক এক্সটেনশন ইনস্টল করতে পারে। বেশিরভাগ এক্সটেনশন নির্দিষ্ট এডিটরের জন্য ব্যবহারের উদ্দেশ্যে তৈরি এবং বেশিরভাগ এডিটর উপলব্ধ এক্সটেনশন খুঁজে বের করার একটি উপায় নিয়ে আসে।
- *কাস্টমাইজেশন* ডেভেলপারদের তাদের প্রয়োজন অনুযায়ী একটি অনন্য ডেভেলপমেন্ট এনভায়রনমেন্ট তৈরি করতে সক্ষম করে। বেশিরভাগ এডিটর অত্যন্ত কাস্টমাইজযোগ্য এবং ডেভেলপারদের কাস্টম এক্সটেনশন তৈরি করার অনুমতি দেয়।
#### জনপ্রিয় এডিটর এবং ওয়েব ডেভেলপমেন্ট এক্সটেনশন
@ -135,9 +135,9 @@ back add r0,r1
### ব্রাউজার
আরেকটি গুরুত্বপূর্ণ টুল হলো ব্রাউজার। ওয়েব ডেভেলপাররা ব্রাউজারের উপর নির্ভর করেন তাদের কোড ওয়েবে কীভাবে কাজ করে তা দেখার জন্য। এটি এডিটরে লেখা HTML এর মতো একটি ওয়েব পেজের ভিজ্যুয়াল উপাদানগুলো প্রদর্শন করতেও ব্যবহৃত হয়।
আরেকটি গুরুত্বপূর্ণ সরঞ্জাম হলো ব্রাউজার। ওয়েব ডেভেলপাররা ব্রাউজার ব্যবহার করেন তাদের কোড ওয়েবে কীভাবে কাজ করে তা দেখার জন্য। এটি এডিটরে লেখা HTML-এর মতো একটি ওয়েব পৃষ্ঠার ভিজ্যুয়াল উপাদানগুলো প্রদর্শনের জন্যও ব্যবহৃত হয়।
অনেক ব্রাউজার *ডেভেলপার টুলস* (DevTools) নিয়ে আসে, যা ডেভেলপারদের তাদের অ্যাপ্লিকেশন সম্পর্কে গুরুত্বপূর্ণ তথ্য সংগ্রহ এবং ধারণ করতে সাহায্য করে। উদাহরণস্বরূপ: যদি একটি ওয়েব পেজে ত্রুটি থাকে, কখন তা ঘটেছে তা জানা কখনও কখনও সহায়ক হতে পারে। ব্রাউজারের DevTools কনফিগার করা যেতে পারে এই তথ্য সংগ্রহ করার জন্য।
অনেক ব্রাউজার *ডেভেলপার টুলস* (DevTools) নিয়ে আসে, যা ডেভেলপারদের তাদের অ্যাপ্লিকেশন সম্পর্কে গুরুত্বপূর্ণ তথ্য সংগ্রহ এবং ধারণ করতে সাহায্য করার জন্য একটি সহায়ক বৈশিষ্ট্য এবং তথ্যর সেট। উদাহরণস্বরূপ: যদি একটি ওয়েব পৃষ্ঠায় ত্রুটি থাকে, কখন সেগুলো ঘটেছে তা জানা কখনও কখনও সহায়ক হতে পারে। ব্রাউজারের DevTools কনফিগার করা যেতে পারে এই তথ্য ধারণ করার জন্য।
#### জনপ্রিয় ব্রাউজার এবং DevTools
@ -147,7 +147,7 @@ back add r0,r1
### কমান্ড লাইন টুলস
কিছু ডেভেলপার তাদের দৈনন্দিন কাজের জন্য কম গ্রাফিকাল ভিউ পছন্দ করেন এবং কমান্ড লাইন ব্যবহার করে এটি অর্জন করেন। কোড লেখার জন্য প্রচুর টাইপিং প্রয়োজন এবং কিছু ডেভেলপার তাদের কীবোর্ডের ফ্লো ব্যাহত করতে চান না। তারা ডেস্কটপ উইন্ডো পরিবর্তন, বিভিন্ন ফাইল নিয়ে কাজ করা এবং টুল ব্যবহার করার জন্য কীবোর্ড শর্টকাট ব্যবহার করেন। বেশিরভাগ কাজ মাউস দিয়ে সম্পন্ন করা যায়, কিন্তু কমান্ড লাইনের একটি সুবিধা হলো অনেক কিছু কমান্ড লাইন টুলস দিয়ে সম্পন্ন করা যায় মাউস এবং কীবোর্ডের মধ্যে পরিবর্তন না করেই। কমান্ড লাইনের আরেকটি সুবিধা হলো এগুলো কনফিগারযোগ্য এবং আপনি একটি কাস্টম কনফিগারেশন সংরক্ষণ করতে পারেন, পরে এটি পরিবর্তন করতে পারেন এবং এটি অন্য ডেভেলপমেন্ট মেশিনে ইমপোর্ট করতে পারেন। যেহেতু ডেভেলপমেন্ট এনভায়রনমেন্টগুলো প্রতিটি ডেভেলপারের জন্য অনন্য, কিছু ডেভেলপার কমান্ড লাইন এড়িয়ে চলেন, কিছু সম্পূর্ণভাবে এর উপর নির্ভর করেন, এবং কিছু মিশ্র পদ্ধতি পছন্দ করেন।
কিছু ডেভেলপার তাদের দৈনন্দিন কাজের জন্য কম গ্রাফিকাল ভিউ পছন্দ করেন এবং কমান্ড লাইন ব্যবহার করে এটি সম্পন্ন করেন। কোড লেখার জন্য প্রচুর টাইপিং প্রয়োজন এবং কিছু ডেভেলপার তাদের কীবোর্ডের ফ্লো ব্যাহত করতে চান না। তারা ডেস্কটপ উইন্ডো পরিবর্তন করতে, বিভিন্ন ফাইল নিয়ে কাজ করতে এবং সরঞ্জাম ব্যবহার করতে কীবোর্ড শর্টকাট ব্যবহার করেন। বেশিরভাগ কাজ মাউস দিয়ে সম্পন্ন করা যায়, তবে কমান্ড লাইনের একটি সুবিধা হলো অনেক কিছু কমান্ড লাইন টুলস দিয়ে সম্পন্ন করা যায় মাউস এবং কীবোর্ডের মধ্যে পরিবর্তন না করেই। কমান্ড লাইনের আরেকটি সুবিধা হলো এগুলো কনফিগারযোগ্য এবং আপনি একটি কাস্টম কনফিগারেশন সংরক্ষণ করতে পারেন, পরে এটি পরিবর্তন করতে পারেন এবং এটি অন্য ডেভেলপমেন্ট মেশিনে ইমপোর্ট করতে পারেন। যেহেতু ডেভেলপমেন্ট এনভায়রনমেন্টগুলো প্রতিটি ডেভেলপারের জন্য এতই অনন্য, কিছু ডেভেলপার কমান্ড লাইন ব্যবহার এড়িয়ে চলেন, কিছু সম্পূর্ণভাবে এর উপর নির্ভর করেন এবং কিছু মিশ্রণ পছন্দ করেন।
### জনপ্রিয় কমান্ড লাইন অপশন
@ -182,17 +182,17 @@ back add r0,r1
### ডকুমেন্টেশন
যখন একজন ডেভেলপার নতুন কিছু শিখতে চান, তারা সাধারণত ডকুমেন্টেশনের দিকে ঝোঁকেন এটি কীভাবে ব্যবহার করতে হয় তা শিখতে। ডেভেলপাররা প্রায়ই ডকুমেন্টেশনের উপর নির্ভর করেন টুলস এবং ভাষাগুলো সঠিকভাবে ব্যবহার করার জন্য এবং এটি কীভাবে কাজ করে তার গভীর জ্ঞান অর্জনের জন্য।
যখন একজন ডেভেলপার নতুন কিছু শিখতে চান, তারা সম্ভবত ডকুমেন্টেশনের দিকে ঝুঁকবেন এটি কীভাবে ব্যবহার করতে হয় তা শিখতে। ডেভেলপাররা প্রায়ই ডকুমেন্টেশনের উপর নির্ভর করেন সরঞ্জাম এবং ভাষাগুলো সঠিকভাবে ব্যবহার করার জন্য এবং এটি কীভাবে কাজ করে তার গভীর জ্ঞান অর্জনের জন্য।
#### ওয়েব ডেভেলপমেন্টের জনপ্রিয় ডকুমেন্টেশন
- [Mozilla Developer Network (MDN)](https://developer.mozilla.org/docs/Web), Mozilla থেকে, যারা [Firefox](https://www.mozilla.org/firefox/) ব্রাউজার প্রকাশ রেছে
- [Mozilla Developer Network (MDN)](https://developer.mozilla.org/docs/Web), Mozilla থেকে, [Firefox](https://www.mozilla.org/firefox/) ব্রাউজারের প্রকাশক
- [Frontend Masters](https://frontendmasters.com/learn/)
- [Web.dev](https://web.dev), Google থেকে, যারা [Chrome](https://www.google.com/chrome/) প্রকাশ রেছে
- [Web.dev](https://web.dev), Google থেকে, [Chrome](https://www.google.com/chrome/) এর প্রকাশক
- [Microsoft's own developer docs](https://docs.microsoft.com/microsoft-edge/#microsoft-edge-for-developers), [Microsoft Edge](https://www.microsoft.com/edge) এর জন্য
- [W3 Schools](https://www.w3schools.com/where_to_start.asp)
✅ একটু গবেষণা করুন: এখন যেহেতু আপনি একজন ওয়েব ডেভেলপারের এনভায়রনমেন্টের মৌলিক বিষয়গুলো জানেন, এটি একজন ওয়েব ডিজাইনারের এনভায়রনমেন্টের সাথে তুলনা করুন।
✅ একটু গবেষণা করুন: এখন যেহেতু আপনি একজন ওয়েব ডেভেলপারের পরিবেশের মৌলিক বিষয়গুলো জানেন, এটি একজন ওয়েব ডিজাইনারের পরিবেশের সাথে তুলনা করুন এবং পার্থক্য খুঁজে বের করুন।
---
@ -200,16 +200,18 @@ back add r0,r1
কিছু প্রোগ্রামিং ভাষার তুলনা করুন। জাভাস্ক্রিপ্ট বনাম জাভার কিছু অনন্য বৈশিষ্ট্য কী? COBOL বনাম Go এর ক্ষেত্রে কীভাবে তুলনা করবেন?
## পোস্ট-লেকচার কুইজ
[পোস্ট-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/2)
## পোস্ট-পাঠ কুইজ
[পোস্ট-পাঠ কুইজ](https://ff-quizzes.netlify.app/web/)
## রিভিউ এবং সেলফ স্টাডি
## পর্যালোচনা এবং স্ব-অধ্যয়ন
প্রোগ্রামারের জন্য উপলব্ধ বিভিন্ন ভাষা সম্পর্কে একটু পড়াশোনা করুন। একটি ভাষায় একটি লাইন লিখুন, এবং তারপর এটি অন্য দুটি ভাষায় পুনরায় লিখুন। আপনি কী শিখলেন?
প্রোগ্রামারের জন্য উপলব্ধ বিভিন্ন ভাষা সম্পর্কে একটু পড়াশোনা করুন। একটি ভাষায় একটি লাইন লিখুন, এবং তারপর এটি অন্য দুটি ভাষায় পুনরায় লিখুন। আপনি কী শিখলেন?
## অ্যাসাইনমেন্ট
[Reading the Docs](assignment.md)
[ডকুমেন্ট পড়া](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়বদ্ধ নই
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "05666cecb8983a72cf0ce1d18932b5b7",
"translation_date": "2025-08-25T22:46:03+00:00",
"original_hash": "361249da70432ddfd4741c917d1a6f50",
"translation_date": "2025-08-28T23:09:13+00:00",
"source_file": "1-getting-started-lessons/2-github-basics/README.md",
"language_code": "bn"
}
@ -15,31 +15,31 @@ CO_OP_TRANSLATOR_METADATA:
> স্কেচনোট: [Tomomi Imura](https://twitter.com/girlie_mac)
## প্রাক-পাঠ কুইজ
[প্রাক-পাঠ কুইজ](https://ff-quizzes.netlify.app/web/quiz/3)
[প্রাক-পাঠ কুইজ](https://ff-quizzes.netlify.app)
## পরিচিতি
এই পাঠে আমরা আলোচনা করব:
- আপনার মেশিনে কাজ ট্র্যাক করা
- আপনার মেশিনে করা কাজ ট্র্যাক করা
- অন্যদের সাথে প্রকল্পে কাজ করা
- ওপেন সোর্স সফটওয়্যারে কীভাবে অবদান রাখা যায়
### পূর্বশর্ত
শুরু করার আগে, আপনাকে নিশ্চিত করতে হবে যে Git ইনস্টল করা আছে। টার্মিনালে টাইপ করুন:
শুরু করার আগে, আপনাকে দেখতে হবে Git ইনস্টল করা আছে কিনা। টার্মিনালে টাইপ করুন:
`git --version`
যদি Git ইনস্টল না থাকে, [Git ডাউনলোড করুন](https://git-scm.com/downloads)। তারপর, আপনার লোকাল Git প্রোফাইল সেটআপ করুন টার্মিনালে:
যদি Git ইনস্টল না থাকে, [Git ডাউনলোড করুন](https://git-scm.com/downloads)। রপর, আপনার লোকাল Git প্রোফাইল সেটআপ করুন টার্মিনালে:
* `git config --global user.name "your-name"`
* `git config --global user.email "your-email"`
যাচাই করতে চাইলে টাইপ করুন:
Git ইতিমধ্যে কনফিগার করা আছে কিনা তা পরীক্ষা করতে টাইপ করুন:
`git config --list`
আপনার একটি GitHub অ্যাকাউন্ট, একটি কোড এডিটর (যেমন Visual Studio Code), এবং টার্মিনাল (বা: কমান্ড প্রম্পট) খুলতে হবে।
[github.com](https://github.com/) এ যান এবং একটি অ্যাকাউন্ট তৈরি করুন যদি না করে থাকেন, অথবা লগইন করুন এবং আপনার প্রোফাইল পূরণ করুন।
[github.com](https://github.com/) এ যান এবং যদি আপনার অ্যাকাউন্ট না থাকে তবে একটি তৈরি করুন, অথবা লগইন করে আপনার প্রোফাইল পূরণ করুন।
✅ GitHub একমাত্র কোড রিপোজিটরি নয়; আরও অনেক আছে, তবে GitHub সবচেয়ে পরিচিত।
@ -51,7 +51,7 @@ CO_OP_TRANSLATOR_METADATA:
## কোড ব্যবস্থাপনা
ধরুন আপনার লোকাল মেশিনে একটি কোড প্রকল্পের ফোল্ডার আছে এবং আপনি Git ব্যবহার করে আপনার অগ্রগতি ট্র্যাক করতে চান - এটি একটি ভার্সন কন্ট্রোল সিস্টেম। কিছু মানুষ Git ব্যবহারকে ভবিষ্যতের নিজের জন্য একটি প্রেমপত্র লেখার সাথে তুলনা করে। আপনার কমিট মেসেজগুলো পড়লে আপনি কেন একটি সিদ্ধান্ত নিয়েছিলেন তা মনে করতে পারবেন, অথবা পরিবর্তন "রোলব্যাক" করতে পারবেন - যদি আপনি ভালো "কমিট মেসেজ" লিখেন।
ধরুন আপনার লোকাল মেশিনে একটি কোড প্রকল্পের ফোল্ডার আছে এবং আপনি Git ব্যবহার করে আপনার অগ্রগতি ট্র্যাক করতে চান - এটি একটি ভার্সন কন্ট্রোল সিস্টেম। কিছু লোক Git ব্যবহারকে ভবিষ্যতের নিজের জন্য একটি প্রেমপত্র লেখার সাথে তুলনা করে। আপনার কমিট মেসেজগুলো কয়েক দিন, সপ্তাহ বা মাস পরে পড়লে আপনি বুঝতে পারবেন কেন আপনি একটি সিদ্ধান্ত নিয়েছিলেন, অথবা একটি পরিবর্তন "রোলব্যাক" করতে পারবেন - যদি আপনি ভালো "কমিট মেসেজ" লিখেন।
### কাজ: একটি রিপোজিটরি তৈরি করুন এবং কোড কমিট করুন
@ -59,12 +59,12 @@ CO_OP_TRANSLATOR_METADATA:
>
> [![Git এবং GitHub মৌলিক বিষয় ভিডিও](https://img.youtube.com/vi/9R31OUPpxU4/0.jpg)](https://www.youtube.com/watch?v=9R31OUPpxU4)
1. **GitHub-এ রিপোজিটরি তৈরি করুন**। GitHub.com-এ, রিপোজিটরি ট্যাবে অথবা নেভিগেশন বার টপ-রাইট থেকে **নতুন রিপো** বাটনটি খুঁজুন।
1. **GitHub-এ রিপোজিটরি তৈরি করুন**। GitHub.com-এ, রিপোজিটরি ট্যাবে বা নেভিগেশন বার টপ-রাইট থেকে **নতুন রিপো** বোতামটি খুঁজুন।
1. আপনার রিপোজিটরিকে একটি নাম দিন
1. আপনার রিপোজিটরিকে (ফোল্ডার) একটি নাম দিন
1. **রিপোজিটরি তৈরি করুন** নির্বাচন করুন।
1. **আপনার কাজের ফোল্ডারে যান**। টার্মিনালে, সেই ফোল্ডারে যান (ডিরেক্টরি) যা আপনি ট্র্যাক করতে চান। টাইপ করুন:
1. **আপনার কাজের ফোল্ডারে যান**। আপনার টার্মিনালে, সেই ফোল্ডারে (ডিরেক্টরি) যান যা আপনি ট্র্যাক করতে চান। টাইপ করুন:
```bash
cd [name of your folder]
@ -76,7 +76,7 @@ CO_OP_TRANSLATOR_METADATA:
git init
```
1. **স্ট্যাটাস চেক করুন**। রিপোজিটরির স্ট্যাটাস চেক করতে টাইপ করুন:
1. **স্ট্যাটাস পরীক্ষা করুন**। আপনার রিপোজিটরির স্ট্যাটাস পরীক্ষা করতে টাইপ করুন:
```bash
git status
@ -93,7 +93,7 @@ CO_OP_TRANSLATOR_METADATA:
modified: file2.txt
```
সাধারণত `git status` কমান্ড আপনাকে জানায় কোন ফাইলগুলো _সেভ_ করার জন্য প্রস্তুত অথবা কোন ফাইলগুলোতে পরিবর্তন আছে যা আপনি সংরক্ষণ করতে চান।
সাধারণত `git status` কমান্ড আপনাকে জানায় কোন ফাইলগুলো _সেভ_ করার জন্য প্রস্তুত বা কোন ফাইলগুলোতে পরিবর্তন আছে যা আপনি সংরক্ষণ করতে চান।
1. **সব ফাইল ট্র্যাকিংয়ে যোগ করুন**
এটিকে স্টেজিং ফাইল/স্টেজিং এরিয়াতে ফাইল যোগ করাও বলা হয়।
@ -110,7 +110,7 @@ CO_OP_TRANSLATOR_METADATA:
git add [file or folder name]
```
এটি আমাদের নির্দিষ্ট ফাইলগুলো স্টেজিং এরিয়াতে যোগ করতে সাহায্য করে যখন আমরা সব ফাইল একসাথে কমিট করতে চাই না।
এটি আমাদের নির্দিষ্ট ফাইলগুলোকে স্টেজিং এরিয়াতে যোগ করতে সাহায্য করে যখন আমরা সব ফাইল একসাথে কমিট করতে চাই না।
1. **সব ফাইল আনস্টেজ করুন**
@ -126,17 +126,17 @@ CO_OP_TRANSLATOR_METADATA:
git reset [file or folder name]
```
এই কমান্ড আমাদের নির্দিষ্ট ফাইলটি আনস্টেজ করতে সাহায্য করে যা আমরা পরবর্তী কমিটে অন্তর্ভুক্ত করতে চাই না।
এই কমান্ড আমাদের নির্দিষ্ট ফাইলটি একসাথে আনস্টেজ করতে সাহায্য করে যা আমরা পরবর্তী কমিটে অন্তর্ভুক্ত করতে চাই না।
1. **আপনার কাজ সংরক্ষণ করুন**। এই পর্যায়ে আপনি ফাইলগুলোকে তথাকথিত _স্টেজিং এরিয়া_ তে যোগ করেছেন। এটি এমন একটি জায়গা যেখানে Git আপনার ফাইলগুলো ট্র্যাক করছে। পরিবর্তন স্থায়ী করতে আপনাকে ফাইলগুলো _কমিট_ করতে হবে। এটি করতে `git commit` কমান্ড ব্যবহার করুন। একটি _কমিট_ আপনার রিপোর ইতিহাসে একটি সংরক্ষণের পয়েন্টকে প্রতিনিধিত্ব করে। টাইপ করুন:
1. **আপনার কাজ সংরক্ষণ করুন**। এই পর্যায়ে আপনি ফাইলগুলোকে তথাকথিত _স্টেজিং এরিয়া_ তে যোগ করেছেন। এটি এমন একটি জায়গা যেখানে Git আপনার ফাইলগুলো ট্র্যাক করছে। পরিবর্তন স্থায়ী করতে আপনাকে ফাইলগুলো _কমিট_ করতে হবে। এটি করতে `git commit` কমান্ড ব্যবহার করে একটি _কমিট_ তৈরি করুন। একটি _কমিট_ আপনার রিপোর ইতিহাসে একটি সেভিং পয়েন্টকে উপস্থাপন করে। টাইপ করুন:
```bash
git commit -m "first commit"
```
এটি আপনার সব ফাইল কমিট করে, "first commit" মেসেজ যোগ করে। ভবিষ্যতের কমিট মেসেজগুলোতে আপনি আরও বর্ণনামূলক হতে চাইবেন যাতে আপনার পরিবর্তনের ধরন বোঝানো যায়।
এটি আপনার সব ফাইল কমিট করে এবং "first commit" মেসেজ যোগ করে। ভবিষ্যতের কমিট মেসেজগুলোর জন্য আপনি আরও বর্ণনামূলক হতে চাইবেন যাতে আপনি কী ধরনের পরিবর্তন করেছেন তা বোঝানো যায়।
1. **আপনার লোকাল Git রিপোকে GitHub-এর সাথে সংযুক্ত করুন**। একটি Git রিপো আপনার মেশিনে ভালো, তবে এক পর্যায়ে আপনি আপনার ফাইলগুলোর ব্যাকআপ কোথাও রাখতে চাইবেন এবং অন্যদেরকে আপনার রিপোতে কাজ করার আমন্ত্রণ জানাতে চাইবেন। GitHub এমন একটি জায়গা যেখানে এটি করা যায়। আমরা ইতিমধ্যে GitHub-এ একটি রিপো তৈরি করেছি, তাই আমাদের শুধু লোকাল Git রিপোকে GitHub-এর সাথে সংযুক্ত করতে হবে`git remote add` কমান্ড এটি করবে। টাইপ করুন:
1. **আপনার লোকাল Git রিপোকে GitHub-এর সাথে সংযুক্ত করুন**। একটি Git রিপো আপনার মেশিনে ভালো, তবে এক পর্যায়ে আপনি আপনার ফাইলগুলোর ব্যাকআপ কোথাও রাখতে চাইবেন এবং অন্যদের আপনার রিপোতে কাজ করার জন্য আমন্ত্রণ জানাতে চাইবেন। GitHub এমন একটি জায়গা যেখানে এটি করা যায়। মনে রাখুন আমরা ইতিমধ্যে GitHub-এ একটি রিপো তৈরি করেছি, তাই আমাদের যা করতে হবে তা হলো আমাদের লোকাল Git রিপোকে GitHub-এর সাথে সংযুক্ত করা`git remote add` কমান্ড এটি করবে। টাইপ করুন:
> নোট, কমান্ড টাইপ করার আগে আপনার GitHub রিপো পেজে যান এবং রিপোজিটরি URL খুঁজুন। আপনি এটি নিচের কমান্ডে ব্যবহার করবেন। ```https://github.com/username/repository_name.git``` কে আপনার GitHub URL দিয়ে প্রতিস্থাপন করুন।
@ -144,9 +144,9 @@ CO_OP_TRANSLATOR_METADATA:
git remote add origin https://github.com/username/repository_name.git
```
এটি একটি _রিমোট_, বা সংযোগ, তৈরি করে যার নাম "origin" এবং এটি পূর্বে তৈরি করা GitHub রিপোজিটরির দিকে নির্দেশ করে।
এটি একটি _রিমোট_, বা সংযোগ তৈরি করে, যার নাম "origin" এবং এটি আপনার আগে তৈরি করা GitHub রিপোজিটরির দিকে নির্দেশ করে।
1. **লোকাল ফাইলগুলো GitHub-এ পাঠান**। এখন পর্যন্ত আপনি লোকাল রিপো এবং GitHub রিপোর মধ্যে একটি সংযোগ তৈরি করেছেন। এই ফাইলগুলো GitHub-এ পাঠাতে `git push` কমান্ড ব্যবহার করুন:
1. **লোকাল ফাইলগুলো GitHub-এ পাঠান**। এখন পর্যন্ত আপনি লোকাল রিপো এবং GitHub রিপোর মধ্যে একটি _সংযোগ_ তৈরি করেছেন। এই ফাইলগুলো GitHub-এ পাঠাতে `git push` কমান্ড ব্যবহার করুন:
> নোট, আপনার ব্রাঞ্চের নাম ```main``` থেকে আলাদা হতে পারে।
@ -156,7 +156,7 @@ CO_OP_TRANSLATOR_METADATA:
এটি আপনার "main" ব্রাঞ্চের কমিটগুলো GitHub-এ পাঠায়।
2. **আরও পরিবর্তন যোগ করুন**। যদি আপনি আরও পরিবর্তন করতে চান এবং সেগুলো GitHub-এ পাঠাতে চান, তাহলে আপনাকে শুধু এই তিনটি কমান্ড ব্যবহার করতে হবে:
2. **আরও পরিবর্তন যোগ করুন**। যদি আপনি আরও পরিবর্তন করতে চান এবং সেগুলো GitHub-এ পাঠাতে চান, তাহলে আপনাকে শুধুমাত্র এই তিনটি কমান্ড ব্যবহার করতে হবে:
```bash
git add .
@ -164,7 +164,7 @@ CO_OP_TRANSLATOR_METADATA:
git push
```
> টিপ, আপনি `.gitignore` ফাইল গ্রহণ করতে চাইতে পারেন যাতে আপনি যে ফাইলগুলো ট্র্যাক করতে চান না সেগুলো GitHub-এ প্রদর্শিত না হয় - যেমন সেই নোট ফাইলটি যা আপনি একই ফোল্ডারে সংরক্ষণ করেন কিন্তু পাবলিক রিপোজিটরিতে এর কোনো স্থান নেই। `.gitignore` ফাইলের টেমপ্লেট [এখানে](https://github.com/github/gitignore) পাওয়া যাবে
> টিপ, আপনি `.gitignore` ফাইল গ্রহণ করতে চাইতে পারেন যাতে আপনি GitHub-এ ট্র্যাক করতে না চাওয়া ফাইলগুলো দেখানো থেকে আটকাতে পারেন - যেমন সেই নোট ফাইলটি যা আপনি একই ফোল্ডারে সংরক্ষণ করেন কিন্তু একটি পাবলিক রিপোজিটরিতে থাকার কোনো জায়গা নেই। আপনি [.gitignore টেমপ্লেট](https://github.com/github/gitignore) এ `.gitignore` ফাইলের টেমপ্লেট খুঁজে পেতে পারেন
#### কমিট মেসেজ
@ -172,13 +172,13 @@ CO_OP_TRANSLATOR_METADATA:
যদি প্রয়োগ করা হয়, এই কমিটটি <আপনার সাবজেক্ট লাইন এখানে>
সাবজেক্টে ব্যবহার করুন ইম্পেরেটিভ, বর্তমান কাল: "change" নয় "changed" বা "changes"।
সাবজেক্টের মতো, বডিতেও (ঐচ্ছিক) ইম্পেরেটিভ, বর্তমান কাল ব্যবহার করুন। বডিতে পরিবর্তনের উদ্দেশ্য এবং পূর্ববর্তী আচরণের সাথে এর পার্থক্য অন্তর্ভুক্ত করুন। আপনি `কেন` ব্যাখ্যা করছেন, `কীভাবে` নয়।
যেমন সাবজেক্টে, বডিতেও (ঐচ্ছিক) ইম্পেরেটিভ, বর্তমান কাল ব্যবহার করুন। বডিতে পরিবর্তনের প্রেরণা এবং পূর্ববর্তী আচরণের সাথে এর পার্থক্য অন্তর্ভুক্ত করুন। আপনি `কেন`, `কীভাবে` নয়, ব্যাখ্যা করছেন
কয়েক মিনিট সময় নিয়ে GitHub-এ ঘুরে দেখুন। আপনি কি একটি সত্যিই চমৎকার কমিট মেসেজ খুঁজে পেতে পারেন? আপনি কি একটি খুব সংক্ষিপ্ত মেসেজ খুঁজে পেতে পারেন? আপনার মতে কমিট মেসেজে কোন তথ্য সবচেয়ে গুরুত্বপূর্ণ এবং উপকারী?
✅ GitHub-এ কিছুক্ষণ ঘুরে দেখুন। আপনি কি একটি সত্যিই চমৎকার কমিট মেসেজ খুঁজে পেতে পারেন? আপনি কি একটি খুব সংক্ষিপ্ত মেসেজ খুঁজে পেতে পারেন? আপনার মতে কমিট মেসেজে কোন তথ্য সবচেয়ে গুরুত্বপূর্ণ এবং উপকারী?
### কাজ: সহযোগিতা করুন
GitHub-এ জিনিসগুলো রাখার প্রধান কারণ হলো অন্য ডেভেলপারদের সাথে সহযোগিতা করা সম্ভব করা।
GitHub-এ জিনিসগুলো রাখার প্রধান কারণ ছিল অন্য ডেভেলপারদের সাথে সহযোগিতা করা সম্ভব করা।
## অন্যদের সাথে প্রকল্পে কাজ করা
@ -188,7 +188,7 @@ GitHub-এ জিনিসগুলো রাখার প্রধান কা
আপনার রিপোজিটরিতে, `Insights > Community`-এ যান এবং দেখুন আপনার প্রকল্পটি প্রস্তাবিত কমিউনিটি স্ট্যান্ডার্ডগুলোর সাথে কেমন তুলনা করে।
আপনার GitHub রিপো উন্নত করতে পারে এমন কিছু বিষয়:
এখানে কিছু বিষয় রয়েছে যা আপনার GitHub রিপো উন্নত করতে পারে:
- **বর্ণনা**। আপনি কি আপনার প্রকল্পের জন্য একটি বর্ণনা যোগ করেছেন?
- **README**। আপনি কি একটি README যোগ করেছেন? GitHub একটি [README](https://docs.github.com/articles/about-readmes/?WT.mc_id=academic-77807-sagibbon) লেখার জন্য নির্দেশনা প্রদান করে।
- **অবদান রাখার নির্দেশিকা**। আপনার প্রকল্পে কি [অবদান রাখার নির্দেশিকা](https://docs.github.com/articles/setting-guidelines-for-repository-contributors/?WT.mc_id=academic-77807-sagibbon) আছে?
@ -197,24 +197,24 @@ GitHub-এ জিনিসগুলো রাখার প্রধান কা
এই সমস্ত রিসোর্স নতুন টিম সদস্যদের অনবোর্ডিংয়ে উপকার করবে। এবং এগুলো সাধারণত নতুন অবদানকারীরা আপনার কোড দেখার আগে দেখে, যাতে তারা বুঝতে পারে আপনার প্রকল্প তাদের সময় ব্যয় করার জন্য সঠিক জায়গা কিনা।
✅ README ফাইলগুলো, যদিও প্রস্তুত করতে সময় লাগে, ব্যস্ত মেইনটেইনাররা প্রায়ই এগুলো উপেক্ষা করেন। আপনি কি একটি বিশেষভাবে বর্ণনামূলক README-এর উদাহরণ খুঁজে পেতে পারেন? নোট: [ভালো README তৈরি করতে সাহায্যকারী টুল](https://www.makeareadme.com/) আছে যা আপনি চেষ্টা করতে পারেন।
✅ README ফাইলগুলো, যদিও প্রস্তুত করতে সময় লাগে, ব্যস্ত মেইনটেইনাররা প্রায়ই এগুলো উপেক্ষা করেন। আপনি কি একটি বিশেষভাবে বর্ণনামূলক README-এর উদাহরণ খুঁজে পেতে পারেন? নোট: কিছু [টুল](https://www.makeareadme.com/) রয়েছে যা ভালো README তৈরি করতে সাহায্য করে, যা আপনি চেষ্টা করতে পারেন।
### কাজ: কিছু কোড মার্জ করুন
অবদান রাখার ডকুমেন্টগুলো মানুষকে প্রকল্পে অবদান রাখতে সাহায্য করে। এটি ব্যাখ্যা করে আপনি কী ধরনের অবদান খুঁজছেন এবং প্রক্রিয়াটি কীভাবে কাজ করে। অবদানকারীদের GitHub-এ আপনার রিপোতে অবদান রাখতে একটি সিরিজ ধাপ অনুসরণ করতে হবে:
অবদান রাখার ডকুমেন্টগুলো মানুষকে প্রকল্পে অবদান রাখতে সাহায্য করে। এটি ব্যাখ্যা করে আপনি কী ধরনের অবদান খুঁজছেন এবং প্রক্রিয়াটি কীভাবে কাজ করে। অবদানকারীদের আপনার GitHub রিপোতে অবদান রাখতে একটি সিরিজ ধাপ অনুসরণ করতে হবে:
1. **আপনার রিপো ফর্ক করা**। আপনি সম্ভবত মানুষকে আপনার প্রকল্প _ফর্ক_ করতে চাইবেন। ফর্ক করা মানে তাদের GitHub প্রোফাইলে আপনার রিপোজিটরির একটি প্রতিলিপি তৈরি করা।
1. **ক্লোন**। সেখান থেকে তারা প্রকল্পটি তাদের লোকাল মেশিনে ক্লোন করবে।
1. **একটি ব্রাঞ্চ তৈরি করুন**। আপনি তাদের কাজের জন্য একটি _ব্রাঞ্চ_ তৈরি করতে বলতে চাইবেন
1. **একটি নির্দিষ্ট এলাকায় পরিবর্তন ফোকাস করুন**। অবদানকারীদের একবারে একটি জিনিসে তাদের অবদান কেন্দ্রীভূত করতে বলুন - এভাবে তাদের কাজ _মার্জ_ করার সম্ভাবনা বেশি। ধরুন তারা একটি বাগ ঠিক করে, একটি নতুন ফিচার যোগ করে, এবং কয়েকটি টেস্ট আপডেট করে - যদি আপনি ৩টির মধ্যে ২টি বা ১টি পরিবর্তন বাস্তবায়ন করতে চান বা পারেন?
1. **আপনার রিপো ফর্ক করা**। আপনি সম্ভবত চাইবেন মানুষ আপনার প্রকল্পটি _ফর্ক_ করুক। ফর্ক করা মানে তাদের GitHub প্রোফাইলে আপনার রিপোজিটরির একটি প্রতিলিপি তৈরি করা।
1. **ক্লোন**। এরপর তারা প্রকল্পটি তাদের লোকাল মেশিনে ক্লোন করবে।
1. **একটি ব্রাঞ্চ তৈরি করুন**। আপনি চাইবেন তারা তাদের কাজের জন্য একটি _ব্রাঞ্চ_ তৈরি করুক
1. **তাদের পরিবর্তন একটি এলাকায় কেন্দ্রীভূত করুন**। অবদানকারীদের একবারে একটি জিনিসে তাদের অবদান কেন্দ্রীভূত করতে বলুন - এভাবে তাদের কাজ _মার্জ_ করার সম্ভাবনা বেশি। ধরুন তারা একটি বাগ ঠিক করে, একটি নতুন ফিচার যোগ করে, এবং কয়েকটি টেস্ট আপডেট করে - যদি আপনি ৩টির মধ্যে ২টি বা ১টি পরিবর্তন বাস্তবায়ন করতে চান বা পারেন?
✅ এমন একটি পরিস্থিতি কল্পনা করুন যেখানে ব্রাঞ্চগুলো ভালো কোড লেখার এবং শিপ করার জন্য বিশেষভাবে গুরুত্বপূর্ণ। আপনি কী কী ব্যবহারিক ক্ষেত্র ভাবতে পারেন?
✅ এমন একটি পরিস্থিতি কল্পনা করুন যেখানে ব্রাঞ্চগুলো ভালো কোড লিখতে এবং শিপ করতে বিশেষভাবে গুরুত্বপূর্ণ। আপনি কী ধরনের ব্যবহার কেস কল্পনা করতে পারেন?
> নোট, আপনি নিজেও আপনার কাজের জন্য ব্রাঞ্চ তৈরি করুন। আপনি যে কোনো কমিট করবেন তা আপনি বর্তমানে যে ব্রাঞ্চে "চেক আউট" করেছেন তাতে করা হবে। `git status` ব্যবহার করে দেখুন আপনি কোন ব্রাঞ্চে আছেন।
চলুন একটি অবদানকারীর ওয়ার্কফ্লো নিয়ে আলোচনা করি। ধরে নিন অবদানকারী ইতিমধ্যে রিপো _ফর্ক_ এবং _ক্লোন_ করেছেন, তাই তাদের লোকাল মেশিনে কাজ করার জন্য একটি Git রিপো প্রস্তুত আছে:
চলুন একটি অবদানকারীর ওয়ার্কফ্লো নিয়ে আলোচনা করি। ধরে নিন অবদানকারী ইতিমধ্যে রিপোটি _ফর্ক_ এবং _ক্লোন_ করেছেন, তাই তাদের লোকাল মেশিনে কাজ করার জন্য একটি Git রিপো প্রস্তুত আছে:
1. **একটি ব্রাঞ্চ তৈরি করুন**। `git branch` কমান্ড ব্যবহার করে একটি ব্রাঞ্চ তৈরি করুন যা তারা অবদান রাখতে চা এমন পরিবর্তনগুলো ধারণ করবে:
1. **একটি ব্রাঞ্চ তৈরি করুন**। `git branch` কমান্ড ব্যবহার করে একটি ব্রাঞ্চ তৈরি করুন যা তারা অবদান রাখতে চা এমন পরিবর্তনগুলো ধারণ করবে:
```bash
git branch [branch-name]
@ -235,23 +235,23 @@ GitHub-এ জিনিসগুলো রাখার প্রধান কা
নিশ্চিত করুন আপনি আপনার কমিটকে একটি ভালো নাম দিয়েছেন, আপনার জন্য এবং সেই রিপোর মেইনটেইনারের জন্যও।
1. **আপনার কাজকে `main` ব্রাঞ্চের সাথে একত্রিত করুন**। এক পর্যায়ে আপনি কাজ শেষ করেছেন এবং আপনি আপনার কাজকে `main` ব্রাঞ্চের সাথে একত্রিত করতে চান। `main` ব্রাঞ্চ ইতিমধ্যে পরিবর্তিত হতে পারে, তাই প্রথমে এটি সর্বশেষে আপডেট করন নিম্নলিখিত কমান্ডগুলো ব্যবহার করে:
1. **আপনার কাজ `main` ব্রাঞ্চের সাথে একত্রিত করুন**। এক পর্যায়ে আপনি কাজ শেষ করেছেন এবং আপনি আপনার কাজ `main` ব্রাঞ্চের সাথে একত্রিত করতে চান। `main` ব্রাঞ্চ ইতিমধ্যে পরিবর্তিত হতে পারে, তাই নিশ্চিত করুন আপনি প্রথমে এটি সর্বশেষে আপডেট করেছেন নিম্নলিখিত কমান্ডগুলো ব্যবহার করে:
```bash
git switch main
git pull
```
এই পর্যায়ে আপনি নিশ্চিত করতে চান যে কোনো _কনফ্লিক্ট_, যেখানে Git সহজে পরিবর্তনগুলো _একত্রিত_ করতে পারে না, আপনার কাজের ব্রাঞ্চে ঘটে। তাই নিম্নলিখিত কমান্ডগুলো চালান:
এই পর্যায়ে আপনি নিশ্চিত করতে চান যে কোনো _কনফ্লিক্ট_, এমন পরিস্থিতি যেখানে Git সহজে পরিবর্তনগুলো _একত্রিত_ করতে পারে না, আপনার কাজের ব্রাঞ্চে ঘটে। তাই নিম্নলিখিত কমান্ডগুলো চালান:
```bash
git switch [branch_name]
git merge main
```
এটি `main` থেকে সব পরিবর্তন আপনার ব্রাঞ্চে নিয়ে আসবে এবং আশা করি আপনি সহজেই চালিয়ে যেতে পারবেন। যদি না পারেন, VS Code আপনাকে জানাবে যেখানে Git _বিভ্রান্ত_ এবং আপনি প্রভাবিত ফাইলগুলো সংশোধন করবেন যাতে সঠিক বিষয়বস্তু থাকে
এটি `main` থেকে সব পরিবর্তন আপনার ব্রাঞ্চে নিয়ে আসবে এবং আশা করি আপনি সহজেই চালিয়ে যেতে পারবেন। যদি না পারেন, VS Code আপনাকে জানাবে কোথায় Git _বিভ্রান্ত_ এবং আপনি প্রভাবিত ফাইলগুলো পরিবর্তন করে সঠিক বিষয়বস্তু নির্ধারণ করবেন
1. **আপনার কাজ GitHub-এ পাঠান**। আপনার কাজ GitHub-এ পাঠানো মানে দুটি জিনিস। আপনার ব্রাঞ্চকে আপনার রিপোতে পুশ করা এবং তারপর একটি PR, Pull Request খুলুন।
1. **আপনার কাজ GitHub-এ পাঠান**। আপনার কাজ GitHub-এ পাঠানো মানে দুটি জিনিস। আপনার ব্রাঞ্চকে আপনার রিপোতে পুশ করা এবং একটি PR, Pull Request খুলুন।
```bash
git push --set-upstream origin [branch-name]
@ -259,79 +259,81 @@ GitHub-এ জিনিসগুলো রাখার প্রধান কা
উপরের কমান্ডটি আপনার ফর্ক করা রিপোতে ব্রাঞ্চ তৈরি করে।
1. **একটি PR খুলুন**। এরপর, আপনি একটি PR খুলতে চান। আপনি এটি করতে পারেন আপনার ফর্ক করা রিপোতে GitHub-এ গিয়ে। GitHub-এ আপনি একটি ইঙ্গিত দেখতে পাবেন যেখানে এটি জিজ্ঞাসা করে আপনি একটি নতুন PR তৈরি করতে চান কিনা, আপনি এটি ক্লিক করবেন এবং একটি ইন্টারফেসে নিয়ে যাওয়া হবে যেখানে আপনি কমিট মেসেজের শিরোনাম পরিবর্তন করতে পারেন, এটি আরও উপযুক্ত বর্ণনা দিতে পারেন। এখন আপনি যে রিপোটি ফর্ক করেছেন তার মেইনটেইনার এই PR দেখবেন এবং _আশা করি_ তারা এটি প্রশংসা করবেন এবং আপনার PR _মার্জ_ করবেন। আপনি এখন একজন অবদানকারী, বাহ :)
1. **একটি PR খুলুন**। এরপর, আপনি একটি PR খুলতে চান। আপনি এটি করতে পারেন ফর্ক করা রিপোতে GitHub-এ গিয়ে। আপনি GitHub-এ একটি ইঙ্গিত দেখতে পাবেন যেখানে এটি জিজ্ঞাসা করে আপনি একটি নতুন PR তৈরি করতে চান কিনা, আপনি এটি ক্লিক করবেন এবং আপনাকে একটি ইন্টারফেসে নিয়ে যাওয়া হবে যেখানে আপনি কমিট মেসেজের শিরোনাম পরিবর্তন করতে পারেন, এটি আরও উপযুক্ত বর্ণনা দিতে পারেন। এখন আপনি যে রিপোটি ফর্ক করেছেন তার মেইনটেইনার এই PR দেখবেন এবং _আশা করি_ তারা এটি প্রশংসা করবেন এবং আপনার PR _মার্জ_ করবেন। আপনি এখন একজন অবদানকারী, বাহ :)
1. **পরিষ্কার করুন**। একটি PR সফলভাবে মার্জ করার পর পরিষ্কার করা ভালো অভ্যাস হিসেবে বিবেচিত হয়। আপনি আপনার লোকাল ব্রাঞ্চ এবং GitHub-এ পুশ করা ব্রাঞ্চ উভয়ই পরিষ্কার করতে চান। প্রথমে এটি লোকালি মুছুন নিম্নলিখিত কমান্ড ব্যবহার করে:
1. **পরিষ্কার করুন**। একটি PR সফলভাবে মার্জ করার পর _পরিষ্কার করা_ ভালো অভ্যাস হিসেবে বিবেচিত হয়। আপনি আপনার লোকাল ব্রাঞ্চ এবং আপনি GitHub-এ পুশ করা ব্রাঞ্চ উভয়ই পরিষ্কার করতে চান। প্রথমে এটি লোকাল থেকে মুছুন নিম্নলিখিত কমান্ড ব্যবহার করে:
```bash
git branch -d [branch-name]
```
Ensure you go the GitHub page for the forked repo next and remove the remote branch you just pushed to it.
`Pull request` শব্দটি কিছুটা মজার শোনায় কারণ প্রকৃতপক্ষে আপনি আপনার পরিবর্তনগুলো প্রকল্পে `push` করতে চান। কিন্তু প্রকল্পের মালিক বা মূল দলকে আপনার পরিবর্তনগুলো বিবেচনা করতে হয় এবং সেগুলো প্রকল্পের "main" branch-এ merge করার আগে সিদ্ধান্ত নিতে হয়। তাই আপনি মূলত একজন maintainer-এর কাছ থেকে পরিবর্তনের অনুমতি চাইছেন।
নিশ্চিত করুন আপনি ফর্ক করা রিপোর GitHub পেজে যান এবং আপনি যে রিমোট ব্রাঞ্চটি পুশ করেছেন সেটি সরিয়ে ফেলুন।
`Pull request` শব্দটি একটু অদ্ভুত শোনায়, কারণ প্রকৃতপক্ষে আপনি আপনার পরিবর্তনগুলো প্রকল্পে `push` করতে চান। কিন্তু প্রকল্পের মালিক বা মূল দলকে আপনার পরিবর্তনগুলো বিবেচনা করতে হয়, যাতে এটি প্রকল্পের "main" শাখার সাথে একীভূত করা যায়। তাই আপনি মূলত প্রকল্পের মালিকের কাছে একটি পরিবর্তনের সিদ্ধান্তের অনুরোধ করছেন।
একটি pull request হলো এমন একটি জায়গা যেখানে একটি branch-এ আনা পরিবর্তনগুলো তুলনা এবং আলোচনা করা হয়, যার মধ্যে থাকে review, comment, integrated test এবং আরও অনেক কিছু। একটি ভালো pull request প্রায় commit message-এর মতোই নিয়ম অনুসরণ করে। আপনি issue tracker-এ একটি issue-এর reference যোগ করতে পারেন, যদি আপনার কাজ কোনো issue সমাধান করে। এটি `#` এবং issue নম্বর ব্যবহার করে করা হয়। উদাহরণস্বরূপ, `#97`
একটি pull request হলো এমন একটি জায়গা যেখানে শাখায় আনা পরিবর্তনগুলো তুলনা এবং আলোচনা করা হয়, রিভিউ, মন্তব্য, ইন্টিগ্রেটেড টেস্ট এবং আরও অনেক কিছু সহ। একটি ভালো pull request প্রায় একই নিয়ম অনুসরণ করে যা একটি commit message করে। আপনি issue tracker-এ একটি issue-এর রেফারেন্স যোগ করতে পারেন, উদাহরণস্বরূপ যখন আপনার কাজ কোনো issue সমাধান করে। এটি `#` এবং issue নম্বর ব্যবহার করে করা হয়। যেমন `#97`
🤞আশা করি সব checks পাস করবে এবং প্রকল্পের মালিকরা আপনার পরিবর্তনগুলো প্রকল্পে merge করবেন🤞
🤞আশা করি সব চেক পাস করবে এবং প্রকল্পের মালিক আপনার পরিবর্তনগুলো প্রকল্পে merge করবেন🤞
আপনার বর্তমান local working branch-কে GitHub-এর corresponding remote branch থেকে সব নতুন commit দিয়ে আপডেট করুন:
আপনার বর্তমান লোকাল কাজের শাখাকে GitHub-এর সংশ্লিষ্ট রিমোট শাখার নতুন commit দিয়ে আপডেট করুন:
`git pull`
## ওপেন সোর্সে কীভাবে অবদান রাখবেন
প্রথমে, GitHub-এ একটি repository (বা **repo**) খুঁজুন যা আপনার আগ্রহের এবং যেখানে আপনি একটি পরিবর্তন যোগ করতে চান। আপনি এর বিষয়বস্তু আপনার মেশিনে কপি করতে চাইবেন।
প্রথমে, GitHub-এ আপনার আগ্রহের একটি রিপোজিটরি (বা **repo**) খুঁজুন, যেখানে আপনি পরিবর্তন করতে চান। আপনি এর কন্টেন্ট আপনার মেশিনে কপি করতে চাইবেন।
✅ 'beginner-friendly' repo খুঁজে পাওয়ার একটি ভালো উপায় হলো [ট্যাগ 'good-first-issue' দিয়ে অনুসন্ধান করা](https://github.blog/2020-01-22-browse-good-first-issues-to-start-contributing-to-open-source/)।
✅ 'শুরুর জন্য সহজ' রিপোজিটরি খুঁজতে [good-first-issue ট্যাগ দিয়ে সার্চ করুন](https://github.blog/2020-01-22-browse-good-first-issues-to-start-contributing-to-open-source/)।
![একটি repo স্থানীয়ভাবে কপি করুন](../../../../translated_images/clone_repo.5085c48d666ead57664f050d806e325d7f883be6838c821e08bc823ab7c66665.bn.png)
![রিপো লোকালি কপি করুন](../../../../translated_images/clone_repo.5085c48d666ead57664f050d806e325d7f883be6838c821e08bc823ab7c66665.bn.png)
কোড কপি করার বিভিন্ন উপায় রয়েছে। একটি উপায় হলো repository-এর বিষয়বস্তু "clone" করা, HTTPS, SSH, বা GitHub CLI (Command Line Interface) ব্যবহার করে।
কোড কপি করার বিভিন্ন উপায় আছে। একটি উপায় হলো রিপোজিটরির কন্টেন্ট "clone" করা, HTTPS, SSH, বা GitHub CLI (Command Line Interface) ব্যবহার করে।
আপনার terminal খুলুন এবং repository clone করুন এভাবে:
আপনার টার্মিনাল খুলুন এবং রিপোজিটরি ক্লোন করুন:
`git clone https://github.com/ProjectURL`
প্রকল্পে কাজ করতে, সঠিক ফোল্ডারে যান:
প্রকল্পে কাজ করতে সঠিক ফোল্ডারে যান:
`cd ProjectURL`
আপনি [Codespaces](https://github.com/features/codespaces), GitHub-এর embedded code editor / cloud development environment, বা [GitHub Desktop](https://desktop.github.com/) ব্যবহার করে পুরো প্রকল্পটি খুলতে পারেন।
আপনি পুরো প্রকল্পটি [Codespaces](https://github.com/features/codespaces), GitHub-এর এম্বেডেড কোড এডিটর / ক্লাউড ডেভেলপমেন্ট এনভায়রনমেন্ট, অথবা [GitHub Desktop](https://desktop.github.com/) ব্যবহার করে খুলতে পারেন।
অবশেষে, আপনি কোডটি একটি zipped folder-এ ডাউনলোড করতে পারেন।
অবশেষে, আপনি কোডটি একটি জিপ করা ফোল্ডারে ডাউনলোড করতে পারেন।
### GitHub সম্পর্কে আরও কিছু আকর্ষণীয় বিষয়
### GitHub সম্পর্কে আরও কিছু আকর্ষণীয় বিষয়
আপনি GitHub-এ যেকোনো public repository-কে star, watch এবং/অথবা "fork" করতে পারেন। আপনার starred repositories-গুলো top-right drop-down menu-তে খুঁজে পাবেন। এটি কোডের জন্য bookmarking-এর মতো।
আপনি GitHub-এ যেকোনো পাবলিক রিপোজিটরিকে স্টার, ওয়াচ এবং/অথবা "fork" করতে পারেন। আপনার স্টার করা রিপোজিটরি আপনি উপরের ডানদিকে ড্রপ-ডাউন মেনুতে খুঁজে পাবেন। এটি কোডের জন্য বুকমার্ক করার মতো।
প্রকল্পগুলোতে একটি issue tracker থাকে, সাধারণত GitHub-এর "Issues" tab-এ, যদি অন্যথায় উল্লেখ না করা হয়, যেখানে প্রকল্প সম্পর্কিত সমস্যাগুলো নিয়ে আলোচনা করা হয়। এবং Pull Requests tab হলো যেখানে চলমান পরিবর্তনগুলো নিয়ে আলোচনা এবং review করা হয়
প্রকল্পগুলোতে একটি issue tracker থাকে, সাধারণত GitHub-এর "Issues" ট্যাবে, যেখানে প্রকল্প সম্পর্কিত বিষয়গুলো নিয়ে আলোচনা করা হয়। এবং Pull Requests ট্যাবে চলমান পরিবর্তনগুলো নিয়ে আলোচনা এবং রিভিউ করা হয়
প্রকল্পগুলোতে forum, mailing list, বা Slack, Discord বা IRC-এর মতো chat channel-এ আলোচনা থাকতে পারে।
প্রকল্পগুলোতে ফোরাম, মেইলিং লিস্ট, বা Slack, Discord বা IRC-এর মতো চ্যাট চ্যানেলে আলোচনা হতে পারে।
✅ আপনার নতুন GitHub repo-তে ঘুরে দেখুন এবং কিছু জিনিস চেষ্টা করুন, যেমন settings সম্পাদনা করা, আপনার repo-তে তথ্য যোগ করা, এবং একটি প্রকল্প তৈরি করা (যেমন Kanban board)। এখানে অনেক কিছু করার আছে!
✅ আপনার নতুন GitHub রিপোজিটরির চারপাশে ঘুরে দেখুন এবং কিছু জিনিস চেষ্টা করুন, যেমন সেটিংস সম্পাদনা করা, আপনার রিপোতে তথ্য যোগ করা, এবং একটি প্রকল্প তৈরি করা (যেমন একটি Kanban বোর্ড)। এখানে অনেক কিছু করার আছে!
---
## 🚀 চ্যালেঞ্জ
## 🚀 চ্যালেঞ্জ
একজন বন্ধুর সাথে জুটি বাঁধুন এবং একে অপরের কোডে কাজ করুন। একটি প্রকল্প যৌথভাবে তৈরি করুন, কোড fork করুন, branch তৈরি করুন, এবং পরিবর্তনগুলো merge করুন।
একজন বন্ধুর সাথে জুটি বাঁধুন এবং একে অপরের কোডে কাজ করুন। একটি প্রকল্প যৌথভাবে তৈরি করুন, কোড fork করুন, শাখা তৈরি করুন, এবং পরিবর্তন merge করুন।
## Post-Lecture Quiz
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/4)
## পোস্ট-লেকচার কুইজ
[পোস্ট-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/en/)
## পর্যালোচনা এবং স্ব-অধ্যয়
## রিভিউ এবং স্ব-অধ্যয়
[ওপেন সোর্স সফটওয়্যারে অবদান রাখার বিষয়ে আরও পড়ুন](https://opensource.guide/how-to-contribute/#how-to-submit-a-contribution)।
[ওপেন সোর্স সফটওয়্যারে অবদান রাখার](https://opensource.guide/how-to-contribute/#how-to-submit-a-contribution) বিষয়ে আরও পড়ুন
[Git cheatsheet](https://training.github.com/downloads/github-git-cheat-sheet/)।
[Git চিটশিট](https://training.github.com/downloads/github-git-cheat-sheet/)।
অনুশীলন, অনুশীলন, অনুশীলন। GitHub-এ [skills.github.com](https://skills.github.com)-এর মাধ্যমে চমৎকার learning paths রয়েছে:
অনুশীলন, অনুশীলন, অনুশীলন। GitHub-এ [skills.github.com](https://skills.github.com)-এর মাধ্যমে চমৎকার লার্নিং পাথ রয়েছে:
- [GitHub-এ প্রথম সপ্তাহ](https://skills.github.com/#first-week-on-github)
আপনি আরও উন্নত কোর্সও খুঁজে পাবেন।
## Assignment
## অ্যাসাইনমেন্ট
[GitHub-এ প্রথম সপ্তাহ কোর্স](https://skills.github.com/#first-week-on-github) সম্পূর্ণ করুন।
[GitHub-এ প্রথম সপ্তাহ কোর্স](https://skills.github.com/#first-week-on-github) সম্পন্ন করুন।
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়ী থাকব না।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e4cd5b1faed4adab5acf720f82798003",
"translation_date": "2025-08-25T22:57:22+00:00",
"original_hash": "f0c88c3e2cefa8952d356f802b1e47ca",
"translation_date": "2025-08-28T23:08:25+00:00",
"source_file": "1-getting-started-lessons/3-accessibility/README.md",
"language_code": "bn"
}
@ -12,14 +12,14 @@ CO_OP_TRANSLATOR_METADATA:
![অ্যাক্সেসিবিলিটি সম্পর্কে সবকিছু](../../../../translated_images/webdev101-a11y.8ef3025c858d897a403a1a42c0897c76e11b724d9a8a0c0578dd4316f7507622.bn.png)
> স্কেচনোট: [Tomomi Imura](https://twitter.com/girlie_mac)
## লেকচারের আগে কুইজ
[লেকচারের আগে কুইজ](https://ff-quizzes.netlify.app/web/quiz/5)
## প্রাক-লেকচার কুইজ
[প্রাক-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/)
> ওয়েবের শক্তি র সার্বজনীনতায়। প্রতিবন্ধকতা নির্বিশেষে সবার জন্য অ্যাক্সেস নিশ্চিত করাই এর একটি গুরুত্বপূর্ণ দিক।
> ওয়েবের শক্তি তার সার্বজনীনতায়। প্রতিবন্ধকতা নির্বিশেষে সবার জন্য অ্যাক্সেস নিশ্চিত করাই এর একটি গুরুত্বপূর্ণ দিক।
>
> \- স্যার টিমোথি বার্নার্স-লি, W3C ডিরেক্টর এবং ওয়ার্ল্ড ওয়াইড ওয়েবের উদ্ভাব
> \- স্যার টিমোথি বার্নার্স-লি, W3C ডিরেক্টর এবং ওয়ার্ল্ড ওয়াইড ওয়েবের আবিষ্কার
এই উক্তিটি অ্যাক্সেসযোগ্য ওয়েবসাইট তৈরির গুরুত্বকে নিখুঁতভাবে তুলে ধরে। এমন একটি অ্যাপ্লিকেশন যা সবাই ব্যবহার করতে পারে না, তা প্রকৃতপক্ষে বর্জনমূলক। ওয়েব ডেভেলপার হিসেবে আমাদের সবসময় অ্যাক্সেসিবিলিটিকে মাথায় রাখতে হবে। শুরু থেকেই এই বিষয়ে মনোযোগ দিলে আপনি নিশ্চিত করতে পারবেন যে, আপনার তৈরি পৃষ্ঠাগুলি সবাই ব্যবহার করতে পারবে। এই পাঠে, আপনি শিখবেন কীভাবে অ্যাক্সেসযোগ্য ওয়েব অ্যাসেট তৈরি করবেন এবং কোন কোন টুল আপনাকে এই কাজে সাহায্য করতে পারে।
এই উক্তিটি অ্যাক্সেসযোগ্য ওয়েবসাইট তৈরির গুরুত্বকে পুরোপুরি তুলে ধরে। একটি অ্যাপ্লিকেশন যা সবাই ব্যবহার করতে পারে না, তা মূলত বর্জনমূলক। ওয়েব ডেভেলপার হিসেবে আমাদের সবসময় অ্যাক্সেসিবিলিটির কথা মাথায় রাখা উচিত। শুরু থেকেই এই বিষয়ে মনোযোগ দিলে আপনি নিশ্চিত করতে পারবেন যে আপনার তৈরি পেজগুলো সবাই ব্যবহার করতে পারবে। এই পাঠে, আপনি শিখবেন কীভাবে অ্যাক্সেসযোগ্য ওয়েব অ্যাসেট তৈরি করবেন এবং কোন টুলগুলো আপনাকে সাহায্য করতে পারে।
> আপনি এই পাঠটি [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101/accessibility/?WT.mc_id=academic-77807-sagibbon) এ নিতে পারেন!
@ -27,35 +27,35 @@ CO_OP_TRANSLATOR_METADATA:
### স্ক্রিন রিডার
অ্যাক্সেসিবিলিটির সবচেয়ে পরিচিত টুলগুলোর একটি হলো স্ক্রিন রিডার।
সবচেয়ে পরিচিত অ্যাক্সেসিবিলিটি টুলগুলোর মধ্যে একটি হলো স্ক্রিন রিডার।
[স্ক্রিন রিডার](https://en.wikipedia.org/wiki/Screen_reader) সাধারণত দৃষ্টিহীন বা দৃষ্টি প্রতিবন্ধী ব্যক্তিরা ব্যবহার করেন। আমরা যেমন ব্রাউজার ব্যবহার করে তথ্য উপস্থাপন নিশ্চিত করি, তেমনি স্ক্রিন রিডারেও সঠিকভাবে তথ্য উপস্থাপন নিশ্চিত করতে হবে।
[স্ক্রিন রিডার](https://en.wikipedia.org/wiki/Screen_reader) সাধারণত দৃষ্টিশক্তি প্রতিবন্ধীদের জন্য ব্যবহৃত হয়। আমরা যখন ব্রাউজার সঠিকভাবে তথ্য প্রদর্শন করছে কিনা তা নিশ্চিত করার জন্য সময় ব্যয় করি, তখন আমাদের নিশ্চিত করতে হবে স্ক্রিন রিডারও একইভাবে তথ্য প্রদর্শন করছে।
স্ক্রিন রিডার সাধারণত একটি পৃষ্ঠার উপরের দিক থেকে নিচ পর্যন্ত শব্দ করে পড়ে। যদি আপনার পৃষ্ঠাটি শুধুমাত্র টেক্সট দিয়ে তৈরি হয়, তবে এটি ব্রাউজারের মতোই তথ্য উপস্থাপন করবে। তবে ওয়েব পৃষ্ঠাগুলি সাধারণত শুধুমাত্র টেক্সট নয়; এতে লিঙ্ক, গ্রাফিক্স, রঙ এবং অন্যান্য ভিজ্যুয়াল উপাদান থাকে। স্ক্রিন রিডার সঠিকভাবে এই তথ্য পড়তে পারে তা নিশ্চিত করতে হবে।
স্ক্রিন রিডার সাধারণত একটি পেজের উপরের অংশ থেকে নিচ পর্যন্ত শব্দে পড়ে। যদি আপনার পেজটি শুধুমাত্র টেক্সট হয়, তাহলে রিডার এটি ব্রাউজারের মতোই তথ্য প্রদর্শন করবে। তবে, ওয়েব পেজগুলো সাধারণত শুধুমাত্র টেক্সট নয়; এতে লিঙ্ক, গ্রাফিক্স, রঙ এবং অন্যান্য ভিজ্যুয়াল উপাদান থাকে। স্ক্রিন রিডার সঠিকভাবে এই তথ্য পড়তে পারে তা নিশ্চিত করতে হবে।
প্রতিটি ওয়েব ডেভেলপারের স্ক্রিন রিডার সম্পর্কে ধারণা থাকা উচিত। এটি আপনার ব্যবহারকারীদের একটি গুরুত্বপূর্ণ টুল। যেমন আপনি ব্রাউজারের কার্যপ্রণালী জানেন, তেমনি স্ক্রিন রিডারের কার্যপ্রণালীও জানা উচিত। সৌভাগ্যবশত, বেশিরভাগ অপারেটিং সিস্টেমে স্ক্রিন রিডার বিল্ট-ইন থাকে।
প্রত্যেক ওয়েব ডেভেলপারকে স্ক্রিন রিডারের সাথে পরিচিত হওয়া উচিত। এটি আপনার ব্যবহারকারীদের জন্য একটি গুরুত্বপূর্ণ ক্লায়েন্ট। যেমন আপনি ব্রাউজারের কার্যক্রম সম্পর্কে জানেন, তেমনি স্ক্রিন রিডারের কার্যক্রমও জানা উচিত। সৌভাগ্যক্রমে, বেশিরভাগ অপারেটিং সিস্টেমে স্ক্রিন রিডার বিল্ট-ইন থাকে।
কিছু ব্রাউজারে বিল্ট-ইন টুল এবং এক্সটেনশন থাকে যা টেক্সট পড়ে শোনাতে পারে বা কিছু মৌলিক নেভিগেশন ফিচার সরবরাহ করতে পারে, যেমন [এই অ্যাক্সেসিবিলিটি-কেন্দ্রিক Edge ব্রাউজার টুলস](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features)। তবে এগুলো স্ক্রিন রিডার টেস্টিং টুল নয় এবং সেগুলোর সাথে গুলিয়ে ফেলা উচিত নয়।
কিছু ব্রাউজারে বিল্ট-ইন টুল এবং এক্সটেনশন থাকে যা টেক্সট পড়তে পারে বা কিছু মৌলিক নেভিগেশন ফিচার প্রদান করতে পারে, যেমন [Edge ব্রাউজারের এই অ্যাক্সেসিবিলিটি টুলগুলো](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features)। এগুলোও গুরুত্বপূর্ণ অ্যাক্সেসিবিলিটি টুল, তবে স্ক্রিন রিডার টেস্টিং টুল হিসেবে এগুলোকে ভুলভাবে ব্যবহার করা উচিত নয়।
একটি স্ক্রিন রিডার এবং ব্রাউজার টেক্সট রিডার ব্যবহার করে দেখুন। Windows-এ [Narrator](https://support.microsoft.com/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1/?WT.mc_id=academic-77807-sagibbon) ডিফল্টভাবে অন্তর্ভুক্ত থাকে, এবং [JAWS](https://webaim.org/articles/jaws/) এবং [NVDA](https://www.nvaccess.org/about-nvda/) ইনস্টল করা যায়। macOS এবং iOS-এ [VoiceOver](https://support.apple.com/guide/voiceover/welcome/10) ডিফল্টভাবে অন্তর্ভুক্ত থাকে।
✅ স্ক্রিন রিডার এবং ব্রাউজার টেক্সট রিডার ব্যবহার করে দেখুন। Windows-এ [Narrator](https://support.microsoft.com/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1/?WT.mc_id=academic-77807-sagibbon) ডিফল্টভাবে অন্তর্ভুক্ত থাকে, এবং [JAWS](https://webaim.org/articles/jaws/) এবং [NVDA](https://www.nvaccess.org/about-nvda/) ইনস্টল করা যেতে পারে। macOS এবং iOS-এ [VoiceOver](https://support.apple.com/guide/voiceover/welcome/10) ডিফল্টভাবে অন্তর্ভুক্ত থাকে।
### জুম
দৃষ্টি প্রতিবন্ধী ব্যক্তিরা সাধারণত আরেকটি টুল ব্যবহার করেন, যা হলো জুম। সবচেয়ে সাধারণ জুম হলো স্ট্যাটিক জুম, যা `Control + প্লাস চিহ্ন (+)` ব্যবহার করে বা স্ক্রিন রেজোলিউশন কমিয়ে নিয়ন্ত্রণ করা হয়। এই ধরনের জুম পুরো পৃষ্ঠাটিকে পুনরায় আকার দেয়, তাই [রেসপন্সিভ ডিজাইন](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Responsive_Design) ব্যবহার করা গুরুত্বপূর্ণ যাতে বড় জুম লেভেলে ভালো ব্যবহারকারীর অভিজ্ঞতা নিশ্চিত হয়।
দৃষ্টিশক্তি প্রতিবন্ধীদের জন্য আরেকটি সাধারণ টুল হলো জুমিং। সবচেয়ে সাধারণ জুমিং হলো স্ট্যাটিক জুম, যা `Control + plus sign (+)` বা স্ক্রিন রেজোলিউশন কমিয়ে নিয়ন্ত্রণ করা হয়। এই ধরনের জুম পুরো পেজকে রিসাইজ করে, তাই [রেসপন্সিভ ডিজাইন](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Responsive_Design) ব্যবহার করা গুরুত্বপূর্ণ যাতে বড় জুম লেভেলে ভালো ব্যবহারকারীর অভিজ্ঞতা প্রদান করা যায়।
আরেক ধরনের জুম হলো বিশেষায়িত সফটওয়্যার ব্যবহার করে স্ক্রিনের একটি নির্দিষ্ট অংশ বড় করা এবং প্যান করা, অনেকটা একটি বাস্তব ম্যাগনিফাইং গ্লাসের মতো। Windows-এ [Magnifier](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198) বিল্ট-ইন থাকে, এবং [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) একটি তৃতীয় পক্ষের ম্যাগনিফিকেশন সফটওয়্যার যা আরও বেশি ফিচার এবং বড় ব্যবহারকারী বেস সরবরাহ করে। macOS এবং iOS-এ [Zoom](https://www.apple.com/accessibility/mac/vision/) নামে একটি বিল্ট-ইন ম্যাগনিফিকেশন সফটওয়্যার রয়েছে।
আরেক ধরনের জুম বিশেষ সফটওয়্যার ব্যবহার করে স্ক্রিনের একটি অংশকে বড় করে এবং প্যান করে, অনেকটা বাস্তব ম্যাগনিফাইং গ্লাসের মতো। Windows-এ [Magnifier](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198) বিল্ট-ইন থাকে, এবং [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) একটি তৃতীয় পক্ষের ম্যাগনিফিকেশন সফটওয়্যার যা আরও বেশি ফিচার এবং বড় ব্যবহারকারী বেস প্রদান করে। macOS এবং iOS-এ বিল্ট-ইন ম্যাগনিফিকেশন সফটওয়্যার [Zoom](https://www.apple.com/accessibility/mac/vision/) অন্তর্ভুক্ত থাকে।
### কনট্রাস্ট চেকার
ওয়েবসাইটের রঙ এমনভাবে নির্বাচন করতে হবে যাতে রঙ-অন্ধ ব্যবহারকারী বা যারা কম কনট্রাস্ট রঙ দেখতে অসুবিধা অনুভব করেন, তাদের প্রয়োজন মেটানো যায়।
ওয়েবসাইটে রঙ সাবধানে নির্বাচন করতে হবে যাতে রঙ-অন্ধ ব্যবহারকারী বা যারা কম কনট্রাস্ট রঙ দেখতে অসুবিধা অনুভব করেন তাদের প্রয়োজন মেটানো যায়।
✅ একটি ওয়েবসাইট পরীক্ষা করুন যা আপনি পছন্দ করেন এবং ব্রাউজার এক্সটেনশন ব্যবহার করে রঙের ব্যবহার বিশ্লেষণ করুন, যেমন [WCAG-এর কালার চেকার](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=en-US&WT.mc_id=academic-77807-sagibbon)। আপনি কী শিখলেন?
✅ একটি ওয়েবসাইট পরীক্ষা করুন যা আপনি ব্যবহার করতে পছন্দ করেন এবং ব্রাউজার এক্সটেনশন যেমন [WCAG এর কালার চেকার](https://microsoftedge.microsoft.com/addons/detail/wcag-color-contrast-check/idahaggnlnekelhgplklhfpchbfdmkjp?hl=en-US&WT.mc_id=academic-77807-sagibbon) ব্যবহার করে রঙের ব্যবহার পরীক্ষা করুন। আপনি কী শিখলেন?
### লাইটহাউস
### Lighthouse
আপনার ব্রাউজারের ডেভেলপার টুল এলাকায় লাইটহাউস টুল পাওয়া যাবে। এই টুলটি একটি ওয়েবসাইটের অ্যাক্সেসিবিলিটি (এবং অন্যান্য বিশ্লেষণ) সম্পর্কে প্রাথমিক ধারণা পেতে গুরুত্বপূর্ণ। যদিও শুধুমাত্র লাইটহাউসের উপর নির্ভর করা উচিত নয়, ১০০% স্কোর একটি ভালো সূচনা পয়েন্ট
আপনার ব্রাউজারের ডেভেলপার টুল এলাকায় Lighthouse টুল পাওয়া যাবে। এই টুলটি একটি ওয়েবসাইটের অ্যাক্সেসিবিলিটি (এবং অন্যান্য বিশ্লেষণ) সম্পর্কে প্রাথমিক ধারণা পেতে গুরুত্বপূর্ণ। যদিও শুধুমাত্র Lighthouse-এর উপর নির্ভর করা উচিত নয়, ১০০% স্কোর একটি সহায়ক ভিত্তি হিসেবে কাজ করে
✅ আপনার ব্রাউজারের ডেভেলপার টুল প্যানেলে লাইটহাউস খুঁজুন এবং যেকোনো সাইটে একটি বিশ্লেষণ চালান। আপনি কী আবিষ্কার করেন?
✅ আপনার ব্রাউজারের ডেভেলপার টুল প্যানেলে Lighthouse খুঁজুন এবং যেকোনো সাইটে একটি বিশ্লেষণ চালান। আপনি কী আবিষ্কার করেন?
## অ্যাক্সেসিবিলিটির জন্য ডিজাইন করা
@ -63,88 +63,86 @@ CO_OP_TRANSLATOR_METADATA:
- [Accessible U - University of Minnesota](https://accessibility.umn.edu/your-role/web-developers)
যদিও আমরা অ্যাক্সেসযোগ্য সাইট তৈরির প্রতিটি দিক কভার করতে পারব না, নিচে কিছু মূল নীতিমালা দেওয়া হলো যা আপনি বাস্তবায়ন করতে চাইবেন। শুরু থেকেই একটি অ্যাক্সেসযোগ্য পৃষ্ঠা ডিজাইন করা **সবসময়** সহজতর হয়, তুলনায় একটি বিদ্যমান পৃষ্ঠাকে অ্যাক্সেসযোগ্য করার চেয়ে।
যদিও আমরা অ্যাক্সেসযোগ্য সাইট তৈরির প্রতিটি দিক কভার করতে পারব না, নিচে কিছু মূল নীতিমালা রয়েছে যা আপনি বাস্তবায়ন করতে চাইবেন। শুরু থেকেই একটি অ্যাক্সেসযোগ্য পেজ ডিজাইন করা **সবসময়** একটি বিদ্যমান পেজকে অ্যাক্সেসযোগ্য করার চেয়ে সহজ
## ভালো প্রদর্শন নীতিমালা
### রঙ নিরাপদ প্যালেট
মানুষ পৃথিবীকে বিভিন্নভাবে দেখে, এবং এর মধ্যে রঙও অন্তর্ভুক্ত। আপনার সাইটের জন্য একটি রঙ স্কিম নির্বাচন করার সময় নিশ্চিত করুন এটি সবার জন্য অ্যাক্সেসযোগ্য। একটি চমৎকার [রঙ প্যালেট তৈরির টুল হলো Color Safe](http://colorsafe.co/)।
মানুষ পৃথিবীকে বিভিন্নভাবে দেখে, এবং এর মধ্যে রঙও অন্তর্ভুক্ত। আপনার সাইটের জন্য একটি রঙ স্কিম নির্বাচন করার সময়, নিশ্চিত করুন এটি সবার জন্য অ্যাক্সেসযোগ্য। একটি চমৎকার [রঙ প্যালেট তৈরি করার টুল হলো Color Safe](http://colorsafe.co/)।
✅ এমন একটি ওয়েবসাইট চিহ্নিত করুন যেখানে রঙ ব্যবহারে বড় সমস্যা রয়েছে। কেন?
✅ একটি ওয়েবসাইট চিহ্নিত করুন যা রঙ ব্যবহারে খুব সমস্যাযুক্ত। কেন?
### সঠিক HTML ব্যবহার করুন
CSS এবং JavaScript ব্যবহার করে যেকোনো উপাদানকে যেকোনো ধরনের কন্ট্রোলে রূপান্তর করা সম্ভব। `<span>` ব্যবহার করে একটি `<button>` তৈরি করা যেতে পারে, এবং `<b>` ব্যবহার করে একটি হাইপারলিঙ্ক তৈরি করা যেতে পারে। যদিও এটি স্টাইলিংয়ের জন্য সহজ মনে হতে পারে, এটি স্ক্রিন রিডারের জন্য কোনো তথ্য প্রদান করে না। পৃষ্ঠায় কন্ট্রোল তৈরি করার সময় সঠিক HTML ব্যবহার করুন। যদি আপনি একটি হাইপারলিঙ্ক চান, `<a>` ব্যবহার করুন। সঠিক কন্ট্রোলের জন্য সঠিক HTML ব্যবহার করাকে বলা হয় সেমান্টিক HTML ব্যবহার করা।
CSS এবং JavaScript ব্যবহার করে যেকোনো এলিমেন্টকে যেকোনো ধরনের কন্ট্রোলের মতো দেখানো সম্ভব। `<span>` ব্যবহার করে একটি `<button>` তৈরি করা যেতে পারে, এবং `<b>` একটি হাইপারলিঙ্কে পরিণত হতে পারে। যদিও এটি স্টাইলিংয়ের জন্য সহজ বলে মনে হতে পারে, এটি স্ক্রিন রিডারের জন্য কিছুই প্রকাশ করে না। একটি পেজে কন্ট্রোল তৈরি করার সময় সঠিক HTML ব্যবহার করুন। যদি আপনি একটি হাইপারলিঙ্ক চান, `<a>` ব্যবহার করুন। সঠিক কন্ট্রোলের জন্য সঠিক HTML ব্যবহার করাকে বলা হয় Semantic HTML ব্যবহার করা।
✅ যেকোনো ওয়েবসাইটে যান এবং দেখুন ডিজাইনার এবং ডেভেলপাররা HTML সঠিকভাবে ব্যবহার করছেন কিনা। আপনি কি এমন কোনো বোতাম খুঁজে পেয়েছেন যা একটি লিঙ্ক হওয়া উচিত? টিপ: ব্রাউজারে 'View Page Source' নির্বাচন করতে ডান ক্লিক করুন এবং আন্ডারলাইন কোড দেখুন।
✅ যেকোনো ওয়েবসাইটে যান এবং দেখুন ডিজাইনার এবং ডেভেলপাররা HTML সঠিকভাবে ব্যবহার করছেন কিনা। আপনি কি এমন কোনো বাটন খুঁজে পান যা একটি লিঙ্ক হওয়া উচিত? টিপ: আপনার ব্রাউজারে 'View Page Source' নির্বাচন করতে রাইট ক্লিক করুন এবং আন্ডারলাইন কোড দেখুন।
### একটি বর্ণনামূলক শিরোনাম হায়ারার্কি তৈরি করুন
### বর্ণনামূলক শিরোনাম হায়ারার্কি তৈরি করুন
স্ক্রিন রিডার ব্যবহারকারীরা [শিরোনামের উপর ব্যাপকভাবে নির্ভর করেন](https://webaim.org/projects/screenreadersurvey8/#finding) তথ্য খুঁজে পেতে এবং একটি পৃষ্ঠার মধ্য দিয়ে নেভিগেট করতে। বর্ণনামূলক শিরোনাম কন্টেন্ট লেখা এবং সেমান্টিক শিরোনাম ট্যাগ ব্যবহার করা একটি সহজে নেভিগেটযোগ্য সাইট তৈরির জন্য গুরুত্বপূর্ণ।
স্ক্রিন রিডার ব্যবহারকারীরা [শিরোনামের উপর ব্যাপকভাবে নির্ভর করেন](https://webaim.org/projects/screenreadersurvey8/#finding) তথ্য খুঁজে পেতে এবং একটি পেজে নেভিগেট করতে। বর্ণনামূলক শিরোনাম কন্টেন্ট লেখা এবং সেমান্টিক শিরোনাম ট্যাগ ব্যবহার করা স্ক্রিন রিডার ব্যবহারকারীদের জন্য একটি সহজে নেভিগেটযোগ্য সাইট তৈরি করার জন্য গুরুত্বপূর্ণ।
### ভালো ভিজ্যুয়াল ক্লু ব্যবহার করুন
CSS একটি পৃষ্ঠার যেকোনো উপাদানের চেহারা সম্পূর্ণ নিয়ন্ত্রণ করতে দেয়। আপনি একটি টেক্সট বক্স তৈরি করতে পারেন যার কোনো আউটলাইন নেই বা একটি হাইপারলিঙ্ক তৈরি করতে পারেন যার কোনো আন্ডারলাইন নেই। দুর্ভাগ্যবশত, এই ক্লুগুলি সরিয়ে ফেলা তাদের জন্য চ্যালেঞ্জিং করে তুলতে পারে যারা এগুলোর উপর নির্ভর করেন।
CSS একটি পেজে যেকোনো এলিমেন্টের চেহারা সম্পূর্ণ নিয়ন্ত্রণ করার সুযোগ দেয়। আপনি আউটলাইন ছাড়া টেক্সট বক্স বা আন্ডারলাইন ছাড়া হাইপারলিঙ্ক তৈরি করতে পারেন। দুর্ভাগ্যক্রমে এই ক্লুগুলো সরিয়ে ফেললে যারা এগুলোর উপর নির্ভর করেন তাদের জন্য কন্ট্রোল চিনতে অসুবিধা হতে পারে
## লিঙ্ক টেক্সটের গুরুত্ব
হাইপারলিঙ্ক ওয়েব নেভিগেশনের মূল উপাদান। সুতরাং, একটি স্ক্রিন রিডার সঠিকভাবে লিঙ্ক পড়তে পারে তা নিশ্চিত করা সবার জন্য আপনার সাইট নেভিগেট করা সহজ করে তোলে।
হাইপারলিঙ্ক ওয়েব নেভিগেশনের মূল। ফলে, একটি স্ক্রিন রিডার সঠিকভাবে লিঙ্ক পড়তে পারে তা নিশ্চিত করা সবার জন্য আপনার সাইট নেভিগেট করা সহজ করে তোলে।
### স্ক্রিন রিডার এবং লিঙ্ক
আপনি যেমনটি আশা করবেন, স্ক্রিন রিডার লিঙ্ক টেক্সটকে পৃষ্ঠার অন্য যেকোনো টেক্সটের মতোই পড়ে। এই বিষয়টি মাথায় রেখে, নিচের প্রদর্শিত টেক্সটটি গ্রহণযোগ্য মনে হতে পারে।
আপনি যেমন আশা করবেন, স্ক্রিন রিডার লিঙ্ক টেক্সটকে পেজের অন্য টেক্সটের মতোই পড়ে। এই বিষয়টি মাথায় রেখে, নিচের প্রদর্শিত টেক্সটটি গ্রহণযোগ্য মনে হতে পারে।
> ছোট পেঙ্গুইন, যাকে কখনও কখনও পরী পেঙ্গুইনও বলা হয়, এটি বিশ্বের সবচেয়ে ছোট পেঙ্গুইন। [এখানে ক্লিক করুন](https://en.wikipedia.org/wiki/Little_penguin) আরও তথ্যের জন্য।
> ছোট পেঙ্গুইন, কখনও কখনও পরী পেঙ্গুইন নামে পরিচিত, বিশ্বের সবচেয়ে ছোট পেঙ্গুইন। [এখানে ক্লিক করুন](https://en.wikipedia.org/wiki/Little_penguin) আরও তথ্যের জন্য।
> ছোট পেঙ্গুইন, যাকে কখনও কখনও পরী পেঙ্গুইনও বলা হয়, এটি বিশ্বের সবচেয়ে ছোট পেঙ্গুইন। আরও তথ্যের জন্য https://en.wikipedia.org/wiki/Little_penguin দেখুন।
> ছোট পেঙ্গুইন, কখনও কখনও পরী পেঙ্গুইন নামে পরিচিত, বিশ্বের সবচেয়ে ছোট পেঙ্গুইন। আরও তথ্যের জন্য https://en.wikipedia.org/wiki/Little_penguin দেখুন।
> **NOTE** আপনি যা পড়তে যাচ্ছেন, মনে রাখবেন আপনি **কখনওই** উপরের মতো লিঙ্ক তৈরি করবেন না।
মনে রাখবেন, স্ক্রিন রিডার ব্রাউজারের থেকে আলাদা একটি ইন্টারফেস এবং এর বৈশিষ্ট্যও আলাদা।
> **NOTE** আপনি যা পড়তে যাচ্ছেন, মনে রাখবেন আপনি **কখনও** এমন লিঙ্ক তৈরি করবেন না যা উপরের মতো দেখায়।
### URL ব্যবহার করার সমস্যা
স্ক্রিন রিডার টেক্সট পড়ে। যদি টেক্সটে একটি URL থাকে, স্ক্রিন রিডার সেটি পড়বে। সাধারণত, URL কোনো অর্থপূর্ণ তথ্য প্রদান করে না এবং বিরক্তিকর শোনাতে পারে। আপনি যদি কখনও আপনার ফোনে একটি টেক্সট মেসেজের URL শব্দ করে পড়তে শুনে থাকেন, তবে আপনি এটি অনুভব করেছেন।
স্ক্রিন রিডার টেক্সট পড়ে। যদি টেক্সটে একটি URL থাকে, স্ক্রিন রিডার URL পড়বে। সাধারণভাবে, URL অর্থপূর্ণ তথ্য প্রকাশ করে না এবং বিরক্তিকর শোনাতে পারে। আপনি যদি কখনও আপনার ফোনে একটি URL সহ একটি টেক্সট মেসেজ শব্দে পড়তে শুনে থাকেন, তাহলে আপনি এটি অনুভব করতে পারেন।
### "এখানে ক্লিক করুন" ব্যবহার করার সমস্যা
স্ক্রিন রিডার শুধুমাত্র পৃষ্ঠার হাইপারলিঙ্ক পড়ার ক্ষমতা রাখে, অনেকটা একজন দৃষ্টিশক্তিসম্পন্ন ব্যক্তি পৃষ্ঠার লিঙ্ক স্ক্যান করার মতো। যদি লিঙ্ক টেক্সট সবসময় "এখানে ক্লিক করুন" হয়, ব্যবহারকারী শুধুমাত্র "এখানে ক্লিক করুন, এখানে ক্লিক করুন, এখানে ক্লিক করুন, ..." শুনবে। সব লিঙ্ক এখন একে অপরের থেকে আলাদা করা অসম্ভব হয়ে যাবে
স্ক্রিন রিডার শুধুমাত্র একটি পেজের হাইপারলিঙ্ক পড়ার ক্ষমতা রাখে, অনেকটা একজন দৃষ্টিশক্তি সম্পন্ন ব্যক্তি একটি পেজে লিঙ্ক স্ক্যান করার মতো। যদি লিঙ্ক টেক্সট সবসময় "এখানে ক্লিক করুন" হয়, ব্যবহারকারী শুধুমাত্র "এখানে ক্লিক করুন, এখানে ক্লিক করুন, এখানে ক্লিক করুন, ..." শুনবে। সব লিঙ্ক এখন একে অপরের থেকে আলাদা করা অসম্ভব।
### ভালো লিঙ্ক টেক্সট
ভালো লিঙ্ক টেক্সট সংক্ষেপে বর্ণনা করে যে লিঙ্কের অপর প্রান্তে কী আছে। উপরের উদাহরণে ছোট পেঙ্গুইন সম্পর্কে কথা বলা হয়েছে, লিঙ্কটি প্রজাতি সম্পর্কে উইকিপিডিয়া পৃষ্ঠায় নিয়ে যায়। *ছোট পেঙ্গুইন* শব্দগুচ্ছটি নিখুঁত লিঙ্ক টেক্সট হবে কারণ এটি স্পষ্ট করে যে কেউ যদি লিঙ্কে ক্লিক করে তবে তারা কী শিখবে - ছোট পেঙ্গুইন।
ভালো লিঙ্ক টেক্সট সংক্ষেপে লিঙ্কের অপর পাশে কী আছে তা বর্ণনা করে। উপরের উদাহরণে ছোট পেঙ্গুইন সম্পর্কে কথা বলা হচ্ছে, লিঙ্কটি প্রজাতি সম্পর্কে Wikipedia পেজে নিয়ে যায়। *ছোট পেঙ্গুইন* শব্দগুচ্ছটি নিখুঁত লিঙ্ক টেক্সট হিসেবে কাজ করবে কারণ এটি স্পষ্ট করে দেয় কেউ যদি লিঙ্কে ক্লিক করে তাহলে তারা কী শিখবে - ছোট পেঙ্গুইন।
> [ছোট পেঙ্গুইন](https://en.wikipedia.org/wiki/Little_penguin), যাকে কখনও কখনও পরী পেঙ্গুইনও বলা হয়, এটি বিশ্বের সবচেয়ে ছোট পেঙ্গুইন।
> [ছোট পেঙ্গুইন](https://en.wikipedia.org/wiki/Little_penguin), কখনও কখনও পরী পেঙ্গুইন নামে পরিচিত, বিশ্বের সবচেয়ে ছোট পেঙ্গুইন।
✅ কয়েক মিনিট ওয়েবে ঘুরে এমন পৃষ্ঠাগুলি খুঁজুন যেখানে অস্পষ্ট লিঙ্কিং কৌশল ব্যবহার করা হয়েছে। সেগুলো তুলনা ভালোভাবে লিঙ্ক করা সাইটগুলোর সাথে করুন। আপনি কী শিখলেন?
✅ কয়েক মিনিটের জন্য ওয়েব ব্রাউজ করুন এবং এমন পেজ খুঁজুন যা অস্পষ্ট লিঙ্কিং কৌশল ব্যবহার করে। সেগুলো তুলনা করুন অন্য, ভালোভাবে লিঙ্ক করা সাইটের সাথে। আপনি কী শিখলেন?
#### সার্চ ইঞ্জিন নোট
আপনার সাইট সবার জন্য অ্যাক্সেসযোগ্য নিশ্চিত করার জন্য, আপনি সার্চ ইঞ্জিনগুলোকেও আপনার সাইট নেভিগেট করতে সাহায্য করবেন। সার্চ ইঞ্জিন লিঙ্ক টেক্সট ব্যবহার করে পৃষ্ঠার বিষয়বস্তু শিখে। সুতরাং ভালো লিঙ্ক টেক্সট ব্যবহার করা সবার জন্য উপকারী!
আপনার সাইট সবার জন্য অ্যাক্সেসযোগ্য করতে নিশ্চিত করার জন্য, আপনি সার্চ ইঞ্জিনগুলোকেও আপনার সাইট নেভিগেট করতে সাহায্য করবেন। সার্চ ইঞ্জিন লিঙ্ক টেক্সট ব্যবহার করে পেজের বিষয়বস্তু শিখে। তাই ভালো লিঙ্ক টেক্সট ব্যবহার করা সবার জন্য সহায়ক!
### ARIA
নিম্নলিখিত পৃষ্ঠাটি কল্পনা করুন:
নিম্নলিখিত পেজটি কল্পনা করুন:
| পণ্য | বিবরণ | অর্ডার |
| ------------ | ----------------- | ------------ |
| উইজেট | [বিবরণ](../../../../1-getting-started-lessons/3-accessibility/') | [অর্ডার](../../../../1-getting-started-lessons/3-accessibility/') |
| সুপার উইজেট | [বিবরণ](../../../../1-getting-started-lessons/3-accessibility/') | [অর্ডার](../../../../1-getting-started-lessons/3-accessibility/') |
| ------------ | ------------------ | ------------ |
| Widget | [বিবরণ](../../../../1-getting-started-lessons/3-accessibility/') | [অর্ডার](../../../../1-getting-started-lessons/3-accessibility/') |
| Super widget | [বিবরণ](../../../../1-getting-started-lessons/3-accessibility/') | [অর্ডার](../../../../1-getting-started-lessons/3-accessibility/') |
এই উদাহরণে, বিবরণ এবং অর্ডার টেক্সট পুনরাবৃত্তি করা ব্রাউজার ব্যবহারকারীদের জন্য অর্থবহ। তবে, স্ক্রিন রিডার ব্যবহারকারী শুধুমাত্র *বিবরণ* এবং *অর্ডার* শব্দগুলি বারবার শুনবে, কোনো প্রসঙ্গ ছাড়াই।
এই উদাহরণে, বিবরণ এবং অর্ডার টেক্সট পুনরাবৃত্তি করা ব্রাউজার ব্যবহারকারীদের জন্য অর্থপূর্ণ। তবে, স্ক্রিন রিডার ব্যবহারকারী শুধুমাত্র *বিবরণ* এবং *অর্ডার* শব্দগুলো পুনরাবৃত্তি শুনবে, কোনো প্রসঙ্গ ছাড়াই।
এই ধরনের পরিস্থিতি সমর্থন করার জন্য, HTML-এ [Accessible Rich Internet Applications (ARIA)](https://developer.mozilla.org/docs/Web/Accessibility/ARIA) নামে একটি অ্যাট্রিবিউট সেট রয়েছে। এই অ্যাট্রিবিউটগুলি স্ক্রিন রিডারগুলিকে অতিরিক্ত তথ্য প্রদান করতে দেয়।
এই ধরনের পরিস্থিতি সমর্থন করার জন্য, HTML একটি সেট অ্যাট্রিবিউট সমর্থন করে যা [Accessible Rich Internet Applications (ARIA)](https://developer.mozilla.org/docs/Web/Accessibility/ARIA) নামে পরিচিত। এই অ্যাট্রিবিউটগুলো স্ক্রিন রিডারকে অতিরিক্ত তথ্য প্রদান করতে দেয়।
> **NOTE**: HTML-এর অনেক দিকের মতো, ব্রাউজার এবং স্ক্রিন রিডার সমর্থন পরিবর্তিত হতে পারে। তবে, বেশিরভাগ প্রধান ক্লায়েন্ট ARIA অ্যাট্রিবিউট সমর্থন করে।
আপনি `aria-label` ব্যবহার করে লিঙ্কটি বর্ণনা করতে পারেন যখন পৃষ্ঠার ফরম্যাট এটি অনুমতি দেয় না। উইজেটের জন্য বিবরণ সেট করা যেতে পারে
আপনি `aria-label` ব্যবহার করে লিঙ্কটি বর্ণনা করতে পারেন যখন পেজের ফরম্যাট এটি অনুমতি দেয় না। Widget-এর জন্য বিবরণ সেট করা যেতে পারে
``` html
<a href="#" aria-label="Widget description">description</a>
```
✅ সাধারণত, উপরে বর্ণিত সেমান্টিক মার্কআপ ব্যবহার করা ARIA ব্যবহারের চেয়ে বেশি গুরুত্বপূর্ণ, তবে কখনও কখনও বিভিন্ন HTML উইজেটের জন্য সেমান্টিক সমতুল্য থাকে না। একটি ভালো উদাহরণ হলো একটি ট্রি। ট্রির জন্য কোনো HTML সমতুল্য নেই, তাই আপনি এই উপাদানের জন্য জেনেরিক `<div>`-কে একটি সঠিক ভূমিকা এবং ARIA মান দিয়ে চিহ্নিত করেন। [MDN-এর ARIA ডকুমেন্টেশন](https://developer.mozilla.org/docs/Web/Accessibility/ARIA) আরও দরকারী তথ্য সরবরাহ করে।
✅ সাধারণভাবে, Semantic মার্কআপ ব্যবহার করা ARIA ব্যবহারের চেয়ে বেশি গুরুত্বপূর্ণ, তবে কখনও কখনও বিভিন্ন HTML উইজেটের জন্য কোনো সেমান্টিক সমতুল্য থাকে না। একটি ভালো উদাহরণ হলো Tree। Tree-এর জন্য HTML সমতুল্য নেই, তাই আপনি এই এলিমেন্টের জন্য সাধারণ `<div>`-কে একটি সঠিক role এবং aria মান দিয়ে চিহ্নিত করেন। [MDN ডকুমেন্টেশন on ARIA](https://developer.mozilla.org/docs/Web/Accessibility/ARIA) আরও দরকারী তথ্য ধারণ করে।
```html
<h2 id="tree-label">File Viewer</h2>
@ -153,17 +151,23 @@ CSS একটি পৃষ্ঠার যেকোনো উপাদানে
</div>
```
## ছবি
## ইমেজ
এটি বলার অপেক্ষা রাখে না যে স্ক্রিন রিডার স্বয়ংক্রিয়ভাবে একটি ছবিতে কী আছে তা পড়তে পারে না। ছবিগুলিকে অ্যাক্সেসযোগ্য করা খুব বেশি কাজের প্রয়োজন হয় না - এটি `alt` অ্যাট্রিবিউটের জন্যই। সমস্ত অর্থবহ ছবিতে তাদের বর্ণনা করার জন্য একটি `alt` থাকা উচিত
যেসব ছবি শুধুমাত্র অলঙ্কারমূলক, তাদের `alt` অ্যাট্রিবিউট একটি খালি স্ট্রিং দিয়ে সেট করা উচিত: `alt=""`। এটি স্ক্রিন রিডারকে অলঙ্কারমূলক ছবিগুলি অপ্রয়োজনীয়ভাবে ঘোষণা করা থেকে বিরত রাখে।
এটি বলার অপেক্ষা রাখে না যে স্ক্রিন রিডার স্বয়ংক্রিয়ভাবে একটি ইমেজে কী আছে তা পড়তে পারে না। ইমেজগুলো অ্যাক্সেসযোগ্য করা খুব বেশি কাজের বিষয় নয় - এটি `alt` অ্যাট্রিবিউটের জন্যই। সব অর্থপূর্ণ ইমেজের একটি `alt` থাকা উচিত যা তারা কী তা বর্ণনা করে।
যেসব ইমেজ শুধুমাত্র অলঙ্করণমূলক, তাদের `alt` অ্যাট্রিবিউট একটি খালি স্ট্রিং দিয়ে সেট করা উচিত: `alt=""`। এটি স্ক্রিন রিডারকে অলঙ্করণমূলক ইমেজ অপ্রয়োজনীয়ভাবে ঘোষণা করা থেকে বিরত রাখে।
✅ আপনি যেমনটি আশা করবেন, সার্চ ইঞ্জিনও ছবিতে কী আছে তা বুঝতে পারে না। তারা `alt` টেক্সট ব্যবহার করে। সুতরাং আবারও, আপনার পৃষ্ঠাকে অ্যাক্সেসযোগ্য করা অতিরিক্ত সুবিধা প্রদান করে!
✅ আপনি যেমন আশা করবেন, সার্চ ইঞ্জিনও একটি ইমেজে কী আছে তা বুঝতে পারে না। তারা `alt` টেক্সট ব্যবহার করে। তাই আবারও, আপনার পেজ অ্যাক্সেসযোগ্য নিশ্চিত করা অতিরিক্ত সুবিধা প্রদান করে!
## কীবোর্ড
কিছু ব্যবহারকারী মাউস বা ট্র্যাকপ্যাড ব্যবহার করতে অক্ষম, পরিবর্তে কীবোর্ড ইন্টারঅ্যাকশনের উপর নির্ভর করেন একটি উপাদান থেকে অন্য উপাদানে যেতে। আপনার ওয়েবসাইটটি এমনভাবে উপস্থাপন করা গুরুত্বপূর্ণ যাতে কীবোর্ড ব্যবহারকারী একটি ডকুমেন্টের নিচে নেভিগেট করার সময় প্রতিটি ইন্টারঅ্যাকটিভ উপাদানে অ্যাক্সেস করতে পারেন। আপনি যদি সেমান্টিক মার্কআপ ব্যবহার করে আপনার ওয়েব পৃষ্ঠাগুলি তৈরি করেন এবং CSS ব্যবহার করে তাদের ভিজ্যুয়াল লেআউট স্টাইল করেন, তবে আপনার সাইটটি কীবোর্ড-নেভিগেটেবল হওয়া উচিত, তবে এটি ম্যানুয়ালি পরীক্ষা করা গুরুত্বপূর্ণ। [কীবোর্ড ন
অনেক সরকার অ্যাক্সেসিবিলিটি সংক্রান্ত আইনের প্রয়োজনীয়তা নিয়ে বিধি-নিষেধ আরোপ করেছে। আপনার দেশের অ্যাক্সেসিবিলিটি আইন সম্পর্কে জানুন। কী অন্তর্ভুক্ত এবং কী অন্তর্ভুক্ত নয়? একটি উদাহরণ হলো [এই সরকারি ওয়েবসাইট](https://accessibility.blog.gov.uk/)।
কিছু ব্যবহারকারী মাউস বা ট্র্যাকপ্যাড ব্যবহার করতে অক্ষম, পরিবর্তে কীবোর্ড ইন্টারঅ্যাকশন ব্যবহার করে একটি এলিমেন্ট থেকে পরবর্তী এলিমেন্টে ট্যাব করে। আপনার ওয়েবসাইটের বিষয়বস্তু একটি যৌক্তিক ক্রমে উপস্থাপন করা গুরুত্বপূর্ণ যাতে কীবোর্ড ব্যবহারকারী একটি ডকুমেন্টে প্রতিটি ইন্টারঅ্যাকটিভ এলিমেন্ট অ্যাক্সেস করতে পারে। যদি আপনি সেমান্টিক মার্কআপ ব্যবহার করে আপনার ওয়েব পেজ তৈরি করেন এবং CSS ব্যবহার করে তাদের ভিজ্যুয়াল লেআউট স্টাইল করেন, তাহলে আপনার সাইট কীবোর্ড-নেভিগেটযোগ্য হওয়া উচিত, তবে এটি ম্যানুয়ালি পরীক্ষা করা গুরুত্বপূর্ণ। [কীবোর্ড নেভিগেশন কৌশল](https://webaim.org/techniques/keyboard/) সম্পর্কে আরও জানুন।
✅ যেকোনো ওয়েবসাইটে যান এবং শুধুমাত্র আপনার কীবোর্ড ব্যবহার করে এটি নেভিগেট করার চেষ্টা করুন। কী কাজ করে, কী কাজ করে না? কেন?
## সারাংশ
কিছু মানুষের জন্য অ্যাক্সেসযোগ্য ওয়েব একটি সত্যিকারের 'ওয়ার্ল্ড-ওয়াইড ওয়েব' নয়। আপনি যে সাইটগুলো তৈরি করেন তা অ্যাক্সেসযোগ্য নিশ্চিত করার সেরা উপায় হলো শুরু
অনেক সরকার অ্যাক্সেসিবিলিটি প্রয়োজনীয়তার বিষয়ে আইন প্রণয়ন করেছে। আপনার দেশের অ্যাক্সেসিবিলিটি আইন সম্পর্কে জানুন। কী অন্তর্ভুক্ত করা হয়েছে এবং কী অন্তর্ভুক্ত করা হয়নি? একটি উদাহরণ হলো [এই সরকারি ওয়েবসাইট](https://accessibility.blog.gov.uk/)।
## অ্যাসাইনমেন্ট
@ -171,5 +175,7 @@ CSS একটি পৃষ্ঠার যেকোনো উপাদানে
ক্রেডিট: [Turtle Ipsum](https://github.com/Instrument/semantic-html-sample) by Instrument
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। এর মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়ী থাকব না।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতা নিশ্চিত করার চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়ী থাকব না।

@ -1,62 +1,62 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "fc6aef8ecfdd5b0ad2afa6e6ba52bfde",
"translation_date": "2025-08-25T21:53:25+00:00",
"original_hash": "b95fdd8310ef467305015ece1b0f9411",
"translation_date": "2025-08-28T23:01:51+00:00",
"source_file": "2-js-basics/1-data-types/README.md",
"language_code": "bn"
}
-->
# জাভাস্ক্রিপ্ট বেসিক: ডেটা টাইপস
# জাভাস্ক্রিপ্টের বেসিক: ডেটা টাইপস
![জাভাস্ক্রিপ্ট বেসিক - ডেটা টাইপস](../../../../translated_images/webdev101-js-datatypes.4cc470179730702c756480d3ffa46507f746e5975ebf80f99fdaaf1cff09a7f4.bn.png)
![জাভাস্ক্রিপ্টের বেসিক - ডেটা টাইপস](../../../../translated_images/webdev101-js-datatypes.4cc470179730702c756480d3ffa46507f746e5975ebf80f99fdaaf1cff09a7f4.bn.png)
> স্কেচনোট করেছেন [Tomomi Imura](https://twitter.com/girlie_mac)
## প্রাক-লেকচার কুইজ
[প্রাক-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/7)
[প্রাক-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/)
এই পাঠে জাভাস্ক্রিপ্টের বেসিক বিষয়গুলো আলোচনা করা হয়েছে, যা ওয়েবের ইন্টারঅ্যাকটিভিটি প্রদান করে।
> আপনি এই পাঠটি [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-variables/?WT.mc_id=academic-77807-sagibbon) এ নিতে পারেন!
[![ভরিয়েবলস](https://img.youtube.com/vi/JNIXfGiDWM8/0.jpg)](https://youtube.com/watch?v=JNIXfGiDWM8 "জাভাস্ক্রিপ্টে ভরিয়েবলস")
[![ভ্যারিয়েবলস](https://img.youtube.com/vi/JNIXfGiDWM8/0.jpg)](https://youtube.com/watch?v=JNIXfGiDWM8 "জাভাস্ক্রিপ্টে ভ্যারিয়েবলস")
[![জাভাস্ক্রিপ্টে ডেটা টাইপস](https://img.youtube.com/vi/AWfA95eLdq8/0.jpg)](https://youtube.com/watch?v=AWfA95eLdq8 "জাভাস্ক্রিপ্টে ডেটা টাইপস")
> 🎥 উপরের ছবিগুলিতে ক্লিক করুন ভেরিয়েবলস এবং ডেটা টাইপস সম্পর্কিত ভিডিও দেখার জন্য
> 🎥 উপরের ছবিগুলিতে ক্লিক করুন ভ্যারিয়েবলস এবং ডেটা টাইপস নিয়ে ভিডিও দেখার জন্য
চলুন ভরিয়েবলস এবং তাদের মধ্যে থাকা ডেটা টাইপস দিয়ে শুরু করি!
চলুন ভ্যারিয়েবলস এবং তাদের মধ্যে থাকা ডেটা টাইপস দিয়ে শুরু করি!
## ভরিয়েবলস
## ভ্যারিয়েবলস
রিয়েবলস এমন মান সংরক্ষণ করে যা আপনার কোডে ব্যবহার এবং পরিবর্তন করা যায়।
্যারিয়েবলস এমন মান সংরক্ষণ করে যা আপনার কোডে ব্যবহার এবং পরিবর্তন করা যায়।
একটি ভরিয়েবল তৈরি এবং **ডিক্লেয়ার** করার সিনট্যাক্স হলো **[keyword] [name]**। এটি দুটি অংশ নিয়ে গঠিত:
একটি ভ্যারিয়েবল তৈরি এবং **ডিক্লেয়ার** করার সিনট্যাক্স হলো **[keyword] [name]**। এটি দুটি অংশ নিয়ে গঠিত:
- **কীওয়ার্ড**। কীওয়ার্ড হতে পারে `let` বা `var`
`let` কীওয়ার্ডটি ES6-এ পরিচিত হয় এবং এটি ভেরিয়েবলকে একটি _ব্লক স্কোপ_ প্রদান করে। `var` এর পরিবর্তে `let` ব্যবহার করার পরামর্শ দেওয়া হয়। আমরা ভবিষ্যতে ব্লক স্কোপ নিয়ে আরও বিস্তারিত আলোচনা করব।
- **েরিয়েবলের নাম**, এটি আপনি নিজের পছন্দমতো নির্ধারণ করবেন।
`let` কীওয়ার্ডটি ES6 এ প্রবর্তিত হয়েছে এবং এটি ভ্যারিয়েবলকে একটি _ব্লক স্কোপ_ প্রদান করে। `var` এর পরিবর্তে `let` ব্যবহার করার পরামর্শ দেওয়া হয়। আমরা ভবিষ্যতে ব্লক স্কোপ নিয়ে আরও বিস্তারিত আলোচনা করব।
- **্যারিয়েবলের নাম**, এটি আপনি নিজে পছন্দ করে নির্ধারণ করবেন।
### কাজ - ভেরিয়েবলের সাথে কাজ করা
### কাজ - ভ্যারিয়েবল নিয়ে কাজ করা
1. **একটি ভরিয়েবল ডিক্লেয়ার করুন**। `let` কীওয়ার্ড ব্যবহার করে একটি ভরিয়েবল ডিক্লেয়ার করুন:
1. **একটি ভ্যারিয়েবল ডিক্লেয়ার করুন**। `let` কীওয়ার্ড ব্যবহার করে একটি ভ্যারিয়েবল ডিক্লেয়ার করুন:
```javascript
let myVariable;
```
`myVariable` এখন `let` কীওয়ার্ড ব্যবহার করে ডিক্লেয়ার করা হয়েছে। এটি বর্তমানে কোনো মান ধারণ করছে না।
এখন `myVariable` ভ্যারিয়েবলটি `let` কীওয়ার্ড ব্যবহার করে ডিক্লেয়ার করা হয়েছে। এটি বর্তমানে কোনো মান ধারণ করছে না।
1. **একটি মান অ্যাসাইন করুন**। `=` অপারেটর ব্যবহার করে একটি ভরিয়েবলে মান সংরক্ষণ করুন, এর পরে প্রত্যাশিত মান দিন।
1. **একটি মান অ্যাসাইন করুন**। `=` অপারেটর ব্যবহার করে একটি ভ্যারিয়েবলে মান সংরক্ষণ করুন, এর পরে প্রত্যাশিত মান দিন।
```javascript
myVariable = 123;
```
> নোট: এই পাঠে `=` এর ব্যবহার "অ্যাসাইনমেন্ট অপারেটর" বোঝায়, যা একটি ভরিয়েবলে মান সেট করতে ব্যবহৃত হয়। এটি সমতা নির্দেশ করে না।
> নোট: এই পাঠে `=` এর ব্যবহার "অ্যাসাইনমেন্ট অপারেটর" বোঝায়, যা একটি ভ্যারিয়েবলে মান সেট করতে ব্যবহৃত হয়। এটি সমতা নির্দেশ করে না।
`myVariable` এখন 123 মান দিয়ে *ইনিশিয়ালাইজড* হয়েছে।
এখন `myVariable` ভ্যারিয়েবলটি 123 মান দিয়ে *ইনিশিয়ালাইজড* হয়েছে।
1. **রিফ্যাক্টর করুন**। আপনার কোডটি নিম্নলিখিত স্টেটমেন্ট দিয়ে প্রতিস্থাপন করুন।
@ -64,30 +64,30 @@ CO_OP_TRANSLATOR_METADATA:
let myVariable = 123;
```
উপরেরটি একটি _স্পষ্ট ইনিশিয়ালাইজেশন_, যেখানে একটি ভরিয়েবল ডিক্লেয়ার করা হয় এবং একই সাথে একটি মান অ্যাসাইন করা হয়।
উপরেরটি একটি _স্পষ্ট ইনিশিয়ালাইজেশন_, যেখানে একটি ভ্যারিয়েবল ডিক্লেয়ার করা হয় এবং একই সাথে একটি মান অ্যাসাইন করা হয়।
1. **েরিয়েবলের মান পরিবর্তন করুন**। ভেরিয়েবলের মান নিম্নলিখিতভাবে পরিবর্তন করুন:
1. **্যারিয়েবলের মান পরিবর্তন করুন**। ভ্যারিয়েবলের মান নিম্নলিখিতভাবে পরিবর্তন করুন:
```javascript
myVariable = 321;
```
একবার একটি ভরিয়েবল ডিক্লেয়ার করা হলে, আপনি কোডের যেকোনো স্থানে `=` অপারেটর এবং নতুন মান ব্যবহার করে এর মান পরিবর্তন করতে পারেন।
একবার একটি ভ্যারিয়েবল ডিক্লেয়ার করা হলে, আপনি কোডের যেকোনো স্থানে `=` অপারেটর এবং নতুন মান ব্যবহার করে এর মান পরিবর্তন করতে পারেন।
✅ চেষ্টা করুন! আপনি আপনার ব্রাউজারেই জাভাস্ক্রিপ্ট লিখতে পারেন। একটি ব্রাউজার উইন্ডো খুলুন এবং ডেভেলপার টুলস-এ যান। কনসোলে টাইপ করুন `let myVariable = 123`, এন্টার চাপুন, তারপর টাইপ করুন `myVariable`। কী ঘটে? নোট করুন, আপনি এই ধারণাগুলি পরবর্তী পাঠে আরও শিখবেন।
## কনস্ট্যান্টস
একটি কনস্ট্যান্ট ডিক্লেয়ার এবং ইনিশিয়ালাইজ করার প্রক্রিয়া ভরিয়েবলের মতোই, তবে এখানে `const` কীওয়ার্ড ব্যবহৃত হয়। সাধারণত কনস্ট্যান্টস সব বড় হাতের অক্ষরে ডিক্লেয়ার করা হয়।
একটি কনস্ট্যান্ট ডিক্লেয়ার এবং ইনিশিয়ালাইজ করার প্রক্রিয়া ভ্যারিয়েবলের মতোই, তবে এখানে `const` কীওয়ার্ড ব্যবহার করা হয়। সাধারণত কনস্ট্যান্টস সব বড় হাতের অক্ষরে ডিক্লেয়ার করা হয়।
```javascript
const MY_VARIABLE = 123;
```
কনস্ট্যান্টস ভরিয়েবলের মতোই, তবে দুটি ব্যতিক্রম রয়েছে:
কনস্ট্যান্টস ভ্যারিয়েবলের মতোই, তবে দুটি ব্যতিক্রম রয়েছে:
- **অবশ্যই একটি মান থাকতে হবে**। কনস্ট্যান্টস ইনিশিয়ালাইজড হতে হবে, নতুবা কোড চালানোর সময় একটি ত্রুটি ঘটবে।
- **রেফারেন্স পরিবর্তন করা যাবে না**। একবার ইনিশিয়ালাইজড হলে কনস্ট্যান্টের রেফারেন্স পরিবর্তন করা যাবে না, নতুবা একটি ত্রুটি ঘটবে। চলুন দুটি উদাহরণ দেখি:
- **অবশ্যই একটি মান থাকতে হবে**। কনস্ট্যান্টস ইনিশিয়ালাইজড না হলে কোড চালানোর সময় একটি ত্রুটি ঘটবে।
- **রেফারেন্স পরিবর্তন করা যাবে না**। একবার ইনিশিয়ালাইজড হলে কনস্ট্যান্টের রেফারেন্স পরিবর্তন করা যাবে না, অন্যথায় কোড চালানোর সময় ত্রুটি ঘটবে। দুটি উদাহরণ দেখা যাক:
- **সাধারণ মান**। নিম্নলিখিতটি অনুমোদিত নয়:
```javascript
@ -111,11 +111,11 @@ const MY_VARIABLE = 123;
উপরের ক্ষেত্রে আপনি অবজেক্টের মান পরিবর্তন করছেন, কিন্তু রেফারেন্সটি নয়, যা অনুমোদিত।
> নোট, একটি `const` মানে রেফারেন্স পুনরায় অ্যাসাইনমেন্ট থেকে সুরক্ষিত। তবে মানটি _অপরিবর্তনীয়_ নয় এবং এটি পরিবর্তন হতে পারে, বিশেষত যদি এটি একটি জটিল কনস্ট্রাক্ট হয় যেমন একটি অবজেক্ট।
> নোট, একটি `const` মানে রেফারেন্সটি পুনরায় অ্যাসাইনমেন্ট থেকে সুরক্ষিত। তবে মানটি _অপরিবর্তনীয়_ নয় এবং এটি পরিবর্তন হতে পারে, বিশেষত যদি এটি একটি জটিল কনস্ট্রাক্ট যেমন অবজেক্ট হয়
## ডেটা টাইপস
রিয়েবলস বিভিন্ন ধরনের মান সংরক্ষণ করতে পারে, যেমন সংখ্যা এবং টেক্সট। এই বিভিন্ন ধরনের মানকে **ডেটা টাইপ** বলা হয়। ডেটা টাইপস সফটওয়্যার ডেভেলপমেন্টের একটি গুরুত্বপূর্ণ অংশ কারণ এটি ডেভেলপারদের সিদ্ধান্ত নিতে সাহায্য করে যে কোডটি কীভাবে লেখা উচিত এবং সফটওয়্যারটি কীভাবে চলবে। তদ্ব্যতীত, কিছু ডেটা টাইপের অনন্য বৈশিষ্ট্য রয়েছে যা একটি মানে অতিরিক্ত তথ্য রূপান্তর বা বের করতে সাহায্য করে।
্যারিয়েবলস বিভিন্ন ধরনের মান সংরক্ষণ করতে পারে, যেমন সংখ্যা এবং টেক্সট। এই বিভিন্ন ধরনের মানকে **ডেটা টাইপ** বলা হয়। ডেটা টাইপস সফটওয়্যার ডেভেলপমেন্টের একটি গুরুত্বপূর্ণ অংশ, কারণ এটি ডেভেলপারদের সিদ্ধান্ত নিতে সাহায্য করে যে কোডটি কীভাবে লেখা উচিত এবং সফটওয়্যারটি কীভাবে চলবে। তদ্ব্যতীত, কিছু ডেটা টাইপের অনন্য বৈশিষ্ট্য রয়েছে যা একটি মানে অতিরিক্ত তথ্য রূপান্তর বা বের করতে সাহায্য করে।
✅ ডেটা টাইপসকে জাভাস্ক্রিপ্ট ডেটা প্রিমিটিভসও বলা হয়, কারণ এগুলি ভাষার দ্বারা প্রদত্ত সর্বনিম্ন স্তরের ডেটা টাইপ। এখানে ৭টি প্রিমিটিভ ডেটা টাইপ রয়েছে: string, number, bigint, boolean, undefined, null এবং symbol। এক মিনিট সময় নিয়ে কল্পনা করুন প্রতিটি প্রিমিটিভ কী প্রতিনিধিত্ব করে। একটি `zebra` কী? `0` কী? `true` কী?
@ -125,19 +125,19 @@ const MY_VARIABLE = 123;
`let myVariable = 123;`
রিয়েবলস সব ধরনের সংখ্যা সংরক্ষণ করতে পারে, যেমন দশমিক বা ঋণাত্মক সংখ্যা। সংখ্যাগুলি গাণিতিক অপারেটরের সাথে ব্যবহার করা যায়, যা [পরবর্তী অংশে](../../../../2-js-basics/1-data-types) আলোচনা করা হয়েছে।
্যারিয়েবলস সব ধরনের সংখ্যা সংরক্ষণ করতে পারে, যেমন দশমিক বা ঋণাত্মক সংখ্যা। সংখ্যাগুলি গাণিতিক অপারেটরের সাথে ব্যবহার করা যায়, যা [পরবর্তী অংশে](../../../../2-js-basics/1-data-types) আলোচনা করা হয়েছে।
### গাণিতিক অপারেটরস
গাণিতিক ফাংশন সম্পাদনের জন্য বিভিন্ন ধরনের অপারেটর রয়েছে, এবং এর মধ্যে কিছু এখানে তালিকাভুক্ত করা হলো:
| প্রতীক | বরনা | উদাহরণ |
| ------ | ---------------------------------------------------------------------- | -------------------------------- |
| `+` | **যোগ**: দুটি সংখ্যার যোগফল নির্ণয় করে | `1 + 2 //প্রত্যাশিত উত্তর 3` |
| `-` | **বিয়োগ**: দুটি সংখ্যার পার্থক্য নির্ণয় করে | `1 - 2 //প্রত্যাশিত উত্তর -1` |
| `*` | **গুণ**: দুটি সংখ্যার গুণফল নির্ণয় করে | `1 * 2 //প্রত্যাশিত উত্তর 2` |
| `/` | **ভাগ**: দুটি সংখ্যার ভাগফল নির্ণয় করে | `1 / 2 //প্রত্যাশিত উত্তর 0.5` |
| `%` | **অবশিষ্টাংশ**: দুটি সংখ্যার ভাগফল থেকে অবশিষ্টাংশ নির্ণয় করে | `1 % 2 //প্রত্যাশিত উত্তর 1` |
| প্রতীক | বিবরণ | উদাহরণ |
| ------ | --------------------------------------------------------------------- | -------------------------------- |
| `+` | **যোগ**: দুটি সংখ্যার যোগফল নির্ণয় করে | `1 + 2 //প্রত্যাশিত উত্তর 3` |
| `-` | **বিয়োগ**: দুটি সংখ্যার পার্থক্য নির্ণয় করে | `1 - 2 //প্রত্যাশিত উত্তর -1` |
| `*` | **গুণ**: দুটি সংখ্যার গুণফল নির্ণয় করে | `1 * 2 //প্রত্যাশিত উত্তর 2` |
| `/` | **ভাগ**: দুটি সংখ্যার ভাগফল নির্ণয় করে | `1 / 2 //প্রত্যাশিত উত্তর 0.5` |
| `%` | **অবশিষ্টাংশ**: দুটি সংখ্যার ভাগফল থেকে অবশিষ্টাংশ নির্ণয় করে | `1 % 2 //প্রত্যাশিত উত্তর 1` |
✅ চেষ্টা করুন! আপনার ব্রাউজারের কনসোলে একটি গাণিতিক অপারেশন চেষ্টা করুন। ফলাফল কি আপনাকে অবাক করে?
@ -147,9 +147,9 @@ const MY_VARIABLE = 123;
- `'এটি একটি স্ট্রিং'`
- `"এটিও একটি স্ট্রিং"`
- `let myString = 'এটি একটি স্ট্রিং মান যা একটি ভরিয়েবলে সংরক্ষিত';`
- `let myString = 'এটি একটি স্ট্রিং মান যা একটি ভ্যারিয়েবলে সংরক্ষিত';`
স্ট্রিং লেখার সময় উদ্ধৃতি ব্যবহার করতে মনে রাখুন, নতুবা জাভাস্ক্রিপ্ট এটি একটি ভেরিয়েবলের নাম বলে ধরে নেবে।
স্ট্রিং লেখার সময় উদ্ধৃতি ব্যবহার করতে ভুলবেন না, অন্যথায় জাভাস্ক্রিপ্ট এটি একটি ভ্যারিয়েবলের নাম বলে ধরে নেবে।
### স্ট্রিং ফরম্যাটিং
@ -167,9 +167,9 @@ myString1 + ", " + myString2 + "!"; //Hello, World!
```
✅ কেন `1 + 1 = 2` জাভাস্ক্রিপ্টে, কিন্তু `'1' + '1' = 11`? চিন্তা করুন। `'1' + 1` এর ক্ষেত্রে কী হয়?
✅ কেন জাভাস্ক্রিপ্টে `1 + 1 = 2`, কিন্তু `'1' + '1' = 11`? চিন্তা করুন। `'1' + 1` এর ক্ষেত্রে কী হয়?
**টেমপ্লেট লিটারালস** স্ট্রিং ফরম্যাট করার আরেকটি উপায়, যেখানে উদ্ধৃতির পরিবর্তে ব্যাকটিক ব্যবহার করা হয়। যা কিছু সাধারণ টেক্সট নয়, তা `${ }` প্লেসহোল্ডারের মধ্যে রাখতে হবে। এর মধ্যে স্ট্রিং হতে পারে এমন যেকোনো ভরিয়েবল অন্তর্ভুক্ত।
**টেমপ্লেট লিটারালস** স্ট্রিং ফরম্যাট করার আরেকটি উপায়, যেখানে উদ্ধৃতির পরিবর্তে ব্যাকটিক ব্যবহার করা হয়। যা কিছু সাধারণ টেক্সট নয়, তা `${ }` প্লেসহোল্ডারের মধ্যে রাখতে হবে। এর মধ্যে স্ট্রিং হতে পারে এমন যেকোনো ভ্যারিয়েবল অন্তর্ভুক্ত।
```javascript
let myString1 = "Hello";
@ -179,29 +179,29 @@ let myString2 = "World";
`${myString1}, ${myString2}!` //Hello, World!
```
আপনার ফরম্যাটিং লক্ষ্য অর্জনে যেকোনো পদ্ধতি ব্যবহার করতে পারেন, তবে টেমপ্লেট লিটারালস স্পেস এবং লাইন ব্রেককে সম্মান করবে।
আপনি যেকোনো পদ্ধতি ব্যবহার করে আপনার ফরম্যাটিং লক্ষ্য অর্জন করতে পারেন, তবে টেমপ্লেট লিটারালস স্পেস এবং লাইন ব্রেককে সম্মান করবে।
কখন আপনি একটি টেমপ্লেট লিটারাল ব্যবহার করবেন এবং কখন একটি সাধারণ স্ট্রিং ব্যবহার করবেন?
✅ আপনি কখন একটি টেমপ্লেট লিটারাল এবং কখন একটি সাধারণ স্ট্রিং ব্যবহার করবেন?
### বুলিয়ানস
বুলিয়ানসের মান কেবল দুটি হতে পারে: `true` বা `false`। বুলিয়ানস নির্ধারণ করতে সাহায্য করে কোন কোডের লাইনগুলো নির্দিষ্ট শর্ত পূরণ হলে চলবে। অনেক ক্ষেত্রে, [অপারেটরস](../../../../2-js-basics/1-data-types) বুলিয়ানের মান সেট করতে সাহায্য করে এবং আপনি প্রায়ই ভরিয়েবলসকে ইনিশিয়ালাইজড বা তাদের মান অপারেটরের মাধ্যমে আপডেট তে দেখবেন।
বুলিয়ানসের মান কেবল দুটি হতে পারে: `true` বা `false`। বুলিয়ানস নির্ধারণ করতে সাহায্য করে কোন কোডের লাইনগুলো নির্দিষ্ট শর্ত পূরণ হলে চলবে। অনেক ক্ষেত্রে, [অপারেটরস](../../../../2-js-basics/1-data-types) বুলিয়ানের মান সেট করতে সাহায্য করে এবং আপনি প্রায়ই ভ্যারিয়েবলসকে ইনিশিয়ালাইজড বা তাদের মান অপারেটরের মাধ্যমে আপডেট করতে দেখবেন।
- `let myTrueBool = true`
- `let myFalseBool = false`
✅ একটি ভেরিয়েবলকে 'truthy' বলে বিবেচনা করা যেতে পারে যদি এটি একটি বুলিয়ান `true` এ মূল্যায়িত হয়। মজার বিষয় হলো, জাভাস্ক্রিপ্টে [সব মান truthy, যদি না সেগুলো falsy হিসেবে সংজ্ঞায়িত হয়](https://developer.mozilla.org/docs/Glossary/Truthy)।
✅ একটি ভ্যারিয়েবলকে 'truthy' বিবেচনা করা যেতে পারে যদি এটি একটি বুলিয়ান `true` এ মূল্যায়িত হয়। মজার বিষয় হলো, জাভাস্ক্রিপ্টে [সব মান truthy, যদি না সেগুলো falsy হিসেবে সংজ্ঞায়িত হয়](https://developer.mozilla.org/docs/Glossary/Truthy)।
---
## 🚀 চ্যালেঞ্জ
জাভাস্ক্রিপ্ট মাঝে মাঝে ডেটা টাইপস পরিচালনার অপ্রত্যাশিত উপায়গুলোর জন্য কুখ্যাত। এই 'gotchas' সম্পর্কে একটু গবেষণা করুন। উদাহরণস্বরূপ: কেস সেনসিটিভিটি সমস্যার কারণ হতে পারে! এটি আপনার কনসোলে চেষ্টা করুন: `let age = 1; let Age = 2; age == Age` (ফলাফল `false` -- কেন?)। আপনি আর কী কী gotchas খুঁজে পেতে পারেন?
জাভাস্ক্রিপ্ট মাঝে মাঝে ডেটা টাইপস পরিচালনার অপ্রত্যাশিত উপায়গুলোর জন্য কুখ্যাত। এই 'gotchas' নিয়ে একটু গবেষণা করুন। উদাহরণস্বরূপ: কেস সেনসিটিভিটি সমস্যার কারণ হতে পারে! এটি আপনার কনসোলে চেষ্টা করুন: `let age = 1; let Age = 2; age == Age` (ফলাফল `false` -- কেন?)। আপনি আর কী কী gotchas খুঁজে পেতে পারেন?
## পোস্ট-লেকচার কুইজ
[পোস্ট-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/8)
[পোস্ট-লেকচার কুইজ](https://ff-quizzes.netlify.app)
## পর্যালোচনা ও স্ব-অধ্যয়ন
## রিভিউ এবং স্ব-অধ্যয়ন
[জাভাস্ক্রিপ্ট এক্সারসাইজের এই তালিকা](https://css-tricks.com/snippets/javascript/) দেখুন এবং একটি চেষ্টা করুন। আপনি কী শিখলেন?
@ -209,5 +209,7 @@ let myString2 = "World";
[ডেটা টাইপস প্র্যাকটিস](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতা নিশ্চিত করার চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়বদ্ধ থাকব না।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতা নিশ্চিত করার চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "b4612bbb9ace984f374fcc80e3e035ad",
"translation_date": "2025-08-25T21:40:52+00:00",
"original_hash": "92e136090efc4341b1d51c37924c1802",
"translation_date": "2025-08-28T23:00:40+00:00",
"source_file": "2-js-basics/2-functions-methods/README.md",
"language_code": "bn"
}
@ -10,28 +10,28 @@ CO_OP_TRANSLATOR_METADATA:
# জাভাস্ক্রিপ্ট বেসিকস: মেথড এবং ফাংশন
![জাভাস্ক্রিপ্ট বেসিকস - ফাংশন](../../../../translated_images/webdev101-js-functions.be049c4726e94f8b7605c36330ac42eeb5cd8ed02bcdd60fdac778174d6cb865.bn.png)
> স্কেচনোট করেছেন [Tomomi Imura](https://twitter.com/girlie_mac)
> স্কেচনোট: [Tomomi Imura](https://twitter.com/girlie_mac)
## প্রাক-লেকচার কুইজ
[প্রাক-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/9)
## প্রি-লেকচার কুইজ
[প্রি-লেকচার কুইজ](https://ff-quizzes.netlify.app)
কোড লেখার সময় আমরা সবসময় চাই আমাদের কোডটি পড়তে সহজ এবং বোধগম্য হোক। যদিও এটি প্রথমে অদ্ভুত শোনাতে পারে, কোড সাধারণত লেখার চেয়ে অনেক বেশি বার পড়া হয়। ডেভেলপারদের টুলবক্সে একটি গুরুত্বপূর্ণ উপকরণ যা কোড রক্ষণাবেক্ষণযোগ্য করে তোলে তা হলো **ফাংশন**
কোড লেখার সময় আমরা সবসময় চাই আমাদের কোডটি সহজে পড়া যায়। যদিও এটি প্রথমে অদ্ভুত শোনায়, কোড লেখার চেয়ে অনেক বেশি বার পড়া হয়। ডেভেলপারদের টুলবক্সে একটি গুরুত্বপূর্ণ টুল হলো **ফাংশন**, যা কোডকে রক্ষণাবেক্ষণযোগ্য রাখতে সাহায্য করে
[![মেথড এবং ফাংশন](https://img.youtube.com/vi/XgKsD6Zwvlc/0.jpg)](https://youtube.com/watch?v=XgKsD6Zwvlc "মেথড এবং ফাংশন")
> 🎥 উপরের ছবিতে ক্লিক করুন মেথড এবং ফাংশন সম্পর্কে একটি ভিডিও দেখার জন্য।
> আপনি এই পাঠটি [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-functions/?WT.mc_id=academic-77807-sagibbon) এ নিতে পারেন!
> আপনি এই লেসনটি [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-functions/?WT.mc_id=academic-77807-sagibbon) এ নিতে পারেন!
## ফাংশন
মূলত, একটি ফাংশন হলো কোডের একটি ব্লক যা আমরা প্রয়োজন অনুযায়ী চালাতে পারি। এটি এমন পরিস্থিতির জন্য আদর্শ যেখানে একই কাজ বারবার করতে হয়; একাধিক স্থানে একই লজিক ডুপ্লিকেট করার পরিবর্তে (যা আপডেট করা কঠিন হয়ে পড়ে), আমরা এটি একটি কেন্দ্রীয় স্থানে রাখতে পারি এবং যখনই প্রয়োজন তখন এটি কল করতে পারি - এমনকি এক ফাংশন থেকে অন্য ফাংশনও কল করা যায়!
ফাংশন মূলত কোডের একটি ব্লক যা আমরা প্রয়োজন অনুযায়ী চালাতে পারি। এটি এমন পরিস্থিতির জন্য আদর্শ যেখানে একই কাজ বারবার করতে হ; একাধিক স্থানে একই লজিক ডুপ্লিকেট করার পরিবর্তে (যা আপডেট করা কঠিন করে তুলবে), আমরা এটি একটি কেন্দ্রীভূত স্থানে রাখতে পারি এবং যখনই প্রয়োজন তখন এটি কল করতে পারি - এমনকি অন্য ফাংশন থেকেও ফাংশন কল করা যায়!
একটি ফাংশনের নাম দেওয়ার ক্ষমতাও সমান গুরুত্বপূর্ণ। যদিও এটি তুচ্ছ মনে হতে পারে, নামটি কোডের একটি অংশকে দ্রুত ডকুমেন্ট করার একটি উপায় প্রদান করে। আপনি এটি একটি বোতামের লেবেলের মতো ভাবতে পারেন। যদি আমি একটি বোতামে ক্লিক করি যেখানে লেখা আছে "Cancel timer", আমি জানি এটি ঘড়ি বন্ধ করবে।
ফাংশনের নামকরণ করার ক্ষমতাও গুরুত্বপূর্ণ। যদিও এটি তুচ্ছ মনে হতে পারে, নামটি কোডের একটি অংশকে দ্রুত ডকুমেন্ট করার একটি উপা প্রদান করে। আপনি এটি একটি বোতামের লেবেলের মতো ভাবতে পারেন। যদি আমি একটি বোতামে ক্লিক করি যেখানে লেখা আছে "Cancel timer", আমি জানি এটি ঘি বন্ধ করবে।
## ফাংশন তৈরি এবং কল করা
ফাংশনের সিনট্যাক্স নিম্নরূপ দেখায়:
ফাংশনের সিনট্যাক্স নিচের মতো দেখায়:
```javascript
function nameOfFunction() { // function definition
@ -39,7 +39,7 @@ function nameOfFunction() { // function definition
}
```
যদি আমি একটি ফাংশন তৈরি করতে চাই যা একটি শুভেচ্ছা বার্তা প্রদর্শন করবে, এটি এমন দেখাতে পারে:
যদি আমি একটি ফাংশন তৈরি করতে চাই যা একটি অভিবাদন দেখাবে, এটি এমন দেখতে পারে:
```javascript
function displayGreeting() {
@ -47,28 +47,28 @@ function displayGreeting() {
}
```
যখনই আমরা আমাদের ফাংশন কল (অথবা ইনভোক) করতে চাই, আমরা ফাংশনের নামের পরে `()` ব্যবহার করি। এটি লক্ষণীয় যে আমাদের ফাংশনটি আমরা কল করার আগে বা পরে সংজ্ঞায়িত করা যেতে পারে; জাভাস্ক্রিপ্ট কম্পাইলার এটি খুঁজে নেবে।
যখনই আমরা আমাদের ফাংশন কল (বা ইনভোক) করতে চাই, আমরা ফাংশনের নামের পরে `()` ব্যবহার করি। এটি উল্লেখযোগ্য যে আমাদের ফাংশনটি আমরা কল করার আগে বা পরে সংজ্ঞায়িত করতে পারি; জাভাস্ক্রিপ্ট কম্পাইলার এটি খুঁজে নেবে।
```javascript
// calling our function
displayGreeting();
```
> **NOTE:** একটি বিশেষ ধরনের ফাংশন রয়েছে যা **মেথড** নামে পরিচিত, যা আপনি ইতিমধ্যেই ব্যবহার করছেন! আসলে, আমরা এটি আমাদের উপরের ডেমোতে দেখেছি যখন আমরা `console.log` ব্যবহার করেছি। মেথড এবং ফাংশনের মধ্যে পার্থক্য হলো মেথড একটি অবজেক্টের সাথে সংযুক্ত থাকে (`console` আমাদের উদাহরণে), যেখানে ফাংশন ফ্রি ফ্লোটিং হয়। অনেক ডেভেলপার এই শব্দগুলোকে একে অপরের পরিবর্তে ব্যবহার করেন।
> **NOTE:** একটি বিশেষ ধরনের ফাংশন ছে যা **মেথড** নামে পরিচিত, যা আপনি ইতিমধ্যেই ব্যবহার করছেন! আসলে, আমরা এটি আমাদের উপরের ডেমোতে দেখেছি যখন আমরা `console.log` ব্যবহার করেছি। মেথড এবং ফাংশনের মধ্যে পার্থক্য হলো মেথড একটি অবজেক্টের সাথে সংযুক্ত থাকে (`console` আমাদের উদাহরণে), যেখানে ফাংশন স্বাধীনভাবে থাকে। অনেক ডেভেলপার এই শব্দগুলো বিনিময়যোগ্যভাবে ব্যবহার করেন।
### ফাংশনের সেরা অনুশীলন
### ফাংশন তৈরির সেরা অভ্যাস
ফাংশন তৈরি করার সময় কিছু সেরা অনুশীলন মনে রাখা গুরুত্বপূর্ণ:
ফাংশন তৈরির সময় কিছু সেরা অভ্যাস মনে রাখা উচিত:
- সর্বদা বর্ণনামূলক নাম ব্যবহার করুন যাতে আপনি জানেন ফাংশনটি কী করবে
- শব্দগুলো একত্রিত করতে **camelCasing** ব্যবহার করুন
- সবসময় বর্ণনামূলক নাম ব্যবহার করুন যাতে আপনি জানেন ফাংশনটি কী করবে
- **camelCasing** ব্যবহার করে শব্দগুলো একত্রিত করুন
- আপনার ফাংশনগুলোকে একটি নির্দিষ্ট কাজের উপর কেন্দ্রীভূত রাখুন
## ফাংশনে তথ্য প্রেরণ
## ফাংশনে তথ্য পাঠানো
একটি ফাংশনকে আরও পুনঃব্যবহারযোগ্য করতে আপনি প্রায়ই এতে তথ্য প্রেরণ করতে চাইবেন। যদি আমরা আমাদের উপরের `displayGreeting` উদাহরণটি বিবেচনা করি, এটি শুধুমাত্র **Hello, world!** প্রদর্শন করবে। এটি খুব বেশি কার্যকরী ফাংশন নয়। যদি আমরা এটি একটু বেশি নমনীয় করতে চাই, যেমন কাউকে শুভেচ্ছা জানানোর জন্য নাম নির্দিষ্ট করার অনুমতি দেওয়া, তাহলে আমরা একটি **প্যারামিটার** যোগ করতে পারি। একটি প্যারামিটার (যাকে কখনও কখনও **আর্গুমেন্ট** বলা হয়) হলো ফাংশনে পাঠানো অতিরিক্ত তথ্য।
একটি ফাংশনকে আরও পুনঃব্যবহারযোগ্য করতে আপনি প্রায়ই এতে তথ্য পাঠাতে চাইবেন। যদি আমরা আমাদের উপরের `displayGreeting` উদাহরণটি বিবেচনা করি, এটি শুধুমাত্র **Hello, world!** দেখাবে। এটি খুব একটা কার্যকরী ফাংশন নয়। যদি আমরা এটিকে একটু বেশি নমনীয় করতে চাই, যেমন কাউকে অভিবাদন জানানোর জন্য নাম নির্দিষ্ট করার অনুমতি দেওা, তাহলে আমরা একটি **প্যারামিটার** যোগ করতে পারি। একটি প্যারামিটার (যাকে কখনও কখনও **argument** বলা হয়) হলো ফাংশনে পাঠানো অতিরিক্ত তথ্য।
প্যারামিটারগুলো সংজ্ঞা অংশে বন্ধনীতে তালিকাভুক্ত থাকে এবং কমা দিয়ে পৃথক করা হয়, যেমন:
প্যারামিটারগুলো সংজ্ঞার অংশে বন্ধনীর মধ্যে তালিকাভুক্ত থাকে এবং কমা দিয়ে পৃথক করা হয়, যেমন:
```javascript
function name(param, param2, param3) {
@ -76,7 +76,7 @@ function name(param, param2, param3) {
}
```
আমরা আমাদের `displayGreeting` আপডেট করতে পারি যাতে এটি একটি নাম গ্রহণ করে এবং তা প্রদর্শন করে।
আমরা আমাদের `displayGreeting` আপডেট করতে পারি যাতে এটি একটি নাম গ্রহণ করে এবং সেটি প্রদর্শন করে।
```javascript
function displayGreeting(name) {
@ -85,7 +85,7 @@ function displayGreeting(name) {
}
```
যখন আমরা আমাদের ফাংশন কল করতে চাই এবং প্যারামিটার প্রেরণ করতে চাই, আমরা এটি বন্ধনীর মধ্যে নির্দিষ্ট করি।
যখন আমরা আমাদের ফাংশন কল করতে চাই এবং প্যারামিটার পাঠাতে চাই, আমরা এটি বন্ধনীর মধ্যে নির্দিষ্ট করি।
```javascript
displayGreeting('Christopher');
@ -94,7 +94,7 @@ displayGreeting('Christopher');
## ডিফল্ট মান
আমরা আমাদের ফাংশনকে আরও নমনীয় করতে আরও প্যারামিটার যোগ করতে পারি। কিন্তু যদি আমরা চাই না যে প্রতিটি মান নির্দিষ্ট করা বাধ্যতামূলক হোক? আমাদের শুভেচ্ছা উদাহরণ ধরে রাখলে, আমরা নামটিকে প্রয়োজনীয় রাখতে পারি (আমাদের জানতে হবে কাকে শুভেচ্ছা জানানো হচ্ছে), কিন্তু আমরা চাই শুভেচ্ছাটি ইচ্ছামতো কাস্টমাইজ করার অনুমতি দিতে। যদি কেউ এটি কাস্টমাইজ করতে না চায়, আমরা একটি ডিফল্ট মান প্রদান করি। একটি প্যারামিটারে ডিফল্ট মান প্রদান করতে, আমরা এটি একটি ভেরিয়েবলের মান সেট করার মতো করে সেট করি - `parameterName = 'defaultValue'`। একটি সম্পূর্ণ উদাহরণ দেখতে:
আমরা আমাদের ফাংশনকে আরও নমনী করতে আরও প্যারামিটার যোগ করতে পারি। কিন্তু যদি আমরা চাই না যে প্রতিটি মান নির্দিষ্ট করা বাধ্যতামূলক হোক? আমাদের অভিবাদন উদাহরণ ধরে রাখলে, আমরা নামকে বাধ্যতামূলক রাখতে পারি (আমাদের জানতে হবে কাকে অভিবাদন জানানো হচ্ছে), কিন্তু আমরা চাই অভিবাদনটি ইচ্ছামতো কাস্টমাইজ করার অনুমতি দিতে। যদি কেউ এটি কাস্টমাইজ করতে না চায়, তাহলে আমরা একটি ডিফল্ট মান প্রদান করি। একটি প্যারামিটারে ডিফল্ট মান প্রদান করতে, আমরা এটি একটি ভেরিেবলের মান সেট করার মতো করে সেট করি - `parameterName = 'defaultValue'`। একটি সম্পূর্ণ উদাহরণ দেখতে:
```javascript
function displayGreeting(name, salutation='Hello') {
@ -102,7 +102,7 @@ function displayGreeting(name, salutation='Hello') {
}
```
যখন আমরা ফাংশন কল করি, তখন আমরা সিদ্ধান্ত নিতে পারি যে আমরা `salutation` এর জন্য একটি মান সেট করব কিনা।
যখন আমরা ফাংশন কল করি, তখন আমরা সিদ্ধান্ত নিতে পারি যে `salutation` এর জন্য একটি মান সেট করব কিনা।
```javascript
displayGreeting('Christopher');
@ -114,17 +114,17 @@ displayGreeting('Christopher', 'Hi');
## রিটার্ন মান
এখন পর্যন্ত আমরা যে ফাংশন তৈরি করেছি তা সর্বদা [console](https://developer.mozilla.org/docs/Web/API/console) এ আউটপুট দেবে। কখনও কখনও এটি ঠিক আমাদের যা প্রয়োজন তা হতে পারে, বিশেষত যখন আমরা এমন ফাংশন তৈরি করি যা অন্যান্য সার্ভিস কল করবে। কিন্তু যদি আমি একটি হেল্পার ফাংশন তৈরি করতে চাই যা একটি গণনা সম্পন্ন করবে এবং মানটি ফেরত দেবে যাতে আমি এটি অন্য কোথাও ব্যবহার করতে পারি?
এখন পর্যন্ত আমরা যে ফাংশন তৈরি করেছি তা সবসময় [console](https://developer.mozilla.org/docs/Web/API/console) এ আউটপুট দেবে। কখনও কখনও এটি ঠিক আমাদের যা প্রোজন তা হতে পারে, বিশেষত যখন আমরা এমন ফাংশন তৈরি করি যা অন্য সার্ভিস কল করবে। কিন্তু যদি আমি একটি হেল্পার ফাংশন তৈরি করতে চাই যা একটি গণনা সম্পন্ন করে এবং মানটি ফেরত দেয় যাতে আমি এটি অন্য কোথাও ব্যবহার করতে পারি?
আমরা এটি একটি **রিটার্ন মান** ব্যবহার করে করতে পারি। একটি রিটার্ন মান ফাংশন দ্বারা ফেরত দেওয়া হয় এবং এটি একটি ভেরিয়েবলে সংরক্ষণ করা যেতে পারে যেমন আমরা একটি স্ট্রিং বা সংখ্যার মতো একটি স্থির মান সংরক্ষণ করতে পারি।
আমরা এটি একটি **রিটার্ন মান** ব্যবহার করে করতে পারি। একটি রিটার্ন মান ফাংশন দ্বারা ফেরত দেওয়া হয় এবং এটি একটি ভেরিয়েবলে সংরক্ষণ করা যায়, যেমন আমরা একটি স্ট্রিং বা সংখ্যার মতো একটি স্থির মান সংরক্ষণ করতে পারি।
যদি একটি ফাংশন কিছু ফেরত দেয় তবে `return` কীওয়ার্ড ব্যবহার করা হয়। `return` কীওয়ার্ডটি কী ফেরত দেওয়া হচ্ছে তার একটি মান বা রেফারেন্স আশা করে, যেমন:
যদি একটি ফাংশন কিছু ফেরত দেয়, তাহলে `return` কীওয়ার্ড ব্যবহার করা হয়। `return` কীওয়ার্ডটি যা ফেরত দেওয়া হচ্ছে তার একটি মান বা রেফারেন্স আশা করে, যেমন:
```javascript
return myVariable;
```
আমরা একটি ফাংশন তৈরি করতে পারি যা একটি শুভেচ্ছা বার্তা তৈরি করবে এবং মানটি কলকারীকে ফেরত দেবে
আমরা একটি ফাংশন তৈরি করতে পারি যা একটি অভিবাদন বার্তা তৈরি করে এবং মানটি কলারের কাছে ফেরত দেয়
```javascript
function createGreetingMessage(name) {
@ -133,7 +133,7 @@ function createGreetingMessage(name) {
}
```
যখন আমরা এই ফাংশন কল করব, আমরা মানটি একটি ভেরিয়েবলে সংরক্ষণ করব। এটি অনেকটা এমনভাবে কাজ করে যেমন আমরা একটি স্থির মান সেট করি (যেমন `const name = 'Christopher'`)।
যখন আমরা এই ফাংশন কল করব, তখন আমরা মানটি একটি ভেরিয়েবলে সংরক্ষণ করব। এটি ঠিক সেইভাবে হবে যেভাবে আমরা একটি ভেরিয়েবলকে একটি স্থির মানে সেট করি (যেমন `const name = 'Christopher'`)।
```javascript
const greetingMessage = createGreetingMessage('Christopher');
@ -141,11 +141,11 @@ const greetingMessage = createGreetingMessage('Christopher');
## ফাংশনকে ফাংশনের প্যারামিটার হিসেবে ব্যবহার করা
আপনার প্রোগ্রামিং ক্যারিয়ারে অগ্রসর হওয়ার সাথে সাথে, আপনি এমন ফাংশন দেখতে পাবেন যা ফাংশনকে প্যারামিটার হিসেবে গ্রহণ করে। এই চমৎকার কৌশলটি সাধারণত তখন ব্যবহৃত হয় যখন আমরা জানি না কখন কিছু ঘটবে বা সম্পন্ন হবে, কিন্তু আমরা জানি যে আমাদের প্রতিক্রিয়ায় একটি অপারেশন সম্পাদন করতে হবে
আপনার প্রোগ্রামিং ক্যারিয়ারে আপনি এমন ফাংশনের মুখোমুখি হবেন যা ফাংশনকে প্যারামিটার হিসেবে গ্রহণ করে। এই চমৎকার কৌশলটি সাধারণত তখন ব্যবহার করা হয় যখন আমরা জানি না কিছু কখন ঘটবে বা সম্পন্ন হবে, কিন্তু আমরা জানি আমাদের একটি অপারেশন সম্পন্ন করতে হবে প্রতিক্রিয়াস্বরূপ
উদাহরণস্বরূপ, [setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout) বিবেচনা করুন, যা একটি টাইমার শুরু করে এবং এটি সম্পন্ন হলে কোড কার্যকর করে। আমাদের এটি জানাতে হবে যে আমরা কোন কোডটি কার্যকর করতে চাই। এটি একটি ফাংশনের জন্য উপযুক্ত কাজ বলে মনে হচ্ছে!
একটি উদাহরণ হিসেবে, [setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout) বিবেচনা করুন, যা একটি টাইমার শুরু করে এবং এটি সম্পন্ন হলে কোড চালায়। আমাদের এটি জানাতে হবে যে আমরা কোন কোড চালাতে চাই। এটি একটি ফাংশনের জন্য আদর্শ কাজ!
যদি আপনি নিচের কোডটি চালান, ৩ সেকেন্ড পরে আপনি বার্তাটি দেখতে পাবেন **3 seconds has elapsed**
যদি আপনি নিচের কোডটি চালান, ৩ সেকেন্ড পরে আপনি বার্তা **3 seconds has elapsed** দেখতে পাবেন
```javascript
function displayDone() {
@ -157,11 +157,11 @@ setTimeout(displayDone, 3000);
### অ্যানোনিমাস ফাংশন
আসুন আমরা যা তৈরি করেছি তা আবার দেখি। আমরা একটি ফাংশন তৈরি করছি যার একটি নাম রয়েছে যা একবার ব্যবহৃত হবে। আমাদের অ্যাপ্লিকেশন যত জটিল হবে, আমরা দেখতে পাব যে আমরা অনেক ফাংশন তৈরি করছি যা শুধুমাত্র একবার কল করা হবে। এটি আদর্শ নয়। দেখা যাচ্ছে, আমাদের সবসময় একটি নাম প্রদান করার প্রয়োজন নেই!
চলুন আমরা যা তৈরি করেছি তা আবার দেখি। আমরা একটি নাম সহ একটি ফাংশন তৈরি করছি যা একবার ব্যবহার করা হবে। আমাদের অ্যাপ্লিকেশন আরও জটিল হলে, আমরা দেখতে পাব অনেক ফাংশন তৈরি করছি যা শুধুমাত্র একবার কল করা হবে। এটি আদর্শ নয়। আসলে, আমাদের সবসময় একটি নাম প্রদান করার প্রয়োজন নেই!
যখন আমরা একটি ফাংশনকে প্যারামিটার হিসেবে প্রেরণ করি, তখন আমরা এটি আগে থেকে তৈরি না করেও প্যারামিটারের অংশ হিসেবে তৈরি করতে পারি। আমরা একই `function` কীওয়ার্ড ব্যবহার করি, তবে আমরা এটি একটি প্যারামিটার হিসেবে তৈরি করি।
যখন আমরা একটি ফাংশনকে প্যারামিটার হিসেবে পাঠাচ্ছি, আমরা এটি আগে থেকে তৈরি করার প্রক্রিয়া এড়িয়ে যেতে পারি এবং প্যারামিটারের অংশ হিসেবে এটি তৈরি করতে পারি। আমরা একই `function` কীওয়ার্ড ব্যবহার করি, কিন্তু এটি প্যারামিটার হিসেবে তৈরি করি।
আসুন উপরের কোডটি একটি অ্যানোনিমাস ফাংশন ব্যবহার করে পুনরায় লিখি:
চলুন আমাদের উপরের কোডটি অ্যানোনিমাস ফাংশন ব্যবহার করে পুনর্লিখন করি:
```javascript
setTimeout(function() {
@ -169,13 +169,13 @@ setTimeout(function() {
}, 3000);
```
যদি আপনি আমাদের নতুন কোডটি চালান, আপনি লক্ষ্য করবেন আমরা একই ফলাফল পা। আমরা একটি ফাংশন তৈরি করেছি, কিন্তু এটিকে একটি নাম দিতে হয়নি!
যদি আপনি আমাদের নতুন কোডটি চালান, আপনি লক্ষ্য করবেন আমরা একই ফলাফল পাচ্ছি। আমরা একটি ফাংশন তৈরি করেছি, কিন্তু এটিকে একটি নাম দিতে হনি!
### ফ্যাট অ্যারো ফাংশন
অনেক প্রোগ্রামিং ভাষায় (জাভাস্ক্রিপ্ট সহ) একটি সাধারণ শর্টকাট হলো **অ্যারো** বা **ফ্যাট অ্যারো** ফাংশন ব্যবহার করার ক্ষমতা। এটি `=>` নামে একটি বিশেষ চিহ্ন ব্যবহার করে, যা একটি তীরের মতো দেখায় - তাই নামটি! `=>` ব্যবহার করে, আমরা `function` কীওয়ার্ডটি বাদ দিতে পারি।
অনেক প্রোগ্রামিং ভাষা (জাভাস্ক্রিপ্ট সহ) একটি সাধারণ শর্টকাট হলো **অ্যারো** বা **ফ্যাট অ্যারো** ফাংশন ব্যবহার করার ক্ষমতা। এটি একটি বিশেষ সূচক `=>` ব্যবহার করে, যা একটি তীরের মতো দেখায় - তাই নাম! `=>` ব্যবহার করে আমরা `function` কীওয়ার্ডটি বাদ দিতে পারি।
আসুন আমাদের কোডটি আরেকবার পুনরায় লিখি একটি ফ্যাট অ্যারো ফাংশন ব্যবহার করে:
চলুন আমাদের কোডটি আরেকবার পুনর্লিখন করি ফ্যাট অ্যারো ফাংশন ব্যবহার করে:
```javascript
setTimeout(() => {
@ -185,24 +185,26 @@ setTimeout(() => {
### কখন কোন কৌশল ব্যবহার করবেন
আপনি এখন দেখেছেন যে আমরা একটি ফাংশনকে প্যারামিটার হিসেবে প্রেরণের তিনটি উপায় পেয়েছি এবং হয়তো ভাবছেন কখন কোনটি ব্যবহার করবেন। যদি আপনি জানেন যে ফাংশনটি একাধিকবার ব্যবহার করা হবে, তবে এটি সাধারণভাবে তৈরি করুন। যদি এটি শুধুমাত্র একটি স্থানে ব্যবহৃত হবে, তবে সাধারণত একটি অ্যানোনিমাস ফাংশন ব্যবহার করা সেরা। আপনি ফ্যাট অ্যারো ফাংশন বা আরও ঐতিহ্যবাহী `function` সিনট্যাক্স ব্যবহার করবেন কিনা তা আপনার উপর নির্ভর করে, তবে আপনি লক্ষ্য করবেন যে বেশিরভাগ আধুনিক ডেভেলপার `=>` পছন্দ করেন।
আপনি এখন দেখেছেন যে আমরা একটি ফাংশনকে প্যারামিটার হিসেবে পাঠানোর তিনটি উপায় পেয়েছি এবং হয়তো ভাবছেন কখন কোনটি ব্যবহার করবেন। যদি আপনি জানেন যে আপনি ফাংশনটি একাধিকবার ব্যবহার করবেন, তাহলে এটি সাধারণভাবে তৈরি করুন। যদি আপনি এটি শুধুমাত্র একটি স্থানের জন্য ব্যবহার করবেন, সাধারণত অ্যানোনিমাস ফাংশন ব্যবহার করা ভালো। আপনি ফ্যাট অ্যারো ফাংশন বা আরও প্রচলিত `function` সিনট্যাক্স ব্যবহার করবেন কিনা তা আপনার উপর নির্ভর করে, তবে আপনি লক্ষ্য করবেন বেশিরভাগ আধুনিক ডেভেলপার `=>` পছন্দ করেন।
---
## 🚀 চ্যালেঞ্জ
আপনি কি এক বাক্যে ফাংশন এবং মেথডের মধ্যে পার্থক্য ব্যাখ্যা করতে পারেন? চেষ্টা করে দেখুন!
আপনি কি এক বাক্যে ফাংশন এবং মেথডের মধ্যে পার্থক্য ব্যাখ্যা করতে পারেন? চেষ্টা করুন!
## পোস্ট-লেকচার কুইজ
[পোস্ট-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/10)
[পোস্ট-লেকচার কুইজ](https://ff-quizzes.netlify.app)
## পুনরালোচনা ও স্ব-অধ্যয়ন
## রিভিউ এবং সেলফ স্টাডি
[অ্যারো ফাংশন সম্পর্কে আরও পড়া](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) মূল্যবান, কারণ এগুলো ক্রমবর্ধমানভাবে কোড বেসে ব্যবহৃত হচ্ছে। একটি ফাংশন লিখুন এবং তারপর এটি এই সিনট্যাক্স দিয়ে পুনরায় লিখুন।
[অ্যারো ফাংশন সম্পর্কে আরও পা](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) মূল্যবান, কারণ এগুলো ক্রমবর্ধমানভাবে কোড বেসে ব্যবহৃত হচ্ছে। একটি ফাংশন লিখুন এবং তারপর এটি এই সিনট্যাক্স দিয়ে পুনর্লিখন করুন।
## অ্যাসাইনমেন্ট
[ফান উইথ ফাংশনস](assignment.md)
[Fun with Functions](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিক অনুবাদের চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। নথিটির মূল ভাষায় থাকা আসল সংস্করণটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে সৃষ্ট কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যার জন্য আমরা দায়ী নই
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিক অনুবাদ প্রদানের চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "888609c48329c280ca2477d2df40f2e5",
"translation_date": "2025-08-25T21:34:35+00:00",
"original_hash": "f7009631b73556168ca435120a231c98",
"translation_date": "2025-08-28T23:01:19+00:00",
"source_file": "2-js-basics/3-making-decisions/README.md",
"language_code": "bn"
}
@ -11,49 +11,49 @@ CO_OP_TRANSLATOR_METADATA:
![জাভাস্ক্রিপ্ট বেসিকস - সিদ্ধান্ত নেওয়া](../../../../translated_images/webdev101-js-decisions.69e1b20f272dd1f0b1cb2f8adaff3ed2a77c4f91db96d8a0594132a353fa189a.bn.png)
> স্কেচনোট: [Tomomi Imura](https://twitter.com/girlie_mac)
> স্কেচনোট করেছেন [Tomomi Imura](https://twitter.com/girlie_mac)
## প্রি-লেকচার কুইজ
## প্রাক-লেকচার কুইজ
[প্রি-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/11)
[প্রাক-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/11)
সিদ্ধান্ত নেওয়া এবং আপনার কোড কোন ক্রমে চলবে তা নিয়ন্ত্রণ করা আপনার কোডকে পুনরায় ব্যবহারযোগ্য এবং শক্তিশালী করে তোলে। এই অংশে জাভাস্ক্রিপ্টে ডেটা প্রবাহ নিয়ন্ত্রণের সিনট্যাক্স এবং এটি বুলিয়ান ডেটা টাইপের সাথে ব্যবহারের গুরুত্ব আলোচনা করা হয়েছে।
সিদ্ধান্ত নেওয়া এবং আপনার কোড কোন ক্রমে চলবে তা নিয়ন্ত্রণ করা আপনার কোডকে পুনরায় ব্যবহারযোগ্য এবং শক্তিশালী করে তোলে। এই অংশে জাভাস্ক্রিপ্টে ডেটা প্রবাহ নিয়ন্ত্রণের সিনট্যাক্স এবং এটি বুলিয়ান ডেটা টাইপের সাথে ব্যবহারের গুরুত্ব নিয়ে আলোচনা করা হয়েছে।
[![সিদ্ধান্ত নেওয়া](https://img.youtube.com/vi/SxTp8j-fMMY/0.jpg)](https://youtube.com/watch?v=SxTp8j-fMMY "সিদ্ধান্ত নেওয়া")
> 🎥 উপরের ছবিতে ক্লিক করুন সিদ্ধান্ত নেওয়া সম্পর্কে একটি ভিডিও দেখার জন্য
> 🎥 উপরের ছবিতে ক্লিক করে সিদ্ধান্ত নেওয়া নিয়ে একটি ভিডিও দেখুন
> আপনি এই পাঠটি [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-if-else/?WT.mc_id=academic-77807-sagibbon) এ নিতে পারেন!
## বুলিয়ান সম্পর্কে সংক্ষিপ্ত পুনরালোচনা
বুলিয়ান শুধুমাত্র দুটি মান ধারণ করতে পারে: `true` বা `false`। বুলিয়ান নির্ধারণ করে কোন শর্ত পূরণ হলে কোন কোডের লাইন চলবে।
বুলিয়ান কেবল দুটি মান ধারণ করতে পারে: `true` বা `false`। বুলিয়ান নির্ধারণ করে কোন শর্ত পূরণ হলে কোডের কোন লাইনগুলো চলবে।
আপনার বুলিয়ানকে true বা false সেট করুন এভাবে:
`let myTrueBool = true`
`let myFalseBool = false`
✅ বুলিয়ান নামকরণ করা হয়েছে ইংরেজ গণিতবিদ, দার্শনিক এবং যুক্তিবিদ জর্জ বুল (১৮১৫–১৮৬৪) এর নামে।
✅ বুলিয়ান নামটি এসেছে ইংরেজ গণিতবিদ, দার্শনিক এবং যুক্তিবিদ জর্জ বুল (১৮১৫–১৮৬৪) এর নাম থেকে।
## তুলনা অপারেটর এবং বুলিয়ান
অপারেটর ব্যবহার করে শর্ত মূল্যায়ন করা হয়, যা একটি বুলিয়ান মান তৈরি করে। নিচে কিছু সাধারণ অপারেটরের তালিকা দেওয়া হলো।
অপারেটর ব্যবহার করে শর্ত মূল্যায়ন করা হয়, যা একটি বুলিয়ান মান তৈরি করে। নিচে কিছু সাধারণত ব্যবহৃত অপারেটরের তালিকা দেওয়া হলো।
| প্রতীক | বিবরণ | উদাহরণ |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
| `<` | **কম**: দুটি মান তুলনা করে এবং যদি বাম পাশের মান ডান পাশের মানের চেয়ে কম হয়, তাহলে `true` বুলিয়ান ডেটা টাইপ প্রদান করে | `5 < 6 // true` |
| `<=` | **কম বা সমান**: দুটি মান তুলনা করে এবং যদি বাম পাশের মান ডান পাশের মানের চেয়ে কম বা সমান হয়, তাহলে `true` প্রদান করে | `5 <= 6 // true` |
| `>` | **বেশি**: দুটি মান তুলনা করে এবং যদি বাম পাশের মান ডান পাশের মানের চেয়ে বেশি হয়, তাহলে `true` প্রদান করে | `5 > 6 // false` |
| `>=` | **বেশি বা সমান**: দুটি মান তুলনা করে এবং যদি বাম পাশের মান ডান পাশের মানের চেয়ে বেশি বা সমান হয়, তাহলে `true` প্রদান করে | `5 >= 6 // false` |
| `===` | **কঠোর সমতা**: দুটি মান তুলনা করে এবং যদি বাম এবং ডান পাশের মান সমান এবং একই ডেটা টাইপ হয়, তাহলে `true` প্রদান করে | `5 === 6 // false` |
| `!==` | **অসমতা**: দুটি মান তুলনা করে এবং কঠোর সমতা অপারেটর যা প্রদান করব তার বিপরীত বুলিয়ান মান প্রদান করে | `5 !== 6 // true` |
| প্রতীক | বরনা | উদাহরণ |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
| `<` | **কম**: দুটি মান তুলনা করে এবং বাম পাশের মান ডান পাশের মানের চেয়ে কম হলে `true` বুলিয়ান মান প্রদান করে | `5 < 6 // true` |
| `<=` | **কম বা সমান**: দুটি মান তুলনা করে এবং বাম পাশের মান ডান পাশের মানের চেয়ে কম বা সমান হলে `true` বুলিয়ান মান প্রদান করে | `5 <= 6 // true` |
| `>` | **বেশি**: দুটি মান তুলনা করে এবং বাম পাশের মান ডান পাশের মানের চেয়ে বেশি হলে `true` বুলিয়ান মান প্রদান করে | `5 > 6 // false` |
| `>=` | **বেশি বা সমান**: দুটি মান তুলনা করে এবং বাম পাশের মান ডান পাশের মানের চেয়ে বেশি বা সমান হলে `true` বুলিয়ান মান প্রদান করে | `5 >= 6 // false` |
| `===` | **কঠোর সমতা**: দুটি মান তুলনা করে এবং বাম ও ডান পাশের মান সমান এবং একই ডেটা টাইপ হলে `true` বুলিয়ান মান প্রদান করে | `5 === 6 // false` |
| `!==` | **অসমতা**: দুটি মান তুলনা করে এবং কঠোর সমতা অপারেটরের বিপরীত বুলিয়ান মান প্রদান করে | `5 !== 6 // true` |
✅ আপনার জ্ঞান পরীক্ষা করুন ব্রাউজারের কনসোলে কিছু তুলনা লিখে। কোনো ফলাফল কি আপনাকে অবাক করেছে?
✅ আপনার জ্ঞান পরীক্ষা করতে ব্রাউজারের কনসোলে কিছু তুলনা লিখুন। কোনো ফলাফল কি আপনাকে অবাক করে?
## If স্টেটমেন্ট
If স্টেটমেন্ট তার ব্লকের মধ্যে কোড চালাবে যদি শর্তটি true হয়
`if` স্টেটমেন্ট শর্ত সত্য হলে তার ব্লকের মধ্যে থাকা কোড চালাবে
```javascript
if (condition) {
@ -75,7 +75,7 @@ if (currentMoney >= laptopPrice) {
## If..Else স্টেটমেন্ট
`else` স্টেটমেন্ট তার ব্লকের মধ্যে কোড চালাবে যখন শর্তটি false হবে। এটি `if` স্টেটমেন্টের সাথে ঐচ্ছিক।
`else` স্টেটমেন্ট শর্ত মিথ্যা হলে তার ব্লকের মধ্যে থাকা কোড চালাবে। এটি `if` স্টেটমেন্টের সাথে ঐচ্ছিক।
```javascript
let currentMoney;
@ -90,11 +90,11 @@ if (currentMoney >= laptopPrice) {
}
```
✅ এই কোড এবং পরবর্তী কোড ব্রাউজারের কনসোলে চালিয়ে আপনার বোঝা পরীক্ষা করুন। `currentMoney` এবং `laptopPrice` ভেরিেবলের মান পরিবর্তন করে `console.log()` এর আউটপুট পরিবর্তন করুন।
✅ এই কোড এবং পরবর্তী কোড ব্রাউজারের কনসোলে চালিয়ে আপনার বোঝাপড়া পরীক্ষা করুন। `currentMoney` এবং `laptopPrice` ভেরিয়েবলের মান পরিবর্তন করে `console.log()` এর আউটপুট পরিবর্তন করুন।
## Switch স্টেটমেন্ট
`switch` স্টেটমেন্ট বিভিন্ন শর্তের উপর ভিত্তি করে বিভিন্ন কাজ সম্পাদন করতে ব্যবহৃত হয়। `switch` স্টেটমেন্ট ব্যবহার করে অনেক কোড ব্লকের মধ্যে একটি নির্বাচন করুন যা কার্যকর হবে
`switch` স্টেটমেন্ট বিভিন্ন শর্তের উপর ভিত্তি করে বিভিন্ন কাজ সম্পাদন করতে ব্যবহৃত হয়। এটি ব্যবহার করে একাধিক কোড ব্লকের মধ্যে একটি নির্বাচন করা যায়
```javascript
switch (expression) {
@ -127,21 +127,21 @@ switch (a) {
console.log(`The value is ${a}`);
```
✅ এই কোড এবং পরবর্তী কোড ব্রাউজারের কনসোলে চালিয়ে আপনার বোঝার পরীক্ষা করুন। ভেরিয়েবল `a` এর মান পরিবর্তন করে `console.log()` এর আউটপুট পরিবর্তন করুন।
✅ এই কোড এবং পরবর্তী কোড ব্রাউজারের কনসোলে চালিয়ে আপনার বোঝাপড়া পরীক্ষা করুন। ভেরিয়েবল `a` এর মান পরিবর্তন করে `console.log()` এর আউটপুট পরিবর্তন করুন।
## লজিক্যাল অপারেটর এবং বুলিয়ান
সিদ্ধান্ত গ্রহণের জন্য একাধিক তুলনা প্রয়োজন হতে পারে এবং সেগুলো লজিক্যাল অপারেটর দিয়ে যুক্ত করে একটি বুলিয়ান মান তৈরি করা যায়।
সিদ্ধান্ত নেওয়ার জন্য একাধিক তুলনা প্রয়োজন হতে পারে, যা লজিক্যাল অপারেটর দিয়ে যুক্ত করে একটি বুলিয়ান মান তৈরি করা যায়।
| প্রতীক | বিবরণ | উদাহরণ |
| ------ | ----------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| `&&` | **লজিক্যাল AND**: দুটি বুলিয়ান এক্সপ্রেশন তুলনা করে। শুধুমাত্র উভয় পক্ষ true হলে true প্রদান করে | `(5 > 6) && (5 < 6 ) //একটি পক্ষ false, অন্যটি true। ফলাফল false` |
| `\|\|` | **লজিক্যাল OR**: দুটি বুলিয়ান এক্সপ্রেশন তুলনা করে। অন্তত একটি পক্ষ true হলে true প্রদান করে | `(5 > 6) \|\| (5 < 6) //একটি পক্ষ false, অন্যটি true। ফলাফল true` |
| `!` | **লজিক্যাল NOT**: একটি বুলিয়ান এক্সপ্রেশনের বিপরীত মান প্রদান করে | `!(5 > 6) // ৫ ৬ এর চেয়ে বেশি নয়, কিন্তু "!" true প্রদান করবে` |
| প্রতীক | বরনা | উদাহরণ |
| ------ | ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------- |
| `&&` | **লজিক্যাল AND**: দুটি বুলিয়ান এক্সপ্রেশন তুলনা করে। উভয় পক্ষ সত্য হলে কেবলমাত্র সত্য প্রদান করে | `(5 > 6) && (5 < 6 ) //একটি পক্ষ মিথ্যা, অন্যটি সত্য। ফলাফল মিথ্যা` |
| `\|\|` | **লজিক্যাল OR**: দুটি বুলিয়ান এক্সপ্রেশন তুলনা করে। অন্তত একটি পক্ষ সত্য হলে সত্য প্রদান করে | `(5 > 6) \|\| (5 < 6) //একটি পক্ষ মিথ্যা, অন্যটি সত্য। ফলাফল সত্য` |
| `!` | **লজিক্যাল NOT**: একটি বুলিয়ান এক্সপ্রেশনের বিপরীত মান প্রদান করে | `!(5 > 6) // 5 ছয় এর চেয়ে বেশি নয়, কিন্তু "!" সত্য প্রদান করবে` |
## লজিক্যাল অপারেটর দিয়ে শর্ত এবং সিদ্ধান্ত
লজিক্যাল অপারেটর ব্যবহার করে if..else স্টেটমেন্টে শর্ত তৈরি করা যায়।
লজিক্যাল অপারেটর ব্যবহার করে `if..else` স্টেটমেন্টে শর্ত তৈরি করা যায়।
```javascript
let currentMoney;
@ -159,7 +159,7 @@ if (currentMoney >= laptopPrice || currentMoney >= laptopDiscountPrice) {
### নেগেশন অপারেটর
আপনি ইতিমধ্যে দেখেছেন কিভাবে `if...else` স্টেটমেন্ট ব্যবহার করে শর্তযুক্ত লজিক তৈরি করা যায়। `if` এর মধ্যে যা কিছু থাকবে তা true/false এ মূল্যায়িত হতে হবে। `!` অপারেটর ব্যবহার করে আপনি এক্সপ্রেশনকে _নেগেট_ করতে পারেন। এটি দেখতে এমন হবে:
এখন পর্যন্ত আপনি দেখেছেন কিভাবে `if...else` স্টেটমেন্ট ব্যবহার করে শর্তযুক্ত লজিক তৈরি করা যায়। `if` এর মধ্যে যা কিছু যায় তা সত্য/মিথ্যা হতে হবে। `!` অপারেটর ব্যবহার করে আপনি এক্সপ্রেশনকে _নেগেট_ করতে পারেন। এটি দেখতে এমন হবে:
```javascript
if (!condition) {
@ -171,7 +171,7 @@ if (!condition) {
### টার্নারি এক্সপ্রেশন
`if...else` সিদ্ধান্ত লজিক প্রকাশ করার একমাত্র উপায় নয়। আপনি টার্নারি অপারেটর নামক একটি জিনিসও ব্যবহার করতে পারেন। এর সিনট্যাক্স দেখতে এমন:
`if...else` সিদ্ধান্ত লজিক প্রকাশ করার একমাত্র উপায় নয়। আপনি টার্নারি অপারেটর নামক কিছু ব্যবহার করতে পারেন। এর সিনট্যাক্স দেখতে এমন:
```javascript
let variable = condition ? <return this if true> : <return this if false>
@ -185,7 +185,7 @@ let secondNumber = 10;
let biggestNumber = firstNumber > secondNumber ? firstNumber : secondNumber;
```
✅ এই কোডটি কয়েকবার পড়ুন। আপনি কি বুঝতে পারছেন কিভাবে এই অপারেটরগুলো কাজ করছে?
✅ এই কোডটি কয়েকবার পড়ুন। আপনি কি বুঝতে পারছেন কিভাবে এই অপারেটরগুলো কাজ করছে?
উপরের কোডটি বলে যে:
@ -193,7 +193,7 @@ let biggestNumber = firstNumber > secondNumber ? firstNumber : secondNumber;
- তাহলে `firstNumber` কে `biggestNumber` এ অ্যাসাইন করুন
- অন্যথায় `secondNumber` কে অ্যাসাইন করুন।
টার্নারি এক্সপ্রেশনটি নিচের কোডটি লেখার একটি সংক্ষিপ্ত উপায়:
টার্নারি এক্সপ্রেশনটি নিচের কোডটি সংক্ষেপে লেখার একটি উপায়:
```javascript
let biggestNumber;
@ -208,7 +208,7 @@ if (firstNumber > secondNumber) {
## 🚀 চ্যালেঞ্জ
প্রথমে লজিক্যাল অপারেটর ব্যবহার করে একটি প্রোগ্রাম তৈরি করুন এবং তারপর এটি টার্নারি এক্সপ্রেশন ব্যবহার করে পুনরায় লিখুন। আপনার পছন্দের সিনট্যাক্স কোনটি?
একটি প্রোগ্রাম তৈরি করুন যা প্রথমে লজিক্যাল অপারেটর ব্যবহার করে লেখা হবে, এবং পরে এটি টার্নারি এক্সপ্রেশন ব্যবহার করে পুনরায় লেখা হবে। কোন সিনট্যাক্সটি আপনার পছন্দ?
---
@ -216,9 +216,9 @@ if (firstNumber > secondNumber) {
[পোস্ট-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/12)
## পর্যালোচনা এবং স্ব-অধ্যয়ন
## পুনরালোচনা এবং স্ব-অধ্যয়ন
ব্যবহারকারীর জন্য উপলব্ধ বিভিন্ন অপারেটর সম্পর্কে আরও পড়ুন [MDN](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators) এ।
ব্যবহারকারীর জন্য উপলব্ধ বিভিন্ন অপারেটর সম্পর্কে আরও জানুন [MDN](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators) এ।
Josh Comeau এর চমৎকার [অপারেটর লুকআপ](https://joshwcomeau.com/operator-lookup/) দেখুন!
@ -226,5 +226,7 @@ Josh Comeau এর চমৎকার [অপারেটর লুকআপ](ht
[অপারেটর](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিক অনুবাদ প্রদানের চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়ী থাকব না।

@ -1,15 +1,15 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "3f7f87871312cf6cc12662da7d973182",
"translation_date": "2025-08-25T21:47:21+00:00",
"original_hash": "9029f96b0e034839c1799f4595e4bb66",
"translation_date": "2025-08-28T23:02:31+00:00",
"source_file": "2-js-basics/4-arrays-loops/README.md",
"language_code": "bn"
}
-->
# জাভাস্ক্রিপ্টের বুনিয়াদি: অ্যারে এবং লুপ
![জাভাস্ক্রিপ্ট বুনিয়াদি - অ্যারে](../../../../translated_images/webdev101-js-arrays.439d7528b8a294558d0e4302e448d193f8ad7495cc407539cc81f1afe904b470.bn.png)
![জাভাস্ক্রিপ্ট বেসিকস - অ্যারে](../../../../translated_images/webdev101-js-arrays.439d7528b8a294558d0e4302e448d193f8ad7495cc407539cc81f1afe904b470.bn.png)
> স্কেচনোট: [Tomomi Imura](https://twitter.com/girlie_mac)
## প্রাক-লেকচার কুইজ
@ -37,13 +37,13 @@ CO_OP_TRANSLATOR_METADATA:
let myArray = [];
```
এটি একটি খালি অ্যারে, তবে অ্যারে ডেটা দিয়ে পূর্ণ অবস্থায় ঘোষণা করা যেতে পারে। একটি অ্যারেতে একাধিক মান কমা দিয়ে পৃথক করা হয়।
এটি একটি খালি অ্যারে, তবে অ্যারে ডেটা দিয়ে পূর্ণ অবস্থায় ঘোষণা করা যেতে পারে। একটি অ্যারেতে একাধিক মান কমা দিয়ে পৃথক করা হয়।
```javascript
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
```
অ্যারের মানগুলো একটি অনন্য মান পায়, যাকে **ইন্ডেক্স** বলা হয়, যা অ্যারের শুরু থেকে তার দূরত্বের উপর ভিত্তি করে একটি পূর্ণসংখ্যা হিসেবে বরাদ্দ করা হয়। উপরের উদাহরণে, "Chocolate" স্ট্রিংটির ইন্ডেক্স হলো 0, এবং "Rocky Road"-এর ইন্ডেক্স হলো 4। ইন্ডেক্স ব্যবহার করে স্কয়ার ব্র্যাকেটের মাধ্যমে অ্যারের মানগুলো পুনরুদ্ধার, পরিবর্তন বা যোগ করা যায়।
অ্যারের মানগুলোকে একটি অনন্য মান, **ইন্ডেক্স** নামে পরিচিত, দিয়ে বরাদ্দ করা হয়। এটি একটি পূর্ণসংখ্যা যা অ্যারের শুরু থেকে তার দূরত্বের উপর ভিত্তি করে বরাদ্দ করা হয়। উপরের উদাহরণে, "Chocolate" স্ট্রিংটির ইন্ডেক্স হলো 0, এবং "Rocky Road"-এর ইন্ডেক্স হলো 4। ইন্ডেক্স ব্যবহার করে স্কয়ার ব্র্যাকেটের মাধ্যমে অ্যারের মানগুলো পুনরুদ্ধার, পরিবর্তন বা যোগ করা যায়।
✅ আপনাকে কি অবাক করে যে অ্যারে শূন্য ইন্ডেক্স থেকে শুরু হয়? কিছু প্রোগ্রামিং ভাষায় ইন্ডেক্স 1 থেকে শুরু হয়। এর একটি আকর্ষণীয় ইতিহাস রয়েছে, যা আপনি [উইকিপিডিয়ায় পড়তে পারেন](https://en.wikipedia.org/wiki/Zero-based_numbering)।
@ -77,14 +77,14 @@ iceCreamFlavors.length; //5
## লুপ
লুপ আমাদের পুনরাবৃত্তিমূলক বা **ইটারেটিভ** কাজ সম্পাদন করতে দেয় এবং এটি অনেক সময় এবং কোড সাশ্রয় করতে পারে। প্রতিটি ইটারেশন ভেরিয়েবল, মান এবং শর্তে পরিবর্তিত হতে পারে। জাভাস্ক্রিপ্টে বিভিন্ন ধরনের লুপ রয়েছে, এবং তাদের মধ্যে ছোট পার্থক্য রয়েছে, তবে মূলত তারা একই কাজ করে: ডেটার উপর লুপ করা।
লুপ আমাদের পুনরাবৃত্তিমূলক বা **ইটারেটিভ** কাজ সম্পাদন করতে দেয় এবং এটি অনেক সময় এবং কোড বাঁচাতে পারে। প্রতিটি ইটারেশন তাদের ভেরিয়েবল, মান এবং শর্তে ভিন্ন হতে পারে। জাভাস্ক্রিপ্টে বিভিন্ন ধরনের লুপ রয়েছে, এবং তাদের মধ্যে ছোট পার্থক্য রয়েছে, তবে মূলত তারা একই কাজ করে: ডেটার উপর লুপ করা।
### ফর লুপ
`for` লুপে ইটারেট করার জন্য ৩টি অংশ প্রয়োজন:
- `counter` একটি ভেরিয়েবল যা সাধারণত একটি সংখ্যা দিয়ে শুরু হয় এবং ইটারেশনের সংখ্যা গণনা করে
- `condition` একটি এক্সপ্রেশন যা তুলনা অপারেটর ব্যবহার করে লুপকে `false` হলে থামায়
- `iteration-expression` প্রতিটি ইটারেশনের শেষে চালানো হয়, সাধারণত কাউন্টার মান পরিবর্তন করতে ব্যবহৃত হয়
- `iteration-expression` প্রতিটি ইটারেশনের শেষে চালানো হয়, সাধারণত কাউন্টার মান পরিবর্তনের জন্য ব্যবহৃত হয়
```javascript
// Counting up to 10
@ -97,7 +97,7 @@ for (let i = 0; i < 10; i++) {
### হোয়াইল লুপ
`for` লুপের সিনট্যাক্সের বিপরীতে, `while` লুপে শুধুমাত্র একটি শর্ত প্রয়োজন যা শর্ত `false` হলে লুপ থামাবে। লুপের শর্তগুলো সাধারণত অন্যান্য মানের উপর নির্ভর করে, যেমন কাউন্টার, এবং লুপ চলাকালীন এগুলো পরিচালনা করতে হয়। কাউন্টারের প্রাথমিক মানগুলো লুপের বাইরে তৈরি করতে হয়, এবং শর্ত পূরণের জন্য যেকোনো এক্সপ্রেশন, যার মধ্যে কাউন্টার পরিবর্তনও অন্তর্ভুক্ত, লুপের ভিতরে বজায় রাখতে হয়।
`for` লুপের সিনট্যাক্সের বিপরীতে, `while` লুপে শুধুমাত্র একটি শর্ত প্রয়োজন যা শর্ত `false` হলে লুপ থামাবে। লুপের শর্তগুলো সাধারণত অন্যান্য মানের উপর নির্ভর করে, যেমন কাউন্টার, এবং লুপ চলাকালীন এগুলো পরিচালনা করতে হয়। কাউন্টারের জন্য প্রাথমিক মান লুপের বাইরে তৈরি করতে হয়, এবং শর্ত পূরণের জন্য যেকোনো এক্সপ্রেশন, যার মধ্যে কাউন্টার পরিবর্তনও অন্তর্ভুক্ত, লুপের ভিতরে বজায় রাখতে হয়।
```javascript
//Counting up to 10
@ -112,7 +112,7 @@ while (i < 10) {
## লুপ এবং অ্যারে
অ্যারে প্রায়ই লুপের সাথে ব্যবহার করা হয় কারণ বেশিরভাগ শর্ত অ্যারের দৈর্ঘ্য ব্যবহার করে লুপ থামানোর প্রয়োজন হয়, এবং ইন্ডেক্সটি কাউন্টার মানও হতে পারে।
অ্যারে প্রায়ই লুপের সাথে ব্যবহার করা হয় কারণ বেশিরভাগ শর্ত অ্যারের দৈর্ঘ্য প্রয়োজন লুপ থামানোর জন্য, এবং ইন্ডেক্সটি কাউন্টার মানও হতে পারে।
```javascript
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
@ -122,7 +122,7 @@ for (let i = 0; i < iceCreamFlavors.length; i++) {
} //Ends when all flavors are printed
```
✅ আপনার ব্রাউজারের কনসোলে একটি অ্যারে তৈরি করে সেটির উপর লুপ করার চেষ্টা করুন
✅ আপনার নিজের তৈরি একটি অ্যারের উপর লুপিং করার চেষ্টা করুন আপনার ব্রাউজারের কনসোলে
---
@ -135,11 +135,13 @@ for (let i = 0; i < iceCreamFlavors.length; i++) {
## পর্যালোচনা এবং স্ব-অধ্যয়ন
জাভাস্ক্রিপ্টে অ্যারেগুলোর সাথে অনেক মেথড সংযুক্ত থাকে, যা ডেটা পরিচালনার জন্য অত্যন্ত কার্যকর। [এই মেথডগুলো সম্পর্কে পড়ুন](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) এবং আপনার তৈরি করা একটি অ্যারেতে এগুলো (যেমন push, pop, slice এবং splice) ব্যবহার করে দেখুন।
জাভাস্ক্রিপ্টে অ্যারেগুলোর সাথে অনেক মেথড সংযুক্ত থাকে, যা ডেটা পরিচালনার জন্য অত্যন্ত কার্যকর। [এই মেথডগুলো সম্পর্কে পড়ুন](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) এবং আপনার তৈরি একটি অ্যারের উপর কিছু মেথড (যেমন push, pop, slice এবং splice) ব্যবহার করে দেখুন।
## অ্যাসাইনমেন্ট
[অ্যারের উপর লুপ করুন](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিক অনুবাদ প্রদানের চেষ্টা করি, তবে দয়া করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। নথিটির মূল ভাষায় থাকা সংস্করণটিকেই প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে সৃষ্ট কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যার জন্য আমরা দায়ী নই।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতা নিশ্চিত করার চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "46a0639e719b9cf1dfd062aa24cad639",
"translation_date": "2025-08-25T21:07:41+00:00",
"original_hash": "89f7f9f800ce7c9f149e98baaae8491a",
"translation_date": "2025-08-28T23:02:55+00:00",
"source_file": "3-terrarium/1-intro-to-html/README.md",
"language_code": "bn"
}
@ -24,13 +24,13 @@ CO_OP_TRANSLATOR_METADATA:
### পরিচিতি
HTML, বা HyperText Markup Language, হলো ওয়েবের 'কঙ্কাল'। যদি CSS আপনার HTML-কে সাজায় এবং JavaScript এটিকে প্রাণ দেয়, তাহলে HTML হলো আপনার ওয়েব অ্যাপ্লিকেশনের শরীর। HTML এর সিনট্যাক্সও এই ধারণাকে প্রতিফলিত করে, কারণ এতে "head", "body", এবং "footer" ট্যাগ অন্তর্ভুক্ত রয়েছে।
HTML, বা HyperText Markup Language, হলো ওয়েবের 'কঙ্কাল'। যদি CSS আপনার HTML-কে সাজায় এবং JavaScript এটিকে প্রাণবন্ত করে তোলে, তাহলে HTML হলো আপনার ওয়েব অ্যাপ্লিকেশনের শরীর। HTML এর সিনট্যাক্সও এই ধারণাকে প্রতিফলিত করে, কারণ এতে "head", "body", এবং "footer" ট্যাগ অন্তর্ভুক্ত রয়েছে।
এই পাঠে, আমরা HTML ব্যবহার করে আমাদের ভার্চুয়াল টেরারিয়ামের ইন্টারফেসের 'কঙ্কাল' তৈরি করব। এতে একটি শিরোনাম এবং তিনটি কলাম থাকবে: ডান এবং বাম কলাম যেখানে ড্র্যাগযোগ্য গাছপালা থাকবে, এবং একটি কেন্দ্রীয় এলাকা যা আসল কাচের মতো টেরারিয়াম হবে। এই পাঠের শেষে, আপনি কলামগুলিতে গাছপালা দেখতে পাবেন, তবে ইন্টারফেসটি একটু অদ্ভুত দেখাবে; চিন্তা করবেন না, পরবর্তী অংশে আপনি CSS স্টাইল যোগ করে ইন্টারফেসটিকে আরও সুন্দর করবেন।
### কাজ
আপনার কম্পিউটারে 'terrarium' নামে একটি ফোল্ডার তৈরি করুন এবং এর ভিতরে 'index.html' নামে একটি ফাইল তৈরি করুন। আপনি Visual Studio Code-এ এটি করতে পারেন, প্রথমে আপনার terrarium ফোল্ডার তৈরি করে একটি নতুন VS Code উইন্ডো খুলে, 'open folder' ক্লিক করে আপনার নতুন ফোল্ডারে নেভিগেট করুন। Explorer প্যানেলে ছোট 'file' বোতামটি ক্লিক কর নতুন ফাইল তৈরি করুন:
আপনার কম্পিউটারে 'terrarium' নামে একটি ফোল্ডার তৈরি করুন এবং এর ভিতরে 'index.html' নামে একটি ফাইল তৈরি করুন। আপনি এটি Visual Studio Code-এ করতে পারেন। প্রথমে আপনার terrarium ফোল্ডার তৈরি করুন, তারপর একটি নতুন VS Code উইন্ডো খুলুন, 'open folder' ক্লিক করুন এবং আপনার নতুন ফোল্ডারে যান। Explorer প্যানেলে ছোট 'file' বোতামটি ক্লিক করুন এবং নতুন ফাইল তৈরি করুন:
![VS Code-এ explorer](../../../../translated_images/vs-code-index.e2986cf919471eb984a0afef231380c8b132b000635105f2397bd2754d1b689c.bn.png)
@ -42,17 +42,17 @@ HTML, বা HyperText Markup Language, হলো ওয়েবের 'কঙ
* `touch index.html`
* `code index.html` অথবা `nano index.html`
> index.html ফাইলগুলি ব্রাউজারকে নির্দেশ করে যে এটি একটি ফোল্ডারের ডিফল্ট ফাইল; যেমন URL `https://anysite.com/test` একটি ফোল্ডার কাঠামো ব্যবহার করে তৈরি হতে পারে যেখানে `test` নামে একটি ফোল্ডার এবং তার ভিতরে `index.html` রয়েছে; URL-এ `index.html` দেখানোর প্রয়োজন নেই।
> index.html ফাইলগুলি ব্রাউজারকে নির্দেশ করে যে এটি একটি ফোল্ডারের ডিফল্ট ফাইল; যেমন `https://anysite.com/test` URL একটি ফোল্ডার কাঠামো ব্যবহার করে তৈরি হতে পারে যেখানে `test` নামে একটি ফোল্ডার এবং তার ভিতরে `index.html` থাকে; `index.html` URL-এ দেখানোর প্রয়োজন নেই।
---
## DocType এবং html ট্যাগ
HTML ফাইলের প্রথম লাইনটি হলো এর doctype। এটি একটু আশ্চর্যজনক যে এই লাইনটি ফাইলের একেবারে শীর্ষে থাকতে হবে, তবে এটি পুরনো ব্রাউজারকে জানায় যে পৃষ্ঠাটি বর্তমান HTML স্পেসিফিকেশন অনুসারে স্ট্যান্ডার্ড মোডে রেন্ডার করতে হবে।
HTML ফাইলের প্রথম লাইন হলো এর doctype। এটি একটু আশ্চর্যজনক যে এই লাইনটি ফাইলের একেবারে শীর্ষে থাকতে হবে, তবে এটি পুরনো ব্রাউজারকে জানায় যে পৃষ্ঠাটি বর্তমান HTML স্পেসিফিকেশন অনুসারে স্ট্যান্ডার্ড মোডে রেন্ডার করতে হবে।
> টিপ: VS Code-এ, আপনি একটি ট্যাগের উপর হোভার করলে MDN Reference গাইড থেকে এর ব্যবহার সম্পর্কে তথ্য পেতে পারেন।
> টিপ: VS Code-এ, আপনি একটি ট্যাগের উপর মাউস রেখে MDN Reference গাইড থেকে এর ব্যবহার সম্পর্কে তথ্য পেতে পারেন।
দ্বিতীয় লাইনটি হওয়া উচিত `<html>` ট্যাগের ওপেনিং ট্যাগ, এবং তারপরে এর ক্লোজিং ট্যাগ `</html>`। এই ট্যাগগুলি আপনার ইন্টারফেসের মূল উপাদান।
দ্বিতীয় লাইনটি `<html>` ট্যাগের ওপেনিং ট্যাগ হওয়া উচিত, এবং এর পরে `<html>` ট্যাগের ক্লোজিং ট্যাগ `</html>`। এই ট্যাগগুলি আপনার ইন্টারফেসের মূল উপাদান।
### কাজ
@ -63,23 +63,23 @@ HTML ফাইলের প্রথম লাইনটি হলো এর doct
<html></html>
```
✅ DocType সেট করে বিভিন্ন মোড নির্ধারণ করা যায়: [Quirks Mode এবং Standards Mode](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode)। এই মোডগুলি খুব পুরনো ব্রাউজারগুলিকে সমর্থন করত যা এখন সাধারণত ব্যবহৃত হয় না (Netscape Navigator 4 এবং Internet Explorer 5)। আপনি স্ট্যান্ডার্ড doctype ডিক্লারেশনে থাকতে পারেন।
✅ DocType সেট করে বিভিন্ন মোড নির্ধারণ করা যায়: [Quirks Mode এবং Standards Mode](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode)। এই মোডগুলি খুব পুরনো ব্রাউজার (যেমন Netscape Navigator 4 এবং Internet Explorer 5) সমর্থন করার জন্য ব্যবহৃত হয়। আপনি স্ট্যান্ডার্ড doctype ডিক্লারেশন ব্যবহার করতে পারেন।
---
## ডকুমেন্টের 'head'
HTML ডকুমেন্টের 'head' অংশে আপনার ওয়েব পৃষ্ঠার গুরুত্বপূর্ণ তথ্য থাকে, যা [metadata](https://developer.mozilla.org/docs/Web/HTML/Element/meta) নামে পরিচিত। আমাদের ক্ষেত্রে, আমরা ওয়েব সার্ভারকে এই চারটি জিনিস জানাই:
HTML ডকুমেন্টের 'head' অংশে আপনার ওয়েব পৃষ্ঠার গুরুত্বপূর্ণ তথ্য থাকে, যা [মেটাডেটা](https://developer.mozilla.org/docs/Web/HTML/Element/meta) নামে পরিচিত। আমাদের ক্ষেত্রে, আমরা ওয়েব সার্ভারকে এই চারটি বিষয় জানাই:
- পৃষ্ঠার শিরোনাম
- পৃষ্ঠার মেটাডেটা, যার মধ্যে রয়েছে:
- 'character set', যা পৃষ্ঠায় ব্যবহৃত অক্ষর এনকোডিং সম্পর্কে জানায়
- ব্রাউজার তথ্য, যার মধ্যে `x-ua-compatible` রয়েছে যা নির্দেশ করে যে IE=edge ব্রাউজার সমর্থিত
- ভিউপোর্ট লোড হওয়ার সময় কীভাবে আচরণ করবে তার তথ্য। ভিউপোর্টের প্রাথমিক স্কেল ১ সেট করা পৃষ্ঠাটি প্রথম লোড হওয়ার সময় জুম লেভেল নিয়ন্ত্রণ কর
- ব্রাউজার তথ্য, যার মধ্যে `x-ua-compatible` অন্তর্ভুক্ত, যা নির্দেশ করে যে IE=edge ব্রাউজার সমর্থিত
- ভিউপোর্ট লোড হওয়ার সময় কীভাবে আচরণ করবে তার তথ্য। ভিউপোর্টের প্রাথমিক স্কেল ১ সেট করা হলে পৃষ্ঠাটি প্রথম লোড হওয়ার সময় জুম লেভেল নিয়ন্ত্রণ করা যায়
### কাজ
`<html>` ট্যাগের ওপেনিং এবং ক্লোজিং ট্যাগের মধ্যে একটি 'head' ব্লক যোগ করুন।
আপনার ডকুমেন্টে `<html>` ট্যাগের ওপেনিং এবং ক্লোজিং ট্যাগের মধ্যে একটি 'head' ব্লক যোগ করুন।
```html
<head>
@ -90,7 +90,7 @@ HTML ডকুমেন্টের 'head' অংশে আপনার ওয
</head>
```
✅ যদি আপনি এইভাবে একটি ভিউপোর্ট মেটা ট্যাগ সেট করেন: `<meta name="viewport" content="width=600">`, তাহলে কী বে? [ভিউপোর্ট](https://developer.mozilla.org/docs/Web/HTML/Viewport_meta_tag) সম্পর্কে আরও পড়ুন।
✅ যদি আপনি ভিউপোর্ট মেটা ট্যাগটি এইভাবে সেট করেন: `<meta name="viewport" content="width=600">`, তাহলে কী ঘটবে? [ভিউপোর্ট](https://developer.mozilla.org/docs/Web/HTML/Viewport_meta_tag) সম্পর্কে আরও পড়ুন।
---
@ -98,7 +98,7 @@ HTML ডকুমেন্টের 'head' অংশে আপনার ওয
### HTML ট্যাগ
HTML-এ, আপনি আপনার .html ফাইলে ট্যাগ যোগ করে একটি ওয়েব পৃষ্ঠার উপাদান তৈরি করেন। প্রতিটি ট্যাগ সাধারণত একটি ওপেনিং এবং ক্লোজিং ট্যাগ থাকে, যেমন: `<p>hello</p>` একটি প্যারাগ্রাফ নির্দেশ করতে। আপনার ইন্টারফেসের body তৈরি করতে `<html>` ট্যাগ জোড়ার ভিতরে `<body>` ট্যাগের একটি সেট যোগ করুন; এখন আপনার মার্কআপ দেখতে এইরকম:
HTML-এ, আপনি আপনার .html ফাইলে ট্যাগ যোগ করে একটি ওয়েব পৃষ্ঠার উপাদান তৈরি করেন। প্রতিটি ট্যাগ সাধারণত একটি ওপেনিং এবং ক্লোজিং ট্যাগ থাকে, যেমন: `<p>hello</p>` একটি প্যারাগ্রাফ নির্দেশ করতে। আপনার ইন্টারফেসের body তৈরি করতে `<html>` ট্যাগর ভিতরে `<body>` ট্যাগের একটি সেট যোগ করুন; এখন আপনার মার্কআপ এইরকম দেখাবে:
### কাজ
@ -115,17 +115,17 @@ HTML-এ, আপনি আপনার .html ফাইলে ট্যাগ য
</html>
```
এখন, আপনি আপনার পৃষ্ঠা তৈরি করা শুরু করতে পারেন। সাধারণত, আপনি `<div>` ট্যাগ ব্যবহার করে একটি পৃষ্ঠার পৃথক উপাদান তৈরি করেন। আমরা একটি সিরিজ `<div>` উপাদান তৈরি করব যা চিত্র ধারণ করবে।
এখন, আপনি আপনার পৃষ্ঠা তৈরি করা শুরু করতে পারেন। সাধারণত, আপনি `<div>` ট্যাগ ব্যবহার করে একটি পৃষ্ঠার পৃথক উপাদান তৈরি করেন। আমরা একটি সিরিজের `<div>` উপাদান তৈরি করব যা ছবিগুলি ধারণ করবে।
### চিত্র
### ছবি
একটি HTML ট্যাগ যা ক্লোজিং ট্যাগের প্রয়োজন হয় না তা হলো `<img>` ট্যাগ, কারণ এতে একটি `src` উপাদান থাকে যা পৃষ্ঠার আইটেমটি রেন্ডার করার জন্য প্রয়োজনীয় সমস্ত তথ্য ধারণ করে।
আপনার অ্যাপে একটি `images` নামে একটি ফোল্ডার তৈরি করুন এবং তাতে [source code folder](../../../../3-terrarium/solution/images) থেকে সমস্ত চিত্র যোগ করুন; (গাছপালার ১৪টি চিত্র রয়েছে)।
আপনার অ্যাপে `images` নামে একটি ফোল্ডার তৈরি করুন এবং সেখানে [source code folder](../../../../3-terrarium/solution/images) থেকে সমস্ত ছবি যোগ করুন; (গাছপালার ১৪টি ছবি রয়েছে)।
### কাজ
এই গাছপালার চিত্রগুলি `<body></body>` ট্যাগের মধ্যে দুটি কলামে যোগ করুন:
এই গাছপালার ছবিগুলি `<body></body>` ট্যাগের মধ্যে দুটি কলামে যোগ করুন:
```html
<div id="page">
@ -178,33 +178,33 @@ HTML-এ, আপনি আপনার .html ফাইলে ট্যাগ য
</div>
```
> নোট: Spans বনাম Divs। Divs 'block' উপাদান হিসেবে বিবেচিত হয়, এবং Spans 'inline'। যদি আপনি এই divs-কে spans-এ রূপান্তর করেন তাহলে কী হবে?
> নোট: Spans বনাম Divs। Divs 'block' উপাদান হিসেবে বিবেচিত হয়, এবং Spans 'inline'। যদি আপনি এই divs-কে spans-এ রূপান্তর করেন, তাহলে কী ঘটবে?
এই মার্কআপ দিয়ে, গাছপালা এখন স্ক্রিনে প্রদর্শিত হয়। এটি দেখতে খুব খারাপ, কারণ এগুলি এখনও CSS ব্যবহার করে স্টাইল করা হয়নি, এবং আমরা এটি পরবর্তী পাঠে করব।
এই মার্কআপ দিয়ে, গাছপালাগুলি এখন স্ক্রিনে প্রদর্শিত হয়। এটি দেখতে খুব খারাপ, কারণ এগুলি এখনও CSS ব্যবহার করে স্টাইল করা হয়নি, এবং আমরা এটি পরবর্তী পাঠে করব।
প্রতিটি চিত্রে alt টেক্সট রয়েছে যা এমনকি আপনি যদি চিত্রটি দেখতে বা রেন্ডার করতে না পারেন তবুও প্রদর্শিত হবে। এটি অন্তর্ভুক্ত করা একটি গুরুত্বপূর্ণ বৈশিষ্ট্য যা অ্যাক্সেসিবিলিটির জন্য প্রয়োজনীয়। ভবিষ্যতের পাঠে অ্যাক্সেসিবিলিটি সম্পর্কে আরও জানুন; আপাতত, মনে রাখুন যে alt অ্যাট্রিবিউট একটি চিত্রের জন্য বিকল্প তথ্য প্রদান করে যদি কোনো কারণে ব্যবহারকারী এটি দেখতে না পারে (ধীর সংযোগ, src অ্যাট্রিবিউটে ত্রুটি, অথবা ব্যবহারকারী যদি স্ক্রিন রিডার ব্যবহার করে)।
প্রতিটি ছবিতে alt টেক্সট থাকে যা এমনকি আপনি যদি একটি ছবি দেখতে বা রেন্ডার করতে না পারেন তবুও প্রদর্শিত হয়। এটি অন্তর্ভুক্ত করা একটি গুরুত্বপূর্ণ অ্যাট্রিবিউট যা অ্যাক্সেসিবিলিটির জন্য প্রয়োজনীয়। ভবিষ্যতের পাঠে অ্যাক্সেসিবিলিটি সম্পর্কে আরও জানুন; আপাতত, মনে রাখুন যে alt অ্যাট্রিবিউট একটি ছবির জন্য বিকল্প তথ্য প্রদান করে যদি কোনো কারণে ব্যবহারকারী এটি দেখতে না পারে (ধীর সংযোগ, src অ্যাট্রিবিউটে ত্রুটি, অথবা ব্যবহারকারী যদি স্ক্রিন রিডার ব্যবহার করে)।
✅ আপনি কি লক্ষ্য করেছেন যে প্রতিটি চিত্রে একই alt ট্যাগ রয়েছে? এটি কি ভালো অভ্যাস? কেন বা কেন নয়? আপনি কি এই কোডটি উন্নত করতে পারেন?
✅ আপনি কি লক্ষ্য করেছেন যে প্রতিটি ছবির একই alt ট্যাগ রয়েছে? এটি কি ভালো অভ্যাস? কেন বা কেন নয়? আপনি কি এই কোডটি উন্নত করতে পারেন?
---
## সেমান্টিক মার্কআপ
সাধারণভাবে, HTML লেখার সময় অর্থপূর্ণ 'semantics' ব্যবহার করা ভালো। এর মানে কী? এর মানে হলো আপনি HTML ট্যাগ ব্যবহার করেন যাতে তারা যে ধরণের ডেটা বা ইন্টারঅ্যাকশনের জন্য ডিজাইন করা হয়েছে তা উপস্থাপন করে। উদাহরণস্বরূপ, একটি পৃষ্ঠার প্রধান শিরোনাম টেক্সট `<h1>` ট্যাগ ব্যবহার করা উচিত।
সাধারণভাবে, HTML লেখার সময় অর্থপূর্ণ 'সেমান্টিক্স' ব্যবহার করা ভালো। এর অর্থ কী? এর অর্থ হলো আপনি HTML ট্যাগ ব্যবহার করেন যাতে তারা যে ধরণের ডেটা বা ইন্টারঅ্যাকশনের জন্য ডিজাইন করা হয়েছে তা উপস্থাপন করে। উদাহরণস্বরূপ, একটি পৃষ্ঠার প্রধান শিরোনাম টেক্সট `<h1>` ট্যাগ ব্যবহার করা উচিত।
আপনার ওপেনিং `<body>` ট্যাগের ঠিক নিচে নিম্নলিখিত লাইনটি যোগ করুন:
আপনার ওপেনিং `<body>` ট্যাগের ঠিক নিচে এই লাইনটি যোগ করুন:
```html
<h1>My Terrarium</h1>
```
সেমান্টিক মার্কআপ ব্যবহার যেমন `<h1>` দিয়ে হেডার এবং `<ul>` দিয়ে আনঅর্ডারড লিস্ট রেন্ডার করা স্ক্রিন রিডারকে একটি পৃষ্ঠার মাধ্যমে নেভিগেট করতে সাহায্য করে। সাধারণভাবে, বোতামগুলি `<button>` হিসেবে লেখা উচিত এবং তালিকাগুলি `<li>` হওয়া উচিত। যদিও এটি _সম্ভব_ বিশেষভাবে স্টাইল করা `<span>` উপাদান ব্যবহার করে ক্লিক হ্যান্ডলার দিয়ে বোতামগুলিকে নকল করা, এটি প্রতিবন্ধী ব্যবহারকারীদের জন্য ভালো যে তারা প্রযুক্তি ব্যবহার করে একটি পৃষ্ঠায় বোতাম কোথায় রয়েছে তা নির্ধারণ করতে পারে এবং এটি ইন্টারঅ্যাক্ট করতে পারে, যদি উপাদানটি একটি বোতাম হিসেবে প্রদর্শিত হয়। এই কারণে, যতটা সম্ভব সেমান্টিক মার্কআপ ব্যবহার করার চেষ্টা করুন।
সেমান্টিক মার্কআপ ব্যবহার করা, যেমন শিরোনামগুলিকে `<h1>` এবং আনঅর্ডারড লিস্টগুলিকে `<ul>` হিসেবে রেন্ডার করা, স্ক্রিন রিডারকে একটি পৃষ্ঠার মাধ্যমে নেভিগেট করতে সাহায্য করে। সাধারণভাবে, বোতামগুলি `<button>` হিসেবে লেখা উচিত এবং লিস্টগুলি `<li>` হওয়া উচিত। যদিও বিশেষভাবে স্টাইল করা `<span>` উপাদান ব্যবহার করে বোতামগুলিকে নকল করা সম্ভব, এটি প্রতিবন্ধী ব্যবহারকারীদের জন্য প্রযুক্তি ব্যবহার করে একটি পৃষ্ঠায় বোতামটি কোথায় রয়েছে তা নির্ধারণ করা এবং এর সাথে ইন্টারঅ্যাক্ট করা সহজ করে তোলে যদি উপাদানটি বোতাম হিসেবে প্রদর্শিত হয়। এই কারণে, যতটা সম্ভব সেমান্টিক মার্কআপ ব্যবহার করার চেষ্টা করুন।
✅ একটি স্ক্রিন রিডার দেখুন এবং [কীভাবে এটি একটি ওয়েব পৃষ্ঠার সাথে ইন্টারঅ্যাক্ট করে](https://www.youtube.com/watch?v=OUDV1gqs9GA)। আপনি কি দেখতে পাচ্ছেন কেন অ-সেমান্টিক মার্কআপ ব্যবহারকারীকে হতাশ করতে পারে?
✅ একটি স্ক্রিন রিডার এবং [কীভাবে এটি একটি ওয়েব পৃষ্ঠার সাথে ইন্টারঅ্যাক্ট করে](https://www.youtube.com/watch?v=OUDV1gqs9GA) দেখুন। আপনি কি দেখতে পাচ্ছেন কেন অ-সেমান্টিক মার্কআপ ব্যবহারকারীকে হতাশ করতে পারে?
## টেরারিয়াম
এই ইন্টারফেসের শেষ অংশটি এমন মার্কআপ তৈরি করা যা স্টাইল করা হবে টেরারিয়াম তৈরি করে।
এই ইন্টারফেসের শেষ অংশটি এমন মার্কআপ তৈরি করা যা স্টাইল করা হবে এবং একটি টেরারিয়াম তৈরি করে।
### কাজ:
@ -222,13 +222,13 @@ HTML-এ, আপনি আপনার .html ফাইলে ট্যাগ য
</div>
```
✅ যদিও আপনি এই মার্কআপটি স্ক্রিনে যোগ করেছেন, আপনি কিছুই রেন্ডার হতে দেখছেন না। কেন?
✅ যদিও আপনি এই মার্কআপটি স্ক্রিনে যোগ করেছেন, আপনি কিছুই দেখতে পাচ্ছেন না। কেন?
---
## 🚀চ্যালেঞ্জ
HTML-এ কিছু পুরনো 'মজার' ট্যাগ রয়েছে যা এখনও খেলার জন্য মজার, যদিও আপনি [এই ট্যাগগুলি](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) এর মতো ডিপ্রিকেটেড ট্যাগগুলি আপনার মার্কআপে ব্যবহার করা উচিত নয়। তবুও, আপনি কি পুরনো `<marquee>` ট্যাগ ব্যবহার করে h1 শিরোনামটি অনুভূমিকভাবে স্ক্রল করতে পারেন? (যদি করেন, পরে এটি সরাতে ভুলবেন না)
HTML-এ কিছু পুরনো 'মজার' ট্যাগ রয়েছে যা এখনও ব্যবহার করা যায়, যদিও [এই ট্যাগগুলি](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) আপনার মার্কআপে ব্যবহার করা উচিত নয়। তবুও, আপনি কি পুরনো `<marquee>` ট্যাগ ব্যবহার করে h1 শিরোনামটি অনুভূমিকভাবে স্ক্রল করতে পারেন? (যদি করেন, পরে এটি সরাতে ভুলবেন না)
## পোস্ট-লেকচার কুইজ
@ -236,13 +236,15 @@ HTML-এ কিছু পুরনো 'মজার' ট্যাগ রয়
## পর্যালোচনা এবং স্ব-অধ্যয়ন
HTML হলো 'পরীক্ষিত এবং সত্য' বিল্ডিং ব্লক সিস্টেম যা ওয়েবকে আজকের অবস্থানে নিয়ে এসেছে। এর ইতিহাস সম্পর্কে কিছু শিখুন পুরনো এবং নতুন ট্যাগগুলি অধ্যয়ন করে। আপনি কি বুঝতে পারেন কেন কিছু ট্যাগ ডিপ্রিকেটেড হয়েছে এবং কিছু যোগ করা হয়েছে? ভবিষ্যতে কী ট্যাগ যোগ করা হতে পারে?
HTML হলো 'পরীক্ষিত এবং সত্য' বিল্ডিং ব্লক সিস্টেম যা ওয়েবকে আজকের অবস্থানে নিয়ে এসেছে। কিছু পুরনো এবং নতুন ট্যাগ সম্পর্কে পড়াশোনা করে এর ইতিহাস সম্পর্কে জানুন। আপনি কি বুঝতে পারেন কেন কিছু ট্যাগ বাতিল করা হয়েছে এবং কিছু যোগ করা হয়েছে? ভবিষ্যতে কী ট্যাগ যুক্ত হতে পারে?
ওয়েব এবং মোবাইল ডিভাইসের জন্য সাইট তৈরি করার বিষয়ে আরও জানুন [Microsoft Learn](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=academic-77807-sagibbon)
ওয়েব এবং মোবাইল ডিভাইসের জন্য সাইট তৈরি সম্পর্কে আরও জানুন [Microsoft Learn](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=academic-77807-sagibbon) থেকে
## অ্যাসাইনমেন্ট
[আপনার HTML অনুশীলন করুন: একটি ব্লগ মকআপ তৈরি করুন](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতা নিশ্চিত করার চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।

@ -1,15 +1,15 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e375c2aeb94e2407f2667633d39580bd",
"translation_date": "2025-08-25T21:24:58+00:00",
"original_hash": "acb5ae00cde004304296bb97da8ff4c3",
"translation_date": "2025-08-28T23:03:32+00:00",
"source_file": "3-terrarium/2-intro-to-css/README.md",
"language_code": "bn"
}
-->
# টেরারিয়াম প্রকল্প পার্ট ২: CSS-এ পরিচিতি
# টেরারিয়াম প্রকল্প পার্ট ২: CSS পরিচিতি
![CSS-এ পরিচিতি](../../../../translated_images/webdev101-css.3f7af5991bf53a200d79e7257e5e450408d8ea97f5b531d31b2e3976317338ee.bn.png)
![CSS পরিচিতি](../../../../translated_images/webdev101-css.3f7af5991bf53a200d79e7257e5e450408d8ea97f5b531d31b2e3976317338ee.bn.png)
> স্কেচনোট: [Tomomi Imura](https://twitter.com/girlie_mac)
## প্রাক-লেকচার কুইজ
@ -18,11 +18,11 @@ CO_OP_TRANSLATOR_METADATA:
### পরিচিতি
CSS, বা Cascading Style Sheets, ওয়েব ডেভেলপমেন্টের একটি গুরুত্বপূর্ণ সমস্যা সমাধান করে: কীভাবে আপনার ওয়েবসাইটকে সুন্দর দেখানো যায়। আপনার অ্যাপগুলিকে স্টাইলিং করলে সেগুলি আরও ব্যবহারযোগ্য এবং আকর্ষণীয় দেখায়; CSS ব্যবহার করে আপনি Responsive Web Design (RWD) তৈরি করতে পারেন - যা আপনার অ্যাপগুলিকে যেকোনো স্ক্রিন সাইজে ভালো দেখাতে সক্ষম করে। CSS কেবল আপনার অ্যাপকে সুন্দর দেখানোর জন্য নয়; এর স্পেসিফিকেশন অ্যানিমেশন এবং ট্রান্সফর্ম অন্তর্ভুক্ত রয়েছে যা আপনার অ্যাপগুলির জন্য উন্নত ইন্টারঅ্যাকশন সক্ষম করতে পারে। CSS Working Group বর্তমান CSS স্পেসিফিকেশন বজায় রাখতে সাহায্য করে; তাদের কাজ আপনি [World Wide Web Consortium-এর সাইটে](https://www.w3.org/Style/CSS/members) অনুসরণ করতে পারেন।
CSS, বা Cascading Style Sheets, ওয়েব ডেভেলপমেন্টের একটি গুরুত্বপূর্ণ সমস্যা সমাধান করে: কীভাবে আপনার ওয়েবসাইটকে সুন্দর দেখানো যায়। আপনার অ্যাপগুলিকে স্টাইলিং করলে সেগুলি আরও ব্যবহারযোগ্য এবং আকর্ষণীয় দেখায়; CSS ব্যবহার করে আপনি Responsive Web Design (RWD) তৈরি করতে পারেন - যা আপনার অ্যাপগুলিকে যেকোনো স্ক্রিন সাইজে ভালো দেখাতে সক্ষম করে। CSS শুধুমাত্র আপনার অ্যাপকে সুন্দর দেখানোর জন্য নয়; এর স্পেসিফিকেশন অ্যানিমেশন এবং ট্রান্সফর্ম অন্তর্ভুক্ত রে যা আপনার অ্যাপগুলির জন্য উন্নত ইন্টারঅ্যাকশন সক্ষম করতে পারে। CSS Working Group বর্তমান CSS স্পেসিফিকেশন বজায় রাখতে সাহায্য করে; তাদের কাজ আপনি [World Wide Web Consortium-এর সাইটে](https://www.w3.org/Style/CSS/members) অনুসরণ করতে পারেন।
> মনে রাখবেন, CSS একটি ভাষা যা ওয়েবের মতোই ক্রমাগত বিকশিত হয়, এবং সব ব্রাউজার নতুন স্পেসিফিকেশনের অংশগুলো সমর্থন করে না। সবসময় [CanIUse.com](https://caniuse.com) দেখে আপনার ইমপ্লিমেন্টেশন যাচাই করুন।
> মনে রাখবেন, CSS একটি ভাষা যা ওয়েবের মতোই বিকশিত হয়, এবং সব ব্রাউজার নতুন স্পেসিফিকেশনের অংশগুলো সমর্থন করে না। আপনার ইমপ্লিমেন্টেশন যাচাই করতে [CanIUse.com](https://caniuse.com) ব্যবহার করুন।
এই পাঠে, আমরা আমাদের অনলাইন টেরারিয়ামে স্টাইল যোগ করব এবং CSS-এর কয়েকটি ধারণা সম্পর্কে আরও জানব: ক্যাসকেড, ইনহেরিটেন্স, এবং সিলেক্টর, পজিশনিং, এবং CSS ব্যবহার করে লেআউট তৈরি করা। এই প্রক্রিয়ায় আমরা টেরারিয়াম লেআউট করব এবং টেরারিয়াম নিজেই তৈরি করব।
এই পাঠে, আমরা আমাদের অনলাইন টেরারিয়ামে স্টাইল যোগ করব এবং CSS-এর কয়েকটি ধারণা সম্পর্কে আরও জানব: ক্যাসকেড, ইনহেরিটেন্স, এবং সিলেক্টর, পজিশনিং, এবং CSS ব্যবহার করে লেআউট তৈরি করার পদ্ধতি। এই প্রক্রিয়ায় আমরা টেরারিয়াম লেআউট করব এবং প্রকৃত টেরারিয়াম তৈরি করব।
### পূর্বশর্ত
@ -45,7 +45,7 @@ CSS, বা Cascading Style Sheets, ওয়েব ডেভেলপমেন
## ক্যাসকেড
Cascading Style Sheets ধারণাটি অন্তর্ভুক্ত করে যে স্টাইলগুলো 'ক্যাসকেড' করে, যাতে একটি স্টাইল প্রয়োগের অগ্রাধিকার দ্বারা নির্দেশিত হয়। ওয়েবসাইট লেখকের দ্বারা সেট করা স্টাইল ব্রাউজারের সেট করা স্টাইলের উপর অগ্রাধিকার পায়। 'ইনলাইন' স্টাইলগুল এক্সটার্নাল স্টাইল শিটে সেট করা স্টাইলের উপর অগ্রাধিকার পায়।
Cascading Style Sheets ধারণাটি অন্তর্ভুক্ত করে যে স্টাইলগুলি 'ক্যাসকেড' করে, যার ফলে স্টাইল প্রয়োগের অগ্রাধিকার দ্বারা নির্দেশিত হয়। ওয়েবসাইট লেখকের দ্বারা সেট করা স্টাইল ব্রাউজারের সেট করা স্টাইলের উপর অগ্রাধিকার পায়। 'ইনলাইন' স্টাইলগুলি এক্সটার্নাল স্টাইল শিটে সেট করা স্টাইলের উপর অগ্রাধিকার পায়।
### কাজ
@ -63,17 +63,17 @@ h1 {
}
```
✅ আপনার ওয়েব অ্যাপে কোন রঙ প্রদর্শিত হয়? কেন? আপনি কি স্টাইলগুলো ওভাররাইড করার উপায় খুঁজে পেয়েছেন? কখন আপনি এটি করতে চাইবেন, বা কেন নয়?
✅ আপনার ওয়েব অ্যাপে কোন রঙ প্রদর্শিত হয়? কেন? আপনি কি স্টাইল ওভাররাইড করার উপায় খুঁজে পেতে পারেন? কখন আপনি এটি করতে চাইবেন, বা কেন নয়?
---
## ইনহেরিটেন্স
স্টাইলগুল পূর্বপুরুষের স্টাইল থেকে বংশধরদের মধ্যে উত্তরাধিকারসূত্রে প্রাপ্ত হয়, যাতে নেস্টেড এলিমেন্টগুলো তাদের প্যারেন্টের স্টাইল উত্তরাধিকারসূত্রে পায়
স্টাইলগুলি পূর্বপুরুষের স্টাইল থেকে বংশধরদের মধ্যে উত্তরাধিকারসূত্রে প্রাপ্ত হয়, যার ফলে নেস্টেড এলিমেন্টগুলি তাদের প্যারেন্টের স্টাইল গ্রহণ করে
### কাজ
বডির ফন্ট একটি নির্দিষ্ট ফন্টে সেট করুন এবং নেস্টেড এলিমেন্টের ফন্ট পরীক্ষা করুন:
বডির ফন্ট একটি নির্দিষ্ট ফন্টে সেট করুন এবং একটি নেস্টেড এলিমেন্টের ফন্ট পরীক্ষা করুন:
```CSS
body {
@ -81,7 +81,7 @@ body {
}
```
আপনার ব্রাউজারের কনসোলের 'Elements' ট্যাবে যান এবং H1-এর ফন্ট পর্যবেক্ষণ করুন। এটি বডি থেকে তার ফন্ট উত্তরাধিকারসূত্রে পায়, যা ব্রাউজারে উল্লেখ করা হয়েছে:
আপনার ব্রাউজারের কনসোলের 'Elements' ট্যাবে যান এবং H1-এর ফন্ট পর্যবেক্ষণ করুন। এটি বডি থেকে তার ফন্ট উত্তরাধিকারসূত্রে পায়, যা ব্রাউজারের মধ্যে উল্লেখ করা হয়েছে:
![উত্তরাধিকারসূত্রে প্রাপ্ত ফন্ট](../../../../translated_images/1.cc07a5cbe114ad1d4728c35134584ac1b87db688eff83cf75985cf31fe0ed95c.bn.png)
@ -93,7 +93,7 @@ body {
### ট্যাগ
এখন পর্যন্ত, আপনার `style.css` ফাইলে কেবল কয়েকটি ট্যাগ স্টাইল করা হয়েছে, এবং অ্যাপটি বেশ অদ্ভুত দেখাচ্ছে:
এখন পর্যন্ত, আপনার `style.css` ফাইলে শুধুমাত্র কয়েকটি ট্যাগ স্টাইল করা হয়েছে, এবং অ্যাপটি বেশ অদ্ভুত দেখাচ্ছে:
```CSS
body {
@ -106,11 +106,11 @@ h1 {
}
```
এই পদ্ধতিতে একটি ট্যাগ স্টাইলিং আপনাকে অনন্য এলিমেন্টগুলর উপর নিয়ন্ত্রণ দেয়, তবে আপনাকে টেরারিয়ামের অনেক গাছপালার স্টাইল নিয়ন্ত্রণ করতে হবে। এটি করতে, আপনাকে CSS সিলেক্টর ব্যবহার করতে হবে।
এই পদ্ধতিতে একটি ট্যাগ স্টাইলিং আপনাকে অনন্য এলিমেন্টগুলির উপর নিয়ন্ত্রণ দেয়, তবে আপনাকে আপনার টেরারিয়ামের অনেক গাছর স্টাইল নিয়ন্ত্রণ করতে হবে। এটি করতে, আপনাকে CSS সিলেক্টর ব্যবহার করতে হবে।
### আইডি
বাম এবং ডান কন্টেইনারগুলোর লেআউট স্টাইল করতে কিছু স্টাইল যোগ করুন। যেহেতু মার্কআপে কেবল একটি বাম কন্টেইনার এবং একটি ডান কন্টেইনার রয়েছে, সেগুলোকে আইডি দেওয়া হয়েছে। সেগুলো স্টাইল করতে, `#` ব্যবহার করুন:
বাম এবং ডান কন্টেইনারগুলির লেআউট স্টাইল যোগ করুন। যেহেতু শুধুমাত্র একটি বাম কন্টেইনার এবং একটি ডান কন্টেইনার রয়েছে, সেগুলি মার্কআপে আইডি দেওয়া হয়েছে। সেগুলি স্টাইল করতে, `#` ব্যবহার করুন:
```CSS
#left-container {
@ -134,9 +134,9 @@ h1 {
}
```
এখানে, আপনি এই কন্টেইনারগুলকে স্ক্রিনের একেবারে বাম এবং ডান দিকে অ্যাবসোলিউট পজিশনিং দিয়ে রেখেছেন এবং তাদের প্রস্থের জন্য শতাংশ ব্যবহার করেছেন যাতে সেগুলো ছোট মোবাইল স্ক্রিনের জন্য স্কেল করতে পারে।
এখানে, আপনি এই কন্টেইনারগুলিকে স্ক্রিনের একেবারে বাম এবং ডান দিকে অ্যাবসোলিউট পজিশনিং দিয়ে রেখেছেন এবং তাদের প্রস্থের জন্য শতাংশ ব্যবহার করেছেন যাতে তারা ছোট মোবাইল স্ক্রিনের জন্য স্কেল করতে পারে।
✅ এই কোডটি বেশ পুনরাবৃত্তিমূলক, যা "DRY" (Don't Repeat Yourself) নয়; আপনি কি এই আইডিগুলো স্টাইল করার আরও ভালো উপায় খুঁজে পেতে পারেন, হয়তো একটি আইডি এবং একটি ক্লাস ব্যবহার করে? আপনাকে মার্কআপ পরিবর্তন করতে হবে এবং CSS পুনর্গঠন করতে হবে:
✅ এই কোডটি বেশ পুনরাবৃত্ত, যা "DRY" (Don't Repeat Yourself) নয়; আপনি কি এই আইডিগুলিকে স্টাইল করার একটি ভালো উপায় খুঁজে পেতে পারেন, সম্ভবত একটি আইডি এবং একটি ক্লাস দিয়ে? আপনাকে মার্কআপ পরিবর্তন করতে হবে এবং CSS পুনর্গঠন করতে হবে:
```html
<div id="left-container" class="container"></div>
@ -144,9 +144,9 @@ h1 {
### ক্লাস
উপরের উদাহরণে, আপনি স্ক্রিনে দুটি অনন্য এলিমেন্ট স্টাইল করেছেন। যদি আপনি চান যে স্ক্রিনের অনেক এলিমেন্টে স্টাইল প্রয়োগ করা হোক, তবে আপনি CSS ক্লাস ব্যবহার করতে পারেন। বাম এবং ডান কন্টেইনারে গাছপালাগুলোর লেআউট করতে এটি করুন।
উপরের উদাহরণে, আপনি স্ক্রিনে দুটি অনন্য এলিমেন্ট স্টাইল করেছেন। যদি আপনি স্ক্রিনে অনেক এলিমেন্টের উপর স্টাইল প্রয়োগ করতে চান, আপনি CSS ক্লাস ব্যবহার করতে পারেন। বাম এবং ডান কন্টেইনারগুলিতে গাছগুলির লেআউট করতে এটি করুন।
লক্ষ্য করুন যে HTML মার্কআপে প্রতিটি গাছপালার একটি আইডি এবং ক্লাসের সংমিশ্রণ রয়েছে। এখানে আইডিগুলো পরবর্তীতে জাভাস্ক্রিপ্ট দ্বারা টেরারিয়ামের গাছপালার অবস্থান নিয়ন্ত্রণ করতে ব্যবহৃত হবে। তবে ক্লাসগুলো সব গাছপালাকে একটি নির্দিষ্ট স্টাইল দেয়।
মনে রাখবেন যে HTML মার্কআপে প্রতিটি গাছের একটি আইডি এবং ক্লাসের সংমিশ্রণ রয়েছে। এখানে আইডিগুলি পরে যোগ করা জাভাস্ক্রিপ্ট দ্বারা টেরারিয়াম গাছের অবস্থান ম্যানিপুলেট করতে ব্যবহৃত হয়। তবে ক্লাসগুলি সমস্ত গাছকে একটি নির্দিষ্ট স্টাইল দেয়।
```html
<div class="plant-holder">
@ -154,7 +154,7 @@ h1 {
</div>
```
আপনার `style.css` ফাইলে নিম্নলিখিত কোড যোগ করুন:
আপনার `style.css` ফাইলে নিম্নলিখিত যোগ করুন:
```CSS
.plant-holder {
@ -171,37 +171,37 @@ h1 {
}
```
এই অংশে উল্লেখযোগ্য হলো রিলেটিভ এবং অ্যাবসোলিউট পজিশনিংয়ের মিশ্রণ, যা আমরা পরবর্তী অংশে আলোচনা করব। উচ্চতাগুলো শতাংশে কীভাবে পরিচালিত হয়েছে তা লক্ষ্য করুন:
এই স্নিপেটে উল্লেখযোগ্য হল আপেক্ষিক এবং অ্যাবসোলিউট পজিশনিংয়ের মিশ্রণ, যা আমরা পরবর্তী বিভাগে আলোচনা করব। উচ্চতা শতাংশের মাধ্যমে পরিচালনার পদ্ধতি লক্ষ্য করুন:
আপনি প্ল্যান্ট হোল্ডারের উচ্চতা ১৩% সেট করেছেন, যা একটি ভালো সংখ্যা যাতে প্রতিটি উল্লম্ব কন্টেইনারে সব গাছপালা স্ক্রল ছাড়াই প্রদর্শিত হয়
আপনি গাছের হোল্ডারের উচ্চতা ১৩% সেট করেছেন, একটি ভালো সংখ্যা যা নিশ্চি কর যে সমস্ত গাছ প্রতিটি উল্লম্ব কন্টেইনারে প্রদর্শিত হয় স্ক্রোলিংয়ের প্রয়োজন ছাড়াই
প্ল্যান্ট হোল্ডারকে বাম দিকে সরানো হয়েছে যাতে গাছপালাগুলো তাদের কন্টেইনারের মধ্যে আরও কেন্দ্রীভূত হয়। ইমেজগুলোতে একটি বড় পরিমাণ স্বচ্ছ ব্যাকগ্রাউন্ড রয়েছে যাতে সেগুল আরও সহজে ড্র্যাগ করা যায়, তাই স্ক্রিনে আরও ভালোভাবে ফিট করার জন্য সেগুলো বাম দিকে ঠেলে দেওয়া হয়েছে
আপনি গাছের হোল্ডারকে বাম দিকে সরিয়ে দিয়েছেন যাতে গাছগুলি তাদের কন্টেইনারের মধ্যে আরও কেন্দ্রীভূত হয়। ছবিগুলির একটি বড় পরিমাণে স্বচ্ছ ব্যাকগ্রাউন্ড রয়েছে যাতে সেগুলি আরও সহজে ড্র্যাগ করা যায়, তাই স্ক্রিনে আরও ভালোভাবে ফিট করার জন্য সেগুলিকে বাম দিকে ঠেলে দেওয়া প্রয়োজন
তারপর, গাছপালাকে ১৫০% এর একটি সর্বোচ্চ প্রস্থ দেওয়া হয়েছে। এটি ব্রাউজার স্কেল করার সাথে সাথে এটি স্কেল ডাউন করতে দেয়। আপনার ব্রাউজারটি রিসাইজ করার চেষ্টা করুন; গাছপালাগুলো তাদের কন্টেইনারে থাকে কিন্তু ফিট করার জন্য স্কেল ডাউন করে।
তারপর, গাছটিকে ১৫০% এর একটি ম্যাক্স-উইডথ দেওয়া হয়েছে। এটি ব্রাউজার স্কেল ডাউন হওয়ার সাথে সাথে স্কেল ডাউন করতে দেয়। আপনার ব্রাউজারটি রিসাইজ করার চেষ্টা করুন; গাছগুলি তাদের কন্টেইনারে থাকে কিন্তু স্কেল ডাউন করে ফিট করার জন্য
এছাড়াও উল্লেখযোগ্য হল z-index-এর ব্যবহার, যা একটি এলিমেন্টের আপেক্ষিক উচ্চতা নিয়ন্ত্রণ করে (যাতে গাছপালাগুলো কন্টেইনারের উপরে থাকে এবং টেরারিয়ামের ভিতরে বসে থাকে বলে মনে হয়)।
এছাড়াও উল্লেখযোগ্য হল z-index-এর ব্যবহার, যা একটি এলিমেন্টের আপেক্ষিক উচ্চতা নিয়ন্ত্রণ করে (যাতে গাছগুলি কন্টেইনারের উপরে বসে এবং টেরারিয়ামের ভিতরে বসে থাকে বলে মনে হয়)।
✅ কেন আপনার প্ল্যান্ট হোল্ডার এবং প্ল্যান্ট CSS সিলেক্টর উভয়েরই প্রয়োজন?
✅ কেন আপনার একটি গাছের হোল্ডার এবং একটি গাছ CSS সিলেক্টর উভয়েরই প্রয়োজন?
## CSS পজিশনিং
পজিশন প্রপার্টিগুলোর (স্ট্যাটিক, রিলেটিভ, ফিক্সড, অ্যাবসোলিউট, এবং স্টিকি পজিশন) মিশ্রণ কিছুটা জটিল হতে পারে, তবে সঠিকভাবে করলে এটি আপনার পৃষ্ঠাগুলোর এলিমেন্টগুলোর উপর ভালো নিয়ন্ত্রণ দেয়।
পজিশন প্রপার্টি (স্ট্যাটিক, রিলেটিভ, ফিক্সড, অ্যাবসোলিউট, এবং স্টিকি পজিশন) মিশ্রিত করা একটু জটিল হতে পারে, তবে সঠিকভাবে করা হলে এটি আপনার পৃষ্ঠার এলিমেন্টগুলির উপর ভালো নিয়ন্ত্রণ দেয়।
অ্যাবসোলিউট পজিশনড এলিমেন্টগুলো তাদের নিকটতম পজিশনড পূর্বপুরুষদের তুলনায় পজিশনড হয়, এবং যদি কোনো পূর্বপুরুষ না থাকে, তবে এটি ডকুমেন্ট বডি অনুযায়ী পজিশন হয়।
অ্যাবসোলিউট পজিশন করা এলিমেন্টগুলি তাদের নিকটতম পজিশন করা পূর্বপুরুষদের তুলনায় পজিশন করা হয়, এবং যদি কোনো পূর্বপুরুষ না থাকে, এটি ডকুমেন্ট বডি অনুযায়ী পজিশন করা হয়।
রিলেটিভ পজিশনড এলিমেন্টগুলো তাদের প্রাথমিক অবস্থান থেকে CSS-এর নির্দেশনা অনুযায়ী তাদের অবস্থান সামঞ্জস্য করে
রিলেটিভ পজিশন করা এলিমেন্টগুলি তাদের প্রাথমিক অবস্থান থেকে দূরে সরিয়ে CSS-এর নির্দেশনা অনুযায়ী পজিশন করা হয়
আমাদের উদাহরণে, `plant-holder` একটি রিলেটিভ পজিশনড এলিমেন্ট যা একটি অ্যাবসোলিউট পজিশনড কন্টেইনারের মধ্যে পজিশনড। এর ফলে সাইডবার কন্টেইনারগুলো বাম এবং ডান দিকে পিন করা হয়, এবং প্ল্যান্ট-হোল্ডার নেস্টেড হয়, সাইডবারগুলোর মধ্যে নিজেকে সামঞ্জস্য করে, গাছপালাগুলোকে একটি উল্লম্ব সারিতে রাখার জন্য জায়গা দেয়।
আমাদের উদাহরণে, `plant-holder` একটি রিলেটিভ-পজিশন করা এলিমেন্ট যা একটি অ্যাবসোলিউট-পজিশন করা কন্টেইনারের মধ্যে পজিশন করা হয়েছে। এর ফলাফল হল যে সাইডবার কন্টেইনারগুলি বাম এবং ডান দিকে পিন করা হয়েছে, এবং plant-holder নেস্টেড, সাইডবারগুলির মধ্যে নিজেকে সামঞ্জস্য করে, গাছগুলিকে একটি উল্লম্ব সারিতে রাখার জন্য জায়গা দেয়।
> `plant` নিজেই একটি অ্যাবসোলিউট পজিশনিং পেয়েছে, যা এটি ড্র্যাগযোগ্য করতে প্রয়োজনীয়, যেমন আপনি পরবর্তী পাঠে আবিষ্কার করবেন।
> `plant` নিজে অ্যাবসোলিউট পজিশনিং পেয়েছে, যা এটি ড্র্যাগযোগ্য করতে প্রয়োজনীয়, যেমন আপনি পরবর্তী পাঠে আবিষ্কার করবেন।
✅ সাইড কন্টেইনার এবং প্ল্যান্ট-হোল্ডারের পজিশনিং টাইপগুলো পরিবর্তন করার চেষ্টা করুন। কী ঘটে?
✅ সাইড কন্টেইনার এবং plant-holder-এর পজিশনিং টাইপ পরিবর্তন করার চেষ্টা করুন। কী ঘটে?
## CSS লেআউট
এখন আপনি যা শিখেছেন তা ব্যবহার করে CSS দিয়ে টেরারিয়াম নিজেই তৈরি করবেন!
প্রথমে, `.terrarium` ডিভের চাইল্ডগুলোকে CSS ব্যবহার করে একটি গোলাকার আয়তাকারে স্টাইল করুন:
প্রথমে, `.terrarium` div-এর শিশুদের CSS ব্যবহার করে একটি গোলাকার আয়তক্ষেত্র হিসাবে স্টাইল করুন:
```CSS
.jar-walls {
@ -250,17 +250,17 @@ h1 {
}
```
এখানে শতাংশের ব্যবহার লক্ষ্য করুন। যদি আপনি আপনার ব্রাউজার স্কেল ডাউন করেন, আপনি দেখতে পােন কীভাবে জারটি স্কেল করে। এছাড়াও জার এলিমেন্টগুলর প্রস্থ এবং উচ্চতার শতাংশ এবং প্রতিটি এলিমেন্ট কীভাবে ভিউপোর্টের নিচে কেন্দ্রে পিন করা হয়েছে তা লক্ষ্য করুন।
এখানে শতাংশের ব্যবহার লক্ষ্য করুন। যদি আপনি আপনার ব্রাউজার স্কেল ডাউন করেন, আপনি দেখতে পােন কীভাবে জারটি স্কেল করে। এছাড়াও জার এলিমেন্টগুলির প্রস্থ এবং উচ্চতার শতাংশ এবং প্রতিটি এলিমেন্ট কীভাবে কেন্দ্রে অ্যাবসোলিউট পজিশন করা হয়েছে এবং ভিউপোর্টের নিচে পিন করা হয়েছে তা লক্ষ্য করুন।
আমরা `rem` ব্যবহার করছি বর্ডার-রেডিয়াসের জন্য, যা একটি ফন্ট-রিলেটিভ দৈর্ঘ্য। এই ধরনের রিলেটিভ মাপ সম্পর্কে আরও পড়ুন [CSS স্পেসিফিকেশনে](https://www.w3.org/TR/css-values-3/#font-relative-lengths)।
আমরা `rem` ব্যবহার করছি বর্ডার-রেডিয়াসের জন্য, একটি ফন্ট-রিলেটিভ দৈর্ঘ্য। এই ধরনের আপেক্ষিক পরিমাপ সম্পর্কে আরও পড়ুন [CSS স্পেসিফিকেশনে](https://www.w3.org/TR/css-values-3/#font-relative-lengths)।
✅ জারর রঙ এবং অপাসিটি পরিবর্তন করার চেষ্টা করুন বনাম মাটির। কী ঘটে? কেন?
✅ জার এবং মাটির রঙ এবং অপাসিটি পরিবর্তন করার চেষ্টা করুন। কী ঘটে? কেন?
---
## 🚀চ্যালেঞ্জ
জারের বাম নিচের এলাকায় একটি 'বাবল' শাইন যোগ করুন যাতে এটি আরও কাচের মতো দেখায়। আপনি `.jar-glossy-long` এবং `.jar-glossy-short` স্টাইল করবেন যাতে এটি প্রতিফলিত শাইনের মতো দেখায়। এটি দেখতে এমন হবে:
জারের বাম নিচের এলাকায় একটি 'বাবল' শাইন যোগ করুন যাতে এটি আরও কাচের মতো দেখায়। আপনি `.jar-glossy-long` এবং `.jar-glossy-short` স্টাইল করবেন যাতে এটি প্রতিফলিত শাইনের মতো দেখায়। এটি দেখতে এমন হবে:
![শেষ টেরারিয়াম](../../../../translated_images/terrarium-final.2f07047ffc597d0a06b06cab28a77801a10dd12fdb6c7fc630e9c40665491c53.bn.png)
@ -272,11 +272,13 @@ h1 {
## পর্যালোচনা ও স্ব-অধ্যয়ন
CSS দেখতে সহজ মনে হতে পারে, তবে সব ব্রাউজার এবং সব স্ক্রিন সাইজের জন্য একটি অ্যাপ নিখুঁতভাবে স্টাইল করার সময় অনেক চ্যালেঞ্জ থাকে। CSS-Grid এবং Flexbox হলো এমন কিছু টুল যা কাজটিকে আরও কাঠামোগত এবং নির্ভরযোগ্য করে তুলতে তৈরি করা হয়েছে। এই টুলগুল সম্পর্কে জানুন [Flexbox Froggy](https://flexboxfroggy.com/) এবং [Grid Garden](https://codepip.com/games/grid-garden/) খেলে।
CSS সহজ মনে হতে পারে, তবে সমস্ত ব্রাউজার এবং স্ক্রিন সাইজের জন্য একটি অ্যাপ নিখুঁতভাবে স্টাইল করার সময় অনেক চ্যালেঞ্জ থাকে। CSS-Grid এবং Flexbox এমন টুল যা কাজটিকে একটু বেশি কাঠামোগত এবং নির্ভরযোগ্য করে তুলতে তৈরি করা হয়েছে। এই টুলগুলি সম্পর্কে জানুন [Flexbox Froggy](https://flexboxfroggy.com/) এবং [Grid Garden](https://codepip.com/games/grid-garden/) খেলে।
## অ্যাসাইনমেন্ট
[CSS পুনর্গঠন](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। এর মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।

@ -1,57 +1,57 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "30f8903a1f290e3d438dc2c70fe60259",
"translation_date": "2025-08-25T21:16:31+00:00",
"original_hash": "61c14b27044861e5e69db35dd52c4403",
"translation_date": "2025-08-28T23:04:10+00:00",
"source_file": "3-terrarium/3-intro-to-DOM-and-closures/README.md",
"language_code": "bn"
}
-->
# টেরারিয়াম প্রকল্প পার্ট ৩: DOM ম্যানিপুলেশন এবং একটি ক্লোজার
# টেরারিয়াম প্রকল্প পার্ট ৩: DOM ম্যানিপুলেশন এবং ক্লোজার
![DOM এবং একটি ক্লোজার](../../../../translated_images/webdev101-js.10280393044d7eaaec7e847574946add7ddae6be2b2194567d848b61d849334a.bn.png)
![DOM এবং ক্লোজার](../../../../translated_images/webdev101-js.10280393044d7eaaec7e847574946add7ddae6be2b2194567d848b61d849334a.bn.png)
> স্কেচনোট: [Tomomi Imura](https://twitter.com/girlie_mac)
## প্রাক-লেকচার কুইজ
## প্রি-লেকচার কুইজ
[প্রাক-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/19)
[প্রি-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/19)
### ভূমিকা
DOM বা "ডকুমেন্ট অবজেক্ট মডেল" ম্যানিপুলেশন ওয়েব ডেভেলপমেন্টের একটি গুরুত্বপূর্ণ দিক। [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction) অনুসারে, "ডকুমেন্ট অবজেক্ট মডেল (DOM) হলো ওয়েবের একটি ডকুমেন্টের কাঠামো এবং বিষয়বস্তুর প্রতিনিধিত্বকারী ডেটা।" ওয়েবে DOM ম্যানিপুলেশন সংক্রান্ত চ্যালেঞ্জগুলো প্রায়ই জাভাস্ক্রিপ্ট ফ্রেমওয়ার্ক ব্যবহারর কারণ হয়ে দাঁড়ায়, তবে আমরা এখানে ভ্যানিলা জাভাস্ক্রিপ্ট ব্যবহার করেই এটি পরিচালনা করব!
DOM বা "ডকুমেন্ট অবজেক্ট মডেল" ম্যানিপুলেট করা ওয়েব ডেভেলপমেন্টের একটি গুরুত্বপূর্ণ দিক। [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction) অনুসারে, "ডকুমেন্ট অবজেক্ট মডেল (DOM) হলো ওয়েবের একটি ডকুমেন্টের কাঠামো এবং বিষয়বস্তুর প্রতিনিধিত্বকারী ডেটা।" DOM ম্যানিপুলেশন নিয়ে চ্যালেঞ্জগুলোই প্রায়শই জাভাস্ক্রিপ্ট ফ্রেমওয়ার্ক ব্যবহার করার কারণ হয়ে দাঁড়ায়, তবে আমরা এখানে ভ্যানিলা জাভাস্ক্রিপ্ট দিয়ে কাজ করব!
এছাড়াও, এই পাঠে [জাভাস্ক্রিপ্ট ক্লোজার](https://developer.mozilla.org/docs/Web/JavaScript/Closures) ধারণাটি পরিচিত করানো হবে। এটি এমন একটি ফাংশন যা আরেকটি ফাংশনের মধ্যে আবদ্ধ থাকে, ফলে অভ্যন্তরীণ ফাংশনটি বাইরের ফাংশনের স্কোপে অ্যাক্সেস পায়।
এছাড়াও, এই পাঠে [জাভাস্ক্রিপ্ট ক্লোজার](https://developer.mozilla.org/docs/Web/JavaScript/Closures) ধারণাটি পরিচয় করানো হবে। ক্লোজার হলো একটি ফাংশন যা অন্য একটি ফাংশনের মধ্যে আবদ্ধ থাকে, যাতে অভ্যন্তরীণ ফাংশন বাইরের ফাংশনের স্কোপে অ্যাক্সেস পায়।
> জাভাস্ক্রিপ্ট ক্লোজার একটি বিস্তৃত এবং জটিল বিষয়। এই পাঠে আমরা এর মৌলিক ধারণা নিয়ে আলোচনা করব। টেরারিয়ামের কোডে আপনি একটি ক্লোজার দেখতে পাবেন: একটি অভ্যন্তরীণ ফাংশন এবং একটি বাইরের ফাংশন এমনভাবে তৈরি করা হয়েছে যাতে অভ্যন্তরীণ ফাংশনটি বাইরের ফাংশনের স্কোপে অ্যাক্সেস পায়। এই বিষয়ে আরও বিস্তারিত জানতে [বিস্তৃত ডকুমেন্টেশন](https://developer.mozilla.org/docs/Web/JavaScript/Closures) দেখুন।
> জাভাস্ক্রিপ্ট ক্লোজার একটি বিশাল এবং জটিল বিষয়। এই পাঠে আমরা এর মৌলিক ধারণা নিয়ে আলোচনা করব। টেরারিয়ামের কোডে আপনি একটি ক্লোজার দেখতে পাবেন: একটি অভ্যন্তরীণ ফাংশন এবং একটি বাইরের ফাংশন এমনভাবে তৈরি করা হয়েছে যাতে অভ্যন্তরীণ ফাংশন বাইরের ফাংশনের স্কোপে অ্যাক্সেস পায়। এই বিষয়ে আরও বিস্তারিত জানতে [বিস্তৃত ডকুমেন্টেশন](https://developer.mozilla.org/docs/Web/JavaScript/Closures) দেখুন।
আমরা DOM ম্যানিপুলেশনের জন্য একটি ক্লোজার ব্যবহার করব।
আমরা DOM ম্যানিপুলেট করতে একটি ক্লোজার ব্যবহার করব।
DOM-কে একটি গাছের মতো ভাবুন, যা একটি ওয়েব পেজ ডকুমেন্টকে ম্যানিপুলেট করার সমস্ত উপায় উপস্থাপন করে। বিভিন্ন API (অ্যাপ্লিকেশন প্রোগ্রাম ইন্টারফেস) তৈরি করা হয়েছে যাতে প্রোগ্রামাররা তাদের পছন্দের প্রোগ্রামিং ভাষা ব্যবহার করে DOM-এ অ্যাক্সেস করতে এবং এটি সম্পাদনা, পরিবর্তন, পুনর্বিন্যাস এবং পরিচালনা করতে পারে।
DOM-কে একটি গাছের মতো ভাবুন, যা একটি ওয়েব পেজ ডকুমেন্টকে ম্যানিপুলেট করার বিভিন্ন উপায় উপস্থাপন করে। বিভিন্ন API (অ্যাপ্লিকেশন প্রোগ্রাম ইন্টারফেস) তৈরি করা হয়েছে যাতে প্রোগ্রামাররা তাদের পছন্দের প্রোগ্রামিং ভাষা ব্যবহার করে DOM-এ অ্যাক্সেস করতে পারে এবং এটি সম্পাদনা, পরিবর্তন, পুনর্বিন্যাস এবং পরিচালনা করতে পারে।
![DOM গাছের উপস্থাপনা](../../../../translated_images/dom-tree.7daf0e763cbbba9273f9a66fe04c98276d7d23932309b195cb273a9cf1819b42.bn.png)
> DOM এবং এর সাথে সম্পর্কিত HTML মার্কআপের একটি উপস্থাপনা। [Olfa Nasraoui](https://www.researchgate.net/publication/221417012_Profile-Based_Focused_Crawler_for_Social_Media-Sharing_Websites) থেকে নেওয়া
> DOM এবং HTML মার্কআপের একটি উপস্থাপনা যা এটি রেফারেন্স করে। [Olfa Nasraoui](https://www.researchgate.net/publication/221417012_Profile-Based_Focused_Crawler_for_Social_Media-Sharing_Websites) থেকে।
এই পাঠে, আমরা আমাদের ইন্টারেক্টিভ টেরারিয়াম প্রকল্পটি সম্পন্ন করব, যেখানে ব্যবহারকারী পৃষ্ঠার গাছপালাগুলো ম্যানিপুলেট করতে পারবে।
এই পাঠে, আমরা আমাদের ইন্টারেক্টিভ টেরারিয়াম প্রকল্প সম্পন্ন করব, যেখানে ব্যবহারকারী পেজে থাকা গাছপালা ম্যানিপুলেট করতে পারবে।
### প্রয়োজনীয়তা
### পূর্বশর্ত
আপনার টেরারিয়ামের HTML এবং CSS তৈরি করা থাকা উচিত। এই পাঠের শেষে আপনি গাছপালাগুলো টেরারিয়ামে টেনে নিয়ে যেতে এবং সেখান থেকে সরাতে সক্ষম হবেন।
আপনার টেরারিয়ামের HTML এবং CSS তৈরি করা উচিত। এই পাঠের শেষে আপনি গাছপালাগুলো টেরারিয়ামে ঢোকানো এবং বের করার জন্য ড্র্যাগ করতে সক্ষম হবেন।
### কাজ
আপনার টেরারিয়াম ফোল্ডারে একটি নতুন ফাইল তৈরি করুন যার নাম `script.js`। এই ফাইলটি `<head>` সেকশনে ইমপোর্ট করুন:
আপনার টেরারিয়াম ফোল্ডারে একটি নতুন ফাইল তৈরি করুন `script.js` নামে। এই ফাইলটি `<head>` সেকশনে ইমপোর্ট করুন:
```html
<script src="./script.js" defer></script>
```
> নোট: একটি এক্সটার্নাল জাভাস্ক্রিপ্ট ফাইল HTML ফাইলে ইমপোর্ট করার সময় `defer` ব্যবহার করুন যাতে জাভাস্ক্রিপ্টটি HTML ফাইলটি পুরোপুরি লোড হওয়ার পরেই কার্যকর হয়। আপনি `async` অ্যাট্রিবিউটও ব্যবহার করতে পারেন, যা স্ক্রিপ্টটিকে HTML ফাইলটি পার্স করার সময় কার্যকর হতে দেয়, তবে আমাদের ক্ষেত্রে, ড্র্যাগ স্ক্রিপ্ট কার্যকর হওয়ার আগে HTML উপাদানগুলো সম্পূর্ণ উপলব্ধ থাকা গুরুত্বপূর্ণ।
> নোট: HTML ফাইল সম্পূর্ণ লোড হওয়ার পর জাভাস্ক্রিপ্ট চালানোর জন্য `defer` ব্যবহার করুন। আপনি `async` অ্যাট্রিবিউটও ব্যবহার করতে পারেন, যা HTML ফাইল পার্স করার সময় স্ক্রিপ্ট চালানোর অনুমতি দেয়। তবে আমাদের ক্ষেত্রে, ড্র্যাগ স্ক্রিপ্ট চালানোর আগে HTML এলিমেন্টগুলো সম্পূর্ণ উপলব্ধ থাকা গুরুত্বপূর্ণ।
---
## DOM উপাদানগুলো
## DOM এলিমেন্টগুলো
প্রথমে আপনাকে DOM-এ ম্যানিপুলেট করতে চান এমন উপাদানগুলোর রেফারেন্স তৈরি করতে হবে। আমাদের ক্ষেত্রে, এগুলো হলো সাইডবারে থাকা ১৪টি গাছপালা।
প্রথমে আপনাকে DOM-এ ম্যানিপুলেট করতে চান এমন এলিমেন্টগুলোর রেফারেন্স তৈরি করতে হবে। আমাদের ক্ষেত্রে, এগুলো হলো সাইডবারে অপেক্ষমাণ ১৪টি গাছপালা।
### কাজ
@ -72,15 +72,15 @@ dragElement(document.getElementById('plant13'));
dragElement(document.getElementById('plant14'));
```
এখানে কী হচ্ছে? আপনি ডকুমেন্টটি রেফারেন্স করছেন এবং এর DOM-এর মধ্যে একটি নির্দিষ্ট Id সহ একটি উপাদান খুঁজছেন। মনে আছে প্রথম HTML পাঠে আপনি প্রতিটি গাছপালার ছবিতে আলাদা Id দিয়েছিলেন (`id="plant1"`)। এখন আপনি সেই প্রচেষ্টার ফলাফল ব্যবহার করবেন। প্রতিটি উপাদান চিহ্নিত করার পর, আপনি সেই আইটেমটি একটি `dragElement` নামক ফাংশনে পাঠাচ্ছেন, যা আপনি কিছুক্ষণের মধ্যে তৈরি করবেন। এর ফলে HTML-এর উপাদানটি এখন ড্র্যাগ-সক্ষম হয়ে যাবে, বা শীঘ্রই হবে।
এখানে কী হচ্ছে? আপনি ডকুমেন্ট রেফারেন্স করছেন এবং এর DOM-এ একটি নির্দিষ্ট Id সহ এলিমেন্ট খুঁজছেন। মনে করুন, HTML-এর প্রথম পাঠে আপনি প্রতিটি গাছপালার ইমেজে আলাদা Id দিয়েছিলেন (`id="plant1"`)। এখন আপনি সেই প্রচেষ্টার ব্যবহার করবেন। প্রতিটি এলিমেন্ট শনাক্ত করার পর, আপনি সেই আইটেমকে একটি ফাংশনে (`dragElement`) পাঠাচ্ছেন, যা আপনি কিছুক্ষণের মধ্যে তৈরি করবেন। এইভাবে HTML-এর এলিমেন্টটি এখন ড্র্যাগ-সক্ষম হয়ে উঠবে।
✅ আমরা কে Id দিয়ে উপাদানগুলো রেফারেন্স করি? CSS ক্লাস দিয়ে কেন নয়? এই প্রশ্নের উত্তর পেতে আপনি CSS-এর পূর্ববর্তী পাঠটি দেখতে পারেন
কেন আমরা এলিমেন্টগুলোকে Id দিয়ে রেফারেন্স করি? CSS ক্লাস দিয়ে কেন নয়? CSS-এর পূর্ববর্তী পাঠটি দেখুন এই প্রশ্নের উত্তর খুঁজতে
---
## ক্লোজার
এখন আপনি `dragElement` ক্লোজার তৈরি করতে প্রস্তুত, যা একটি বাইরের ফাংশন যা একটি বা একাধিক অভ্যন্তরীণ ফাংশনকে আবদ্ধ করে (আমাদের ক্ষেত্রে, তিনটি থাকবে)
এখন আপনি `dragElement` ক্লোজার তৈরি করতে প্রস্তুত, যা একটি বাইরের ফাংশন যা একটি বা একাধিক অভ্যন্তরীণ ফাংশনকে আবদ্ধ করে।
ক্লোজার তখনই কার্যকর হয় যখন এক বা একাধিক ফাংশনকে বাইরের ফাংশনের স্কোপে অ্যাক্সেস করতে হয়। একটি উদাহরণ দেখুন:
@ -96,13 +96,13 @@ displayCandy();
console.log(candy)
```
এই উদাহরণে, `displayCandy` ফাংশনটি এমন একটি ফাংশনকে ঘিরে রাখে যা একটি নতুন ক্যান্ডি টাইপকে একটি অ্যারের মধ্যে ঠেলে দেয় যা ইতিমধ্যে ফাংশনে বিদ্যমান। আপনি যদি এই কোডটি চালান, তবে `candy` অ্যারে অপরিবর্তিত থাকবে, কারণ এটি একটি লোকাল ভেরিয়েবল (ক্লোজারের জন্য লোকাল)।
এই উদাহরণে, `displayCandy` ফাংশন একটি ফাংশনকে ঘিরে রাখে, যা একটি অ্যারে-তে নতুন ক্যান্ডি টাইপ যোগ করে। যদি আপনি এই কোড চালান, তাহলে `candy` অ্যারে অপ্রকাশিত থাকবে, কারণ এটি একটি লোকাল ভ্যারিয়েবল (ক্লোজারের লোকাল স্কোপে সীমাবদ্ধ)।
✅ কীভাবে আপনি `candy` অ্যারেটিকে অ্যাক্সেসযোগ্য করতে পারেন? এটি ক্লোজারের বাইরে সরিয়ে দেখুন। এভাবে, অ্যারেটি গ্লোবাল হয়ে যাবে, এবং ক্লোজারের লোকাল স্কোপে সীমাবদ্ধ থাকবে না।
✅ কীভাবে আপনি `candy` অ্যারে-কে অ্যাক্সেসযোগ্য করবেন? এটি ক্লোজারের বাইরে সরিয়ে দেখুন। এভাবে, অ্যারে গ্লোবাল হয়ে যাবে, এবং ক্লোজারের লোকাল স্কোপে সীমাবদ্ধ থাকবে না।
### কাজ
`script.js`-এ উপাদান ঘোষণাগুলোর নিচে একটি ফাংশন তৈরি করুন:
`script.js`-এ এলিমেন্ট ডিক্লারেশনের নিচে একটি ফাংশন তৈরি করুন:
```javascript
function dragElement(terrariumElement) {
@ -115,17 +115,17 @@ function dragElement(terrariumElement) {
}
```
`dragElement` তার `terrariumElement` অবজেক্টটি স্ক্রিপ্টের শীর্ষে থাকা ঘোষণাগুলো থেকে পায়। এরপর, আপনি কিছু লোকাল পজিশনকে `0` এ সেট করেন সেই অবজেক্টের জন্য যা ফাংশনে পাস করা হয়েছে। এগুলো হলো লোকাল ভেরিয়েবল, যা প্রতিটি উপাদানের জন্য ম্যানিপুলেট করা হবে যখন আপনি ক্লোজারের মধ্যে ড্র্যাগ এবং ড্রপ কার্যকারিতা যোগ করবেন। টেরারিয়ামটি এই ড্র্যাগ করা উপাদানগুলো দ্বারা পূর্ণ হবে, তাই অ্যাপ্লিকেশনটি তাদের অবস্থান ট্র্যাক করতে হবে।
`dragElement` তার `terrariumElement` অবজেক্টটি স্ক্রিপ্টের শীর্ষে থাকা ডিক্লারেশন থেকে পায়। এরপর, আপনি কিছু লোকাল পজিশন `0` সেট করেন ফাংশনে পাস করা অবজেক্টের জন্য। এগুলো হলো লোকাল ভ্যারিয়েবল, যা প্রতিটি এলিমেন্টের জন্য ম্যানিপুলেট করা হবে যখন আপনি ক্লোজারের মধ্যে ড্র্যাগ এবং ড্রপ ফাংশনালিটি যোগ করবেন। টেরারিয়ামটি এই ড্র্যাগ করা এলিমেন্টগুলো দ্বারা পূর্ণ হবে, তাই অ্যাপ্লিকেশনটি তাদের অবস্থান ট্র্যাক করতে হবে।
এছাড়াও, `terrariumElement` যা এই ফাংশনে পাস করা হয়েছে, সেটি একটি `pointerdown` ইভেন্টে অ্যাসাইন করা হয়েছে, যা [ওয়েব API](https://developer.mozilla.org/docs/Web/API)-এর অংশ যা DOM ম্যানেজমেন্টে সহায়ক`onpointerdown` তখনই ফায়ার হয় যখন একটি বোতাম চাপা হয়, বা আমাদের ক্ষেত্রে, একটি ড্র্যাগযোগ্য উপাদান স্পর্শ করা হয়। এই ইভেন্ট হ্যান্ডলার [ওয়েব এবং মোবাইল ব্রাউজার](https://caniuse.com/?search=onpointerdown)-এ কাজ করে, কিছু ব্যতিক্রম ছাড়া।
এছাড়াও, `terrariumElement`-কে এই ফাংশনে পাস করা হয় এবং এটি একটি `pointerdown` ইভেন্টে অ্যাসাইন করা হয়, যা [ওয়েব API](https://developer.mozilla.org/docs/Web/API)-এর অংশ। `onpointerdown` তখনই ফায়ার হয় যখন একটি বাটন চাপা হয়, বা আমাদের ক্ষেত্রে, একটি ড্র্যাগযোগ্য এলিমেন্ট স্পর্শ করা হয়। এই ইভেন্ট হ্যান্ডলার [ওয়েব এবং মোবাইল ব্রাউজার](https://caniuse.com/?search=onpointerdown)-এ কাজ করে, কিছু ব্যতিক্রম ছাড়া।
✅ [ইভেন্ট হ্যান্ডলার `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) অনেক বেশি ব্রাউজার সমর্থন পায়; এখানে কেন এটি ব্যবহার করবেন না? আপনি এখানে তৈরি করতে চাওয়া সুনির্দিষ্ট স্ক্রিন ইন্টারঅ্যাকশনের কথা ভাবুন।
✅ [ইভেন্ট হ্যান্ডলার `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) অনেক বেশি ক্রস-ব্রাউজার সাপোর্ট পায়; এখানে কেন এটি ব্যবহার করবেন না? ভাবুন আপনি ঠিক কী ধরনের স্ক্রিন ইন্টারঅ্যাকশন তৈরি করতে চান।
---
## পয়েন্টারড্র্যাগ ফাংশন
## Pointerdrag ফাংশন
`terrariumElement` এখন ড্র্যাগ করার জন্য প্রস্তুত; যখন `onpointerdown` ইভেন্টটি ফায়ার হয়, তখন `pointerDrag` ফাংশনটি আহ্বান করা হয়। এই লাইনটির ঠিক নিচে ফাংশনটি যোগ করুন: `terrariumElement.onpointerdown = pointerDrag;`:
`terrariumElement` এখন ড্র্যাগ করার জন্য প্রস্তুত; যখন `onpointerdown` ইভেন্ট ফায়ার হয়, তখন `pointerDrag` ফাংশনটি চালু হয়। এই লাইনটির ঠিক নিচে ফাংশনটি যোগ করুন: `terrariumElement.onpointerdown = pointerDrag;`:
### কাজ
@ -138,32 +138,31 @@ function pointerDrag(e) {
}
```
এখানে অনেক কিছু ঘটে। প্রথমে, আপনি `e.preventDefault();` ব্যবহার করে `pointerdown`-এ সাধারণত ঘটে এমন ডিফল্ট ইভেন্টগুলোকে প্রতিরোধ করেন। এভাবে আপনি ইন্টারফেসের আচরণের উপর আরও নিয়ন্ত্রণ পান।
এখানে কয়েকটি বিষয় ঘটে। প্রথমে, আপনি `e.preventDefault();` ব্যবহার করে pointerdown-এ সাধারণত ঘটে এমন ডিফল্ট ইভেন্টগুলো বন্ধ করেন। এইভাবে আপনি ইন্টারফেসের আচরণের উপর আরও নিয়ন্ত্রণ পান।
> পুরো স্ক্রিপ্ট ফাইলটি তৈরি করার পর এই লাইনটি বাদ দিয়ে দেখুন কী হয়?
> স্ক্রিপ্ট ফাইলটি সম্পূর্ণ তৈরি করার পর এই লাইনটি সরিয়ে দেখুন কী ঘটে?
দ্বিতীয়ত, `index.html` একটি ব্রাউজার উইন্ডোতে খুলুন এবং ইন্টারফেসটি পরিদর্শন করুন। যখন আপনি একটি গাছপালা ক্লিক করেন, তখন আপনি দেখতে পাবেন কীভাবে 'e' ইভেন্টটি ক্যাপচার করা হয়। ইভেন্টটি বিশ্লেষণ করে দেখুন কত তথ্য একটি `pointerdown` ইভেন্ট দ্বারা সংগ্রহ করা হয়!
দ্বিতীয়ত, `index.html` একটি ব্রাউজার উইন্ডোতে খুলুন এবং ইন্টারফেসটি ইন্সপেক্ট করুন। যখন আপনি একটি গাছপালা ক্লিক করেন, তখন আপনি দেখতে পাবেন কীভাবে 'e' ইভেন্টটি ক্যাপচার করা হয়। ইভেন্টটি বিশ্লেষণ করুন এবং দেখুন pointerdown ইভেন্টে কত তথ্য সংগ্রহ করা হয়!
পরবর্তী ধাপে, লক্ষ্য করুন কীভাবে লোকাল ভেরিয়েবল `pos3` এবং `pos4`-কে `e.clientX`-এ সেট করা হয়েছে আপনি ইন্সপেকশন প্যানেলে `e` মানগুলো খুঁজে পেতে পারেন। এই মানগুলো গাছপালার x এবং y কোঅর্ডিনেটগুলো ক্যাপচার করে যখন আপনি এটি ক্লিক বা স্পর্শ করেন। আপনি গাছপালাগুলোর আচরণের উপর সূক্ষ্ম নিয়ন্ত্রণ রাখতে চান, তাই তাদের কোঅর্ডিনেটগুলো ট্র্যাক করেন
এরপর, লক্ষ্য করুন কীভাবে লোকাল ভ্যারিয়েবল `pos3` এবং `pos4`-কে `e.clientX`-এ সেট করা হয়। ইন্সপেকশন প্যানেলে আপনি `e` মানগুলো খুঁজে পেতে পারেন। এই মানগুলো গাছপালার x এবং y কোঅর্ডিনেটগুলো ক্যাপচার করে যখন আপনি এটি ক্লিক বা স্পর্শ করেন। গাছপালার আচরণ সূক্ষ্মভাবে নিয়ন্ত্রণ করতে হলে আপনাকে তাদের কোঅর্ডিনেটগুলো ট্র্যাক করতে হবে
✅ এটি কি আরও পরিষ্কার হচ্ছে কেন পুরো অ্যাপটি একটি বড় ক্লোজার দিয়ে তৈরি করা হয়েছে? যদি তা না হতো, তাহলে কীভাবে আপনি ১৪টি ড্র্যাগযোগ্য গাছপালার প্রতিটির স্কোপ বজায় রাখতেন?
✅ এটি কি আরও পরিষ্কার হচ্ছে কেন পুরো অ্যাপটি একটি বড় ক্লোজার দিয়ে তৈরি করা হয়েছে? যদি না হয়, তাহলে কীভাবে আপনি ১৪টি ড্র্যাগযোগ্য গাছপালার স্কোপ বজায় রাখবেন?
`pos4 = e.clientY`-এর নিচে আরও দুটি পয়েন্টার ইভেন্ট ম্যানিপুলেশন যোগ করে প্রাথমিক ফাংশনটি সম্পূর্ণ করুন:
প্রাথমিক ফাংশনটি সম্পূর্ণ করতে আরও দুটি pointer ইভেন্ট ম্যানিপুলেশন যোগ করুন `pos4 = e.clientY`-এর নিচে:
```html
document.onpointermove = elementDrag;
document.onpointerup = stopElementDrag;
```
এখন আপনি নির্দেশ করছেন যে গাছপালাটি pointer-এর সাথে ড্র্যাগ করা হবে এবং pointer ছেড়ে দিলে ড্র্যাগিং বন্ধ হবে। `onpointermove` এবং `onpointerup` একই API-এর অংশ যা `onpointerdown`। ইন্টারফেস এখন এরর ছুঁড়বে কারণ আপনি এখনও `elementDrag` এবং `stopElementDrag` ফাংশনগুলো সংজ্ঞায়িত করেননি, তাই এগুলো তৈরি করুন।
এখন আপনি নির্দেশ করছেন যে আপনি গাছপালাটিকে পয়েন্টারের সাথে টেনে নিয়ে যেতে চান এবং গাছপালাটি ছেড়ে দিলে ড্র্যাগিং অঙ্গভঙ্গি থেমে যাবে। `onpointermove` এবং `onpointerup` একই API-এর অংশ যা `onpointerdown`। ইন্টারফেস এখন ত্রুটি নিক্ষেপ করবে কারণ আপনি এখনও `elementDrag` এবং `stopElementDrag` ফাংশনগুলো সংজ্ঞায়িত করেননি, তাই এগুলো পরবর্তী ধাপে তৈরি করুন।
## elementDrag এবং stopElementDrag ফাংশনগুলো
## `elementDrag` এবং `stopElementDrag` ফাংশন
আপনি দুটি অভ্যন্তরীণ ফাংশন যোগ করে আপনার ক্লোজার সম্পূর্ণ করবেন যা গাছপালা ড্র্যাগ করার সময় এবং ড্র্যাগ বন্ধ করার সময় কী হবে তা পরিচালনা করবে। আপনি এমন একটি আচরণ চান যেখানে আপনি যেকোনো সময় যেকোনো গাছপালা টেনে নিয়ে যেতে পারেন এবং এটি স্ক্রিনের যেকোনো জায়গায় রাখতে পারেন। এই ইন্টারফেসটি বেশ নমনীয় (উদাহরণস্বরূপ, এখানে কোনো ড্রপ জোন নেই) যাতে আপনি আপনার টেরারিয়ামটি নিজের মতো করে ডিজাইন করতে পারেন।
আপনার ক্লোজার সম্পূর্ণ করতে দুটি অভ্যন্তরীণ ফাংশন যোগ করবেন, যা গাছপালা ড্র্যাগ করার সময় এবং ড্র্যাগ বন্ধ করার সময় কী হবে তা পরিচালনা করবে। আপনি চান যে ব্যবহারকারী যেকোনো সময় যেকোনো গাছপালা ড্র্যাগ করতে এবং স্ক্রিনে যেকোনো জায়গায় রাখতে পারবে। এই ইন্টারফেসটি বেশ অ-নির্দেশনামূলক (যেমন কোনো ড্রপ জোন নেই) যাতে আপনি আপনার টেরারিয়ামটি নিজের মতো করে ডিজাইন করতে পারেন।
### কাজ
`pointerDrag`-এর বন্ধনী বন্ধ হওয়ার ঠিক পর`elementDrag` ফাংশনটি যোগ করুন:
`pointerDrag`-এর বন্ধনী শেষ`elementDrag` ফাংশনটি যোগ করুন:
```javascript
function elementDrag(e) {
@ -176,18 +175,17 @@ function elementDrag(e) {
terrariumElement.style.left = terrariumElement.offsetLeft - pos1 + 'px';
}
```
এই ফাংশনে, আপনি প্রাথমিক পজিশন ১--এ অনেক পরিবর্তন করেন, যা বাইরের ফাংশনে লোকাল ভ্যারিয়েবল হিসেবে সেট করা হয়েছিল। এখানে কী হচ্ছে?
এই ফাংশনে, আপনি প্রাথমিক অবস্থান ১--কে অনেক সম্পাদনা করেন যা আপনি বাইরের ফাংশনে লোকাল ভেরিয়েবল হিসেবে সেট করেছিলেন। এখানে কী হচ্ছে?
যখন আপনি ড্র্যাগ করেন, তখন আপনি `pos1`-কে পুনরায় অ্যাসাইন করেন, এটি `pos3` (যা আপনি আগে `e.clientX` হিসেবে সেট করেছিলেন) এবং বর্তমান `e.clientX` মানের মধ্যে পার্থক্যের সমান করে। আপনি `pos2`-এর জন্য একই অপারেশন করেন। এরপর, আপনি `pos3` এবং `pos4`-কে উপাদানের নতুন X এবং Y কোঅর্ডিনেটে রিসেট করেন। আপনি ড্র্যাগ করার সময় কনসোলে এই পরিবর্তনগুলো দেখতে পারেন। এরপর, আপনি গাছপালার CSS স্টাইল ম্যানিপুলেট করেন যাতে এর নতুন অবস্থান সেট করা যায়, যা `pos1` এবং `pos2`-এর নতুন অবস্থানের উপর ভিত্তি করে গণনা করা হয়, এর অফসেটের সাথে তুলনা করে।
ড্র্যাগ করার সময়, আপনি `pos1`-কে পুনরায় অ্যাসাইন করেন, যা `pos3` (যা আগে `e.clientX` হিসেবে সেট করা হয়েছিল) থেকে বর্তমান `e.clientX` মান বিয়োগ করে। একই অপারেশন `pos2`-এর জন্য করা হয়। এরপর, আপনি `pos3` এবং `pos4`-কে এলিমেন্টের নতুন X এবং Y কোঅর্ডিনেট হিসেবে রিসেট করেন। আপনি ড্র্যাগ করার সময় কনসোলে এই পরিবর্তনগুলো দেখতে পারেন। এরপর, আপনি গাছপালার CSS স্টাইল ম্যানিপুলেট করেন, যাতে তার নতুন অবস্থান `pos1` এবং `pos2`-এর নতুন অবস্থানের উপর ভিত্তি করে সেট করা হয়।
> `offsetTop` এবং `offsetLeft` হলো CSS প্রোপার্টি যা একটি উপাদানের অবস্থান সেট করে তার প্যারেন্টের উপর ভিত্তি করে; এর প্যারেন্ট যেকোনো উপাদান হতে পারে যা `static` হিসেবে পজিশন করা হয়নি।
> `offsetTop` এবং `offsetLeft` হলো CSS প্রপার্টি, যা একটি এলিমেন্টের অবস্থান তার প্যারেন্টের উপর ভিত্তি করে সেট করে; এর প্যারেন্ট যেকোনো এলিমেন্ট হতে পারে যা `static` হিসেবে পজিশন করা হয়নি।
এই অবস্থান পুনর্গণনা টেরারিয়াম এবং এর গাছপালাগুলোর আচরণ সূক্ষ্মভাবে টিউন করতে দেয়
এই অবস্থান পুনগণনা টেরারিয়াম এবং এর গাছপালার আচরণ সূক্ষ্মভাবে নিয়ন্ত্রণ করতে সাহায্য করে
### কাজ
ইন্টারফেসটি সম্পূর্ণ করতে চূড়ান্ত কাজ হলো `stopElementDrag` ফাংশনটি `elementDrag`-এর বন্ধনী বন্ধ হওয়ার পরে যোগ করা:
ইন্টারফেস সম্পূর্ণ করতে `stopElementDrag` ফাংশনটি `elementDrag`-এর বন্ধনী শেষে যোগ করুন:
```javascript
function stopElementDrag() {
@ -196,27 +194,27 @@ function stopElementDrag() {
}
```
এই ছোট ফাংশনটি `onpointerup` এবং `onpointermove` ইভেন্টগুলো রিসেট করে যাতে আপনি আবার গাছপালার অগ্রগতি পুনরায় শুরু করতে পারেন বা একটি নতুন গাছপালা ড্র্যাগ করতে পারেন।
এই ছোট ফাংশনটি `onpointerup` এবং `onpointermove` ইভেন্টগুলো রিসেট করে, যাতে আপনি আবার গাছপালার প্রগ্রেস শুরু করতে পারেন বা নতুন গাছপালা ড্র্যাগ করতে পারেন।
✅ যদি আপনি এই ইভেন্টগুলো null-এ সেট না করেন তবে কী হয়?
✅ যদি আপনি এই ইভেন্টগুলো null-এ সেট না করেন, তাহলে কী ঘটে?
এখন আপনি আপনার প্রকল্পটি সম্পন্ন করেছেন!
এখন আপনি আপনার প্রকল্প সম্পন্ন করেছেন!
🥇অভিনন্দন! আপনি আপনার সুন্দর টেরারিয়ামটি শেষ করেছেন। ![শেষ টেরারিয়াম](../../../../translated_images/terrarium-final.0920f16e87c13a84cd2b553a5af9a3ad1cffbd41fbf8ce715d9e9c43809a5e2c.bn.png)
🥇অভিনন্দন! আপনি আপনার সুন্দর টেরারিয়াম তৈরি করেছেন। ![সম্পন্ন টেরারিয়াম](../../../../translated_images/terrarium-final.0920f16e87c13a84cd2b553a5af9a3ad1cffbd41fbf8ce715d9e9c43809a5e2c.bn.png)
---
## 🚀চ্যালেঞ্জ
আপনার ক্লোজারে একটি নতুন ইভেন্ট হ্যান্ডলার যোগ করুন যা গাছপালাগুলোর জন্য আরও কিছু করে; উদাহরণস্বরূপ, একটি গাছপালাকে সামনে আনতে ডাবল-ক্লিক করুন। সৃজনশীল হন!
আপনার ক্লোজারে নতুন ইভেন্ট হ্যান্ডলার যোগ করুন, যাতে গাছপালাগুলোর উপর আরও কিছু করা যায়; উদাহরণস্বরূপ, একটি গাছপালাকে ডাবল-ক্লিক করলে এটি সামনে চলে আসবে। সৃজনশীল হন!
## পোস্ট-লেকচার কুইজ
[পোস্ট-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/20)
## পর্যালোচনা স্ব-অধ্যয়ন
## পর্যালোচনা এবং স্ব-অধ্যয়ন
স্ক্রিনে উপাদানগুলো ড্র্যাগ করা তুচ্ছ মনে হতে পারে, তবে এটি করার অনেক উপায় এবং অনেক ফাঁদ রয়েছে, যা আপনি যে প্রভাবটি চান তার উপর নির্ভর করে। প্রকৃতপক্ষে, একটি সম্পূর্ণ [ড্র্যাগ এবং ড্রপ API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) রয়েছে যা আপনি চেষ্টা করতে পারেন। আমরা এই মডিউলে এটি ব্যবহার করিনি কারণ আমরা একটি ভিন্ন প্রভাব চেয়েছিলাম, তবে এই API আপনার নিজস্ব প্রকল্পে চেষ্টা করুন এবং দেখুন আপনি কী অর্জন করতে পারেন।
স্ক্রিনে এলিমেন্ট ড্র্যাগ করা তুচ্ছ মনে হতে পারে, তবে এটি করার অনেক উপায় রয়েছে এবং আপনি যে প্রভাব চান তার উপর নির্ভর করে অনেক সমস্যাও রয়েছে। আসলে, একটি সম্পূর্ণ [ড্র্যাগ এবং ড্রপ API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) রয়েছে যা আপনি চেষ্টা করতে পারেন। আমরা এই মডিউলে এটি ব্যবহার করিনি কারণ আমরা একট ভিন্ন প্রভাব চেয়েছিলাম, তবে এই API আপনার নিজস্ব প্রকল্পে চেষ্টা করুন এবং দেখুন আপনি কী অর্জন করতে পারেন।
পয়েন্টার ইভেন্ট সম্পর্কে আরও তথ্য খুঁজুন [W3C ডকস](https://www.w3.org/TR/pointerevents1/) এবং [MDN ওয়েব ডকস](https://developer.mozilla.org/docs/Web/API/Pointer_events)-এ।
@ -226,5 +224,7 @@ function stopElementDrag() {
[DOM নিয়ে আরও কাজ করুন](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়ী থাকব না।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e982871b8388c59c22a41b73b5fca70f",
"translation_date": "2025-08-26T01:03:32+00:00",
"original_hash": "1b0aeccb600f83c603cd70cb42df594d",
"translation_date": "2025-08-28T23:05:52+00:00",
"source_file": "4-typing-game/typing-game/README.md",
"language_code": "bn"
}
@ -15,42 +15,42 @@ CO_OP_TRANSLATOR_METADATA:
## ইভেন্ট চালিত প্রোগ্রামিং
ব্রাউজার ভিত্তিক অ্যাপ্লিকেশন তৈরি করার সময়, আমরা ব্যবহারকারীর জন্য একটি গ্রাফিকাল ইউজার ইন্টারফেস (GUI) প্রদান করি যাতে তারা আমাদের তৈরি করা জিনিসের সাথে ইন্টারঅ্যাক্ট করতে পারে। ব্রাউজারের সাথে ইন্টারঅ্যাক্ট করার সবচেয়ে সাধারণ উপায় হল বিভিন্ন উপাদানে ক্লিক করা এবং টাইপ করা। একজন ডেভেলপার হিসেবে আমাদের চ্যালেঞ্জ হল, আমরা জানি না তারা কখন এই কাজগুলো করবে!
ব্রাউজার ভিত্তিক অ্যাপ্লিকেশন তৈরি করার সময়, আমরা ব্যবহারকারীর জন্য একটি গ্রাফিকাল ইউজার ইন্টারফেস (GUI) প্রদান করি, যা তারা আমাদের তৈরি করা জিনিসের সাথে ইন্টারঅ্যাক্ট করতে ব্যবহার করে। ব্রাউজারের সাথে ইন্টারঅ্যাক্ট করার সবচেয়ে সাধারণ উপায় হল বিভিন্ন উপাদানে ক্লিক করা এবং টাইপ করা। একজন ডেভেলপার হিসেবে আমাদের চ্যালেঞ্জ হল, আমরা জানি না তারা কখন এই কাজগুলো করবে!
[ইভেন্ট চালিত প্রোগ্রামিং](https://en.wikipedia.org/wiki/Event-driven_programming) হল সেই ধরনের প্রোগ্রামিং যা আমাদের GUI তৈরি করতে প্রয়োজন। যদি আমরা এই বাক্যাংশটি একটু বিশ্লেষণ করি, তাহলে দেখতে পাবো মূল শব্দটি হল **ইভেন্ট**। [ইভেন্ট](https://www.merriam-webster.com/dictionary/event), মেরিয়াম-ওয়েবস্টার অনুযায়ী, "কিছু যা ঘটে" হিসাবে সংজ্ঞায়িত। এটি আমাদের পরিস্থিতি পুরোপুরি বর্ণনা করে। আমরা জানি কিছু ঘটবে যার জন্য আমরা কিছু কোড চালাতে চাই, কিন্তু আমরা জানি না এটি কখন ঘটবে।
[ইভেন্ট চালিত প্রোগ্রামিং](https://en.wikipedia.org/wiki/Event-driven_programming) হল সেই ধরনের প্রোগ্রামিং যা আমাদের GUI তৈরি করতে করতে হয়। যদি আমরা এই শব্দটি একটু বিশ্লেষণ করি, তাহলে আমরা দেখতে পাই মূল শব্দটি হল **ইভেন্ট**। [ইভেন্ট](https://www.merriam-webster.com/dictionary/event), মেরিয়াম-ওয়েবস্টারের মতে, "কিছু যা ঘটে" হিসাবে সংজ্ঞায়িত করা হয়েছে। এটি আমাদের পরিস্থিতি পুরোপুরি বর্ণনা করে। আমরা জানি কিছু ঘটতে যাচ্ছে যার জন্য আমরা কিছু কোড কার্যকর করতে চাই, কিন্তু আমরা জানি না এটি কখন ঘটবে।
আমরা যে কোডটি চালাতে চাই তা চিহ্নিত করার উপায় হল একটি ফাংশন তৈরি করা। [প্রসিডিউরাল প্রোগ্রামিং](https://en.wikipedia.org/wiki/Procedural_programming) এ, ফাংশনগুলো একটি নির্দিষ্ট ক্রমে ডাকা হয়। ইভেন্ট চালিত প্রোগ্রামিংয়ের ক্ষেত্রেও একই জিনিস সত্য হবে। পার্থক্য হল **কীভাবে** ফাংশনগুলো ডাকা হবে।
আমরা যে কোডের অংশটি কার্যকর করতে চাই তা চিহ্নিত করার উপায় হল একটি ফাংশন তৈরি করা। যখন আমরা [প্রসিডিউরাল প্রোগ্রামিং](https://en.wikipedia.org/wiki/Procedural_programming) নিয়ে চিন্তা করি, তখন ফাংশনগুলো একটি নির্দিষ্ট ক্রমে কল করা হয়। ইভেন্ট চালিত প্রোগ্রামিংয়ের ক্ষেত্রেও একই জিনিস সত্য হবে। পার্থক্য হল **কীভাবে** ফাংশনগুলো কল করা হবে।
ইভেন্ট (যেমন বোতাম ক্লিক করা, টাইপ করা ইত্যাদি) পরিচালনা করতে, আমরা **ইভেন্ট লিসনার** নিবন্ধন করি। একটি ইভেন্ট লিসনার হল একটি ফাংশন যা একটি ইভেন্ট ঘটার জন্য অপেক্ষা করে এবং তার প্রতিক্রিয়ায় কার্যকর হয়। ইভেন্ট লিসনার UI আপডেট করতে পারে, সার্ভারে কল করতে পারে, বা ব্যবহারকারীর ক্রিয়ার প্রতিক্রিয়ায় যা প্রয়োজন তা করতে পারে। আমরা [addEventListener](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener) ব্যবহার করে একটি ইভেন্ট লিসনার যোগ করি এবং কার্যকর করার জন্য একটি ফাংশন প্রদান করি।
ইভেন্ট (বাটন ক্লিক করা, টাইপ করা ইত্যাদি) পরিচালনা করতে, আমরা **ইভেন্ট লিসনার** নিবন্ধন করি। একটি ইভেন্ট লিসনার হল একটি ফাংশন যা একটি ইভেন্ট ঘটার জন্য অপেক্ষা করে এবং প্রতিক্রিয়ায় কার্যকর হয়। ইভেন্ট লিসনার UI আপডেট করতে পারে, সার্ভারে কল করতে পারে, বা ব্যবহারকারীর ক্রিয়ার প্রতিক্রিয়ায় যা কিছু করা দরকার তা করতে পারে। আমরা [addEventListener](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener) ব্যবহার করে একটি ইভেন্ট লিসনার যোগ করি এবং কার্যকর করার জন্য একটি ফাংশন প্রদান করি।
> **NOTE:** এটি উল্লেখ করা গুরুত্বপূর্ণ যে ইভেন্ট লিসনার তৈরি করার অনেক উপায় রয়েছে। আপনি অ্যানোনিমাস ফাংশন ব্যবহার করতে পারেন, অথবা নামকৃত ফাংশন তৈরি করতে পারেন। আপনি বিভিন্ন শর্টকাট ব্যবহার করতে পারেন, যেমন `click` প্রপার্টি সেট করা, অথবা `addEventListener` ব্যবহার করা। আমাদের অনুশীলনে আমরা `addEventListener` এবং অ্যানোনিমাস ফাংশনের উপর ফোকাস করব, কারণ এটি ওয়েব ডেভেলপারদের মধ্যে সবচেয়ে সাধারণ কৌশল। এটি সবচেয়ে নমনীয়ও, কারণ `addEventListener` সব ইভেন্টের জন্য কাজ করে এবং ইভেন্টের নাম প্যারামিটার হিসবে প্রদান করা যায়।
> **NOTE:** ইভেন্ট লিসনার তৈরি করার অনেক উপায় রয়েছে। আপনি অ্যানোনিমাস ফাংশন ব্যবহার করতে পারেন, অথবা নামযুক্ত ফাংশন তৈরি করতে পারেন। আপনি বিভিন্ন শর্টকাট ব্যবহার করতে পারেন, যেমন `click` প্রপার্টি সেট করা, অথবা `addEventListener` ব্যবহার করা। আমাদের অনুশীলনে আমরা `addEventListener` এবং অ্যানোনিমাস ফাংশনের উপর ফোকাস করব, কারণ এটি ওয়েব ডেভেলপারদের সবচেয়ে সাধারণ কৌশল। এটি সবচেয়ে নমনীয়ও, কারণ `addEventListener` সব ইভেন্টের জন্য কাজ করে এবং ইভেন্টের নাম প্যারামিটার হিসবে প্রদান করা যায়।
### সাধারণ ইভেন্ট
অ্যাপ্লিকেশন তৈরি করার সময় [ডজনখানেক ইভেন্ট](https://developer.mozilla.org/docs/Web/Events) রয়েছে যা আপনি শুনতে পারেন। মূলত ব্যবহারকারী একটি পৃষ্ঠায় যা কিছু করে তা একটি ইভেন্ট তৈরি করে, যা আপনাকে তাদের অভিজ্ঞতা নিশ্চিত করার জন্য প্রচুর ক্ষমতা দেয়। সৌভাগ্যবশত, সাধারণত আপনাকে কেবল কয়েকটি ইভেন্টের প্রয়োজন হয়। এখানে কয়েকটি সাধারণ ইভেন্ট রয়েছে (যার মধ্যে দুটি আমরা আমাদের গেম তৈরি করার সময় ব্যবহার করব):
অ্যাপ্লিকেশন তৈরি করার সময় আপনি শুনতে পারেন এমন [ডজনখানেক ইভেন্ট](https://developer.mozilla.org/docs/Web/Events) রয়েছে। মূলত ব্যবহারকারী একটি পৃষ্ঠায় যা কিছু করে তা একটি ইভেন্ট তৈরি করে, যা আপনাকে তাদের পছন্দসই অভিজ্ঞতা নিশ্চিত করার জন্য প্রচুর ক্ষমতা দেয়। সৌভাগ্যক্রমে, সাধারণত আপনাকে শুধুমাত্র কয়েকটি ইভেন্টের প্রয়োজন হবে। এখানে কয়েকটি সাধারণ ইভেন্ট রয়েছে (যার মধ্যে দুটি আমরা আমাদের গেম তৈরি করার সময় ব্যবহার করব):
- [click](https://developer.mozilla.org/docs/Web/API/Element/click_event): ব্যবহারকারী কিছুতে ক্লিক করেছে, সাধারণত একটি বোতাম বা হাইপারলিঙ্ক
- [contextmenu](https://developer.mozilla.org/docs/Web/API/Element/contextmenu_event): ব্যবহারকারী ডান মাউস বোতামে ক্লিক করেছে
- [click](https://developer.mozilla.org/docs/Web/API/Element/click_event): ব্যবহারকারী কিছু ক্লিক করেছে, সাধারণত একটি বাটন বা হাইপারলিঙ্ক
- [contextmenu](https://developer.mozilla.org/docs/Web/API/Element/contextmenu_event): ব্যবহারকারী ডান মাউস বাটন ক্লিক করেছে
- [select](https://developer.mozilla.org/docs/Web/API/Element/select_event): ব্যবহারকারী কিছু টেক্সট হাইলাইট করেছে
- [input](https://developer.mozilla.org/docs/Web/API/Element/input_event): ব্যবহারকারী কিছু টেক্সট ইনপুট করেছে
## গেম তৈরি করা
আমরা একটি গেম তৈরি করব যাতে ইভেন্টগুলো কীভাবে কাজ করে তা অন্বেষণ করা যায়। আমাদের গেমটি একজন খেলোয়াড়ের টাইপিং দক্ষতা পরীক্ষা করবে, যা সমস্ত ডেভেলপারদের জন্য একটি অত্যন্ত গুরুত্বপূর্ণ দক্ষতা। আমাদের সবার টাইপিং অনুশীলন করা উচিত! গেমটির সাধারণ প্রবাহটি এরকম হবে:
আমরা ইভেন্টগুলো কীভাবে কাজ করে তা অন্বেষণ করতে একটি গেম তৈরি করতে যাচ্ছি। আমাদের গেমটি একজন খেলোয়াড়ের টাইপিং দক্ষতা পরীক্ষা করবে, যা সমস্ত ডেভেলপারদের জন্য সবচেয়ে অবমূল্যায়িত দক্ষতাগুলোর মধ্যে একটি। আমাদের সবার টাইপিং অনুশীলন করা উচিত! গেমটির সাধারণ প্রবাহটি এরকম হবে:
- খেলোয়াড় স্টার্ট বোতামে ক্লিক করবে এবং টাইপ করার জন্য একটি কোট পাবে
- খেলোয়াড় যত দ্রুত সম্ভব একটি টেক্সটবক্সে কোটটি টাইপ কর
- প্রতিটি শব্দ সম্পন্ন হওয়ার সাথে সাথে পরবর্তীটি হাইলাইট হবে
- যদি খেলোয়াড় টাইপো করে, টেক্সটবক্সটি লাল হয়ে যাবে
- খেলোয়াড় কোটটি সম্পন্ন করলে, একটি সাফল্যের বার্তা প্রদর্শিত হবে এবং সময় গণনা দেখানো হবে
- খেলোয়াড় স্টার্ট বাটনে ক্লিক করে এবং টাইপ করার জন্য একটি কোট পায়
- খেলোয়াড় একটি টেক্সটবক্সে যত দ্রুত সম্ভব কোটটি টাইপ করে
- প্রতিটি শব্দ সম্পন্ন হওয়ার সাথে সাথে পরবর্তীটি হাইলাইট হয়
- যদি খেলোয়াড়ের টাইপিংয়ে ভুল থাকে, টেক্সটবক্সটি লাল হয়ে যায়
- যখন খেলোয়াড় কোটটি সম্পন্ন করে, একটি সফলতার বার্তা প্রদর্শিত হয় এবং সময় গণনা দেখানো হয়
চলুন আমাদের গেমটি তৈরি করি এবং ইভেন্ট সম্পর্কে শিখি!
### ফাইল কাঠামো
### ফাইলের কাঠামো
আমাদের মোট তিনটি ফাইল প্রয়োজন হবে: **index.html**, **script.js** এবং **style.css**। চলুন এগুলো সেটআপ করি যাতে আমাদের কাজ সহজ হয়।
আমাদের মোট তিনটি ফাইলের প্রয়োজন হবে: **index.html**, **script.js** এবং **style.css**। চলুন এগুলো সেটআপ করি যাতে আমাদের কাজ সহজ হয়।
- একটি নতুন ফোল্ডার তৈরি করুন এবং কনসোল বা টার্মিনাল উইন্ডোতে নিম্নলিখিত কমান্ডটি চালান:
- একটি নতুন ফোল্ডার তৈরি করুন আপনার কাজের জন্য। কনসোল বা টার্মিনাল উইন্ডো খুলুন এবং নিম্নলিখিত কমান্ড দিন:
```bash
# Linux or macOS
@ -66,21 +66,21 @@ md typing-game && cd typing-game
code .
```
- ভিজ্যুয়াল স্টুডিও কোডে ফোল্ডারে তিনটি ফাইল যোগ করুন নিম্নলিখিত নাম দিয়ে:
- ফোল্ডারে তিনটি ফাইল যোগ করুন ভিজ্যুয়াল স্টুডিও কোডে নিম্নলিখিত নাম দিয়ে:
- index.html
- script.js
- style.css
## ইউজার ইন্টারফেস তৈরি করা
যদি আমরা প্রয়োজনীয়তাগুলো বিশ্লেষণ করি, তাহলে আমরা জানি আমাদের HTML পৃষ্ঠায় কয়েকটি উপাদান প্রয়োজন। এটি একটি রেসিপির মতো, যেখানে আমাদের কিছু উপাদান দরকার:
যদি আমরা প্রয়োজনীয়তাগুলো বিশ্লেষণ করি, তাহলে আমরা জানি আমাদের HTML পৃষ্ঠায় কয়েকটি উপাদানের প্রয়োজন হবে। এটি একটি রেসিপির মতো, যেখানে আমাদের কিছু উপাদান দরকার:
- ব্যবহারকারীর টাইপ করার জন্য কোট প্রদর্শনের জায়গা
- বার্তা প্রদর্শনের জায়গা, যেমন একটি সাফল্যের বার্তা
- বার্তা প্রদর্শনের জায়গা, যেমন সফলতার বার্তা
- টাইপ করার জন্য একটি টেক্সটবক্স
- একটি স্টার্ট বোতাম
- একটি স্টার্ট বাটন
প্রতিটি উপাদানের জন্য ID প্রয়োজন যাতে আমরা সেগুলোর সাথে আমাদের জাভাস্ক্রিপ্টে কাজ করতে পারি। আমরা CSS এবং জাভাস্ক্রিপ্ট ফাইলগুলোর রেফারেন্সও যোগ করব।
প্রতিটি উপাদানের জন্য ID প্রয়োজন হবে যাতে আমরা সেগুলো আমাদের জাভাস্ক্রিপ্টে ব্যবহার করতে পারি। আমরা CSS এবং জাভাস্ক্রিপ্ট ফাইলগুলোর রেফারেন্সও যোগ করব যা আমরা তৈরি করতে যাচ্ছি
একটি নতুন ফাইল তৈরি করুন যার নাম **index.html**। নিম্নলিখিত HTML যোগ করুন:
@ -107,24 +107,24 @@ code .
### অ্যাপ্লিকেশন চালু করা
সবসময়ই ধাপে ধাপে ডেভেলপ করা ভালো যাতে জিনিসগুলো দেখতে কেমন তা বোঝা যায়। চলুন আমাদের অ্যাপ্লিকেশন চালু করি। ভিজ্যুয়াল স্টুডিও কোডের জন্য একটি চমৎকার এক্সটেনশন রয়েছে [লাইভ সার্ভার](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon), যা আপনার অ্যাপ্লিকেশনটি লোকাল হোস্ট করবে এবং প্রতিবার আপনি সেভ করলে ব্রাউজার রিফ্রেশ করবে।
সবসময়ই ভালো হয় ধাপে ধাপে ডেভেলপ করা যাতে জিনিসগুলো দেখতে কেমন তা বোঝা যায়। চলুন আমাদের অ্যাপ্লিকেশন চালু করি। ভিজ্যুয়াল স্টুডিও কোডের জন্য একটি চমৎকার এক্সটেনশন রয়েছে [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon), যা আপনার অ্যাপ্লিকেশনটি লোকালভাবে হোস্ট করবে এবং আপনি যখনই সেভ করবেন তখন ব্রাউজারটি রিফ্রেশ করবে।
- [লাইভ সার্ভার](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) ইনস্টল করুন লিঙ্কটি অনুসরণ করে এবং **Install** এ ক্লিক করে
- ব্রাউজার আপনাকে ভিজ্যুয়াল স্টুডিও কোড খুলতে বলবে, এবং তারপর ভিজ্যুয়াল স্টুডিও কোড ইনস্টলেশন সম্পন্ন করবে
- প্রয়োজন হলে ভিজ্যুয়াল স্টুডিও কোড পুনরায় চালু করুন
- ইনস্টল করার পর, ভিজ্যুয়াল স্টুডিও কোডে Ctrl-Shift-P (বা Cmd-Shift-P) চাপুন কমান্ড প্যালেট খুলতে
- [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) ইনস্টল করুন। লিঙ্কে ক্লিক করুন এবং **Install** বাটনে ক্লিক করুন।
- ব্রাউজার আপনাকে ভিজ্যুয়াল স্টুডিও কোড খুলতে বলবে, এবং তারপর ভিজ্যুয়াল স্টুডিও কোড ইনস্টলেশন সম্পন্ন করতে বলবে
- প্রয়োজন হলে ভিজ্যুয়াল স্টুডিও কোড পুনরায় চালু করুন
- ইনস্টল করার পর, ভিজ্যুয়াল স্টুডিও কোডে Ctrl-Shift-P (বা Cmd-Shift-P) চাপুন কমান্ড প্যালেট খুলতে
- টাইপ করুন **Live Server: Open with Live Server**
- লাইভ সার্ভার আপনার অ্যাপ্লিকেশন হোস্ট করা শুরু করবে
- একটি ব্রাউজার খুলুন এবং **https://localhost:5500** এ যান
- আপনি এখন আপনার তৈরি পৃষ্ঠাটি দেখতে পাবেন!
- Live Server আপনার অ্যাপ্লিকেশন হোস্ট করা শুরু করবে
- একটি ব্রাউজার খুলুন এবং **https://localhost:5500** এ যান
- এখন আপনি তৈরি করা পৃষ্ঠাটি দেখতে পাবেন!
চলুন কিছু কার্যকারিতা যোগ করি।
## CSS যোগ করা
আমাদের HTML তৈরি হয়ে গেলে, চলুন মূল স্টাইলিংয়ের জন্য CSS যোগ করি। আমাদের খেলোয়াড় যে শব্দটি টাইপ করা উচিত তা হাইলাইট করতে হবে এবং তারা ভুল টাইপ করলে টেক্সটবক্সটি রঙিন করতে হবে। আমরা এটি দুটি ক্লাস ব্যবহার করে করব।
আমাদের HTML তৈরি করার পর, চলুন CSS যোগ করি মূল স্টাইলিংয়ের জন্য। আমাদের খেলোয়াড় যে শব্দটি টাইপ করা উচিত তা হাইলাইট করতে হবে এবং তারা ভুল টাইপ করলে টেক্সটবক্সটি রঙিন করতে হবে। আমরা এটি দুটি ক্লাস ব্যবহার করে করব।
একটি নতুন ফাইল তৈরি করুন যার নাম **style.css** এবং নিম্নলিখিত সিনট্যাক্স যোগ করুন:
একটি নতুন ফাইল তৈরি করুন যার নাম **style.css** এবং নিম্নলিখিত সিনট্যাক্স যোগ করুন
```css
/* inside style.css */
@ -138,32 +138,32 @@ code .
}
```
✅ CSS এর ক্ষেত্রে আপনি আপনার পৃষ্ঠাটি যেভাবে চান সেভাবে সাজাতে পারেন। কিছু সময় নিন এবং পৃষ্ঠাটিকে আরও আকর্ষণীয় করে তুলুন:
✅ CSS-এর ক্ষেত্রে আপনি আপনার পৃষ্ঠাটি যেভাবে চান সেভাবে সাজাতে পারেন। কিছু সময় নিন এবং পৃষ্ঠাটি আরও আকর্ষণীয় করুন:
- একটি ভিন্ন ফন্ট বেছে নি
- শিরোনামগুলো রঙিন করুন
- একটি ভিন্ন ফন্ট নির্বাচন করু
- হেডারগুলো রঙিন করুন
- আইটেমগুলো পুনরায় আকার দিন
## জাভাস্ক্রিপ্ট
আমাদের UI তৈরি হয়ে গেলে, এখন আমাদের মনোযোগ কেন্দ্রীভূত করব জাভাস্ক্রিপ্টে যা লজিক প্রদান করবে। আমরা এটি কয়েকটি ধাপে ভাগ করব:
আমাদের UI তৈরি করার পর, এখন আমাদের মনোযোগ কেন্দ্রীভূত করতে হ জাভাস্ক্রিপ্টে, যা লজিক প্রদান করবে। আমরা এটি কয়েকটি ধাপে ভাগ করব:
- [কনস্ট্যান্ট তৈরি করা](../../../../4-typing-game/typing-game)
- [গেম শুরু করার ইভেন্ট লিসনার](../../../../4-typing-game/typing-game)
- [টাইপিংয়ের ইভেন্ট লিসনার](../../../../4-typing-game/typing-game)
- [গেম শুরু করার ইভেন্ট লিসনার](../../../../4-typing-game/typing-game)
- [টাইপিংয়ের ইভেন্ট লিসনার](../../../../4-typing-game/typing-game)
কিন্তু প্রথমে, একটি নতুন ফাইল তৈরি করুন যার নাম **script.js**
### কনস্ট্যান্ট যোগ করা
আমাদের প্রোগ্রামিং সহজ করার জন্য কয়েকটি আইটেম প্রয়োজন হবে। এটি একটি রেসিপির মতো, যেখানে আমাদের কিছু উপাদান দরকার:
আমাদের প্রোগ্রামিংকে সহজ করার জন্য কয়েকটি আইটেমের প্রয়োজন হবে। আবার, এটি একটি রেসিপির মতো, যেখানে আমাদের প্রয়োজন:
- সমস্ত কোটের তালিকা সহ একটি অ্যারে
- বর্তমান কোটের জন্য সমস্ত শব্দ সংরক্ষণ করার জন্য একটি খালি অ্যারে
- বর্তমান কোটের সমস্ত শব্দ সংরক্ষণর জন্য একটি খালি অ্যারে
- খেলোয়াড় বর্তমানে যে শব্দটি টাইপ করছে তার সূচক সংরক্ষণের জায়গা
- খেলোয়াড় স্টার্টে ক্লিক করার সময়
আমাদের UI উপাদানগুলোর রেফারেন্সও প্রয়োজন হবে:
আমর UI উপাদানগুলোর রেফারেন্সও চাই:
- টেক্সটবক্স (**typed-value**)
- কোট প্রদর্শন (**quote**)
@ -194,19 +194,19 @@ const typedValueElement = document.getElementById('typed-value');
✅ আপনার গেমে আরও কোট যোগ করুন
> **NOTE:** আমরা `document.getElementById` ব্যবহার করে যেকোনো সময় উপাদানগুলো পুনরুদ্ধার করতে পারি। যেহেতু আমরা নিয়মিত এই উপাদানগুলো উল্লেখ করব, তাই স্ট্রিং লিটারালের টাইপো এড়াতে আমরা কনস্ট্যান্ট ব্যবহার করব। [Vue.js](https://vuejs.org/) বা [React](https://reactjs.org/) এর মতো ফ্রেমওয়ার্কগুলো আপনাকে আপনার কোড কেন্দ্রীভূত করতে আরও ভালভাবে সাহায্য করতে পারে।
> **NOTE:** আমরা যখনই কোডে উপাদানগুলো পুনরুদ্ধার করতে চাই তখন `document.getElementById` ব্যবহার করতে পারি। যেহেতু আমরা নিয়মিতভাবে এই উপাদানগুলো উল্লেখ করতে যাচ্ছি, আমরা স্ট্রিং লিটারালগুলোর টাইপো এড়াতে কনস্ট্যান্ট ব্যবহার করব। [Vue.js](https://vuejs.org/) বা [React](https://reactjs.org/) এর মতো ফ্রেমওয়ার্কগুলো আপনাকে আপনার কোড কেন্দ্রীভূত করতে আরও ভালভাবে পরিচালনা করতে সাহায্য করতে পারে।
`const`, `let` এবং `var` ব্যবহার করার বিষয়ে একটি ভিডিও দেখুন
`const`, `let` এবং `var` ব্যবহার করার বিষয়ে একটি ভিডিও দেখুন
[![ভেরিয়েবলের ধরন](https://img.youtube.com/vi/JNIXfGiDWM8/0.jpg)](https://youtube.com/watch?v=JNIXfGiDWM8 "ভেরিয়েবলের ধরন")
> 🎥 উপরের ছবিতে ক্লিক করুন ভেরিয়েবল সম্পর্কে একটি ভিডিও দেখার জন্য
> 🎥 উপরের ছবিতে ক্লিক করুন ভেরিয়েবল সম্পর্কে একটি ভিডিও দেখতে
### শুরু করার লজিক যোগ করা
গেমটি শুরু করতে, খেলোয়াড় স্টার্টে ক্লিক করবে। অবশ্যই, আমরা জানি না তারা কখন স্টার্টে ক্লিক করবে। এটি এমন একটি ক্ষেত্রে যেখানে [ইভেন্ট লিসেনার](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener) কার্যকর হয়। একটি ইভেন্ট লিসেনার আমাদের কিছু ঘটার জন্য অপেক্ষা করতে এবং তার প্রতিক্রিয়ায় কোড কার্যকর করতে দেয়। আমাদের ক্ষেত্রে, আমরা চাই ব্যবহারকারী স্টার্টে ক্লিক করলে কোড কার্যকর হোক
গেমটি শুরু করতে, খেলোয়াড় স্টার্টে ক্লিক করবে। অবশ্যই, আমরা জানি না তারা কখন স্টার্টে ক্লিক করবে। এখানে একটি [ইভেন্ট লিসনার](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener) কার্যকর হবে। একটি ইভেন্ট লিসনার আমাদের কিছু ঘটার জন্য (ইভেন্ট) অপেক্ষা করতে এবং প্রতিক্রিয়ায় কোড কার্যকর করতে দেয়। আমাদের ক্ষেত্রে, আমরা চাই ব্যবহারকারী যখন স্টার্টে ক্লিক করবে তখন কোড কার্যকর হবে
যখন ব্যবহারকারী **স্টার্ট**-এ ক্লিক করবে, তখন আমাদের একটি কোট নির্বাচন করতে হবে, UI সেটআপ করতে হবে, এবং বর্তমান শব্দ এবং টাইমিং ট্র্যাক করতে হবে। নিচে জাভাস্ক্রিপ্ট দেওয়া হয়েছে যা আপনাকে যোগ করতে হবে; আমরা স্ক্রিপ্ট ব্লকের পরে এটি আলোচনা করব।
যখন ব্যবহারকারী **স্টার্ট** ক্লিক করবে, তখন আমাদের একটি কোট নির্বাচন করতে হবে, ইউজার ইন্টারফেস সেটআপ করতে হবে এবং বর্তমান শব্দ এবং টাইমিংয়ের জন্য ট্র্যাকিং সেটআপ করতে হবে। নিচে জাভাস্ক্রিপ্ট য়েছে যা আপনাকে যোগ করতে হবে; আমরা স্ক্রিপ্ট ব্লকের পরে এটি আলোচনা করব।
```javascript
// at the end of script.js
@ -243,25 +243,25 @@ document.getElementById('start').addEventListener('click', () => {
চলুন কোডটি বিশ্লেষণ করি!
- শব্দ ট্র্যাকিং সেটআপ করুন
- [Math.floor](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) এবং [Math.random](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Math/random) ব্যবহার করে আমরা `quotes` অ্যারে থেকে এলোমেলোভাবে একটি কোট নির্বাচন করি
- আমরা `quote` কে `words` এর একটি অ্যারেতে রূপান্তর করি যাতে আমরা খেলোয়াড় বর্তমানে যে শব্দটি টাইপ করছে তা ট্র্যাক করতে পারি
- `wordIndex` 0 এ সেট করা হয়, কারণ খেলোয়াড় প্রথম শব্দ দিয়ে শুরু করবে
- UI সেটআপ করুন
- `spanWords` এর একটি অ্যারে তৈরি করুন, যা প্রতিটি শব্দকে একটি `span` উপাদানের মধ্যে রাখে
- এটি আমাদের ডিসপ্লেতে শব্দটি হাইলাইট করতে দেবে
- `join` ব্যবহার করে অ্যারেটিকে একটি স্ট্রিংয়ে রূপান্তর করুন যা আমরা `quoteElement` এর `innerHTML` আপডেট করতে ব্যবহার করতে পারি
- এটি খেলোয়াড়ের জন্য কোটটি প্রদর্শন করবে
- প্রথম `span` উপাদানের `className` `highlight` এ সেট করুন যাতে এটি হলুদ রঙে হাইলাইট হয়
- `messageElement` পরিষ্কার করুন `innerText` কে `''` সেট করে
- টেক্সটবক্স সেটআপ করুন
- `typedValueElement` এর বর্তমান `value` পরিষ্কার করুন
- `typedValueElement``focus` সেট করুন
- টাইমার শুরু করুন `getTime` কল করে
- শব্দ ট্র্যাকিং সেটআপ কর
- [Math.floor](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) এবং [Math.random](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Math/random) ব্যবহার করে আমরা `quotes` অ্যারে থেকে একটি কোট এলোমেলোভাবে নির্বাচন করি
- আমরা `quote` কে `words` এর একটি অ্যারেতে রূপান্তর করি যাতে আমরা খেলোয়াড় বর্তমানে যে শব্দটি টাইপ করছে তা ট্র্যাক করতে পারি
- `wordIndex` 0-এ সেট করা হয়, কারণ খেলোয়াড় প্রথম শব্দ থেকে শুরু করবে।
- UI সেটআপ কর
- `spanWords` এর একটি অ্যারে তৈরি করুন, যা প্রতিটি শব্দকে একটি `span` উপাদানের মধ্যে রাখে
- এটি আমাদের প্রদর্শনে শব্দটি হাইলাইট করতে সাহায্য করবে।
- `join` ব্যবহার করে অ্যারেটিকে একটি স্ট্রিংয়ে রূপান্তর করুন যা আমরা `quoteElement` এর `innerHTML` আপডেট করতে ব্যবহার করতে পারি
- এটি খেলোয়াড়ের জন্য কোটটি প্রদর্শন করবে
- প্রথম `span` উপাদানের `className` `highlight` এ সেট করুন যাতে এটি হলুদ রঙে হাইলাইট হয়
- `messageElement` পরিষ্কার করুন `innerText` কে `''` সেট করে
- টেক্সটবক্স সেটআপ কর
- বর্তমান `typedValueElement` এর `value` পরিষ্কার করুন
- `typedValueElement``focus` সেট করুন
- টাইমার শুরু করুন `getTime` কল করে
### টাইপিং লজিক যোগ করা
যখন খেলোয়াড় টাইপ করে, তখন একটি `input` ইভেন্ট উত্থাপিত হবে। এই ইভেন্ট লিসেনারটি নিশ্চিত করবে যে খেলোয়াড় সঠিকভাবে শব্দটি টাইপ করছে কিনা এবং গেমের বর্তমান অবস্থা পরিচালনা করবে। **script.js** এ ফিরে যান, এবং নিচের কোডটি শেষে যোগ করুন। আমরা পরে এটি বিশ্লেষণ করব।
যখন খেলোয়াড় টাইপ করে, তখন একটি `input` ইভেন্ট তৈরি হবে। এই ইভেন্ট লিসনারটি নিশ্চিত করবে যে খেলোয়াড় শব্দটি সঠিকভাবে টাইপ করছে এবং গেমের বর্তমান অবস্থা পরিচালনা করবে। **script.js** এ ফিরে যান এবং নিচের কোডটি শেষে যোগ করুন। আমরা পরে এটি বিশ্লেষণ করব।
```javascript
// at the end of script.js
@ -300,29 +300,29 @@ typedValueElement.addEventListener('input', () => {
});
```
চলুন কোডটি বিশ্লেষণ করি! আমরা শুরু করি বর্তমান শব্দ এবং খেলোয়াড় এখন পর্যন্ত যা টাইপ করেছে তা ধরে নিয়ে। তারপর আমরা ধাপে ধাপে লজিক পরীক্ষা করি, যেখানে আমরা যাচাই করি কোট সম্পূর্ণ হয়েছে কিনা, শব্দ সম্পূর্ণ হয়েছে কিনা, শব্দ সঠিক কিনা, অথবা (শেষে), কোনো ত্রুটি আছে কিনা
- কোট সম্পূর্ণ হয়েছে, যা নির্দেশ করে `typedValue` `currentWord` এর সমান এবং `wordIndex` `words` এর `length` এর চেয়ে এক কম
- `elapsedTime` গণনা করুন `startTime` থেকে বর্তমান সময় বিয়োগ করে
- `elapsedTime` কে ১, দিয়ে ভাগ করুন মিলিসেকেন্ড থেকে সেকেন্ডে রূপান্তর করতে
- একটি সাফল্যের বার্তা প্রদর্শন করুন
- শব্দ সম্পূর্ণ হয়েছে, যা নির্দেশ করে `typedValue` একটি স্পেস দিয়ে শেষ হয়েছে (শব্দের শেষ) এবং `typedValue` `currentWord` এর সমান
- `typedElement` এর `value` কে `''` সেট করুন যাতে পরবর্তী শব্দ টাইপ করা যায়
- `wordIndex` ইনক্রিমেন্ট করুন পরবর্তী শব্দে যাওয়ার জন্য
- `quoteElement` এর সমস্ত `childNodes` এর মাধ্যমে লুপ করুন এবং `className` কে `''` সেট করুন ডিফল্ট ডিসপ্লেতে ফিরে যাওয়ার জন্য
- বর্তমান শব্দের `className` `highlight` এ সেট করুন এটি পরবর্তী টাইপ করার শব্দ হিসাবে চিহ্নিত করতে
- শব্দটি বর্তমানে সঠিকভাবে টাইপ করা হয়েছে (কিন্তু সম্পূর্ণ নয়), যা নির্দেশ করে `currentWord` `typedValue` দিয়ে শুরু হয়েছে
- `typedValueElement` কে ডিফল্ট হিসাবে প্রদর্শন নিশ্চিত করুন `className` পরিষ্কার করে
- যদি আমরা এতদূর পৌঁছাই, তাহলে একটি ত্রুটি আছে
- `typedValueElement` এর `className` `error` এ সেট করুন
চলুন কোডটি বিশ্লেষণ করি! আমরা বর্তমান শব্দ এবং খেলোয়াড় এখন পর্যন্ত যা টাইপ করেছে তা গ্রহণ করি। তারপর আমরা ওয়াটারফল লজিক ব্যবহার করি, যেখানে আমরা যাচাই করি কোট সম্পন্ন হয়েছে কিনা, শব্দ সম্পন্ন হয়েছে কিনা, শব্দ সঠিক কিনা, অথবা (শেষে), যদি কোনো ত্রুটি থাকে
- কোট সম্পন্ন হয়েছে, নির্দেশিত `typedValue` `currentWord` এর সমান এবং `wordIndex` `words` এর `length` এর এক কম
- `elapsedTime` গণনা করুন `startTime` থেকে বর্তমান সময় বিয়োগ করে
- `elapsedTime` কে 1,000 দিয়ে ভাগ করুন মিলিসেকেন্ড থেকে সেকেন্ডে রূপান্তর করতে
- একটি সফলতার বার্তা প্রদর্শন করুন
- শব্দ সম্পন্ন হয়েছে, নির্দেশিত `typedValue` একটি স্পেস দিয়ে শেষ হয়েছে (শব্দের শেষ) এবং `typedValue` `currentWord` এর সমান
- পরবর্তী শব্দ টাইপ করার জন্য `typedElement` এর `value` কে `''` সেট করুন
- পরবর্তী শব্দে যাওয়ার জন্য `wordIndex` বৃদ্ধি করুন।
- `quoteElement` এর সমস্ত `childNodes` এর মাধ্যমে লুপ করুন এবং `className` কে `''` সেট করুন ডিফল্ট প্রদর্শনে ফিরে যাওয়ার জন্য
- বর্তমান শব্দের `className` `highlight` এ সেট করুন যাতে এটি টাইপ করার জন্য পরবর্তী শব্দ হিসাবে চিহ্নিত হয়।
- শব্দটি বর্তমানে সঠিকভাবে টাইপ করা হয়েছে (কিন্তু সম্পন্ন হয়নি), নির্দেশিত `currentWord` `typedValue` দিয়ে শুরু হয়েছে
- `typedValueElement` কে ডিফল্ট প্রদর্শন নিশ্চিত করুন `className` পরিষ্কার করে
- যদি আমরা এতদূর পৌঁছাই, তাহলে একটি ত্রুটি রয়েছে।
- `typedValueElement` এর `className` `error` এ সেট করুন
## আপনার অ্যাপ্লিকেশন পরীক্ষা করুন
আপনি শেষ পর্যন্ত পৌঁছেছেন! শেষ ধাপটি হল আমাদের অ্যাপ্লিকেশনটি কাজ করছে কিনা তা নিশ্চিত করা। এটি চেষ্টা করুন! যদি কোনো ত্রুটি থাকে তবে চিন্তা করবেন না; **সব ডেভেলপারদেরই ত্রুটি হয়** বার্তাগুলো পরীক্ষা করুন এবং প্রয়োজন অনুযায়ী ডিবাগ করুন।
আপনি শেষ পর্যন্ত পৌঁছেছেন! শেষ ধাপটি হল নিশ্চিত করা যে আমাদের অ্যাপ্লিকেশন কাজ করছে। এটি পরীক্ষা করুন! যদি কোনো ত্রুটি থাকে, চিন্তা করবেন না; **সব ডেভেলপারদেরই ত্রুটি হয়** বার্তাগুলো পরীক্ষা করুন এবং প্রয়োজন অনুযায়ী ডিবাগ করুন।
**স্টার্ট**-এ ক্লিক করুন এবং টাইপ করা শুরু করুন! এটি কিছুটা এরকম দেখতে হবে:
**স্টার্ট** এ ক্লিক করুন এবং টাইপ করা শুরু করুন! এটি কিছুটা এরকম দেখতে হবে:
![গেমটি কাজ করার অ্যানিমেশন](../../../../4-typing-game/images/demo.gif)
![গেমটি চলমান অবস্থার অ্যানিমেশন](../../../../4-typing-game/images/demo.gif)
---
@ -330,11 +330,10 @@ typedValueElement.addEventListener('input', () => {
আরও কার্যকারিতা যোগ করুন
- সম্পন্ন হলে `input` ইভেন্ট লিসেনার নিষ্ক্রিয় করুন এবং বোতামে ক্লিক করলে এটি পুনরায় সক্রিয় করুন
- খেলোয়াড় কোটটি সম্পন্ন করলে টেক্সটবক্স নিষ্ক্রিয় করুন
- একটি মডাল ডায়ালগ বক্সে সাফল্যের বার্তা প্রদর্শন করুন
- [localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage) ব্যবহার করে উচ্চ স্কোর সংরক্ষণ করুন
- সম্পন্ন হলে `input` ইভেন্ট লিসনার নিষ্ক্রিয় করুন এবং বাটন ক্লিক করলে পুনরায় সক্রিয় করুন।
- খেলোয়াড় কোট সম্পন্ন করলে টেক্সটবক্স নিষ্ক্রিয় করুন।
- সফলতার বার্তা সহ একটি মডাল ডায়ালগ বক্স প্রদর্শন করুন।
- [localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage) ব্যবহার করে উচ্চ স্কোর সংরক্ষণ করুন।
## লেকচার-পরবর্তী কুইজ
[লেকচার-পরবর্তী কুইজ](https://ff-quizzes.netlify.app/web/quiz/22)
@ -347,5 +346,7 @@ typedValueElement.addEventListener('input', () => {
[একটি নতুন কীবোর্ড গেম তৈরি করুন](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়ী থাকব না।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "0bb55e0b98600afab801eea115228873",
"translation_date": "2025-08-25T23:38:23+00:00",
"original_hash": "2326d04e194a10aa760b51f5e5a1f61d",
"translation_date": "2025-08-28T22:55:05+00:00",
"source_file": "5-browser-extension/1-about-browsers/README.md",
"language_code": "bn"
}
@ -10,7 +10,7 @@ CO_OP_TRANSLATOR_METADATA:
# ব্রাউজার এক্সটেনশন প্রকল্প পার্ট ১: ব্রাউজার সম্পর্কে সবকিছু
![ব্রাউজার স্কেচনোট](../../../../translated_images/browser.60317c9be8b7f84adce43e30bff8d47a1ae15793beab762317b2bc6b74337c1a.bn.jpg)
> স্কেচনোট করেছেন [Wassim Chegham](https://dev.to/wassimchegham/ever-wondered-what-happens-when-you-type-in-a-url-in-an-address-bar-in-a-browser-3dob)
> স্কেচনোট: [ওয়াসিম চেগাম](https://dev.to/wassimchegham/ever-wondered-what-happens-when-you-type-in-a-url-in-an-address-bar-in-a-browser-3dob)
## প্রাক-লেকচার কুইজ
@ -22,30 +22,30 @@ CO_OP_TRANSLATOR_METADATA:
### ব্রাউজার সম্পর্কে
এই পাঠের সিরিজে, আপনি শিখবেন কীভাবে একটি ব্রাউজার এক্সটেনশন তৈরি করতে হয় যা Chrome, Firefox এবং Edge ব্রাউজারে কাজ করবে। এই অংশে, আপনি আবিষ্কার করবেন কীভাবে ব্রাউজার কাজ করে এবং ব্রাউজার এক্সটেনশনের উপাদানগুলো তৈরি করবেন।
এই পাঠের সিরিজে, আপনি একটি ব্রাউজার এক্সটেনশন তৈরি করতে শিখবেন যা Chrome, Firefox এবং Edge ব্রাউজারে কাজ করবে। এই অংশে, আপনি ব্রাউজার কীভাবে কাজ করে তা জানবেন এবং ব্রাউজার এক্সটেনশনের উপাদানগুলো তৈরি করবেন।
কিন্তু ব্রাউজার আসলে কী? এটি একটি সফটওয়্যার অ্যাপ্লিকেশন যা ব্যবহারকারীকে একটি সার্ভার থেকে কন্টেন্ট অ্যাক্সেস করতে এবং ওয়েব পেজে প্রদর্শন করতে দেয়।
কিন্তু ব্রাউজার আসলে কী? এটি একটি সফটওয়্যার অ্যাপ্লিকেশন যা ব্যবহারকারীকে সার্ভার থেকে কন্টেন্ট অ্যাক্সেস করতে এবং ওয়েব পেজে প্রদর্শন করতে দেয়।
✅ একটি ছোট ইতিহাস: প্রথম ব্রাউজারের নাম ছিল 'WorldWideWeb' এবং এটি ১৯৯০ সালে স্যার টিমোথি বার্নার্স-লি তৈরি করেছিলেন।
✅ একট ইতিহাস: প্রথম ব্রাউজারের নাম ছিল 'WorldWideWeb', যা ১৯৯০ সালে স্যার টিমোথি বার্নার্স-লি তৈরি করেছিলেন।
![প্রথম দিকের ব্রাউজার](../../../../translated_images/earlybrowsers.d984b711cdf3a42ddac919d46c4b5ca7232f68ccfbd81395e04e5a64c0015277.bn.jpg)
> কিছু প্রথম দিকের ব্রাউজার, [Karen McGrane](https://www.slideshare.net/KMcGrane/week-4-ixd-history-personal-computing) এর মাধ্যমে
> কিছু প্রথম দিকের ব্রাউজার, সূত্র: [ক্যারেন ম্যাকগ্রেন](https://www.slideshare.net/KMcGrane/week-4-ixd-history-personal-computing)
যখন একজন ব্যবহারকারী একটি URL (Uniform Resource Locator) ঠিকানা ব্যবহার করে ইন্টারনেটে সংযুক্ত হন, সাধারণত Hypertext Transfer Protocol এর মাধ্যমে `http` বা `https` ঠিকানা ব্যবহার করে, তখন ব্রাউজার একটি ওয়েব সার্ভারের সাথে যোগাযোগ করে এবং একটি ওয়েব পেজ নিয়ে আসে।
যখন একজন ব্যবহারকারী URL (Uniform Resource Locator) ঠিকানা ব্যবহার করে ইন্টারনেটে সংযুক্ত হন, সাধারণত Hypertext Transfer Protocol ব্যবহার করে `http` বা `https` ঠিকানা দিয়ে, ব্রাউজার একটি ওয়েব সার্ভারের সাথে যোগাযোগ করে এবং একটি ওয়েব পেজ নিয়ে আসে।
এই পর্যায়ে, ব্রাউজারের রেন্ডারিং ইঞ্জিন এটি ব্যবহারকারীর ডিভাইসে প্রদর্শন করে, যা একটি মোবাইল ফোন, ডেস্কটপ বা ল্যাপটপ হতে পারে
এই পর্যায়ে, ব্রাউজারের রেন্ডারিং ইঞ্জিন এটি ব্যবহারকারীর ডিভাইসে প্রদর্শন করে, যা হতে পারে একটি মোবাইল ফোন, ডেস্কটপ বা ল্যাপটপ।
ব্রাউজার কন্টেন্ট ক্যাশ করার ক্ষমতা রাখে যাতে এটি প্রতিবার সার্ভার থেকে পুনরুদ্ধার করতে না হয়। এটি ব্যবহারকারীর ব্রাউজিং কার্যকলাপের ইতিহাস রেকর্ড করতে পারে, 'কুকিজ' সংরক্ষণ করতে পারে, যা ছোট ডেটার টুকরা যা ব্যবহারকারীর কার্যকলাপ সংরক্ষণ করতে ব্যবহৃত হয়, এবং আরও অনেক কিছু।
ব্রাউজার কন্টেন্ট ক্যাশ করার ক্ষমতা রাখে যাতে এটি প্রতিবার সার্ভার থেকে পুনরুদ্ধার করতে না হয়। এটি ব্যবহারকারীর ব্রাউজিং কার্যকলাপের ইতিহাস রেকর্ড করতে পারে, 'কুকিজ' সংরক্ষণ করতে পারে, যা ছোট ডেটা যা ব্যবহারকারীর কার্যকলাপ সংরক্ষণ করতে ব্যবহৃত হয়, এবং আরও অনেক কিছু।
একটি গুরুত্বপূর্ণ বিষয় মনে রাখার মতো হলো, সব ব্রাউজার এক নয়! প্রতিটি ব্রাউজারের নিজস্ব শক্তি এবং দুর্বলতা রয়েছে, এবং একজন পেশাদার ওয়েব ডেভেলপারকে বুঝতে হবে কীভাবে ওয়েব পেজগুলোকে ক্রস-ব্রাউজারে ভালোভাবে পারফর্ম করানো যায়। এর মধ্যে ছোট ভিউপোর্ট যেমন মোবাইল ফোনের, এবং অফলাইনে থাকা ব্যবহারকারীর জন্য সমাধান অন্তর্ভুক্ত।
ব্রাউজার সম্পর্কে একটি গুরুত্বপূর্ণ বিষয় মনে রাখা দরকার যে সব ব্রাউজার একরকম নয়! প্রতিটি ব্রাউজারের নিজস্ব শক্তি এবং দুর্বলতা রয়েছে, এবং একজন পেশাদার ওয়েব ডেভেলপারকে বুঝতে হবে কীভাবে ওয়েব পেজগুলোকে ক্রস-ব্রাউজারে ভালোভাবে পারফর্ম করানো যায়। এর মধ্যে ছোট ভিউপোর্ট যেমন মোবাইল ফোনের, এবং অফলাইনে থাকা ব্যবহারকারীর জন্য সমর্থন অন্তর্ভুক্ত।
একটি খুব দরকারী ওয়েবসাইট যা আপনি সম্ভবত আপনার পছন্দের ব্রাউজারে বুকমার্ক করতে চাইবেন তা হলো [caniuse.com](https://www.caniuse.com)। যখন আপনি ওয়েব পেজ তৈরি করছেন, তখন caniuse-এর সমর্থিত প্রযুক্তির তালিকা ব্যবহার করা খুবই সহায়ক যাতে আপনি আপনার ব্যবহারকারীদের সর্বোত্তম সমর্থন দিতে পারেন
একটি খুব দরকারী ওয়েবসাইট যা আপনি সম্ভবত আপনার পছন্দের ব্রাউজারে বুকমার্ক করতে চাইবেন তা হলো [caniuse.com](https://www.caniuse.com)। যখন আপনি ওয়েব পেজ তৈরি করছেন, তখন ব্যবহারকারীদের সর্বোত্তম সমর্থন দেওয়ার জন্য caniuse-এর সমর্থিত প্রযুক্তির তালিকা ব্যবহার করা খুবই সহায়ক।
✅ কীভাবে আপনি বুঝবেন কোন ব্রাউজারগুলো আপনার ওয়েব সাইটের ব্যবহারকারীদের মধ্যে সবচেয়ে জনপ্রিয়? আপনার অ্যানালিটিক্স চেক করুন - আপনি আপনার ওয়েব ডেভেলপমেন্ট প্রক্রিয়ার অংশ হিসেবে বিভিন্ন অ্যানালিটিক্স প্যাকেজ ইনস্টল করতে পারেন, এবং সেগুলো আপনাকে জানাবে কোন ব্রাউজারগুলো সবচেয়ে বেশি ব্যবহৃত হচ্ছে
✅ কীভাবে আপনি জানতে পারবেন কোন ব্রাউজার আপনার ওয়েব সাইটের ব্যবহারকারীদের মধ্যে সবচেয়ে জনপ্রিয়? আপনার অ্যানালিটিক্স চেক করুন - আপনি আপনার ওয়েব ডেভেলপমেন্ট প্রক্রিয়ার অংশ হিসেবে বিভিন্ন অ্যানালিটিক্স প্যাকেজ ইনস্টল করতে পারেন, এবং সেগুলো আপনাকে জানাবে কোন ব্রাউজারগুলো সবচেয়ে বেশি ব্যবহৃত হয়
## ব্রাউজার এক্সটেনশন
আপনি কেন একটি ব্রাউজার এক্সটেনশন তৈরি করতে চাইবেন? এটি একটি সুবিধাজনক জিনিস যা আপনার ব্রাউজারে সংযুক্ত করা যায় যখন আপনি এমন কাজগুলোর দ্রুত অ্যাক্সেস চান যা আপনি বারবার করেন। উদাহরণস্বরূপ, যদি আপনি বিভিন্ন ওয়েব পেজে রঙ চেক করার প্রয়োজন অনুভব করেন, আপনি একটি কালার-পিকার ব্রাউজার এক্সটেনশন ইনস্টল করতে পারেন। যদি আপনি পাসওয়ার্ড মনে রাখতে অসুবিধা বোধ করেন, আপনি একটি পাসওয়ার্ড-ম্যানেজমেন্ট ব্রাউজার এক্সটেনশন ব্যবহার করতে পারেন।
কেন আপনি একটি ব্রাউজার এক্সটেনশন তৈরি করতে চাইবেন? এটি একটি সুবিধাজনক জিনিস যা ব্রাউজারে সংযুক্ত করা যায় যখন আপনি এমন কাজগুলোর দ্রুত অ্যাক্সেস চান যা আপনি বারবার করেন। উদাহরণস্বরূপ, যদি আপনি বিভিন্ন ওয়েব পেজে রঙ চেক করতে চান, আপনি একটি কালার-পিকার ব্রাউজার এক্সটেনশন ইনস্টল করতে পারেন। যদি আপনি পাসওয়ার্ড মনে রাখতে অসুবিধা করেন, আপনি একটি পাসওয়ার্ড-ম্যানেজমেন্ট ব্রাউজার এক্সটেনশন ব্যবহার করতে পারেন।
ব্রাউজার এক্সটেনশন তৈরি করাও মজার। এগুলো সাধারণত সীমিত সংখ্যক কাজ পরিচালনা করে যা তারা ভালোভাবে সম্পাদন করে।
@ -53,59 +53,59 @@ CO_OP_TRANSLATOR_METADATA:
### এক্সটেনশন ইনস্টল করা
তৈরি করার আগে, ব্রাউজার এক্সটেনশন তৈরি এবং ডিপ্লয় করার প্রক্রিয়াটি দেখে নিন। যদিও প্রতিটি ব্রাউজার এই কাজটি পরিচালনার ক্ষেত্রে কিছুটা ভিন্ন, Chrome এবং Firefox-এ প্রক্রিয়াটি Edge-এর এই উদাহরণের মতো:
তৈরি করার আগে, ব্রাউজার এক্সটেনশন তৈরি এবং ডিপ্লয় করার প্রক্রিয়া দেখে নিন। যদিও প্রতিটি ব্রাউজার এই কাজটি পরিচালনার ক্ষেত্রে কিছুটা ভিন্ন, Chrome এবং Firefox-এ প্রক্রিয়াটি Edge-এর এই উদাহরণের মতো:
![Edge ব্রাউজারের স্ক্রিনশট যেখানে edge://extensions পেজ এবং সেটিংস মেনু খোলা রয়েছে](../../../../translated_images/install-on-edge.d68781acaf0b3d3dada8b7507cde7a64bf74b7040d9818baaa9070668e819f90.bn.png)
> নোট: ডেভেলপার মোড চালু করতে এবং অন্যান্য স্টোর থেকে এক্সটেনশন অনুমোদন করতে ভুলবেন না
> নোট: ডেভেলপার মোড চালু করুন এবং অন্যান্য স্টোর থেকে এক্সটেনশন অনুমতি দিন
মূলত, প্রক্রিয়াটি হবে:
- `npm run build` ব্যবহার করে আপনার এক্সটেনশন তৈরি করুন
- ব্রাউজারে "Settings and more" বোতাম (উপরের ডানদিকে `...` আইকন) ব্যবহার করে এক্সটেনশন পেইজে যান
- যদি এটি একটি নতুন ইনস্টলেশন হয়, তাহলে `load unpacked` নির্বাচন করুন এবং বিল্ড ফোল্ডার থেকে একটি নতুন এক্সটেনশন আপলোড করুন (আমাদের ক্ষেত্রে এটি `/dist`)
- অথবা, যদি ইতিমধ্যে ইনস্টল করা এক্সটেনশনটি পুনরায় লোড করতে চান, তাহলে `reload` ক্লিক করুন
- `npm run build` ব্যবহার করে আপনার এক্সটেনশন তৈরি করুন
- ব্রাউজারে "Settings and more" বোতাম (উপরের ডানদিকে থাকা `...` আইকন) ব্যবহার করে এক্সটেনশন প্যান-এ যান
- যদি এটি একটি নতুন ইনস্টলেশন হয়, `load unpacked` নির্বাচন করুন এবং এর বিল্ড ফোল্ডার থেকে একটি নতুন এক্সটেনশন আপলোড করুন (আমাদের ক্ষেত্রে এটি `/dist`)
- অথবা, যদি আপনি ইতিমধ্যে ইনস্টল করা এক্সটেনশনটি পুনরায় লোড করছেন, তাহলে `reload` ক্লিক করুন
✅ এই নির্দেশনাগুলো আপনার নিজের তৈরি এক্সটেনশনের জন্য প্রযোজ্য; ব্রাউজারের সংশ্লিষ্ট এক্সটেনশন স্টোরে প্রকাশিত এক্সটেনশন ইনস্টল করতে, আপনাকে সেই [স্টোরগুলোতে](https://microsoftedge.microsoft.com/addons/Microsoft-Edge-Extensions-Home) যেতে হবে এবং আপনার পছন্দের এক্সটেনশন ইনস্টল করতে হবে।
✅ এই নির্দেশনাগুলো আপনার তৈরি করা এক্সটেনশনের জন্য প্রযোজ্য; ব্রাউজার এক্সটেনশন স্টোরে প্রকাশিত এক্সটেনশন ইনস্টল করতে, আপনাকে সংশ্লিষ্ট [স্টোরগুলোতে](https://microsoftedge.microsoft.com/addons/Microsoft-Edge-Extensions-Home) যেতে হবে এবং আপনার পছন্দের এক্সটেনশন ইনস্টল করতে হবে।
### শুরু করুন
আপনি একটি ব্রাউজার এক্সটেনশন তৈরি করতে যাচ্ছেন যা আপনার অঞ্চলের কার্বন ফুটপ্রিন্ট প্রদর্শন করবে, আপনার অঞ্চলের শক্তি ব্যবহারের পরিমাণ এবং শক্তির উৎস দেখাবে। এক্সটেনশনে একটি ফর্ম থাকবে যা একটি API কী সংগ্রহ করবে যাতে আপনি CO2 Signal-এর API অ্যাক্সেস করতে পারেন।
আপনি একটি ব্রাউজার এক্সটেনশন তৈরি করতে যাচ্ছেন যা আপনার অঞ্চলের কার্বন ফুটপ্রিন্ট প্রদর্শন করবে, আপনার অঞ্চলের শক্তি ব্যবহারের পরিমাণ এবং শক্তির উৎস দেখাবে। এক্সটেনশনে একটি ফর্ম থাকবে যা API কী সংগ্রহ করবে যাতে আপনি CO2 Signal-এর API অ্যাক্সেস করতে পারেন।
**আপনার যা প্রয়োজন:**
**আপনার যা দরকার:**
- [একটি API কী](https://www.co2signal.com/); এই পৃষ্ঠায় আপনার ইমেইল প্রবেশ করান এবং একটি কী আপনার কাছে পাঠানো হবে
- [আপনার অঞ্চলের কোড](http://api.electricitymap.org/v3/zones) যা [Electricity Map](https://www.electricitymap.org/map)-এর সাথে সম্পর্কিত (উদাহরণস্বরূপ, বোস্টনে আমি 'US-NEISO' ব্যবহার করি)
- [স্টার্টার কোড](../../../../5-browser-extension/start)। `start` ফোল্ডারটি ডাউনলোড করুন; আপনি এই ফোল্ডারের কোড সম্পূর্ণ করবেন
- [NPM](https://www.npmjs.com) - NPM একটি প্যাকেজ ম্যানেজমেন্ট টুল; এটি লোকালভাবে ইনস্টল করুন এবং আপনার `package.json` ফাইলে তালিকাভুক্ত প্যাকেজগুলো আপনার ওয়েব অ্যাসেটের জন্য ইনস্টল হবে
- [একটি API কী](https://www.co2signal.com/); এই পেজে আপনার ইমেইল প্রবেশ করান এবং একটি কী আপনার কাছে পাঠানো হবে
- [আপনার অঞ্চলের কোড](http://api.electricitymap.org/v3/zones) যা [Electricity Map](https://www.electricitymap.org/map)-এর সাথে সম্পর্কিত (বস্টনে, উদাহরণস্বরূপ, আমি 'US-NEISO' ব্যবহার করি)
- [স্টার্টার কোড](../../../../5-browser-extension/start)। `start` ফোল্ডারটি ডাউনলোড করুন; আপনি এই ফোল্ডারে কোড সম্পন্ন করবেন।
- [NPM](https://www.npmjs.com) - NPM একটি প্যাকেজ ম্যানেজমেন্ট টুল; এটি লোকালভাবে ইনস্টল করুন এবং আপনার `package.json` ফাইলে তালিকাভুক্ত প্যাকেজগুলো আপনার ওয়েব অ্যাসেটের জন্য ইনস্টল হবে
✅ প্যাকেজ ম্যানেজমেন্ট সম্পর্কে আরও জানুন এই [চমৎকার লার্ন মডিউলে](https://docs.microsoft.com/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-77807-sagibbon)
কোডবেসটি একবার দেখে নিন:
dist
-|manifest.json (ডিফল্ট সেটিংস এখানে)
-|index.html (ফ্রন্ট-এন্ড HTML মার্কআপ এখানে)
-|background.js (ব্যাকগ্রাউন্ড JS এখানে)
-|main.js (বিল্ট JS)
src
-|index.js (আপনার JS কোড এখানে যাবে)
dist
-|manifest.json (ডিফল্ট সেটিংস এখানে)
-|index.html (ফ্রন্ট-এন্ড HTML মার্কআপ এখানে)
-|background.js (ব্যাকগ্রাউন্ড JS এখানে)
-|main.js (বিল্ট JS)
src
-|index.js (আপনার JS কোড এখানে)
✅ একবার আপনার API কী এবং অঞ্চল কোড প্রস্তুত হয়ে গেলে, সেগুলো ভবিষ্যতে ব্যবহারের জন্য একটি নোটে সংরক্ষণ করুন।
✅ একবার আপনার API কী এবং অঞ্চল কোড প্রস্তুত হয়ে গেলে, সেগুলো ভবিষ্যতে ব্যবহারের জন্য একটি নোটে সংরক্ষণ করুন।
### এক্সটেনশনের জন্য HTML তৈরি করুন
### এক্সটেনশনের HTML তৈরি করুন
এই এক্সটেনশনের দুটি ভিউ রয়েছে। একটি API কী এবং অঞ্চল কোড সংগ্রহ করার জন্য:
![সম্পূর্ণ এক্সটেনশনের স্ক্রিনশট যেখানে একটি ফর্ম প্রদর্শিত হচ্ছে যা অঞ্চল নাম এবং API কী ইনপুটের জন্য](../../../../translated_images/1.b6da8c1394b07491afeb6b2a8e5aca73ebd3cf478e27bcc9aeabb187e722648e.bn.png)
![সম্পূর্ণ এক্সটেনশনের স্ক্রিনশট যেখানে একটি ফর্ম প্রদর্শিত হচ্ছে যা অঞ্চল নাম এবং API কী-এর জন্য ইনপুট রয়েছে।](../../../../translated_images/1.b6da8c1394b07491afeb6b2a8e5aca73ebd3cf478e27bcc9aeabb187e722648e.bn.png)
এবং দ্বিতীয়টি অঞ্চলের কার্বন ব্যবহারের তথ্য প্রদর্শনের জন্য:
![সম্পূর্ণ এক্সটেনশনের স্ক্রিনশট যেখানে US-NEISO অঞ্চলের কার্বন ব্যবহারের মান এবং জীবাশ্ম জ্বালানির শতাংশ প্রদর্শিত হচ্ছে](../../../../translated_images/2.1dae52ff0804224692cd648afbf2342955d7afe3b0101b617268130dfb427f55.bn.png)
![সম্পূর্ণ এক্সটেনশনের স্ক্রিনশট যেখানে US-NEISO অঞ্চলের কার্বন ব্যবহারের মান এবং জীবাশ্ম জ্বালানির শতাংশ প্রদর্শিত হচ্ছে](../../../../translated_images/2.1dae52ff0804224692cd648afbf2342955d7afe3b0101b617268130dfb427f55.bn.png)
চলুন ফর্মের HTML তৈরি করা এবং CSS দিয়ে এটি স্টাইল করা শুরু করি।
চলুন ফর্মের HTML তৈরি করা শুরু করি এবং CSS দিয়ে এটি স্টাইল করি।
`/dist` ফোল্ডারে, আপনি একটি ফর্ম এবং একটি রেজাল্ট এরিয়া তৈরি করবেন। `index.html` ফাইলে, নির্ধারিত ফর্ম এরিয়াটি পূরণ করুন:
`/dist` ফোল্ডারে, আপনি একটি ফর্ম এবং একটি ফলাফল এলাকা তৈরি করবেন। `index.html` ফাইলের ফর্ম এলাকায় নিম্নলিখিত কোড যোগ করুন:
```HTML
<form class="form-data" autocomplete="on">
@ -122,10 +122,10 @@ src
</div>
<button class="search-btn">Submit</button>
</form>
```
এটি সেই ফর্ম যেখানে আপনার সংরক্ষিত তথ্য ইনপুট এবং লোকাল স্টোরেজে সংরক্ষণ করা হবে।
```
এটি সেই ফর্ম যেখানে আপনার সংরক্ষিত তথ্য ইনপুট হবে এবং লোকাল স্টোরেজে সংরক্ষিত হবে।
এরপর, রেজাল্ট এরিয়া তৈরি করুন; চূড়ান্ত ফর্ম ট্যাগের নিচে কিছু div যোগ করুন:
এরপর, ফলাফল এলাকা তৈরি করুন; চূড়ান্ত ফর্ম ট্যাগের নিচে কিছু div যোগ করুন:
```HTML
<div class="result">
@ -139,24 +139,24 @@ src
</div>
<button class="clear-btn">Change region</button>
</div>
```
এই পর্যায়ে, আপনি একটি বিল্ড চেষ্টা করতে পারেন। নিশ্চিত করুন যে এই এক্সটেনশনের প্যাকেজ ডিপেনডেন্সিগুলো ইনস্টল করেছে:
```
এই পর্যায়ে, আপনি একটি বিল্ড চেষ্টা করতে পারেন। নিশ্চিত করুন যে এই এক্সটেনশনের প্যাকেজ ডিপেনডেন্সিগুলো ইনস্টল করা হয়েছে:
```
npm install
```
```
এই কমান্ডটি npm, Node Package Manager, ব্যবহার করে আপনার এক্সটেনশনের বিল্ড প্রক্রিয়ার জন্য webpack ইনস্টল করবে। আপনি `/dist/main.js`-এ এই প্রক্রিয়ার আউটপুট দেখতে পারেন - আপনি দেখবেন কোডটি বান্ডল করা হয়েছে।
এই কমান্ডটি npm, Node Package Manager ব্যবহার করে আপনার এক্সটেনশনের বিল্ড প্রক্রিয়ার জন্য webpack ইনস্টল করবে। আপনি `/dist/main.js`-এ এই প্রক্রিয়ার আউটপুট দেখতে পারেন - আপনি দেখতে পাবেন কোডটি বান্ডল করা হয়েছে।
এখন, এক্সটেনশনটি তৈরি হওয়া উচিত এবং যদি আপনি এটি Edge-এ একটি এক্সটেনশন হিসেবে ডিপ্লয় করেন, তাহলে আপনি একটি সুন্দরভাবে প্রদর্শিত ফর্ম দেখতে পাবেন।
এখন, এক্সটেনশনটি তৈরি হওয়া উচিত এবং যদি আপনি এটি Edge-এ এক্সটেনশন হিসেবে ডিপ্লয় করেন, আপনি একটি সুন্দরভাবে প্রদর্শিত ফর্ম দেখতে পাবেন।
অভিনন্দন, আপনি একটি ব্রাউজার এক্সটেনশন তৈরির প্রথম ধাপ সম্পন্ন করেছেন। পরবর্তী পাঠগুলোতে, আপনি এটিকে আরও কার্যকর এবং উপযোগী করবেন।
অভিনন্দন, আপনি একটি ব্রাউজার এক্সটেনশন তৈরি করার প্রথম ধাপ সম্পন্ন করেছেন। পরবর্তী পাঠগুলোতে, আপনি এটি আরও কার্যকর এবং উপযোগী করবেন।
---
## 🚀 চ্যালেঞ্জ
একটি ব্রাউজার এক্সটেনশন স্টোর দেখুন এবং একটি এক্সটেনশন আপনার ব্রাউজারে ইনস্টল করুন। আপনি এর ফাইলগুলো আকর্ষণীয় উপায়ে পরীক্ষা করতে পারেন। আপনি কী আবিষ্কার করেন?
একটি ব্রাউজার এক্সটেনশন স্টোর দেখুন এবং একটি আপনার ব্রাউজারে ইনস্টল করুন। আপনি এর ফাইলগুলো আকর্ষণীয় উপায়ে পরীক্ষা করতে পারেন। আপনি কী আবিষ্কার করেন?
## পোস্ট-লেকচার কুইজ
@ -164,17 +164,19 @@ npm install
## পর্যালোচনা ও স্ব-অধ্যয়ন
এই পাঠে আপনি ওয়েব ব্রাউজারের ইতিহাস সম্পর্কে কিছু শিখেছেন; এই সুযোগটি নিন এবং ওয়ার্ল্ড ওয়াইড ওয়েবের উদ্ভাবকরা কীভাবে এর ব্যবহার কল্পনা করেছিলেন তা জানতে এর ইতিহাস সম্পর্কে আরও পড়ুন। কিছু দরকারী সাইট:
এই পাঠে আপনি ওয়েব ব্রাউজারের ইতিহাস সম্পর্কে কিছু শিখেছেন; এই সুযোগটি নিন এবং World Wide Web-এর আবিষ্কারকরা এর ব্যবহার সম্পর্কে কীভাবে কল্পনা করেছিলেন তা জানুন। এর ইতিহাস সম্পর্কে আরও পড়ার জন্য কিছু সহায়ক সাইট:
[ওয়েব ব্রাউজারের ইতিহাস](https://www.mozilla.org/firefox/browsers/browser-history/)
[ওয়েবের ইতিহাস](https://webfoundation.org/about/vision/history-of-the-web/)
[টিম বার্নার্স-লির একটি সাক্ষাৎকার](https://www.theguardian.com/technology/2019/mar/12/tim-berners-lee-on-30-years-of-the-web-if-we-dream-a-little-we-can-get-the-web-we-want)
[টিম বার্নার্স-লির সাথে একটি সাক্ষাৎকার](https://www.theguardian.com/technology/2019/mar/12/tim-berners-lee-on-30-years-of-the-web-if-we-dream-a-little-we-can-get-the-web-we-want)
## অ্যাসাইনমেন্ট
## অ্যাসাইনমেন্ট
[আপনার এক্সটেনশন পুনরায় স্টাইল করুন](assignment.md)
[আপনার এক্সটেনশন পুনরায় স্টাইল করুন](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়ী থাকব না
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিক অনুবাদের চেষ্টা করি, তবে দয়া করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। নথিটির মূল ভাষায় লেখা সংস্করণটিকেই প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে সৃষ্ট কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যার জন্য আমরা দায়ী নই

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e10f168beac4e7b05e30e0eb5c92bf11",
"translation_date": "2025-08-25T23:29:21+00:00",
"original_hash": "a7587943d38d095de8613e1b508609f5",
"translation_date": "2025-08-28T22:57:16+00:00",
"source_file": "5-browser-extension/2-forms-browsers-local-storage/README.md",
"language_code": "bn"
}
@ -23,7 +23,7 @@ CO_OP_TRANSLATOR_METADATA:
এখন পর্যন্ত আপনি আপনার ব্রাউজার এক্সটেনশনের জন্য ফর্ম এবং ফলাফলের `<div>` এর HTML তৈরি করেছেন। এখন থেকে, আপনাকে `/src/index.js` ফাইলে কাজ করতে হবে এবং ধাপে ধাপে আপনার এক্সটেনশন তৈরি করতে হবে। আপনার প্রকল্প সেট আপ এবং বিল্ড প্রসেস সম্পর্কে জানার জন্য [পূর্ববর্তী পাঠ](../1-about-browsers/README.md) দেখুন।
`index.js` ফাইলে কাজ শুরু করে, কিছু `const` ভেরিয়েবল তৈরি করুন যা বিভিন্ন ফিল্ডের সাথে সম্পর্কিত মান ধারণ করবে:
`index.js` ফাইলে কাজ শুরু করে, বিভিন্ন ফিল্ডের সাথে সম্পর্কিত মানগুলি ধরে রাখার জন্য কিছু `const` ভেরিয়েবল তৈরি করুন:
```JavaScript
// form fields
@ -41,7 +41,7 @@ const myregion = document.querySelector('.my-region');
const clearBtn = document.querySelector('.clear-btn');
```
এই সমস্ত ফিল্ডগুলি তাদের CSS ক্লাস দ্বারা রেফারেন্স করা হয়েছে, যেভবে আপনি এটি পূর্ববর্তী পাঠে HTML-এ সেট আপ করেছিলেন।
এই সমস্ত ফিল্ডগুলি তাদের CSS ক্লাস দ্বারা রেফারেন্স করা হয়েছে, যা আপনি পূর্ববর্তী পাঠে HTML-এ সেট আপ করেছিলেন।
### লিসেনার যোগ করুন
@ -57,7 +57,7 @@ init();
### init() ফাংশন এবং reset() ফাংশন তৈরি করুন:
এখন আপনি এক্সটেনশনটি ইনিশিয়ালাইজ করার জন্য ফাংশন তৈরি করবেন, যা init() নামে ডাকা হয়:
এখন আপনি এক্সটেনশনটি ইনিশিয়ালাইজ করার ফাংশন তৈরি করবেন, যা init() নামে ডাকা হয়:
```JavaScript
function init() {
@ -96,31 +96,31 @@ function reset(e) {
এই ফাংশনে কিছু আকর্ষণীয় লজিক রয়েছে। এটি পড়ে আপনি দেখতে পাচ্ছেন কী ঘটে?
- দুটি `const` সেট আপ করা হয়েছে চেক করতে যে ব্যবহারকারী লোকাল স্টোরেজে APIKey এবং region কোড সংরক্ষণ করেছেন কিনা।
- যদি এর যেকোনো একটি null হয়, ফর্মটি প্রদর্শন করুন এবং এর স্টাইল 'block' হিসেবে সেট করুন।
- ফলাফল, লোডিং এবং clearBtn লুকিয়ে রখুন এবং যেকোনো ত্রুটির টেক্সট খালি স্ট্রিংয়ে সেট করুন।
- যদি এর যেকোনো একটি null হয়, ফর্মটি প্রদর্শন করুন এবং এর স্টাইল 'block' এ পরিবর্তন করুন।
- ফলাফল, লোডিং এবং clearBtn লুকান এবং যেকোনো ত্রুটির টেক্সট খালি স্ট্রিংয়ে সেট করুন।
- যদি একটি key এবং region থাকে, একটি রুটিন শুরু করুন:
- API কল করে কার্বন ব্যবহারের ডেটা পান।
- ফলাফল এলাকা লুকান।
- ফর্ম লুকান।
- রিসেট বোতাম দেখান।
পরবর্তী অংশে যাওয়ার আগে, ব্রাউজারে উপলব্ধ একটি খুব গুরুত্বপূর্ণ ধারণা সম্পর্কে শেখা দরকার: [LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage)। LocalStorage একটি দরকারী উপায় ব্রাউজারে স্ট্রিং সংরক্ষণ করার জন্য একটি `key-value` জোড়া হিসবে। এই ধরনের ওয়েব স্টোরেজ জাভাস্ক্রিপ্ট দ্বারা ম্যানিপুলেট করা যায় ব্রাউজারে ডেটা পরিচালনা করতে। LocalStorage মেয়াদোত্তীর্ণ হয় না, যেখানে SessionStorage, আরেক ধরনের ওয়েব স্টোরেজ, ব্রাউজার বন্ধ হলে সাফ হয়ে যায়। বিভিন্ন ধরনের স্টোরেজের ব্যবহারে সুবিধা এবং অসুবিধা রয়েছে।
পরবর্তী ধাপে যাওয়ার আগে, ব্রাউজারে উপলব্ধ একটি খুব গুরুত্বপূর্ণ ধারণা সম্পর্কে শেখা দরকার: [LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage)। LocalStorage একটি দরকারী উপায় ব্রাউজারে স্ট্রিং সংরক্ষণ করার জন্য একটি `key-value` জোড়া হিসবে। এই ধরনের ওয়েব স্টোরেজ জাভাস্ক্রিপ্ট দ্বারা ম্যানিপুলেট করা যায় ব্রাউজারে ডেটা পরিচালনা করতে। LocalStorage মেয়াদোত্তীর্ণ হয় না, যেখানে SessionStorage, আরেক ধরনের ওয়েব স্টোরেজ, ব্রাউজার বন্ধ হলে সাফ হয়ে যায়। বিভিন্ন ধরনের স্টোরেজের ব্যবহারে সুবিধা এবং অসুবিধা রয়েছে।
> নোট - আপনার ব্রাউজার এক্সটেনশনের নিজস্ব লোকাল স্টোরেজ রয়েছে; প্রধান ব্রাউজার উইন্ডো একটি ভিন্ন ইনস্ট্যান্স এবং আলাদাভাবে আচরণ করে।
আপনার APIKey একটি স্ট্রিং মান হিসেবে সেট করুন, উদাহরণস্বরূপ, এবং আপনি দেখতে পাবেন এটি Edge-এ সেট করা হয়েছে একটি ওয়েব পেজ "ইন্সপেক্ট" করে (আপনি ব্রাউজারে ডান-ক্লিক করে ইন্সপেক্ট করতে পারেন) এবং অ্যাপ্লিকেশন ট্যাবে গিয়ে স্টোরেজ দেখতে পারেন।
আপনার APIKey একটি স্ট্রিং মানে সেট করুন, উদাহরণস্বরূপ, এবং আপনি দেখতে পাবেন এটি Edge-এ সেট করা হয়েছে একটি ওয়েব পেজ "ইন্সপেক্ট" করে (আপনি ব্রাউজারে ডান ক্লিক করে ইন্সপেক্ট করতে পারেন) এবং অ্যাপ্লিকেশন ট্যাবে গিয়ে স্টোরেজ দেখতে পারেন।
![লোকাল স্টোরেজ প্যান](../../../../translated_images/localstorage.472f8147b6a3f8d141d9551c95a2da610ac9a3c6a73d4a1c224081c98bae09d9.bn.png)
✅ এমন পরিস্থিতি নিয়ে ভাবুন যেখানে আপনি কিছু ডেটা LocalStorage-এ সংরক্ষণ করতে চান না। সাধারণত, LocalStorage-এ API Keys রাখা একটি খারাপ ধারণা! আপনি কেন তা দেখতে পাচ্ছেন? আমাদের ক্ষেত্রে, যেহেতু আমাদের অ্যাপটি শুধুমাত্র শেখার জন্য এবং এটি অ্যাপ স্টোরে প্রকাশিত হবে না, আমরা এই পদ্ধতি ব্যবহার করব।
✅ এমন পরিস্থিতি নিয়ে ভাবুন যেখানে আপনি কিছু ডেটা LocalStorage-এ সংরক্ষণ করতে চান না। সাধারণত, LocalStorage-এ API Keys রাখা একটি খারাপ ধারণা! কেন তা আপনি দেখতে পাচ্ছেন? আমাদের ক্ষেত্রে, যেহেতু আমাদের অ্যাপটি শুধুমাত্র শেখার জন্য এবং এটি অ্যাপ স্টোরে প্রকাশিত হবে না, আমরা এই পদ্ধতি ব্যবহার করব।
লক্ষ্য করুন যে আপনি LocalStorage ম্যানিপুলেট করতে Web API ব্যবহার করেন, হয় `getItem()`, `setItem()`, বা `removeItem()` ব্যবহার করে। এটি ব্রাউজার জুড়ে ব্যাপকভাবে সমর্থিত।
আপনি LocalStorage ম্যানিপুলেট করতে Web API ব্যবহার করেন, হয় `getItem()`, `setItem()`, বা `removeItem()` ব্যবহার করে। এটি ব্রাউজার জুড়ে ব্যাপকভাবে সমর্থিত।
`displayCarbonUsage()` ফাংশন তৈরি করার আগে যা `init()`-এ ডাকা হয়, চলুন প্রাথমিক ফর্ম জমা দেওয়ার কার্যকারিতা তৈরি করি।
`displayCarbonUsage()` ফাংশন তৈরি করার আগে যা `init()`-এ ডাকা হয়, আসুন প্রাথমিক ফর্ম জমা দেওয়ার কার্যকারিতা তৈরি করি।
### ফর্ম জমা দেওয়া পরিচালনা করুন
`handleSubmit` নামে একটি ফাংশন তৈরি করুন যা একটি ইভেন্ট আর্গুমেন্ট `(e)` গ্রহণ করে। ইভেন্টটি প্রচারিত হওয়া থেকে থামান (এই ক্ষেত্রে, আমরা ব্রাউজারকে রিফ্রেশ হওয়া থেকে থামাতে চাই) এবং একটি নতুন ফাংশন `setUpUser` কল করুন, আর্গুমেন্ট হিসবে `apiKey.value` এবং `region.value` পাস করে। এইভাবে, আপনি প্রাথমিক ফর্মের মাধ্যমে আনা দুটি মান ব্যবহার করেন যখন প্রাসঙ্গিক ফিল্ডগুলি পূরণ করা হয়।
`handleSubmit` নামে একটি ফাংশন তৈরি করুন যা একটি ইভেন্ট আর্গুমেন্ট `(e)` গ্রহণ করে। ইভেন্টটি প্রচারিত হওয়া থেকে থামান (এই ক্ষেত্রে, আমরা ব্রাউজারকে রিফ্রেশ হওয়া থেকে থামাতে চাই) এবং একটি নতুন ফাংশন `setUpUser` কল করুন, আর্গুমেন্ট হিসবে `apiKey.value` এবং `region.value` পাস করে। এইভাবে, আপনি প্রাথমিক ফর্মের মাধ্যমে আনা দুটি মান ব্যবহার করেন যখন প্রাসঙ্গিক ফিল্ডগুলি পূরণ করা হয়।
```JavaScript
function handleSubmit(e) {
@ -129,7 +129,7 @@ function handleSubmit(e) {
}
```
✅ আপনার স্মৃতি সতেজ করুন - পূর্ববর্তী পাঠে আপনি যে HTML সেট আপ করেছিলেন তাতে দুটি ইনপুট ফিল্ড রয়েছে যার `values` আপনি ফাইলের শীর্ষে সেট করা `const` এর মাধ্যমে ক্যাপচার করেন এবং সেগুলি উভয়ই `required` যাতে ব্রাউজার ব্যবহারকারীদের null মান ইনপুট করা থেকে থামায়।
✅ আপনার স্মৃতি সতেজ করুন - পূর্ববর্তী পাঠে আপনি যে HTML সেট আপ করেছিলেন তাতে দুটি ইনপুট ফিল্ড রয়েছে যার `values` আপনি ফাইলের শীর্ষে সেট করা `const` এর মাধ্যমে ক্যাপচার করেন, এবং সেগুলি উভয়ই `required` যাতে ব্রাউজার ব্যবহারকারীদের null মান ইনপুট করা থেকে থামায়।
### ব্যবহারকারী সেট আপ করুন
@ -147,23 +147,23 @@ function setUpUser(apiKey, regionName) {
}
```
এই ফাংশন একটি লোডিং বার্তা দেখায় যখন API কল করা হয়। এই পর্যায়ে, আপনি এই ব্রাউজার এক্সটেনশনের সবচেয়ে গুরুত্বপূর্ণ ফাংশন তৈরি করতে পৌঁছেছেন!
এই ফাংশনটি একটি লোডিং বার্তা দেখায় যখন API কল করা হয়। এই পর্যায়ে, আপনি এই ব্রাউজার এক্সটেনশনের সবচেয়ে গুরুত্বপূর্ণ ফাংশন তৈরি করতে পৌঁছেছেন!
### কার্বন ব্যবহারের তথ্য প্রদর্শন করুন
### কার্বন ব্যবহারের প্রদর্শন
অবশেষে, API-তে প্রশ্ন করার সময় এসেছে!
আরও এগিয়ে যাওয়ার আগে, আমাদের API নিয়ে আলোচনা করা উচিত। API, বা [Application Programming Interfaces](https://www.webopedia.com/TERM/A/API.html), একটি ওয়েব ডেভেলপারের টুলবক্সের একটি গুরুত্বপূর্ণ উপাদান। এগুলি প্রোগ্রামগুলিকে একে অপরের সাথে ইন্টারফেস এবং ইন্টারঅ্যাক্ট করার জন্য মানক উপায় সরবরাহ করে। উদাহরণস্বরূপ, আপনি যদি এমন একটি ওয়েবসাইট তৈরি করেন যা একটি ডাটাবেসে প্রশ্ন করতে হবে, কেউ হয়তো আপনার জন্য একটি API তৈরি করেছে। অনেক ধরনের API থাকলেও, সবচেয়ে জনপ্রিয় একটি [REST API](https://www.smashingmagazine.com/2018/01/understanding-using-rest-api/)।
আরও এগিয়ে যাওয়ার আগে, আমাদের API নিয়ে আলোচনা করা উচিত। API, বা [অ্যাপ্লিকেশন প্রোগ্রামিং ইন্টারফেস](https://www.webopedia.com/TERM/A/API.html), একটি ওয়েব ডেভেলপারের টুলবক্সের একটি গুরুত্বপূর্ণ উপাদান। এগুলি প্রোগ্রামগুলিকে একে অপরের সাথে ইন্টারঅ্যাক্ট এবং ইন্টারফেস করার জন্য মানক উপায় সরবরাহ করে। উদাহরণস্বরূপ, আপনি যদি এমন একটি ওয়েবসাইট তৈরি করেন যা একটি ডাটাবেসে প্রশ্ন করতে হবে, কেউ হয়তো আপনার জন্য একটি API তৈরি করেছে। অনেক ধরনের API থাকলেও, সবচেয়ে জনপ্রিয়গুলির মধ্যে একটি হল [REST API](https://www.smashingmagazine.com/2018/01/understanding-using-rest-api/)।
✅ 'REST' শব্দটি 'Representational State Transfer' এর জন্য দাঁড়ায় এবং বিভিন্নভাবে কনফিগার করা URL ব্যবহার করে ডেটা আনতে বৈশিষ্ট্যযুক্ত। ডেভেলপারদের জন্য উপলব্ধ বিভিন্ন ধরনের API সম্পর্কে একটু গবেষণা করুন। কোন ফরম্যাটটি আপনার কাছে আকর্ষণীয় মনে হয়?
✅ 'REST' শব্দটি 'Representational State Transfer' এর জন্য দাঁড়ায় এবং ডেটা আনতে বিভিন্নভাবে কনফিগার করা URL ব্যবহার করার বৈশিষ্ট্য রয়েছে। ডেভেলপারদের জন্য উপলব্ধ বিভিন্ন ধরনের API সম্পর্কে একটু গবেষণা করুন। কোন ফরম্যাটটি আপনার কাছে আকর্ষণীয় মনে হয়?
এই ফাংশন সম্পর্কে গুরুত্বপূর্ণ বিষয়গুলি লক্ষ্য করুন। প্রথমত, [`async` কীওয়ার্ড](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function) লক্ষ্য করুন। আপনার ফাংশনগুলি এমনভাবে লিখুন যাতে সেগুলি অ্যাসিঙ্ক্রোনাসভাবে চলে, অর্থাৎ ডেটা ফেরত আসার মতো একটি অ্যাকশন সম্পন্ন হওয়ার জন্য অপেক্ষা করে।
এই ফাংশন সম্পর্কে গুরুত্বপূর্ণ বিষয়গুলি লক্ষ্য করুন। প্রথমত, [`async` কীওয়ার্ড](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function) লক্ষ্য করুন। আপনার ফাংশনগুলি অ্যাসিঙ্ক্রোনাসভাবে চালানোর জন্য লেখা মানে এটি একটি অ্যাকশন, যেমন ডেটা ফেরত আসা, সম্পন্ন হওয়ার জন্য অপেক্ষা করে তারপর চালিয়ে যায়
এখানে `async` সম্পর্কে একটি দ্রুত ভিডিও:
এখানে `async` সম্পর্কে একটি দ্রুত ভিডিও রয়েছে:
[![প্রমিজ ম্যানেজ করার জন্য Async এবং Await](https://img.youtube.com/vi/YwmlRkrxvkk/0.jpg)](https://youtube.com/watch?v=YwmlRkrxvkk "প্রমিজ ম্যানেজ করার জন্য Async এবং Await")
> 🎥 উপরের ছবিতে ক্লিক করুন `async/await` সম্পর্কে একটি ভিডিও দেখার জন্য।
> 🎥 উপরের ছবিতে ক্লিক করুন `async/await` সম্পর্কে একটি ভিডিওর জন্য।
C02Signal API-তে প্রশ্ন করার জন্য একটি নতুন ফাংশন তৈরি করুন:
@ -207,9 +207,9 @@ async function displayCarbonUsage(apiKey, region) {
এটি একটি বড় ফাংশন। এখানে কী ঘটছে?
- সেরা অনুশীলন অনুসরণ করে, আপনি এই ফাংশনটিকে অ্যাসিঙ্ক্রোনাসভাবে আচরণ করতে `async` কীওয়ার্ড ব্যবহার করেন। ফাংশনটিতে একটি `try/catch` ব্লক রয়েছে কারণ এটি একটি প্রমিজ ফেরত দেবে যখন API ডেটা ফেরত দেবে। যেহেতু আপনি API কত দ্রুত প্রতিক্রিয়া জানাবে তা নিয়ন্ত্রণ করতে পারবেন না (এটি একেবারেই প্রতিক্রিয়া জানাতে নাও পারে!), আপনাকে এটি অ্যাসিঙ্ক্রোনাসভাবে কল করে এই অনিশ্চয়তা পরিচালনা করতে হবে।
- সেরা অনুশীলন অনুসরণ করে, আপনি এই ফাংশনটিকে অ্যাসিঙ্ক্রোনাস আচরণ করার জন্য একটি `async` কীওয়ার্ড ব্যবহার করেন। ফাংশনটিতে একটি `try/catch` ব্লক রয়েছে কারণ এটি একটি প্রমিজ ফেরত দেবে যখন API ডেটা ফেরত দেবে। যেহেতু আপনি API কত দ্রুত প্রতিক্রিয়া জানাবে তা নিয়ন্ত্রণ করতে পারবেন না (এটি প্রতিক্রিয়া জানাবে না!), আপনাকে এটি অ্যাসিঙ্ক্রোনাসভাবে কল করে এই অনিশ্চয়তা পরিচালনা করতে হবে।
- আপনি co2signal API-তে আপনার অঞ্চলের ডেটা পেতে প্রশ্ন করছেন, আপনার API Key ব্যবহার করে। সেই কী ব্যবহার করতে, আপনাকে আপনার হেডার প্যারামিটারে একটি প্রমাণীকরণের ধরন ব্যবহার করতে হবে।
- একবার API প্রতিক্রিয়া জানালে, আপনি এর প্রতিক্রিয়া ডেটার বিভিন্ন উপাদান আপনার স্ক্রিনের সেই অংশগুলিতে বরাদ্দ করেন যা আপনি এই ডেটা দেখানোর জন্য সেট আপ করেছিলেন।
- একবার API প্রতিক্রিয়া জানালে, আপনি এর প্রতিক্রিয়া ডেটার বিভিন্ন উপাদান আপনার স্ক্রিনের সেই অংশগুলিতে বরাদ্দ করেন যা আপনি এই ডেটা দেখানোর জন্য সেট আপ করেছেন।
- যদি কোনো ত্রুটি থাকে, বা কোনো ফলাফল না থাকে, আপনি একটি ত্রুটির বার্তা দেখান।
✅ অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং প্যাটার্ন ব্যবহার করা আপনার টুলবক্সে আরেকটি খুব দরকারী টুল। [এই ধরনের কোড কনফিগার করার বিভিন্ন উপায়](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function) সম্পর্কে পড়ুন।
@ -220,19 +220,21 @@ async function displayCarbonUsage(apiKey, region) {
## 🚀 চ্যালেঞ্জ
আমরা এই পাঠে এখন পর্যন্ত বেশ কয়েকটি ধরনের API নিয়ে আলোচনা করেছি। একটি ওয়েব API বেছে নিন এবং এটি কী অফার করে তা গভীরভাবে গবেষণা করুন। উদাহরণস্বরূপ, ব্রাউজারে উপলব্ধ API যেমন [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) দেখুন। আপনার মতে একটি দুর্দান্ত API কী করে তোলে?
আমরা এই পাঠগুলিতে এখন পর্যন্ত বেশ কয়েকটি ধরনের API নিয়ে আলোচনা করেছি। একটি ওয়েব API বেছে নিন এবং এটি কী অফার করে তা গভীরভাবে গবেষণা করুন। উদাহরণস্বরূপ, ব্রাউজারে উপলব্ধ API যেমন [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) দেখুন। আপনার মতে একটি দুর্দান্ত API কী তৈরি করে?
## পোস্ট-লেকচার কুইজ
[পোস্ট-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/26)
## পুনরালোচনা ও স্ব-অধ্যয়ন
## পর্যালোচনা এবং স্ব-অধ্যয়ন
এই পাঠে আপনি LocalStorage এবং API সম্পর্কে শিখেছেন, যা পেশাদার ওয়েব ডেভেলপারের জন্য খুবই দরকারী। আপনি কি ভাবতে পারেন কীভাবে এই দুটি জিনিস একসঙ্গে কাজ করে? এমন একটি ওয়েবসাইট আর্কিটেক্ট করার কথা ভাবুন যা একটি API দ্বারা ব্যবহৃত আইটেম সংরক্ষণ করবে।
এই পাঠে আপনি LocalStorage এবং API সম্পর্কে শিখেছেন, যা পেশাদার ওয়েব ডেভেলপারের জন্য খুবই দরকারী। আপনি কি ভাবতে পারেন কীভাবে এই দুটি জিনিস একসাথে কাজ করে? এমন একটি ওয়েবসাইট আর্কিটেক্ট করার কথা ভাবুন যা একটি API দ্বারা ব্যবহৃত আইটেমগুলি সংরক্ষণ করবে।
## অ্যাসাইনমেন্ট
[একটি API গ্রহণ করুন](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতা নিশ্চিত করার চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়ী থাকব না।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখুন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "f198c6b817b4b2a99749f4662e7cae98",
"translation_date": "2025-08-25T23:45:03+00:00",
"original_hash": "49b58721a71cfda824e2f3e1f46908c6",
"translation_date": "2025-08-28T22:56:13+00:00",
"source_file": "5-browser-extension/3-background-tasks-and-performance/README.md",
"language_code": "bn"
}
@ -15,29 +15,29 @@ CO_OP_TRANSLATOR_METADATA:
### ভূমিকা
এই মডিউলের শেষ দুটি পাঠে, আপনি শিখেছেন কীভাবে একটি ফর্ম তৈরি করতে হয় এবং একটি API থেকে আনা ডেটা প্রদর্শনের জন্য একটি এলাকা তৈরি করতে হয়। এটি ওয়েবে একটি ওয়েব উপস্থিতি তৈরির একটি খুব সাধারণ পদ্ধতি। আপনি এমনকি অ্যাসিঙ্ক্রোনাসভাবে ডেটা ফেচ করার পদ্ধতিও শিখেছেন। আপনার ব্রাউজার এক্সটেনশন প্রায় সম্পূর্ণ।
এই মডিউলের শেষ দুটি পাঠে, আপনি শিখেছেন কীভাবে একটি ফর্ম তৈরি করতে হয় এবং একটি API থেকে আনা ডেটা প্রদর্শনের জন্য একটি এলাকা তৈরি করতে হয়। এটি ওয়েবে একটি স্ট্যান্ডার্ড উপস্থিতি তৈরি করার একটি খুব সাধারণ পদ্ধতি। আপনি এমনকি শিখেছেন কীভাবে অ্যাসিঙ্ক্রোনাসভাবে ডেটা ফেচ করতে হয়। আপনার ব্রাউজার এক্সটেনশন প্রায় সম্পূর্ণ।
এখন কিছু ব্যাকগ্রাউন্ড টাস্ক পরিচালনা করা বাকি, যার মধ্যে রয়েছে এক্সটেনশনের আইকনের রঙ রিফ্রেশ করা। এটি একটি চমৎকার সময় ব্রাউজার কীভাবে এই ধরনের কাজ পরিচালনা করে তা নিয়ে আলোচনা করার। আসুন এই ব্রাউজার টাস্কগুলোকে আপনার ওয়েব অ্যাসেট তৈরি করার সময় পারফরম্যান্সের প্রেক্ষাপটে বিবেচনা করি
এখন কিছু ব্যাকগ্রাউন্ড টাস্ক পরিচালনা করা বাকি, যার মধ্যে রয়েছে এক্সটেনশনের আইকনের রঙ রিফ্রেশ করা। এটি একটি চমৎকার সময় ব্রাউজার কীভাবে এই ধরনের কাজ পরিচালনা করে তা নিয়ে আলোচনা করার। আসুন এই ব্রাউজার টাস্কগুলো নিয়ে চিন্তা করি আপনার ওয়েব অ্যাসেট তৈরি করার সময় এর পারফরম্যান্সের প্রেক্ষাপটে।
## ওয়েব পারফরম্যান্সের মৌলিক বিষয়
> "ওয়েবসাইট পারফরম্যান্স দুটি বিষয়ে: পৃষ্ঠা কত দ্রুত লোড হয় এবং এর কোড কত দ্রুত চলে।" -- [জ্যাক গ্রোসবার্ট](https://www.smashingmagazine.com/2012/06/javascript-profiling-chrome-developer-tools/)
> "ওয়েবসাইট পারফরম্যান্স দুটি বিষয়ে: পেজটি কত দ্রুত লোড হয় এবং এর কোড কত দ্রুত চলে।" -- [জ্যাক গ্রোসবার্ট](https://www.smashingmagazine.com/2012/06/javascript-profiling-chrome-developer-tools/)
আপনার ওয়েবসাইটগুলোকে সব ধরনের ডিভাইস, ব্যবহারকারী এবং পরিস্থিতিতে অত্যন্ত দ্রুতগতির করার বিষয়টি বিস্তৃত। এখানে কিছু পয়েন্ট রয়েছে যা আপনাকে একটি স্ট্যান্ডার্ড ওয়েব প্রকল্প বা একটি ব্রাউজার এক্সটেনশন তৈরি করার সময় মনে রাখতে হবে।
আপনার ওয়েবসাইটগুলোকে সব ধরনের ডিভাইস, ব্যবহারকারী এবং পরিস্থিতিতে অত্যন্ত দ্রুতগতির করার বিষয়টি বিস্তৃত। এখানে কিছু পয়েন্ট দেওয়া হলো যা আপনাকে একটি স্ট্যান্ডার্ড ওয়েব প্রকল্প বা ব্রাউজার এক্সটেনশন তৈরি করার সময় মনে রাখতে হবে।
আপনার সাইটটি দক্ষতার সাথে চলছে তা নিশ্চিত করার জন্য প্রথমে যা করতে হবে তা হল এর পারফরম্যান্স সম্পর্কে ডেটা সংগ্রহ করা। এটি করার প্রথম জায়গা হল আপনার ওয়েব ব্রাউজারের ডেভেলপার টুলস। Edge-এ, আপনি "Settings and more" বোতামটি (ব্রাউজারের উপরের ডানদিকে তিনটি ডট আইকন) নির্বাচন করতে পারেন, তারপর More Tools > Developer Tools-এ যান এবং Performance ট্যাবটি খুলুন। আপনি Windows-এ `Ctrl` + `Shift` + `I` বা Mac-এ `Option` + `Command` + `I`বোর্ড শর্টকাট ব্যবহার করেও ডেভেলপার টুলস খুলতে পারেন।
আপনার সাইটটি দক্ষতার সাথে চলছে তা নিশ্চিত করার প্রথম ধাপ হলো এর পারফরম্যান্স সম্পর্কে ডেটা সংগ্রহ করা। এটি করার প্রথম জায়গা হল আপনার ওয়েব ব্রাউজারের ডেভেলপার টুলস। Edge-এ, আপনি "Settings and more" বোতাম (ব্রাউজারের উপরের ডানদিকে তিনটি ডট আইকন) নির্বাচন করতে পারেন, তারপর More Tools > Developer Tools-এ যান এবং Performance ট্যাবটি খুলুন। আপনি Windows-এ `Ctrl` + `Shift` + `I` বা Mac-এ `Option` + `Command` + `I`িবোর্ড শর্টকাট ব্যবহার করেও ডেভেলপার টুলস খুলতে পারেন।
Performance ট্যাবে একটি প্রোফাইলিং টুল রয়েছে। একটি ওয়েবসাইট খুলুন (উদাহরণস্বরূপ, [https://www.microsoft.com](https://www.microsoft.com/?WT.mc_id=academic-77807-sagibbon)) এবং 'Record' বোতামে ক্লিক করুন, তারপর সাইটটি রিফ্রেশ করুন। যেকোনো সময় রেকর্ডিং বন্ধ করুন, এবং আপনি দেখতে পাবেন যে সাইটটি 'স্ক্রিপ্ট', 'রেন্ডার' এবং 'পেইন্ট' করার জন্য কী কী রুটিন তৈরি হয়েছে:
Performance ট্যাবে একটি প্রোফাইলিং টুল রয়েছে। একটি ওয়েবসাইট খুলুন (উদাহরণস্বরূপ, [https://www.microsoft.com](https://www.microsoft.com/?WT.mc_id=academic-77807-sagibbon)) এবং 'Record' বোতামে ক্লিক করুন, তারপর সাইটটি রিফ্রেশ করুন। যেকোনো সময় রেকর্ডিং বন্ধ করুন, এবং আপনি দেখতে পাবেন সাইটটি 'স্ক্রিপ্ট', 'রেন্ডার', এবং 'পেইন্ট' করার জন্য যে রুটিনগুলো তৈরি হয়েছে:
![Edge প্রোফাইলার](../../../../translated_images/profiler.5a4a62479c5df01cfec9aab74173dba13f91d2c968e1a1ae434c26165792df15.bn.png)
✅ Edge-এর Performance প্যানেলে [Microsoft ডকুমেন্টেশন](https://docs.microsoft.com/microsoft-edge/devtools-guide/performance/?WT.mc_id=academic-77807-sagibbon) দেখুন
✅ Edge-এর Performance প্যানেল সম্পর্কে আরও জানতে [Microsoft ডকুমেন্টেশন](https://docs.microsoft.com/microsoft-edge/devtools-guide/performance/?WT.mc_id=academic-77807-sagibbon) দেখুন
> টিপ: আপনার ওয়েবসাইটের স্টার্টআপ টাইমের সঠিক রিডিং পেতে, আপনার ব্রাউজারের ক্যাশে ক্লিয়ার করুন
> টিপ: আপনার ওয়েবসাইটের স্টার্টআপ টাইমের সঠিক রিডিং পেতে, আপনার ব্রাউজারের ক্যাশ পরিষ্কার করুন।
প্রোফাইল টাইমলাইনের উপাদানগুলো নির্বাচন করুন এবং দেখুন আপনার পৃষ্ঠা লোড হওয়ার সময় কী কী ইভেন্ট ঘটে।
প্রোফাইল টাইমলাইনের উপাদানগুলো নির্বাচন করুন এবং দেখুন আপনার পেজ লোড হওয়ার সময় কী কী ইভেন্ট ঘটে।
প্রোফাইল টাইমলাইনের একটি অংশ নির্বাচন করে এবং সারাংশ প্যানটি দেখে আপনার পৃষ্ঠার পারফরম্যান্সের একটি স্ন্যাপশট নিন:
প্রোফাইল টাইমলাইনের একটি অংশ নির্বাচন করে এবং সারাংশ প্যানটি দেখে আপনার পেজের পারফরম্যান্সের একটি স্ন্যাপশট নিন:
![Edge প্রোফাইলার স্ন্যাপশট](../../../../translated_images/snapshot.97750180ebcad73794a3594b36925eb5c8dbaac9e03fec7f9b974188c9ac63c7.bn.png)
@ -45,25 +45,25 @@ Performance ট্যাবে একটি প্রোফাইলিং ট
![Edge ইভেন্ট লগ](../../../../translated_images/log.804026979f3707e00eebcfa028b2b5a88cec6292f858767bb6703afba65a7d9c.bn.png)
✅ আপনার প্রোফাইলারটি জানুন! এই সাইটে ডেভেলপার টুলস খুলুন এবং দেখুন কোনো বোতলনেক আছে কিনা। সবচেয়ে ধীরগতির লোডিং অ্যাসেট কোনটি? সবচেয়ে দ্রুততম কোনটি?
✅ আপনার প্রোফাইলারটি চিনে নিন! এই সাইটে ডেভেলপার টুলস খুলুন এবং দেখুন কোনো বোতলনেক আছে কিনা। সবচেয়ে ধীরগতির লোডিং অ্যাসেট কোনটি? সবচেয়ে দ্রুতগতির কোনটি?
## প্রোফাইলিং চেক
সাধারণভাবে, কিছু "সমস্যার ক্ষেত্র" রয়েছে যা প্রতিটি ওয়েব ডেভেলপারকে একটি সাইট তৈরি করার সময় লক্ষ্য রাখা উচিত, যাতে প্রোডাকশনে ডিপ্লয় করার সময় কোনো অপ্রত্যাশিত সমস্যার সম্মুখীন না হয়।
সাধারণভাবে, কিছু "সমস্যাজনক এলাকা" রয়েছে যা প্রতিটি ওয়েব ডেভেলপারকে একটি সাইট তৈরি করার সময় লক্ষ্য রাখা উচিত, যাতে প্রোডাকশনে ডিপ্লয় করার সময় কোনো অপ্রত্যাশিত সমস্যা না হয়।
**অ্যাসেট সাইজ**: গত কয়েক বছরে ওয়েব আরও 'ভারী' এবং ধীর হয়ে উঠেছে। এর একটি বড় অংশ চিত্র ব্যবহারের সাথে সম্পর্কিত।
**অ্যাসেট সাইজ**: গত কয়েক বছরে ওয়েব 'ভারী' হয়ে উঠেছে এবং এর ফলে ধীরগতির হয়েছে। এর একটি অংশ চিত্র ব্যবহারের সাথে সম্পর্কিত।
✅ [ইন্টারনেট আর্কাইভ](https://httparchive.org/reports/page-weight)-এ পৃষ্ঠা ওজনের ঐতিহাসিক দৃশ্য এবং আরও অনেক কিছু দেখুন।
পেজ ওজন এবং আরও অনেক কিছুর ঐতিহাসিক দৃষ্টিভঙ্গির জন্য [ইন্টারনেট আর্কাইভ](https://httparchive.org/reports/page-weight) দেখুন।
একটি ভালো অভ্যাস হল নিশ্চিত করা যে আপনার চিত্রগুলো অপ্টিমাইজ করা হয়েছে এবং আপনার ব্যবহারকারীদের জন্য সঠিক আকার এবং রেজোলিউশনে সরবরাহ করা হয়েছে।
একটি ভালো অভ্যাস হল নিশ্চিত করা যে আপনার চিত্রগুলো অপ্টিমাইজ করা হয়েছে এবং আপনার ব্যবহারকারীদের জন্য সঠিক সাইজ এবং রেজোলিউশনে সরবরাহ করা হয়েছে।
**DOM ট্রাভার্সাল**: ব্রাউজারকে আপনার লেখা কোডের উপর ভিত্তি করে তার ডকুমেন্ট অবজেক্ট মডেল তৈরি করতে হয়, তাই ভালো পৃষ্ঠা পারফরম্যান্সের স্বার্থে আপনার ট্যাগগুলোকে ন্যূনতম রাখা গুরুত্বপূর্ণ। পৃষ্ঠার জন্য প্রয়োজনীয় CSS ছাড়া অতিরিক্ত কিছু ব্যবহার না করাই ভালো
**DOM ট্রাভার্সাল**: ব্রাউজারকে আপনার লেখা কোডের উপর ভিত্তি করে তার ডকুমেন্ট অবজেক্ট মডেল তৈরি করতে হয়, তাই ভালো পেজ পারফরম্যান্সের স্বার্থে আপনার ট্যাগগুলোকে ন্যূনতম রাখা উচিত, শুধুমাত্র পেজে যা প্রয়োজন তা ব্যবহার এবং স্টাইল করা উচিত। এই পয়েন্টে, পেজের সাথে সম্পর্কিত অতিরিক্ত CSS অপ্টিমাইজ করা যেতে পারে; উদাহরণস্বরূপ, শুধুমাত্র একটি পেজে ব্যবহৃত স্টাইলগুলো প্রধান স্টাইল শীটে অন্তর্ভুক্ত করার প্রয়োজন নেই
**জাভাস্ক্রিপ্ট**: প্রতিটি জাভাস্ক্রিপ্ট ডেভেলপারের উচিত 'রেন্ডার-ব্লকিং' স্ক্রিপ্টগুলোর দিকে নজর রাখা, যেগুলো DOM ট্রাভার্স এবং ব্রাউজারে পেইন্ট করার আগে লোড করতে হয়। আপনার ইনলাইন স্ক্রিপ্টগুলোর সাথে `defer` ব্যবহার করার কথা বিবেচনা করুন (যেমনটি Terrarium মডিউলে করা হয়েছে)।
**জাভাস্ক্রিপ্ট**: প্রতিটি জাভাস্ক্রিপ্ট ডেভেলপারে 'রেন্ডার-ব্লকিং' স্ক্রিপ্টগুলোর দিকে নজর রাখা উচিত, যেগুলো DOM ট্রাভার্স এবং ব্রাউজারে পেইন্ট করার আগে লোড করতে হয়। আপনার ইনলাইন স্ক্রিপ্টগুলোর সাথে `defer` ব্যবহার করার কথা বিবেচনা করুন (যেমনটি Terrarium মডিউলে করা হয়েছে)।
✅ [সাইট স্পিড টেস্ট ওয়েবসাইট](https://www.webpagetest.org/) এ কিছু সাইট চেষ্টা করুন এবং দেখুন সাইট পারফরম্যান্স নির্ধারণের জন্য সাধারণত কী কী চেক করা হয়
সাইট পারফরম্যান্স নির্ধারণের জন্য সাধারণ চেক সম্পর্কে আরও জানতে [সাইট স্পিড টেস্ট ওয়েবসাইট](https://www.webpagetest.org/) এ কিছু সাইট চেষ্টা করুন।
এখন যেহেতু আপনি জানেন ব্রাউজার কীভাবে আপনার পাঠানো অ্যাসেটগুলো রেন্ডার করে, আসুন আপনার এক্সটেনশন সম্পূর্ণ করতে প্রয়োজনীয় শেষ কয়েকটি বিষয় দেখি:
এখন যেহেতু আপনি জানেন ব্রাউজার আপনার পাঠানো অ্যাসেটগুলো কীভাবে রেন্ডার করে, আসুন আপনার এক্সটেনশন সম্পূর্ণ করতে শেষ কয়েকটি জিনিস দেখি:
### রঙ গণনা করার জন্য একটি ফাংশন তৈরি করুন
@ -88,19 +88,19 @@ function calculateColor(value) {
}
```
এখানে কী হচ্ছে? আপনি API কল থেকে প্রাপ্ত একটি মান (কার্বন ইন্টেনসিটি) পাস করেন, এবং তারপর এটি রঙের অ্যারের সূচকের সাথে কতটা কাছাকাছি তা গণনা করেন। তারপর আপনি সেই সবচেয়ে কাছের রঙের মানটি chrome runtime-এ পাঠান।
এখানে কী হচ্ছে? আপনি একটি মান (কার্বন ইন্টেনসিটি) API কল থেকে পাস করছেন যা আপনি আগের পাঠে সম্পন্ন করেছেন, এবং তারপর আপনি এটি রঙের অ্যারের সূচকের সাথে কতটা কাছাকাছি তা গণনা করেন। তারপর আপনি সেই সবচেয়ে কাছের রঙের মানটি chrome runtime-এ পাঠাচ্ছেন।
chrome.runtime-এ [একটি API](https://developer.chrome.com/extensions/runtime) রয়েছে যা সব ধরনের ব্যাকগ্রাউন্ড টাস্ক পরিচালনা করে, এবং আপনার এক্সটেনশন এটি ব্যবহার করছে:
> "chrome.runtime API ব্যবহার করে ব্যাকগ্রাউন্ড পৃষ্ঠা পুনরুদ্ধার করুন, ম্যানিফেস্টের বিবরণ ফেরত দিন এবং অ্যাপ বা এক্সটেনশনের লাইফসাইকেলের ইভেন্টগুলো শোনার এবং সাড়া দেওয়ার জন্য ব্যবহার করুন।"
> "chrome.runtime API ব্যবহার করে ব্যাকগ্রাউন্ড পেজ পুনরুদ্ধার করুন, ম্যানিফেস্ট সম্পর্কে বিস্তারিত তথ্য ফেরত দিন, এবং অ্যাপ বা এক্সটেনশনের লাইফসাইকেলের ইভেন্টগুলোর জন্য শোনার এবং সাড়া দেওয়ার জন্য ব্যবহার করুন। আপনি এই API ব্যবহার করে URL-এর আপেক্ষিক পথকে সম্পূর্ণ-যোগ্য URL-এ রূপান্তর করতে পারেন।"
✅ আপনি যদি Edge-এর জন্য এই ব্রাউজার এক্সটেনশনটি তৈরি করছেন, তবে এটি জেনে অবাক হতে পারেন যে আপনি একটি chrome API ব্যবহার করছেন। নতুন Edge ব্রাউজার সংস্করণগুলো Chromium ব্রাউজার ইঞ্জিনে চলে, তাই আপনি এই টুলগুলো ব্যবহার করতে পারেন।
যদি আপনি Edge-এর জন্য এই ব্রাউজার এক্সটেনশনটি তৈরি করছেন, তবে এটি জেনে অবাক হতে পারেন যে আপনি একটি chrome API ব্যবহার করছেন। নতুন Edge ব্রাউজার সংস্করণগুলো Chromium ব্রাউজার ইঞ্জিনে চলে, তাই আপনি এই টুলগুলো ব্যবহার করতে পারেন।
> নোট, যদি আপনি একটি ব্রাউজার এক্সটেনশন প্রোফাইল করতে চান, এক্সটেনশনের ভিতর থেকে ডেভেলপার টুলস চালু করুন, কারণ এটি নিজস্ব একটি আলাদা ব্রাউজার ইনস্ট্যান্স।
### একটি ডিফল্ট আইকন রঙ সেট করুন
এখন, `init()` ফাংশনে, আইকনটিকে শুরুতে একটি সাধারণ সবুজ রঙে সেট করুন chrome-এর `updateIcon` অ্যাকশন কল করে:
এখন, `init()` ফাংশনে, chrome-এর `updateIcon` অ্যাকশন কল করে আইকনটিকে শুরুতে একটি সাধারণ সবুজ রঙে সেট করুন:
```JavaScript
chrome.runtime.sendMessage({
@ -111,9 +111,9 @@ chrome.runtime.sendMessage({
});
```
### ফাংশনটি কল করুন এবং কলটি কার্যকর করুন
### ফাংশনটি কল করুন, কলটি সম্পাদন করুন
পরবর্তী ধাপে, আপনি যে ফাংশনটি তৈরি করেছেন সেটি C02Signal API থেকে প্রাপ্ত প্রমিসে যোগ করুন:
পরবর্তী ধাপে, আপনি যে ফাংশনটি তৈরি করেছেন সেটি C02Signal API থেকে ফেরত আসা প্রমিসে যোগ করুন:
```JavaScript
//let CO2...
@ -144,17 +144,17 @@ function drawIcon(value) {
এই কোডে, আপনি ব্যাকএন্ড টাস্ক ম্যানেজারে আসা যেকোনো মেসেজের জন্য একটি লিসেনার যোগ করছেন। যদি এটি 'updateIcon' নামে ডাকা হয়, তবে পরবর্তী কোডটি Canvas API ব্যবহার করে সঠিক রঙের একটি আইকন আঁকতে চালানো হয়।
✅ আপনি [Space Game পাঠে](../../6-space-game/2-drawing-to-canvas/README.md) Canvas API সম্পর্কে আরও শিখবেন
✅ আপনি Canvas API সম্পর্কে আরও শিখবেন [Space Game পাঠে](../../6-space-game/2-drawing-to-canvas/README.md)।
এখন, আপনার এক্সটেনশনটি পুনরায় তৈরি করুন (`npm run build`), রিফ্রেশ করুন এবং এক্সটেনশনটি চালু করুন এবং রঙ পরিবর্তন দেখুন। এটি কি কোনো কাজ করার বা থালা-বাসন ধোয়ার ভালো সময়? এখন আপনি জানেন!
এখন, আপনার এক্সটেনশনটি পুনরায় তৈরি করুন (`npm run build`), রিফ্রেশ করুন এবং আপনার এক্সটেনশন চালু করুন এবং রঙ পরিবর্তন দেখুন। এটি কি কোনো কাজ করার বা থালা-বাসন ধোয়ার ভালো সময়? এখন আপনি জানেন!
অভিনন্দন, আপনি একটি কার্যকরী ব্রাউজার এক্সটেনশন তৈরি করেছেন এবং ব্রাউজার কীভাবে কাজ করে এবং কীভাবে এর পারফরম্যান্স প্রোফাইল করতে হয় তা শিখেছেন
অভিনন্দন, আপনি একটি কার্যকরী ব্রাউজার এক্সটেনশন তৈরি করেছেন এবং শিখেছেন কীভাবে ব্রাউজার কাজ করে এবং কীভাবে এর পারফরম্যান্স প্রোফাইল করতে হয়।
---
## 🚀 চ্যালেঞ্জ
কিছু ওপেন সোর্স ওয়েবসাইট তদন্ত করুন যা অনেক দিন আগে তৈরি হয়েছিল এবং তাদের GitHub ইতিহাসের উপর ভিত্তি করে দেখুন তারা বছরের পর বছর ধরে পারফরম্যান্সের জন্য কীভাবে অপ্টিমাইজ করা হয়েছ, যদি আদৌ করা হয়। সবচেয়ে সাধারণ সমস্যার ক্ষেত্র কোনটি?
কিছু ওপেন সোর্স ওয়েবসাইট তদন্ত করুন যা অনেক দিন আগে তৈরি হয়েছিল এবং তাদের GitHub ইতিহাসের ভিত্তিতে দেখুন তারা পারফরম্যান্সের জন্য কীভাবে অপ্টিমাইজ করা হয়েছিল, যদি আদৌ করা হয়। সবচেয়ে সাধারণ সমস্যার পয়েন্ট কোনটি?
## পোস্ট-লেকচার কুইজ
@ -170,5 +170,7 @@ function drawIcon(value) {
[একটি সাইটের পারফরম্যান্স বিশ্লেষণ করুন](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। এর মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়বদ্ধ নই।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না

@ -1,15 +1,15 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "d9da6dc61fb712b29f65e108c79b8a5d",
"translation_date": "2025-08-25T22:30:00+00:00",
"original_hash": "979cfcce2413a87d9e4c67eb79234bc3",
"translation_date": "2025-08-28T23:00:11+00:00",
"source_file": "6-space-game/1-introduction/README.md",
"language_code": "bn"
}
-->
# স্পেস গেম তৈরি করুন পার্ট ১: পরিচিতি
![ভিডিও](../../../../6-space-game/images/pewpew.gif)
![video](../../../../6-space-game/images/pewpew.gif)
## প্রাক-লেকচার কুইজ
@ -17,18 +17,18 @@ CO_OP_TRANSLATOR_METADATA:
### গেম ডেভেলপমেন্টে ইনহেরিটেন্স এবং কম্পোজিশন
আগের পাঠগুলোতে, আপনি যে অ্যাপ তৈরি করেছেন তার ডিজাইন আর্কিটেকচারের বিষয়ে খুব বেশি চিন্তা করার প্রয়োজন ছিল না, কারণ প্রকল্পগুলো খুব ছোট পরিসরে ছিল। তবে, যখন আপনার অ্যাপ্লিকেশন আকার এবং পরিসরে বৃদ্ধি পায়, তখন আর্কিটেকচারাল সিদ্ধান্তগুলো বড় বিষয় হয়ে দাঁড়ায়। জাভাস্ক্রিপ্টে বড় অ্যাপ্লিকেশন তৈরি করার দুটি প্রধান পদ্ধতি রয়েছে: *কম্পোজিশন* বা *ইনহেরিটেন্স*। উভয়েরই সুবিধা এবং অসুবিধা রয়েছে, তবে আসুন এগুলো একটি গেমের প্রসঙ্গ থেকে ব্যাখ্যা করি।
আগের পাঠগুলোতে, আপনি যে অ্যাপ তৈরি করেছেন তার ডিজাইন আর্কিটেকচার নিয়ে খুব বেশি চিন্তা করার দরকার পড়েনি, কারণ প্রকল্পগুলো খুব ছোট পরিসরে ছিল। তবে, যখন আপনার অ্যাপ্লিকেশন আকার এবং পরিসরে বৃদ্ধি পায়, তখন আর্কিটেকচারাল সিদ্ধান্তগুলো বড় বিষয় হয়ে দাঁড়ায়। জাভাস্ক্রিপ্টে বড় অ্যাপ্লিকেশন তৈরি করার দুটি প্রধান পদ্ধতি রয়েছে: *কম্পোজিশন* বা *ইনহেরিটেন্স*। উভয়েরই সুবিধা এবং অসুবিধা রয়েছে, তবে আসুন এগুলো একটি গেমের প্রেক্ষাপটে ব্যাখ্যা করি।
✅ প্রোগ্রামিংয়ের সবচেয়ে বিখ্যাত বইগুলোর একটি [ডিজাইন প্যাটার্নস](https://en.wikipedia.org/wiki/Design_Patterns) নিয়ে।
✅ প্রোগ্রামিং সম্পর্কিত সবচেয়ে বিখ্যাত বইগুলোর একটি [ডিজাইন প্যাটার্নস](https://en.wikipedia.org/wiki/Design_Patterns) নিয়ে।
একটি গেমে আপনার কাছে `গেম অবজেক্ট` থাকে, যা স্ক্রিনে উপস্থিত থাকে। এর মানে হলো এগুলো একটি কার্টেসিয়ান কোঅর্ডিনেট সিস্টেমে অবস্থান করে, যেখনে `x` এবং `y` কোঅর্ডিনেট থাকে। যখন আপনি একটি গেম তৈরি করবেন, আপনি লক্ষ্য করবেন যে আপনার সমস্ত গেম অবজেক্টের একটি সাধারণ বৈশিষ্ট্য থাকে, যা প্রতিটি গেমের জন্য সাধারণ, যেমন:
একটি গেমে আপনার কাছে `গেম অবজেক্ট` থাকে, যা স্ক্রিনে উপস্থিত থাকে। এর মানে হলো এগুলো একটি অবস্থান থাকে কার্টেসিয়ান কোঅর্ডিনেট সিস্টেমে, যা `x` এবং `y` কোঅর্ডিনেট দ্বারা চিহ্নিত হয়। যখন আপনি একটি গেম তৈরি করবেন, আপনি লক্ষ্য করবেন যে আপনার সমস্ত গেম অবজেক্টের একটি সাধারণ বৈশিষ্ট্য থাকে, যা প্রতিটি গেমের জন্য সাধারণ, যেমন:
- **অবস্থান-ভিত্তিক** বেশিরভাগ, যদি না সব, গেম উপাদান অবস্থান-ভিত্তিক হয়। এর মানে হলো এগুলোর একটি অবস্থান থাকে, একটি `x` এবং `y`
- **চলনযোগ্য** এগুলো এমন অবজেক্ট যা নতুন অবস্থানে যেতে পারে। সাধারণত এটি একটি হিরো, একটি মনস্টার বা একটি NPC (নন-প্লেয়ার ক্যারেক্টার), তবে উদাহরণস্বরূপ, একটি স্থির অবজেক্ট যেমন একটি গাছ নয়।
- **স্ব-ধ্বংসকারী** এই অবজেক্টগুলো একটি নির্দিষ্ট সময়ের জন্য বিদ্যমান থাকে, তারপর তারা মুছে ফেলার জন্য প্রস্তুত হয়। সাধারণত এটি একটি `dead` বা `destroyed` বুলিয়ান দ্বারা উপস্থাপিত হয় যা গেম ইঞ্জিনকে সংকেত দেয় যে এই অবজেক্টটি আর রেন্ডার করা উচিত নয়।
- **কুল-ডাউন** 'কুল-ডাউন' একটি সাধারণ বৈশিষ্ট্য যা স্বল্পস্থায়ী অবজেক্টগুলোর মধ্যে দেখা যায়। একটি সাধারণ উদাহরণ হলো একটি টেক্সট বা গ্রাফিকাল ইফেক্ট যেমন একটি বিস্ফোরণ যা কয়েক মিলিসেকেন্ডের জন্য দেখা উচিত।
- **চলনযোগ্য** এগুলো এমন অবজেক্ট যা নতুন অবস্থানে যেতে পারে। সাধারণত এটি একটি হিরো, একটি মনস্টার বা একটি NPC (নন প্লেয়ার ক্যারেক্টার), তবে উদাহরণস্বরূপ, একটি স্থির অবজেক্ট যেমন একটি গাছ নয়।
- **স্ব-ধ্বংসকারী** এই অবজেক্টগুলো শুধুমাত্র একটি নির্দিষ্ট সময়ের জন্য বিদ্যমান থাকে, তারপর তারা মুছে ফেলার জন্য প্রস্তুত হয়। সাধারণত এটি একটি `dead` বা `destroyed` বুলিয়ান দ্বারা উপস্থাপিত হয় যা গেম ইঞ্জিনকে সংকেত দেয় যে এই অবজেক্টটি আর রেন্ডার করা উচিত নয়।
- **কুল-ডাউন** 'কুল-ডাউন' একটি সাধারণ বৈশিষ্ট্য যা স্বল্পস্থায়ী অবজেক্টগুলোর মধ্যে দেখা যায়। একটি সাধারণ উদাহরণ হলো একটি টেক্সট বা গ্রাফিকাল ইফেক্ট যেমন একটি বিস্ফোরণ যা শুধুমাত্র কয়েক মিলিসেকেন্ডের জন্য দেখা উচিত।
✅ একটি গেম যেমন প্যাক-ম্যানের কথা ভাবুন। আপনি কি এই গেমে উপরে তালিকাভুক্ত চারটি অবজেক্ট টাইপ চিহ্নিত করতে পারেন?
✅ একটি গেম যেমন Pac-Man নিয়ে চিন্তা করুন। আপনি কি এই গেমে উপরের চারটি অবজেক্ট টাইপ চিহ্নিত করতে পারেন?
### আচরণ প্রকাশ করা
@ -40,7 +40,7 @@ CO_OP_TRANSLATOR_METADATA:
✅ ইনহেরিটেন্স একটি গুরুত্বপূর্ণ ধারণা। [MDN-এর ইনহেরিটেন্স সম্পর্কিত নিবন্ধ](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain) থেকে আরও জানুন।
কোডের মাধ্যমে প্রকাশ করলে, একটি গেম অবজেক্ট সাধারণত এভাবে দেখতে পারে:
কোডের মাধ্যমে প্রকাশ করলে, একটি গেম অবজেক্ট সাধারণত এরকম দেখতে পারে:
```javascript
@ -88,11 +88,11 @@ hero.moveTo(5,5);
const tree = new Tree();
```
✅ কয়েক মিনিট সময় নিয়ে একটি প্যাক-ম্যান হিরো (উদাহরণস্বরূপ ইনকি, পিঙ্কি বা ব্লিঙ্কি) কল্পনা করুন এবং এটি কীভাবে জাভাস্ক্রিপ্টে লেখা হবে তা ভাবুন।
✅ কয়েক মিনিট সময় নিয়ে Pac-Man এর একটি হিরো (উদাহরণস্বরূপ, Inky, Pinky বা Blinky) কল্পনা করুন এবং এটি কীভাবে জাভাস্ক্রিপ্টে লেখা হবে তা ভাবুন।
**কম্পোজিশন**
অবজেক্ট ইনহেরিটেন্স পরিচালনার একটি ভিন্ন পদ্ধতি হলো *কম্পোজিশন* ব্যবহার করা। তখন অবজেক্টগুলো তাদের আচরণ এভাবে প্রকাশ করে:
অবজেক্ট ইনহেরিটেন্স পরিচালনার একটি ভিন্ন উপায় হলো *কম্পোজিশন* ব্যবহার করা। তখন অবজেক্টগুলো তাদের আচরণ এভাবে প্রকাশ করে:
```javascript
//create a constant gameObject
@ -137,9 +137,9 @@ hero.moveTo(5,5);
const tree = createStatic(0,0, 'Tree');
```
**আমি কোন প্যাটার্ন ব্যবহার করব?**
**কোন প্যাটার্নটি ব্যবহার করব?**
আপনার পছন্দের উপর নির্ভর করে আপনি কোন প্যাটার্নটি বেছে নেবেন। জাভাস্ক্রিপ্ট উভয় পদ্ধতিকে সমর্থন করে।
আপনার উপর নির্ভর করে আপনি কোন প্যাটার্নটি বেছে নেবেন। জাভাস্ক্রিপ্ট উভয় পদ্ধতি সমর্থন করে।
--
@ -147,13 +147,13 @@ const tree = createStatic(0,0, 'Tree');
## পাব/সাব প্যাটার্ন
✅ Pub/Sub এর অর্থ 'পাবলিশ-সাবস্ক্রাইব'
✅ Pub/Sub এর অর্থ 'publish-subscribe'
এই প্যাটার্নটি ধারণা দেয় যে আপনার অ্যাপ্লিকেশনের বিভিন্ন অংশ একে অপরের সম্পর্কে জানবে না। কেন? এটি সাধারণভাবে কী ঘটছে তা দেখতে অনেক সহজ করে তোলে যদি বিভিন্ন অংশ আলাদা থাকে। এটি আচরণ হঠাৎ পরিবর্তন করাও সহজ করে তোলে যদি প্রয়োজন হয়। আমরা এটি কীভাবে অর্জন করি? আমরা কিছু ধারণা প্রতিষ্ঠা করে এটি করি:
এই প্যাটার্নটি ধারণা দেয় যে আপনার অ্যাপ্লিকেশনের বিভিন্ন অংশ একে অপরের সম্পর্কে জানবে না। কেন? এটি সাধারণভাবে কী ঘটছে তা বোঝা অনেক সহজ করে তোলে যদি বিভিন্ন অংশ আলাদা থাকে। এটি আচরণ হঠাৎ পরিবর্তন করাও সহজ করে তোলে যদি প্রয়োজন হয়। আমরা এটি কীভাবে অর্জন করি? আমরা কিছু ধারণা প্রতিষ্ঠা করে এটি করি:
- **মেসেজ**: একটি মেসেজ সাধারণত একটি টেক্সট স্ট্রিং হয় যা একটি ঐচ্ছিক পে-লোড (একটি ডেটা যা মেসেজটি সম্পর্কে স্পষ্ট করে) সহ থাকে। একটি গেমে একটি সাধারণ মেসেজ হতে পারে `KEY_PRESSED_ENTER`
- **পাবলিশার**: এই উপাদানটি একটি মেসেজ *পাবলিশ* করে এবং এটি সমস্ত সাবস্ক্রাইবারদের কাছে পাঠায়।
- **সাবস্ক্রাইবার**: এই উপাদানটি নির্দিষ্ট মেসেজগুলো *শোনে* এবং এই মেসেজটি পাওয়ার ফলস্বরূপ কিছু কাজ সম্পাদন করে, যেমন একটি লেজার ফায়ার করা
- **সাবস্ক্রাইবার**: এই উপাদানটি নির্দিষ্ট মেসেজগুলো *শোনে* এবং এই মেসেজটি পাওয়ার ফলস্বরূপ কিছু কাজ সম্পন্ন করে, যেমন একটি লেজার চালানো
এর বাস্তবায়ন আকারে খুব ছোট হলেও এটি একটি অত্যন্ত শক্তিশালী প্যাটার্ন। এটি কীভাবে বাস্তবায়িত হতে পারে তা এখানে দেখুন:
@ -180,7 +180,7 @@ class EventEmitter {
```
উপরে থাকা কোডটি ব্যবহার করতে আমরা একটি খুব ছোট বাস্তবায়ন তৈরি করতে পারি:
উপরে উল্লেখিত কোড ব্যবহার করে আমরা একটি খুব ছোট বাস্তবায়ন তৈরি করতে পারি:
```javascript
//set up a message structure
@ -204,7 +204,7 @@ window.addEventListener('keyup', (evt) => {
});
```
উপরে আমরা একটি কিবোর্ড ইভেন্ট, `ArrowLeft` সংযুক্ত করেছি এবং `HERO_MOVE_LEFT` মেসেজ পাঠিয়েছি। আমরা সেই মেসেজটি শুনি এবং ফলস্বরূপ `hero`-কে সরাই। এই প্যাটার্নের শক্তি হলো ইভেন্ট লিসনার এবং হিরো একে অপরের সম্পর্কে জানে না। আপনি `ArrowLeft`-কে `A` কীতে পুনরায় ম্যাপ করতে পারেন। এছাড়াও, এটি সম্ভব হবে `ArrowLeft`-এ সম্পূর্ণ ভিন্ন কিছু করার জন্য ইভেন্টEmitter-এর `on` ফাংশনে কয়েকটি সম্পাদনা করে:
উপরে আমরা একটি কিবোর্ড ইভেন্ট, `ArrowLeft` সংযুক্ত করেছি এবং `HERO_MOVE_LEFT` মেসেজ পাঠিয়েছি। আমরা সেই মেসেজটি শুনি এবং ফলস্বরূপ `hero` কে সরাই। এই প্যাটার্নের শক্তি হলো ইভেন্ট লিসনার এবং হিরো একে অপরের সম্পর্কে জানে না। আপনি `ArrowLeft` কে `A` কীতে পুনরায় ম্যাপ করতে পারেন। এছাড়াও, এটি সম্ভব হবে `ArrowLeft` এ সম্পূর্ণ ভিন্ন কিছু করার জন্য ইভেন্টEmitter এর `on` ফাংশনে কয়েকটি সম্পাদনা করে:
```javascript
eventEmitter.on(Messages.HERO_MOVE_LEFT, () => {
@ -212,13 +212,13 @@ eventEmitter.on(Messages.HERO_MOVE_LEFT, () => {
});
```
যখন আপনার গেম বড় হয় তখন জিনিসগুলো আরও জটিল হয়ে ওঠে, এই প্যাটার্নটি জটিলতায় একই থাকে এবং আপনার কোড পরিষ্কার থাকে। এই প্যাটার্নটি গ্রহণ করার জন্য এটি সত্যিই সুপারিশ করা হয়।
যখন আপনার গেম বড় হয় এবং জটিল হয়ে ওঠে, এই প্যাটার্নটি জটিলতায় একই থাকে এবং আপনার কোড পরিষ্কার থাকে। এই প্যাটার্নটি গ্রহণ করার জন্য এটি সত্যিই সুপারিশ করা হয়।
---
## 🚀 চ্যালেঞ্জ
ভাবুন কীভাবে পাব-সাব প্যাটার্ন একটি গেমকে উন্নত করতে পারে। কোন অংশগুলো ইভেন্ট প্রকাশ করবে এবং গেমটি কীভাবে সেগুলোর প্রতিক্রিয়া জানাবে? এখন আপনার সৃজনশীল হওয়ার সময়, একটি নতুন গেমের কথা ভাবুন এবং এর অংশগুলো কীভাবে আচরণ করতে পারে তা কল্পনা করুন।
ভাবুন কীভাবে পাব-সাব প্যাটার্ন একটি গেমকে উন্নত করতে পারে। কোন অংশগুলো ইভেন্ট পাঠাবে, এবং গেমটি কীভাবে সেগুলোর প্রতিক্রিয়া জানাবে? এখন আপনার সৃজনশীল হওয়ার সুযোগ, একটি নতুন গেম নিয়ে চিন্তা করুন এবং এর অংশগুলো কীভাবে আচরণ করতে পারে তা ভাবুন।
## পোস্ট-লেকচার কুইজ
@ -232,5 +232,7 @@ eventEmitter.on(Messages.HERO_MOVE_LEFT, () => {
[একটি গেমের মক আপ তৈরি করুন](assignment.md)
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতা নিশ্চিত করার চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।
---
**দাবিত্যাগ**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতা নিশ্চিত করার চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়ী থাকব না।

@ -1,25 +1,25 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "41be8d35e7f30aa9dad10773c35e89c4",
"translation_date": "2025-08-25T22:17:02+00:00",
"original_hash": "056641280211e52fd0adb81b6058ec55",
"translation_date": "2025-08-28T22:59:27+00:00",
"source_file": "6-space-game/2-drawing-to-canvas/README.md",
"language_code": "bn"
}
-->
# মহাকাশ গেম তৈরি করুন পার্ট ২: হিরো এবং মনস্টার ক্যানভাসে আঁকা
# স্পেস গেম তৈরি করুন পার্ট ২: হিরো এবং মনস্টারকে ক্যানভাসে আঁকুন
## প্রাক-লেকচার কুইজ
## প্রি-লেকচার কুইজ
[প্রাক-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/31)
[প্রি-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/31)
## ক্যানভাস
ক্যানভাস একটি HTML উপাদান যা ডিফল্টভাবে কোনো কন্টেন্ট রাখে না; এটি একটি ফাঁকা পৃষ্ঠা। এটি ব্যবহার করে আঁকতে হবে।
ক্যানভাস একটি HTML এলিমেন্ট যা ডিফল্টভাবে কোনো কন্টেন্ট থাকে না; এটি একটি ফাঁকা পাতা। আপনাকে এটি ব্যবহার করে আঁকতে হবে।
✅ [ক্যানভাস API](https://developer.mozilla.org/docs/Web/API/Canvas_API) সম্পর্কে আরও জানুন MDN-এ।
✅ [ক্যানভাস API সম্পর্কে আরও পড়ুন](https://developer.mozilla.org/docs/Web/API/Canvas_API) MDN-এ।
এটি সাধারণত পৃষ্ঠার বডির অংশ হিসেবে এভাবে ঘোষণা করা হয়:
এটি সাধারণত পেজের বডির অংশ হিসেবে এভাবে ডিক্লেয়ার করা হয়:
```html
<canvas id="myCanvas" width="200" height="100"></canvas>
@ -27,24 +27,24 @@ CO_OP_TRANSLATOR_METADATA:
উপরের কোডে আমরা `id`, `width` এবং `height` সেট করছি।
- `id`: এটি সেট করুন যাতে আপনি এটি রেফারেন্স করতে পারেন যখন এটি নিয়ে কাজ করতে হবে।
- `width`: এটি উপাদানের প্রস্থ।
- `height`: এটি উপাদানের উচ্চতা।
- `id`: এটি সেট করুন যাতে আপনি এটি রেফারেন্স করতে পারেন যখন এর সাথে ইন্টারঅ্যাক্ট করতে হবে।
- `width`: এটি এলিমেন্টের প্রস্থ।
- `height`: এটি এলিমেন্টের উচ্চতা।
## সহজ জ্যামিতিক চিত্র আঁকা
## সাধারণ জ্যামিতিক আকৃতি আঁকা
ক্যানভাস জিনিস আঁকার জন্য একটি কার্টেসিয়ান কোঅর্ডিনেট সিস্টেম ব্যবহার করে। এটি x-অক্ষ এবং y-অক্ষ ব্যবহার করে কোনো কিছুর অবস্থান প্রকাশ করে। অবস্থান `0,0` হল উপরের বাম কোণ এবং নিচের ডান কোণ হল ক্যানভাসের প্রস্থ এবং উচ্চতা
ক্যানভাস জিনিস আঁকার জন্য একটি কার্টেসিয়ান কোঅর্ডিনেট সিস্টেম ব্যবহার করে। এটি x-অক্ষ এবং y-অক্ষ ব্যবহার করে কোনো কিছুর অবস্থান প্রকাশ করে। অবস্থান `0,0` হল উপরের বাম কোণ এবং নিচের ডান কোণ হলো ক্যানভাসের WIDTH এবং HEIGHT
![ক্যানভাসের গ্রিড](../../../../translated_images/canvas_grid.5f209da785ded492a01ece440e3032afe51efa500cc2308e5ea4252487ceaf0b.bn.png)
![ক্যানভাসের গ্রিড](../../../../translated_images/canvas_grid.5f209da785ded492a01ece440e3032afe51efa500cc2308e5ea4252487ceaf0b.bn.png)
> ছবি [MDN](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) থেকে
ক্যানভাস উপাদানে আঁকার জন্য আপনাকে নিম্নলিখিত ধাপগুলো অনুসরণ করতে হবে:
ক্যানভাস এলিমেন্টে আঁকার জন্য আপনাকে নিম্নলিখিত ধাপগুলো অনুসরণ করতে হবে:
1. **রেফারেন্স নিন** ক্যানভাস উপাদানের।
2. **রেফারেন্স নিন** ক্যানভাস উপাদানের উপর থাকা কনটেক্সট উপাদানের
3. **ড্রয়িং অপারেশন করুন** কনটেক্সট উপাদান ব্যবহার করে।
1. **রেফারেন্স নিন** ক্যানভাস এলিমেন্টের।
1. **রেফারেন্স নিন** কন্টেক্সট এলিমেন্টের যা ক্যানভাস এলিমেন্টে থাকে
1. **ড্রিং অপারেশন করুন** কন্টেক্সট এলিমেন্ট ব্যবহার করে।
উপরের ধাপগুলোর জন্য কোড সাধারণত এভাবে দেখায়:
উপরের ধাপগুলোর কোড সাধারণত এভাবে দেখা:
```javascript
// draws a red rectangle
@ -61,19 +61,19 @@ ctx.fillStyle = 'red';
ctx.fillRect(0,0, 200, 200) // x,y,width, height
```
✅ ক্যানভাস API মূলত 2D চিত্রের উপর ফোকাস করে, তবে আপনি ওয়েবসাইটে 3D উপাদানও আঁকতে পারেন; এর জন্য আপনি [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API) ব্যবহার করতে পারেন।
✅ ক্যানভাস API মূলত 2D আকৃতির উপর ফোকাস করে, তবে আপনি ওয়েবসাইটে 3D এলিমেন্টও আঁকতে পারেন; এর জন্য আপনি [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API) ব্যবহার করতে পারেন।
ক্যানভাস API দিয়ে আপনি বিভিন্ন জিনিস আঁকতে পারেন, যেমন:
ক্যানভাস API দিয়ে আপনি বিভিন্ন ধরনের জিনিস আঁকতে পারেন যেমন:
- **জ্যামিতিক চিত্র**, আমরা ইতিমধ্যে দেখিয়েছি কীভাবে একটি আয়তক্ষেত্র আঁকা যায়, তবে আরও অনেক কিছু আঁকা সম্ভব।
- **জ্যামিতিক আকৃতি**, আমরা ইতিমধ্যে দেখিয়েছি কীভাবে একটি রেকটেঙ্গেল আঁকা যায়, তবে আরও অনেক কিছু আঁকা সম্ভব।
- **টেক্সট**, আপনি যেকোনো ফন্ট এবং রঙে টেক্সট আঁকতে পারেন।
- **ছবি**, আপনি একটি .jpg বা .png এর মতো ইমেজ অ্যাসেট থেকে ছবি আঁকতে পারেন।
- **ইমেজ**, আপনি একটি ইমেজ অ্যাসেট যেমন .jpg বা .png থেকে ইমেজ আঁকতে পারেন।
✅ চেষ্টা করুন! আপনি জানেন কীভাবে একটি আয়তক্ষেত্র আঁকতে হয়, এবার একটি বৃত্ত আঁকার চেষ্টা করুন। CodePen-এ কিছু আকর্ষণীয় ক্যানভাস ড্রয়িং দেখুন। এখানে একটি [বিশেষভাবে চমকপ্রদ উদাহরণ](https://codepen.io/dissimulate/pen/KrAwx) রয়েছে।
✅ চেষ্টা করুন! আপনি জানেন কীভাবে একটি রেকটেঙ্গেল আঁকা যায়, এবার একটি বৃত্ত আঁকার চেষ্টা করুন। CodePen-এ কিছু আকর্ষণীয় ক্যানভাস আঁকার উদাহরণ দেখুন। এখানে একটি [বিশেষভাবে চমকপ্রদ উদাহরণ](https://codepen.io/dissimulate/pen/KrAwx) রেছে।
## একটি ইমেজ অ্যাসেট লোড এবং আঁকা
## ইমেজ অ্যাসেট লোড এবং আঁকা
আপনি একটি ইমেজ অ্যাসেট লোড করেন একটি `Image` অবজেক্ট তৈরি করে এবং এর `src` প্রপার্টি সেট করে। এরপর আপনি `load` ইভেন্টটি শোনেন এটি ব্যবহারের জন্য প্রস্তুত কিনা তা জানার জন্য। কোডটি এভাবে দেখায়:
আপনি একটি ইমেজ অ্যাসেট লোড করেন একটি `Image` অবজেক্ট তৈরি করে এবং এর `src` প্রপার্টি সেট করে। এরপর আপনি `load` ইভেন্টে শুনবেন এটি ব্যবহারের জন্য প্রস্তুত কিনা। কোডটি এভাবে দেখায়:
### অ্যাসেট লোড
@ -87,7 +87,7 @@ img.onload = () => {
### অ্যাসেট লোড প্যাটার্ন
উপরের কোডটি একটি কাঠামোর মধ্যে মোড়ানো সুপারিশ করা হয়, যাতে এটি ব্যবহার করা সহজ হয় এবং আপনি এটি সম্পূর্ণ লোড হওয়ার পরেই এটি ম্যানিপুলেট করার চেষ্টা করেন:
উপরের কোডটি এভাবে একটি কনস্ট্রাক্টে মোড়ানো সুপারিশ করা হয়, যাতে এটি ব্যবহার করা সহজ হয় এবং আপনি শুধুমাত্র এটি সম্পূর্ণ লোড হওয়ার পরই এটি ম্যানিপুলেট করার চেষ্টা করেন:
```javascript
function loadAsset(path) {
@ -110,7 +110,7 @@ async function run() {
```
গেম অ্যাসেট স্ক্রিনে আঁকার জন্য আপনার কোডটি এভাবে দেখাবে:
গেম অ্যাসেট স্ক্রিনে আঁকার জন্য আপনার কোড এভাবে দেখাবে:
```javascript
async function run() {
@ -124,11 +124,11 @@ async function run() {
}
```
## এখন আপনার গেম তৈরি শুরু করার সময়
## এখন আপনার গেম তৈরি শুরু করার সম
### কী তৈরি করবেন
আপনি একটি ওয়েব পৃষ্ঠা তৈরি করবেন যেখানে একটি ক্যানভাস উপাদান থাকবে। এটি একটি কালো স্ক্রিন `1024*768` রেন্ডার করবে। আমরা আপনাকে দুটি ছবি দিয়েছি:
আপনি একটি ওয়েব পেজ তৈরি করবেন যেখানে একটি ক্যানভাস এলিমেন্ট থাকবে। এটি একটি কালো স্ক্রিন `1024*768` রেন্ডার করবে। আমরা আপনাকে দুটি ইমেজ সরবরাহ করেছি:
- হিরো শিপ
@ -138,9 +138,9 @@ async function run() {
![মনস্টার শিপ](../../../../translated_images/enemyShip.5df2a822c16650c2fb3c06652e8ec8120cdb9122a6de46b9a1a56d54db22657f.bn.png)
### ডেভেলপমেন্ট শুরু করার জন্য প্রস্তাবিত ধাপ
### ডেভেলপমেন্ট শুরু করার জন্য সুপারিশকৃত ধাপ
`your-work` সাব ফোল্ডারে তৈরি করা ফাইলগুলো খুঁজুন। এতে নিম্নলিখিত ফাইলগুলো থাকা উচিত:
`your-work` সাব ফোল্ডারে তৈরি করা ফাইলগুলো খুঁজে বের করুন। এটি নিম্নলিখিত ফাইলগুলো থাকা উচিত:
```bash
-| assets
@ -151,31 +151,31 @@ async function run() {
-| package.json
```
Visual Studio Code-এ এই ফোল্ডারের একটি কপি খুলুন। আপনার একটি স্থানীয় ডেভেলপমেন্ট পরিবেশ সেটআপ করা প্রয়োজন, বিশেষত Visual Studio Code সহ NPM এবং Node ইনস্টল করা। যদি আপনার কম্পিউটারে `npm` সেটআপ না থাকে, [এখানে কীভাবে সেটআপ করবেন](https://www.npmjs.com/get-npm)।
এই ফোল্ডারের একটি কপি Visual Studio Code-এ খুলুন। আপনার একটি লোকাল ডেভেলপমেন্ট এনভায়রনমেন্ট সেটআপ করা প্রয়োজন, বিশেষত Visual Studio Code সহ NPM এবং Node ইনস্টল করা। যদি আপনার কম্পিউটারে `npm` সেটআপ না থাকে, [এখানে কীভাবে সেটআপ করবেন](https://www.npmjs.com/get-npm)।
আপনার প্রকল্প শুরু করুন `your_work` ফোল্ডারে নেভিগেট করে:
আপনার প্রজেক্ট শুরু করুন `your_work` ফোল্ডারে নেভিগেট করে:
```bash
cd your-work
npm start
```
উপরের কমান্ডটি `http://localhost:5000` ঠিকানায় একটি HTTP সার্ভার শুরু করবে। একটি ব্রাউজার খুলুন এবং এই ঠিকানাটি ইনপুট করুন। এটি এখন একটি ফাঁকা পৃষ্ঠা, তবে এটি পরিবর্তিত হবে।
উপরের কমান্ডটি একটি HTTP সার্ভার চালু করবে ঠিকানা `http://localhost:5000`-এ। একটি ব্রাউজার খুলুন এবং সেই ঠিকানা ইনপুট করুন। এটি এখন একটি ফাঁকা পেজ, তবে এটি পরিবর্তিত হবে।
> নোট: আপনার স্ক্রিনে পরিবর্তন দেখতে ব্রাউজারটি রিফ্রেশ করুন।
> নোট: স্ক্রিনে পরিবর্তন দেখতে আপনার ব্রাউজার রিফ্রেশ করুন।
### কোড যোগ করুন
`your-work/app.js`-এ প্রয়োজনীয় কোড যোগ করুন নিচের সমস্যাগুলো সমাধান করতে:
`your-work/app.js`-এ প্রয়োজনীয় কোড যোগ করুন নিচের সমস্যাগুলো সমাধানের জন্য:
1. **ক্যানভাস আঁকুন** কালো ব্যাকগ্রাউন্ড সহ
> টিপ: `/app.js`-এ সঠিক TODO-র নিচে দুটি লাইন যোগ করুন, যেখানে `ctx` উপাদানটি কালো সেট করুন এবং উপরের/বাম কোঅর্ডিনেট 0,0 এবং উচ্চতা ও প্রস্থ ক্যানভাসের সমান করুন।
2. **টেক্সচার লোড করুন**
> টিপ: `await loadTexture` ব্যবহার করে প্লেয়ার এবং শত্রু ইমেজ যোগ করুন এবং ইমেজ পাথ পাস করুন। আপনি এখনো স্ক্রিনে এগুলো দেখতে পাবেন না!
3. **হিরো আঁকুন** স্ক্রিনের কেন্দ্রে নিচের অর্ধে
> টিপ: `drawImage` API ব্যবহার করে `heroImg` স্ক্রিনে আঁকুন, যেখানে `canvas.width / 2 - 45` এবং `canvas.height - canvas.height / 4` সেট করুন
4. **5*5 মনস্টার আঁকুন**
> টিপ: এখন স্ক্রিনে শত্রুদের আঁকার কোড আনকমেন্ট করন। এরপর `createEnemies` ফাংশনে যান এবং এটি তৈরি করুন।
1. **ড্র করুন** একটি কালো ব্যাকগ্রাউন্ড সহ ক্যানভাস
> টিপ: `/app.js`-এ উপযুক্ত TODO-এর নিচে দুটি লাইন যোগ করুন, `ctx` এলিমেন্টকে কালো সেট করুন এবং টপ/লেফট কোঅর্ডিনেট 0,0 এবং উচ্চতা ও প্রস্থ ক্যানভাসের সমান সেট করুন।
2. **লোড করুন** টেক্সচার
> টিপ: প্লেয়ার এবং শত্রু ইমেজ যোগ করুন `await loadTexture` ব্যবহার করে এবং ইমেজ পাথ পাস করে। আপনি এখনো স্ক্রিনে এগুলো দেখতে পাবেন না!
3. **ড্র করুন** হিরোকে স্ক্রিনের কেন্দ্রে নিচের অর্ধে
> টিপ: `drawImage` API ব্যবহার করে স্ক্রিনে heroImg আঁকুন, `canvas.width / 2 - 45` এবং `canvas.height - canvas.height / 4)` সেট করে
4. **ড্র করুন** 5*5 মনস্টার
> টিপ: এখন আপনি স্ক্রিনে শত্রুদের আঁকার কোড আনকমেন্ট করতে পারেন। এরপর `createEnemies` ফাংশনে যান এবং এটি তৈরি করুন।
প্রথমে কিছু কনস্ট্যান্ট সেট করুন:
@ -186,7 +186,7 @@ npm start
const STOP_X = START_X + MONSTER_WIDTH;
```
এরপর, একটি লুপ তৈরি করুন মনস্টারদের অ্যারে স্ক্রিনে আঁকার জন্য:
এরপর একটি লুপ তৈরি করুন যা মনস্টারদের অ্যারে স্ক্রিনে আঁকবে:
```javascript
for (let x = START_X; x < STOP_X; x += 98) {
@ -198,7 +198,7 @@ npm start
## ফলাফল
শেষ ফলাফলটি এমন দেখাবে:
শেষ ফলাফলটি এভাবে দেখাবে:
![কালো স্ক্রিনে একটি হিরো এবং 5*5 মনস্টার](../../../../translated_images/partI-solution.36c53b48c9ffae2a5e15496b23b604ba5393433e4bf91608a7a0a020eb7a2691.bn.png)
@ -210,19 +210,21 @@ npm start
## 🚀 চ্যালেঞ্জ
আপনি 2D-কেন্দ্রিক ক্যানভাস API সম্পর্কে শিখেছেন; [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API) সম্পর্কে জানুন এবং একটি 3D অবজেক্ট আঁকার চেষ্টা করুন।
আপনি 2D-কেন্দ্রিক ক্যানভাস API সম্পর্কে শিখেছেন; [WebGL API](https://developer.mozilla.org/docs/Web/API/WebGL_API) দেখুন এবং একটি 3D অবজেক্ট আঁকার চেষ্টা করুন।
## পোস্ট-লেকচার কুইজ
[পোস্ট-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/32)
## পুনরালোচনা ও স্ব-অধ্যয়ন
## রিভিউ এবং সেলফ স্টাডি
ক্যানভাস API সম্পর্কে আরও জানুন [এটি পড়ে](https://developer.mozilla.org/docs/Web/API/Canvas_API)।
ক্যানভাস API সম্পর্কে আরও জানুন [এটি পড়ার মাধ্যমে](https://developer.mozilla.org/docs/Web/API/Canvas_API)।
## অ্যাসাইনমেন্ট
[ক্যানভাস API নিয়ে কাজ করুন](assignment.md)
[ক্যানভাস API নিয়ে খেলুন](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। এর মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিক অনুবাদ প্রদানের চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।

@ -1,30 +1,30 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "23f088add24f0f1fa51014a9e27ea280",
"translation_date": "2025-08-25T22:10:44+00:00",
"original_hash": "a9a161871de7706cb0e23b1bd0c74559",
"translation_date": "2025-08-28T22:57:58+00:00",
"source_file": "6-space-game/3-moving-elements-around/README.md",
"language_code": "bn"
}
-->
# মহাকাশ গেম তৈরি করুন পার্ট ৩: গতি যোগ করা
# মহাকাশ গেম তৈরি পর্ব ৩: গতি যোগ করা
## প্রাক-লেকচার কুইজ
[প্রাক-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/33)
গেম তখনই মজার হয় যখন পর্দায় এলিয়েনরা ঘুরে বেড়ায়! এই গেমে আমরা দুটি ধরণের গতি ব্যবহার করব:
গেম তখনই মজার হয় যখন পর্দায় এলিয়েনরা দৌড়াদৌড়ি করে! এই গেমে আমরা দুটি ধরণের গতি ব্যবহার করব:
- **িবোর্ড/মাউস গতি**: যখন ব্যবহারকারী কিবোর্ড বা মাউস ব্যবহার করে পর্দায় একটি বস্তু সরায়।
- **গেম দ্বারা সৃষ্ট গতি**: যখন গেম একটি নির্দিষ্ট সময় ব্যবধানে একটি বস্তু সরায়।
- **ীবোর্ড/মাউস গতি**: যখন ব্যবহারকারী কীবোর্ড বা মাউস ব্যবহার করে পর্দায় একটি বস্তু সরায়।
- **গেম দ্বারা সৃষ্ট গতি**: যখন গেম একটি নির্দিষ্ট সময়ের ব্যবধানে একটি বস্তু সরায়।
তাহলে আমরা কীভাবে পর্দায় জিনিস সরাই? এটি সবই কার্টেসিয়ান কোঅর্ডিনেট নিয়ে: আমরা বস্তুর অবস্থান (x, y) পরিবর্তন করি এবং তারপর পর্দা পুনরায় আঁকি।
তাহলে আমরা কীভাবে পর্দায় জিনিসপত্র সরাই? এটি সবই কার্টেসিয়ান কোঅর্ডিনেট নিয়ে: আমরা বস্তুর অবস্থান (x, y) পরিবর্তন করি এবং তারপর পর্দা পুনরায় আঁকি।
সাধারণত পর্দায় *গতি* অর্জনের জন্য আপনাকে নিম্নলিখিত ধাপগুলি অনুসরণ করতে হয়:
সাধারণত পর্দায় *গতি* অর্জনের জন্য আপনাকে নিম্নলিখিত ধাপগুলি প্রয়োজন:
1. **নতুন অবস্থান নির্ধারণ করুন** একটি বস্তুর জন্য; এটি প্রয়োজন যাতে বস্তুটি সরানো হয়েছে বলে মনে হয়।
2. **পর্দা পরিষ্কার করুন**, পর্দা পুনরায় আঁকার মধ্যে পরিষ্কার করতে হবে। আমরা এটি একটি ব্যাকগ্রাউন্ড রঙ দিয়ে একটি আয়তক্ষেত্র আঁকার মাধ্যমে পরিষ্কার করতে পারি।
3. **নতুন অবস্থানে বস্তু পুনরায় আঁকুন**। এটি করে আমরা অবশেষে একটি অবস্থান থেকে অন্য অবস্থানে বস্তুটি সরানোর কাজ সম্পন্ন করি।
1. **নতুন অবস্থান নির্ধারণ করুন** একটি বস্তুর জন্য; এটি প্রয়োজন যাতে বস্তুটি সরেছে বলে মনে হয়।
2. **পর্দা পরিষ্কার করুন**, প্রতিবার আঁকার মধ্যে পর্দা পরিষ্কার করতে হবে। আমরা এটি একটি ব্যাকগ্রাউন্ড রঙ দিয়ে একটি আয়তক্ষেত্র আঁকার মাধ্যমে পরিষ্কার করতে পারি।
3. **নতুন অবস্থানে বস্তু পুনরায় আঁকুন**। এটি করার মাধ্যমে আমরা অবশেষে একটি অবস্থান থেকে অন্য অবস্থানে বস্তু সরানোর কাজটি সম্পন্ন করি।
কোডে এটি দেখতে এমন হতে পারে:
@ -39,13 +39,13 @@ ctx.fillStyle = "black";
ctx.drawImage(heroImg, hero.x, hero.y);
```
✅ আপনি কি ভাবতে পারেন কেন আপনার হিরোকে প্রতি সেকেন্ডে অনেক ফ্রেমে পুনরায় আঁকা পারফরম্যান্স খরচ বাড়াতে পারে? [এই প্যাটার্নের বিকল্পগুলি](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas) সম্পর্কে পড়ুন।
✅ আপনি কি ভাবতে পারেন কেন প্রতি সেকেন্ডে আপনার হিরোকে অনেকবার পুনরায় আঁকা পারফরম্যান্সের খরচ বাড়াতে পারে? [এই প্যাটার্নের বিকল্পগুলি](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas) সম্পর্কে পড়ুন।
## কিবোর্ড ইভেন্ট পরিচালনা করুন
## কবোর্ড ইভেন্ট পরিচালনা
আপনি ইভেন্ট পরিচালনা করেন নির্দিষ্ট ইভেন্টগুলিকে কোডের সাথে সংযুক্ত করে। কিবোর্ড ইভেন্টগুলি পুরো উইন্ডোতে ট্রিগার হয়, যেখানে মাউস ইভেন্ট যেমন `click` একটি নির্দিষ্ট উপাদান ক্লিক করার সাথে সংযুক্ত হতে পারে। আমরা এই প্রকল্পে কিবোর্ড ইভেন্ট ব্যবহার করব।
আপনি ইভেন্ট পরিচালনা করেন নির্দিষ্ট ইভেন্টগুলিকে কোডের সাথে সংযুক্ত করে। কবোর্ড ইভেন্টগুলি পুরো উইন্ডোতে ট্রিগার হয়, যেখানে মাউস ইভেন্ট যেমন `click` একটি নির্দিষ্ট উপাদান ক্লিক করার সাথে সংযুক্ত হতে পারে। আমরা এই প্রকল্পে কবোর্ড ইভেন্ট ব্যবহার করব।
একটি ইভেন্ট পরিচালনা করতে আপনাকে উইন্ডোর `addEventListener()` পদ্ধতি ব্যবহার করতে হবে এবং এটিকে দুটি ইনপুট প্যারামিটার দিতে হবে। প্রথম প্যারামিটারটি ইভেন্টের নাম, যেমন `keyup`। দ্বিতীয় প্যারামিটারটি সেই ফাংশন যা ইভেন্ট ঘটার ফলে আহ্বান করা উচিত।
ইভেন্ট পরিচালনা করতে আপনাকে উইন্ডোর `addEventListener()` পদ্ধতি ব্যবহার করতে হবে এবং এটিকে দুটি ইনপুট প্যারামিটার দিতে হবে। প্রথম প্যারামিটারটি ইভেন্টের নাম, যেমন `keyup`। দ্বিতীয় প্যারামিটারটি সেই ফাংশন যা ইভেন্টটি ঘটার ফলে আহ্বান করা উচিত।
এখানে একটি উদাহরণ:
@ -60,14 +60,14 @@ window.addEventListener('keyup', (evt) => {
কী ইভেন্টের জন্য ইভেন্টে দুটি প্রপার্টি রয়েছে যা আপনি দেখতে পারেন কোন কী চাপা হয়েছে:
- `key`, এটি চাপা কী-এর একটি স্ট্রিং উপস্থাপনা, যেমন `ArrowUp`
- `keyCode`, এটি একটি সংখ্যার উপস্থাপনা, যেমন `37`, যা `ArrowLeft` এর সাথে মিলে যায়।
- `key`, এটি চাপা কীটির একটি স্ট্রিং রূপ, যেমন `ArrowUp`
- `keyCode`, এটি একটি সংখ্যার রূপ, যেমন `37`, যা `ArrowLeft` এর সাথে মিলে যায়।
✅ কী ইভেন্ট ম্যানিপুলেশন গেম ডেভেলপমেন্টের বাইরেও কার্যকর। এই কৌশলটির জন্য আপনি আর কী কী ব্যবহার ভাবতে পারেন?
✅ কী ইভেন্ট ম্যানিপুলেশন গেম ডেভেলপমেন্টের বাইরেও উপকারী। এই কৌশলটির জন্য আপনি আর কী কী ব্যবহার ভাবতে পারেন?
### বিশেষ কী: একটি সতর্কতা
কিছু *বিশেষ* কী রয়েছে যা উইন্ডোকে প্রভাবিত করে। এর মানে হল যে আপনি যদি একটি `keyup` ইভেন্ট শুনছেন এবং এই বিশেষ কী ব্যবহার করে আপনার হিরোকে সরান, এটি অনুভূমিক স্ক্রলিংও করবে। এই কারণে আপনি যখন আপনার গেম তৈরি করবেন তখন এই বিল্ট-ইন ব্রাউজার আচরণটি *বন্ধ* করতে চাইতে পারেন। এর জন্য আপনাকে এমন কোড প্রয়োজন:
কিছু *বিশেষ* কী রয়েছে যা উইন্ডোকে প্রভাবিত করে। এর মানে হল যে আপনি যদি একটি `keyup` ইভেন্ট শুনছেন এবং এই বিশেষ কী ব্যবহার করে আপনার হিরোকে সরান তবে এটি অনুভূমিক স্ক্রলিংও করবে। এই কারণে আপনি যখন আপনার গেম তৈরি করবেন তখন এই বিল্ট-ইন ব্রাউজার আচরণটি *বন্ধ* করতে চাইতে পারেন। এর জন্য আপনাকে এমন কোড প্রয়োজন:
```javascript
let onKeyDown = function (e) {
@ -88,11 +88,11 @@ let onKeyDown = function (e) {
window.addEventListener('keydown', onKeyDown);
```
উপরের কোডটি নিশ্চিত করবে যে অ্যারো-কী এবং স্পেস কী-এর *ডিফল্ট* আচরণ বন্ধ হয়ে গেছে। *বন্ধ* করার প্রক্রিয়া ঘটে যখন আমরা `e.preventDefault()` কল করি।
উপরের কোডটি নিশ্চিত করবে যে অ্যারো-কী এবং স্পেস কী তাদের *ডিফল্ট* আচরণ বন্ধ করে দিয়েছে। *বন্ধ করার* প্রক্রিয়াটি ঘটে যখন আমরা `e.preventDefault()` কল করি।
## গেম দ্বারা সৃষ্ট গতি
আমরা `setTimeout()` বা `setInterval()` ফাংশন ব্যবহার করে টাইমার দিয়ে জিনিসগুলিকে নিজে থেকেই সরাতে পারি, যা প্রতিটি টিক বা সময় ব্যবধানে বস্তুর অবস্থান আপডেট করে। এটি দেখতে এমন হতে পারে:
আমরা `setTimeout()` বা `setInterval()` ফাংশনের মতো টাইমার ব্যবহার করে জিনিসপত্রকে নিজে থেকেই সরাতে পারি, যা প্রতিটি টিক বা সময়ের ব্যবধানে বস্তুর অবস্থান আপডেট করে। এটি কোডে এমন হতে পারে:
```javascript
let id = setInterval(() => {
@ -103,7 +103,7 @@ let id = setInterval(() => {
## গেম লুপ
গেম লুপ একটি ধারণা যা মূলত একটি ফাংশন যা নিয়মিত ব্যবধানে আহ্বান করা হয়। এটি গেম লুপ বলা হয় কারণ ব্যবহারকারীর কাছে দৃশ্যমান হওয়া উচিত এমন সবকিছু লুপে আঁকা হয়। গেম লুপ গেমের অংশ হওয়া সমস্ত গেম অবজেক্ট ব্যবহার করে, তাদের সবাইকে আঁকে যদি না কোনো কারণে তারা আর গেমের অংশ না থাকে। উদাহরণস্বরূপ, যদি একটি অবজেক্ট একটি শত্রু হয় যা লেজার দ্বারা আঘাতপ্রাপ্ত হয় এবং বিস্ফোরিত হয়, এটি আর বর্তমান গেম লুপের অংশ নয় (আপনি পরবর্তী পাঠে এটি সম্পর্কে আরও শিখবেন)।
গেম লুপ একটি ধারণা যা মূলত একটি ফাংশন যা নিয়মিত ব্যবধানে আহ্বান করা হয়। এটিকে গেম লুপ বলা হয় কারণ ব্যবহারকারীর কাছে দৃশ্যমান হওয়া উচিত এমন সবকিছু লুপে আঁকা হয়। গেম লুপটি গেমের অংশ হওয়া সমস্ত গেম অবজেক্ট ব্যবহার করে, তাদের সবাইকে আঁকে যদি না কোনো কারণে তারা আর গেমের অংশ না থাকে। উদাহরণস্বরূপ, যদি একটি অবজেক্ট একটি শত্রু হয় যা লেজার দ্বারা আঘাতপ্রাপ্ত হয় এবং বিস্ফোরিত হয়, এটি আর বর্তমান গেম লুপের অংশ নয় (আপনি পরবর্তী পাঠে এটি সম্পর্কে আরও শিখবেন)।
গেম লুপ সাধারণত কোডে এমন দেখতে পারে:
@ -119,18 +119,18 @@ let gameLoopId = setInterval(() =>
}, 200);
```
উপরের লুপটি প্রতি `200` মিলিসেকেন্ডে ক্যানভাস পুনরায় আঁকতে আহ্বান করা হয়। আপনার গেমের জন্য সবচেয়ে ভালো সময় ব্যবধান বেছে নেওয়ার ক্ষমতা আপনার রয়েছে।
উপরের লুপটি প্রতি `200` মিলিসেকেন্ডে ক্যানভাস পুনরায় আঁকতে আহ্বান করা হয়। আপনার গেমের জন্য সবচেয়ে উপযুক্ত ইন্টারভালটি বেছে নেওয়ার ক্ষমতা আপনার রয়েছে।
## মহাকাশ গেম চালিয়ে যাওয়া
আপনি বিদ্যমান কোডটি নিয়ে এটি প্রসারিত করবেন। হয় আপনি পার্ট I-এ সম্পন্ন করা কোড দিয়ে শুরু করুন অথবা [পার্ট II-স্টার্টার](../../../../6-space-game/3-moving-elements-around/your-work) এর কোড ব্যবহার করুন।
আপনি বিদ্যমান কোডটি নিয়ে এটি বাড়াবেন। হয় আপনি প্রথম পর্বে সম্পন্ন করা কোড দিয়ে শুরু করুন অথবা [দ্বিতীয় পর্বের স্টার্টার](../../../../6-space-game/3-moving-elements-around/your-work) কোডটি ব্যবহার করুন।
- **হিরোকে সরানো**: আপনি কোড যোগ করবেন যাতে আপনি অ্যারো কী ব্যবহার করে হিরোকে সরাতে পারেন।
- **শত্রুদের সরানো**: আপনাকে কোড যোগ করতে হবে যাতে শত্রুরা একটি নির্দিষ্ট হারে উপরে থেকে নিচে সরতে পারে।
- **হিরো সরানো**: আপনি কোড যোগ করবেন যাতে আপনি অ্যারো কী ব্যবহার করে হিরোকে সরাতে পারেন।
- **শত্রুদের সরানো**: আপনাকে কোড যোগ করতে হবে যাতে শত্রুরা একটি নির্দিষ্ট গতিতে উপরে থেকে নিচে চলে।
## সুপারিশকৃত ধাপ
## প্রস্তাবিত ধাপসমূহ
`your-work` সাব ফোল্ডারে তৈরি করা ফাইলগুলি খুঁজুন। এটি নিম্নলিখিতটি ধারণ করা উচিত:
`your-work` সাব ফোল্ডারে তৈরি করা ফাইলগুলি খুঁজুন। এটি নিম্নলিখিতটি থাকা উচিত:
```bash
-| assets
@ -141,22 +141,22 @@ let gameLoopId = setInterval(() =>
-| package.json
```
আপনার প্রকল্পটি `your_work` ফোল্ডারে শুরু করুন টাইপ করে:
আপনার প্রকল্পটি `your_work` ফোল্ডারে শুরু করুন এই কমান্ডটি টাইপ করে:
```bash
cd your-work
npm start
```
উপরেরটি ঠিকানা `http://localhost:5000` একটি HTTP সার্ভার শুরু করবে। একটি ব্রাউজার খুলুন এবং সেই ঠিকানা ইনপুট করুন, এখন এটি হিরো এবং সমস্ত শত্রুদের রেন্ডার করা উচিত; কিছুই এখনও সরছে না!
উপরেরটি `http://localhost:5000` ঠিকানায় একটি HTTP সার্ভার শুরু করবে। একটি ব্রাউজার খুলুন এবং সেই ঠিকানাটি ইনপুট করুন, এখন এটি হিরো এবং সমস্ত শত্রুদের রেন্ডার করা উচিত; কিছুই এখনও সরছে না!
### কোড যোগ করুন
1. **নির্দিষ্ট অবজেক্ট যোগ করুন** `hero`, `enemy` এবং `game object` এর জন্য, তাদের `x` এবং `y` প্রপার্টি থাকা উচিত। ([Inheritance or composition](../README.md) অংশটি মনে রাখুন)।
1. **`hero`, `enemy` এবং `game object` এর জন্য পৃথক অবজেক্ট যোগ করুন**, তাদের `x` এবং `y` প্রপার্টি থাকা উচিত। (মনে রাখুন [Inheritance বা composition](../README.md) অংশটি)।
*ইঙ্গিত* `game object` হওয়া উচিত যার `x` এবং `y` এবং নিজেকে ক্যানভাসে আঁকার ক্ষমতা রয়েছে।
>টিপ: একটি নতুন GameObject ক্লাস যোগ করে শুরু করুন যার কনস্ট্রাক্টর নিচের মতো নির্ধারিত, এবং তারপর এটি ক্যানভাসে আঁকুন:
>টিপ: নিচের মতো কনস্ট্রাক্টর সহ একটি নতুন GameObject ক্লাস যোগ করা শুরু করুন এবং তারপর এটি ক্যানভাসে আঁকুন:
```javascript
@ -205,9 +205,9 @@ npm start
}
```
2. **কী-ইভেন্ট হ্যান্ডলার যোগ করুন** কী নেভিগেশনের জন্য (হিরোকে উপরে/নিচে, বামে/ডানে সরান)
2. **কী-ইভেন্ট হ্যান্ডলার যোগ করুন** হিরোকে উপরে/নিচে বামে/ডানে সরানোর জন্য।
*মনে রাখন* এটি একটি কার্টেসিয়ান সিস্টেম, উপরের-বাম কোণটি `0,0`। এছাড়াও *ডিফল্ট আচরণ* বন্ধ করার কোড যোগ করতে ভুলবেন না।
*মনে রাখবেন* এটি একটি কার্টেসিয়ান সিস্টেম, উপরের-বাম কোণটি `0,0`। এছাড়াও ডিফল্ট আচরণ বন্ধ করার জন্য কোড যোগ করতে ভুলবেন না।
>টিপ: আপনার onKeyDown ফাংশন তৈরি করুন এবং এটি উইন্ডোর সাথে সংযুক্ত করুন:
@ -221,13 +221,13 @@ npm start
window.addEventListener("keydown", onKeyDown);
```
এই পর্যায়ে আপনার ব্রাউজার কনসোল পরীক্ষা করুন এবং কীস্ট্রোকগুলি লগ হচ্ছে দেখুন।
এই পর্যায়ে আপনার ব্রাউজারের কনসোল পরীক্ষা করুন এবং কীস্ট্রোকগুলি লগ হচ্ছে কিনা দেখুন।
3. **প্রয়োগ করুন** [Pub sub pattern](../README.md), এটি আপনার কোড পরিষ্কার রাখবে যখন আপনি বাকি অংশগুলি অনুসরণ করবেন।
3. **[Pub sub pattern](../README.md) প্রয়োগ করুন**, এটি আপনার কোড পরিষ্কার রাখবে যখন আপনি বাকি অংশগুলি অনুসরণ করবেন।
এটি করার জন্য, আপনি:
এটি করতে, আপনি:
1. **একটি ইভেন্ট লিসেনার যোগ করুন** উইন্ডোতে:
1. **উইন্ডোতে একটি ইভেন্ট লিসেনার যোগ করুন**:
```javascript
window.addEventListener("keyup", (evt) => {
@ -243,7 +243,7 @@ npm start
});
```
1. **একটি EventEmitter ক্লাস তৈরি করুন** বার্তা প্রকাশ এবং সাবস্ক্রাইব করতে:
1. **একটি EventEmitter ক্লাস তৈরি করুন** বার্তা প্রকাশ এবং সাবস্ক্রাইব করার জন্য:
```javascript
class EventEmitter {
@ -313,7 +313,7 @@ npm start
1. **গেম লুপ সেট আপ করুন**
window.onload ফাংশনটি রিফ্যাক্টর করুন গেমটি ইনিশিয়ালাইজ করতে এবং একটি ভালো ব্যবধানে একটি গেম লুপ সেট আপ করতে। আপনি একটি লেজার বিমও যোগ করবেন:
উইন্ডোর onload ফাংশনটি রিফ্যাক্টর করুন গেমটি ইনিশিয়ালাইজ করতে এবং একটি ভালো ইন্টারভালে একটি গেম লুপ সেট আপ করতে। আপনি একটি লেজার বিমও যোগ করবেন:
```javascript
window.onload = async () => {
@ -334,9 +334,9 @@ npm start
};
```
5. **কোড যোগ করুন** শত্রুদের একটি নির্দিষ্ট ব্যবধানে সরানোর জন্য
5. **শত্রুদের একটি নির্দিষ্ট ইন্টারভালে সরানোর জন্য কোড যোগ করুন**
`createEnemies()` ফাংশনটি রিফ্যাক্টর করুন শত্রু তৈরি করতে এবং সেগুলিকে নতুন gameObjects ক্লাসে ঠেলে দিতে:
`createEnemies()` ফাংশনটি রিফ্যাক্টর করুন শত্রু তৈরি করতে এবং তাদের নতুন gameObjects ক্লাসে পুশ করতে:
```javascript
function createEnemies() {
@ -355,7 +355,7 @@ npm start
}
```
এবং একটি `createHero()` ফাংশন যোগ করুন হিরোর জন্য একই প্রক্রিয়া করতে।
এবং হিরোর জন্য একটি `createHero()` ফাংশন যোগ করুন একই প্রক্রিয়া সম্পন্ন করতে।
```javascript
function createHero() {
@ -368,7 +368,7 @@ npm start
}
```
এবং অবশেষে, একটি `drawGameObjects()` ফাংশন যোগ করুন আঁকা শুরু করতে:
এবং অবশেষে, একটি `drawGameObjects()` ফাংশন যোগ করুন ড্রয়িং শুরু করতে:
```javascript
function drawGameObjects(ctx) {
@ -382,7 +382,7 @@ npm start
## 🚀 চ্যালেঞ্জ
যেমনটি আপনি দেখতে পাচ্ছেন, আপনার কোড 'স্প্যাগেটি কোড'-এ পরিণত হতে পারে যখন আপনি ফাংশন, ভেরিয়েবল এবং ক্লাস যোগ করতে শুরু করেন। কীভাবে আপনি আপনার কোড আরও পড়ার যোগ্য করতে আরও ভালোভাবে সংগঠিত করতে পারেন? এমন একটি সিস্টেম স্কেচ করুন যা আপনার কোড সংগঠিত করে, এমনকি যদি এটি এখনও একটি ফাইলে থাকে।
যেমনটি আপনি দেখতে পাচ্ছেন, আপনার কোড 'স্প্যাগেটি কোড'-এ পরিণত হতে পারে যখন আপনি ফাংশন, ভেরিয়েবল এবং ক্লাস যোগ করতে থাকেন। কীভাবে আপনি আপনার কোড আরও পাঠযোগ্য করার জন্য আরও ভালোভাবে সংগঠিত করতে পারেন? এমন একটি সিস্টেম স্কেচ করুন যা আপনার কোড সংগঠিত করে, এমনকি এটি এখনও একটি ফাইলে থাকে।
## পোস্ট-লেকচার কুইজ
@ -390,11 +390,13 @@ npm start
## পর্যালোচনা ও স্ব-অধ্যয়ন
যদিও আমরা ফ্রেমওয়ার্ক ব্যবহার না করে আমাদের গেম লিখছি, গেম ডেভেলপমেন্টের জন্য অনেক জাভাস্ক্রিপ্ট-ভিত্তিক ক্যানভাস ফ্রেমওয়ার্ক রয়েছে। [এই সম্পর্কে পড়ার](https://github.com/collections/javascript-game-engines) জন্য কিছু সময় নিন
যদিও আমরা কোনো ফ্রেমওয়ার্ক ব্যবহার না করে আমাদের গেম লিখছি, গেম ডেভেলপমেন্টের জন্য অনেক জাভাস্ক্রিপ্ট-ভিত্তিক ক্যানভাস ফ্রেমওয়ার্ক রয়েছে। এই বিষয়ে কিছু সময় নিয়ে [পড়াশোনা করুন](https://github.com/collections/javascript-game-engines)।
## অ্যাসাইনমেন্ট
[আপনার কোডে মন্তব্য যোগ করুন](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতা নিশ্চিত করার চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়ী থাকব না।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিক অনুবাদ প্রদানের চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।

@ -1,40 +1,40 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "2e83e38c35dc003f046d7cc0bbfd4920",
"translation_date": "2025-08-25T22:22:41+00:00",
"original_hash": "a6ce295ff03bb49df7a3e17e6e7100a0",
"translation_date": "2025-08-28T22:58:56+00:00",
"source_file": "6-space-game/4-collision-detection/README.md",
"language_code": "bn"
}
-->
# মহাকাশ গেম তৈরি পর্ব : লেজার যোগ করা এবং সংঘর্ষ শনাক্তকরণ
# স্পেস গেম তৈরি করুন পার্ট : লেজার যোগ করা এবং সংঘর্ষ সনাক্তকরণ
## প্রাক-লেকচার কুইজ
## প্রি-লেকচার কুইজ
[প্রাক-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/35)
[প্রি-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/35)
এই পাঠে আপনি শিখবেন কিভাবে জাভাস্ক্রিপ্ট ব্যবহার করে লেজার ছোড়া যায়! আমরা আমাদের গেমে দুটি জিনিস যোগ করব:
এই পাঠে আপনি শিখবেন কভাবে জাভাস্ক্রিপ্ট ব্যবহার করে লেজার ছোড়া যায়! আমরা আমাদের গেমে দুটি জিনিস যোগ করব:
- **একটি লেজার**: এই লেজারটি আপনার হিরোর জাহাজ থেকে ঊর্ধ্বমুখী ছোড়া হবে
- **সংঘর্ষ শনাক্তকরণ**, শুটিং ক্ষমতা বাস্তবায়নের অংশ হিসেবে আমরা কিছু চমৎকার গেমের নিয়ম যোগ করব:
- **লেজার শত্রুকে আঘাত করে**: শত্রু লেজারের আঘাতে ধ্বংস হবে
- **লেজার স্ক্রিনের উপরের অংশে আঘাত করে**: লেজার স্ক্রিনের উপরের অংশে আঘাত করলে তা ধ্বংস হবে
- **শত্রু এবং হিরোর সংঘর্ষ**: শত্রু এবং হিরো একে অপরকে আঘাত করলে উভয়ই ধ্বংস হবে
- **শত্রু স্ক্রিনের নিচে পৌঁছায়**: শত্রু স্ক্রিনের নিচে পৌঁছালে শত্রু এবং হিরো উভয়ই ধ্বংস হবে
- **একটি লেজার**: এই লেজারটি আপনার হিরোর জাহাজ থেকে ঊর্ধ্বমুখী ছোঁড়া হবে।
- **সংঘর্ষ সনাক্তকরণ**, *লেজার ছোঁড়ার* ক্ষমতা বাস্তবায়নের অংশ হিসেবে আমরা কিছু সুন্দর গেমের নিয়ম যোগ করব:
- **লেজার শত্রুকে আঘাত করে**: শত্রু লেজারের আঘাতে মারা যায়।
- **লেজার স্ক্রিনের শীর্ষে আঘাত করে**: স্ক্রিনের শীর্ষে আঘাত করলে লেজার ধ্বংস হয়ে যায়।
- **শত্রু এবং হিরোর সংঘর্ষ**: শত্রু এবং হিরো একে অপরকে আঘাত করলে উভয়ই ধ্বংস হয়ে যায়।
- **শত্রু স্ক্রিনের নিচে আঘাত করে**: শত্রু স্ক্রিনের নিচে পৌঁছালে শত্রু এবং হিরো উভয়ই ধ্বংস হয়ে যায়।
সংক্ষেপে, আপনি -- *হিরো* -- স্ক্রিনের নিচে পৌঁছানোর আগে লেজার দিয়ে সব শত্রুকে ধ্বংস করতে হবে।
সংক্ষেপে, আপনি -- *হিরো* -- স্ক্রিনের নিচে পৌঁছানোর আগে লেজার দিয়ে সব শত্রুকে আঘাত করতে হবে।
✅ প্রথম কম্পিউটার গেমটি সম্পর্কে একটু গবেষণা করুন। এর কার্যকারিতা কী ছিল?
চলুন একসাথে বীরত্ব দেখাই!
## সংঘর্ষ নাক্তকরণ
## সংঘর্ষ নাক্তকরণ
সংঘর্ষ শনাক্তকরণ কীভাবে করব? আমাদের গেম অবজেক্টগুলোকে চলমান আয়তক্ষেত্র হিসেবে ভাবতে হবে। কেন? কারণ গেম অবজেক্ট আঁকার জন্য ব্যবহৃত ইমেজটি একটি আয়তক্ষেত্র: এর `x`, `y`, `width` এবং `height` থাকে।
সংঘর্ষ সনাক্তকরণ কীভাবে করা যায়? আমাদের গেমের অবজেক্টগুলোকে চলমান আয়তক্ষেত্র হিসেবে ভাবতে হবে। কেন? কারণ গেম অবজেক্ট আঁকার জন্য ব্যবহৃত ইমেজটি একটি আয়তক্ষেত্র: এর `x`, `y`, `width` এবং `height` থাকে।
যদি দুটি আয়তক্ষেত্র, যেমন হিরো এবং শত্রু *অন্তর্ভুক্ত* হয়, তাহলে সংঘর্ষ ঘটে। এরপর কী হবে তা গেমের নিয়মের উপর নির্ভর করে। সংঘর্ষ নাক্তকরণ বাস্তবায়নের জন্য আপনাকে নিম্নলিখিত জিনিসগুলো প্রয়োজন:
যদি দুটি আয়তক্ষেত্র, যেমন হিরো এবং শত্রু *অবস্থানগতভাবে একে অপরকে ছেদ করে*, তাহলে সংঘর্ষ ঘটে। এরপর কী ঘটবে তা গেমের নিয়মের উপর নির্ভর করে। সংঘর্ষ নাক্তকরণ বাস্তবায়নের জন্য আপনাকে নিম্নলিখিত জিনিসগুলো করতে হবে:
1. গেম অবজেক্টের একটি আয়তক্ষেত্র উপস্থাপনা পাওয়ার উপায়, যেমন:
1. গেম অবজেক্টের একটি আয়তক্ষেত্রের প্রতিনিধিত্ব পাওয়ার উপায়, যেমন:
```javascript
rectFromGameObject() {
@ -47,7 +47,7 @@ CO_OP_TRANSLATOR_METADATA:
}
```
2. একটি তুলনা ফাংশন, এটি এমন দেখতে হতে পারে:
2. একটি তুলনা ফাংশন, যা দেখতে এমন হতে পারে:
```javascript
function intersectRect(r1, r2) {
@ -58,9 +58,9 @@ CO_OP_TRANSLATOR_METADATA:
}
```
## কীভাবে জিনিস ধ্বংস করব
## জিনিস ধ্বংস করার উপায়
গেমে কিছু ধ্বংস করতে হলে গেমকে জানাতে হবে যে এটি আর গেম লুপে আঁকা হবে না, যা নির্দিষ্ট সময় অন্তর ট্রিগার হয়। এর একটি উপায় হলো, কোনো ঘটনা ঘটলে গেম অবজেক্টকে *মৃত* হিসেবে চিহ্নিত করা:
গেমে জিনিস ধ্বংস করতে হলে গেমকে জানাতে হবে যে এটি আর গেম লুপে আঁকা উচিত নয়, যা একটি নির্দিষ্ট ইন্টারভালে ট্রিগার হয়। এর একটি উপায় হলো, কোনো ঘটনা ঘটলে গেম অবজেক্টকে *মৃত* হিসেবে চিহ্নিত করা:
```javascript
// collision happened
@ -73,17 +73,17 @@ enemy.dead = true
gameObjects = gameObject.filter(go => !go.dead);
```
## কীভাবে লেজার ছোড়া যায়
## কীভাবে লেজার ছোড়া যায়
লেজার ছোড়া মানে হলো একটি কী-ইভেন্টে সাড়া দেওয়া এবং এমন একটি অবজেক্ট তৈরি করা যা নির্দিষ্ট দিকে চলে। এজন্য আমাদের নিম্নলিখিত ধাপগুলো সম্পন্ন করতে হবে:
লেজার ছোড়া মানে হলো একটি কী-ইভেন্টে সাড়া দেওয়া এবং একটি অবজেক্ট তৈরি করা যা একটি নির্দিষ্ট দিকে চলে। এজন্য আমাদের নিম্নলিখিত ধাপগুলো সম্পন্ন করতে হবে:
1. **একটি লেজার অবজেক্ট তৈরি করুন**: হিরোর জাহাজের উপরের অংশ থেকে, যা তৈরি হওয়ার সাথে সাথে স্ক্রিনের উপরের দিকে চলতে শুরু করবে।
2. **কী ইভেন্টের সাথে কোড সংযুক্ত করুন**: কীবোর্ডের এমন একটি কী নির্বাচন করতে হবে যা খেলোয়াড়ের লেজার ছোড়াকে উপস্থাপন করে।
3. **লেজারের মতো দেখতে একটি গেম অবজেক্ট তৈরি করুন** যখন কী চাপা হয়।
1. **একটি লেজার অবজেক্ট তৈরি করুন**: হিরোর জাহাজের শীর্ষ থেকে, যা তৈরি হওয়ার সাথে সাথে স্ক্রিনের শীর্ষের দিকে ঊর্ধ্বমুখী চলতে শুরু করে।
2. **কী-ইভেন্টে কোড সংযুক্ত করুন**: কীবোর্ডে একটি কী নির্বাচন করতে হবে যা প্লেয়ার লেজার ছোঁড়ার প্রতিনিধিত্ব করে।
3. **একটি গেম অবজেক্ট তৈরি করুন যা দেখতে লেজারের মতো** যখন কী চাপা হয়।
## লেজারের কুলডাউন
লেজারটি প্রতিবার কী চাপলে ছোড়া উচিত, যেমন *স্পেস* কী। গেমটি খুব অল্প সময়ে অনেক বেশি লেজার তৈরি করা থেকে বিরত রাখতে আমাদের এটি ঠিক করতে হবে। এটি ঠিক করার উপায় হলো একটি *কুলডাউন* বা টাইমার বাস্তবায়ন করা, যা নিশ্চিত করবে যে একটি লেজার নির্দিষ্ট সময় পরপরই ছোড়া যাবে। এটি নিম্নলিখিতভাবে বাস্তবায়ন করা যায়:
লেজারটি প্রতিবার কী চাপলে ছোড়া উচিত, যেমন *স্পেস* কী। গেমটি খুব অল্প সময়ে অনেক বেশি লেজার তৈরি করা থেকে রোধ করতে আমাদের এটি ঠিক করতে হবে। এই সমস্যার সমাধান হলো একটি *কুলডাউন*, একটি টাইমার, বাস্তবায়ন করা যা নিশ্চিত করে যে একটি লেজার নির্দিষ্ট সময়ের মধ্যে শুধুমাত্র একবার ছোঁড়া যাবে। এটি নিম্নলিখিতভাবে বাস্তবায়ন করা যায়:
```javascript
class Cooldown {
@ -109,23 +109,23 @@ class Weapon {
}
```
মহাকাশ গেম সিরিজের প্রথম পাঠে ফিরে যান এবং *কুলডাউন* সম্পর্কে মনে করিয়ে নিন।
স্পেস গেম সিরিজের প্রথম পাঠে ফিরে যান এবং *কুলডাউন* সম্পর্কে মনে করিয়ে নিন।
## কী তৈরি করতে হবে
আপনাকে আগের পাঠ থেকে বিদ্যমান কোড (যা আপনি পরিষ্কার এবং পুনর্গঠন করেছেন) নিতে হবে এবং এটি সম্প্রসারিত করতে হবে। পর্ব II-এর কোড থেকে শুরু করুন অথবা [পর্ব III- স্টার্টার](../../../../../../../../../your-work) থেকে কোড ব্যবহার করুন।
আপনা আগের পাঠ থেকে বিদ্যমান কোড (যা আপনি পরিষ্কার এবং পুনর্গঠন করেছেন) নিয়ে এটি সম্প্রসারিত করবেন। পার্ট II থেকে কোড শুরু করুন অথবা [পার্ট III- স্টার্টার](../../../../../../../../../your-work) থেকে কোড ব্যবহার করুন।
> টিপ: আপনি যে লেজার নিয়ে কাজ করবেন তা ইতোমধ্যেই আপনার অ্যাসেট ফোল্ডারে রয়েছে এবং কোডে রেফারেন্স করা ছে।
> টিপ: আপনি যে লেজার নিয়ে কাজ করবেন তা ইতোমধ্যেই আপনার অ্যাসেট ফোল্ডারে রয়েছে এবং আপনার কোডে রেফারেন্স করা হয়েছে।
- **সংঘর্ষ নাক্তকরণ যোগ করুন**, যখন একটি লেজার কোনো কিছুর সাথে সংঘর্ষ করে তখন নিম্নলিখিত নিয়মগুলো প্রযোজ্য হবে:
1. **লেজার শত্রুকে আঘাত করে**: শত্রু লেজারের আঘাতে ধ্বংস হবে
2. **লেজার স্ক্রিনের উপরের অংশে আঘাত করে**: লেজার স্ক্রিনের উপরের অংশে আঘাত করলে তা ধ্বংস হবে
3. **শত্রু এবং হিরোর সংঘর্ষ**: শত্রু এবং হিরো একে অপরকে আঘাত করলে উভয়ই ধ্বংস হবে
4. **শত্রু স্ক্রিনের নিচে পৌঁছায়**: শত্রু স্ক্রিনের নিচে পৌঁছালে শত্রু এবং হিরো উভয়ই ধ্বংস হবে
- **সংঘর্ষ নাক্তকরণ যোগ করুন**, যখন একটি লেজার কোনো কিছুর সাথে সংঘর্ষ করে তখন নিম্নলিখিত নিয়মগুলো প্রযোজ্য হবে:
1. **লেজার শত্রুকে আঘাত করে**: শত্রু লেজারের আঘাতে মারা যায়।
2. **লেজার স্ক্রিনের শীর্ষে আঘাত করে**: স্ক্রিনের শীর্ষে আঘাত করলে লেজার ধ্বংস হয়ে যায়।
3. **শত্রু এবং হিরোর সংঘর্ষ**: শত্রু এবং হিরো একে অপরকে আঘাত করলে উভয়ই ধ্বংস হয়ে যায়।
4. **শত্রু স্ক্রিনের নিচে আঘাত করে**: শত্রু স্ক্রিনের নিচে পৌঁছালে শত্রু এবং হিরো উভয়ই ধ্বংস হয়ে যায়।
## প্রস্তাবিত ধাপসমূহ
## সুপারিশকৃত ধাপ
`your-work` সাব ফোল্ডারে আপনার জন্য তৈরি করা ফাইলগুলো খুঁজুন। এটি নিম্নলিখিত ফাইলগুলো থাকা উচিত:
`your-work` সাব ফোল্ডারে তৈরি করা ফাইলগুলো খুঁজে বের করুন। এটি নিম্নলিখিত বিষয়গুলো ধারণ করবে:
```bash
-| assets
@ -137,18 +137,18 @@ class Weapon {
-| package.json
```
আপনার প্রকল্পটি `your_work` ফোল্ডার থেকে শুরু করুন এই কমান্ডটি টাইপ করে:
আপনার প্রজেক্ট শুরু করুন `your_work` ফোল্ডার থেকে টাইপ করে:
```bash
cd your-work
npm start
```
উপরের কমান্ডটি `http://localhost:5000` ঠিকানায় একটি HTTP সার্ভার চালু করবে। একটি ব্রাউজার খুলুন এবং এই ঠিকানাটি প্রবেশ করান, এখন এটি হিরো এবং সব শত্রু দেখাবে, যদিও কিছুই এখনও চলবে না :).
উপরেরটি একটি HTTP সার্ভার চালু করবে ঠিকানায় `http://localhost:5000`। একটি ব্রাউজার খুলুন এবং সেই ঠিকানাটি ইনপুট করুন, এখন এটি হিরো এবং সব শত্রু দেখাবে, কিছুই এখনও চলমান নয় :).
### কোড যোগ করুন
1. **আপনার গেম অবজেক্টের একটি আয়তক্ষেত্র উপস্থাপনা সেটআপ করুন, সংঘর্ষ পরিচালনার জন্য** নিচের কোডটি আপনাকে একটি `GameObject`-এর আয়তক্ষেত্র উপস্থাপনা পেতে সাহায্য করবে। আপনার GameObject ক্লাসটি সম্পাদনা করুন এবং এটি সম্প্রসারিত করুন:
1. **আপনার গেম অবজেক্টের একটি আয়তক্ষেত্রের প্রতিনিধিত্ব সেটআপ করুন, সংঘর্ষ পরিচালনা করতে** নিচের কোডটি আপনাকে একটি `GameObject` এর আয়তক্ষেত্রের প্রতিনিধিত্ব পেতে সাহায্য করবে। আপনার GameObject ক্লাসটি সম্পাদনা করুন:
```javascript
rectFromGameObject() {
@ -161,7 +161,7 @@ npm start
}
```
2. **সংঘর্ষ পরীক্ষা করার কোড যোগ করুন** এটি একটি নতুন ফাংশন হবে যা দুটি আয়তক্ষেত্রের অন্তর্ভুক্তি পরীক্ষা করবে:
2. **সংঘর্ষ পরীক্ষা করার কোড যোগ করুন** এটি একটি নতুন ফাংশন হবে যা পরীক্ষা করবে দুটি আয়তক্ষেত্র একে অপরকে ছেদ করছে কিনা:
```javascript
function intersectRect(r1, r2) {
@ -174,7 +174,7 @@ npm start
}
```
3. **লেজার ছোড়ার ক্ষমতা যোগ করুন**
3. **লেজার ছোড়ার ক্ষমতা যোগ করুন**
1. **কী-ইভেন্ট বার্তা যোগ করুন**। *স্পেস* কীটি হিরো জাহাজের ঠিক উপরে একটি লেজার তৈরি করবে। Messages অবজেক্টে তিনটি কনস্ট্যান্ট যোগ করুন:
```javascript
@ -183,7 +183,7 @@ npm start
COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",
```
1. **স্পেস কী পরিচালনা করুন**। `window.addEventListener`-এর keyup ফাংশনটি সম্পাদনা করুন যাতে এটি স্পেস কী পরিচালনা করে:
1. **স্পেস কী পরিচালনা করুন**। `window.addEventListener` এর keyup ফাংশনটি সম্পাদনা করুন স্পেস পরিচালনা করে:
```javascript
} else if(evt.keyCode === 32) {
@ -191,7 +191,7 @@ npm start
}
```
1. **লিসেনার যোগ করুন**। `initGame()` ফাংশনটি সম্পাদনা করুন যাতে স্পেস বার চাপলে হিরো লেজার ছড়তে পারে:
1. **লিসেনার যোগ করুন**। `initGame()` ফাংশনটি সম্পাদনা করুন নিশ্চিত করতে যে স্পেস বার চাপলে হিরো লেজার ছোঁড়তে পারে:
```javascript
eventEmitter.on(Messages.KEY_EVENT_SPACE, () => {
@ -200,7 +200,7 @@ npm start
}
```
এবং একটি নতুন `eventEmitter.on()` ফাংশন যোগ করুন যাতে শত্রু লেজারের সাথে সংঘর্ষ করলে নির্দিষ্ট আচরণ ঘটে:
এবং একটি নতুন `eventEmitter.on()` ফাংশন যোগ করুন নিশ্চিত করতে যে শত্রু লেজারের সাথে সংঘর্ষ করলে কী ঘটবে:
```javascript
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
@ -209,7 +209,7 @@ npm start
})
```
1. **অবজেক্ট সরান**, নিশ্চিত করুন যে লেজার ধীরে ধীরে স্ক্রিনের উপরের দিকে চলে। আপনি একটি নতুন Laser ক্লাস তৈরি করবেন যা `GameObject` সম্প্রসারিত করবে, যেমন আপনি আগে করেছেন:
1. **অবজেক্ট সরান**, নিশ্চিত করুন যে লেজার ধীরে ধীরে স্ক্রিনের শীর্ষে চলে যায়। আপনি একটি নতুন Laser ক্লাস তৈরি করবেন যা `GameObject` কে প্রসারিত করবে, যেমন আপনি আগে করেছেন:
```javascript
class Laser extends GameObject {
@ -230,7 +230,7 @@ npm start
}
```
1. **সংঘর্ষ পরিচালনা করুন**, লেজারের জন্য সংঘর্ষের নিয়ম বাস্তবায়ন করুন। একটি `updateGameObjects()` ফাংশন যোগ করুন যা সংঘর্ষকারী অবজেক্টগুলো পরীক্ষা করে:
1. **সংঘর্ষ পরিচালনা করুন**, লেজারের জন্য সংঘর্ষের নিয়ম বাস্তবায়ন করুন। একটি `updateGameObjects()` ফাংশন যোগ করুন যা সংঘর্ষের জন্য অবজেক্টগুলো পরীক্ষা করে:
```javascript
function updateGameObjects() {
@ -252,11 +252,11 @@ npm start
}
```
নিশ্চিত করুন যে `updateGameObjects()`-কে আপনার গেম লুপে `window.onload`-এ যোগ করা হয়েছে।
নিশ্চিত করুন যে `updateGameObjects()` আপনার গেম লুপে `window.onload` এ যোগ করা হয়েছে।
4. **লেজারের কুলডাউন বাস্তবায়ন করুন**, যাতে এটি নির্দিষ্ট সময় পরপরই ছোড়া যায়।
4. **লেজারের কুলডাউন বাস্তবায়ন করুন**, যাতে এটি নির্দিষ্ট সময়ের মধ্যে শুধুমাত্র একবার ছোঁড়া যায়।
শেষ পর্যন্ত, Hero ক্লাসটি সম্পাদনা করুন যাতে এটি কুলডাউন করতে পারে:
অবশেষে, Hero ক্লাসটি সম্পাদনা করুন যাতে এটি কুলডাউন করতে পারে:
```javascript
class Hero extends GameObject {
@ -285,13 +285,13 @@ npm start
}
```
খন আপনার গেমে কিছু কার্যকারিতা রয়েছে! আপনি আপনার অ্যারো কী দিয়ে নেভিগেট করতে পারেন, স্পেস বার দিয়ে লেজার ছুড়তে পারবেন, এবং শত্রুরা লেজারের আঘাতে অদৃশ্য হয়ে যাবে। দারুণ কাজ!
ই পর্যায়ে, আপনার গেমে কিছু কার্যকারিতা রয়েছে! আপনি আপনার অ্যারো কী দিয়ে নেভিগেট করতে পারেন, স্পেস বার দিয়ে লেজার ছোঁড়তে পারেন, এবং শত্রুরা লেজারের আঘাতে অদৃশ্য হয়ে যায়। খুব ভালো কাজ করেছেন!
---
## 🚀 চ্যালেঞ্জ
একটি বিস্ফোরণ যোগ করুন! [Space Art রিপোজিটরি](../../../../6-space-game/solution/spaceArt/readme.txt)-তে গেম অ্যাসেটগুলো দেখুন এবং লেজার কোনো এলিয়েনকে আঘাত করলে একটি বিস্ফোরণ যোগ করার চেষ্টা করুন
একটি বিস্ফোরণ যোগ করুন! [স্পেস আর্ট রিপো](../../../../6-space-game/solution/spaceArt/readme.txt) এর গেম অ্যাসেটগুলো দেখুন এবং চেষ্টা করুন লেজার এলিয়েনকে আঘাত করলে একটি বিস্ফোরণ যোগ করতে
## পোস্ট-লেকচার কুইজ
@ -299,11 +299,13 @@ npm start
## পর্যালোচনা ও স্ব-অধ্যয়ন
আপনার গেমে এখন পর্যন্ত ব্যবহৃত ইন্টারভ্যাল নিয়ে পরীক্ষা করুন। ইন্টারভ্যাল পরিবর্তন করলে কী ঘটে? [জাভাস্ক্রিপ্ট টাইমিং ইভেন্ট](https://www.freecodecamp.org/news/javascript-timing-events-settimeout-and-setinterval/) সম্পর্কে আরও পড়ুন।
আপনার গেমে এখন পর্যন্ত ব্যবহৃত ইন্টারভালগুলো নিয়ে পরীক্ষা করুন। আপনি এগুলো পরিবর্তন করলে কী ঘটে? [জাভাস্ক্রিপ্ট টাইমিং ইভেন্ট](https://www.freecodecamp.org/news/javascript-timing-events-settimeout-and-setinterval/) সম্পর্কে আরও পড়ুন।
## অ্যাসাইনমেন্ট
[সংঘর্ষ অন্বেষণ করুন](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। এর মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিক অনুবাদ প্রদানের চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।

@ -1,23 +1,23 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "4e8250db84b027c9ff816b4e4c093457",
"translation_date": "2025-08-25T22:03:51+00:00",
"original_hash": "adda95e02afa3fbee67b6e385b1109e1",
"translation_date": "2025-08-28T22:58:32+00:00",
"source_file": "6-space-game/5-keeping-score/README.md",
"language_code": "bn"
}
-->
# স্পেস গেম তৈরি করুন পার্ট ৫: স্কোরিং এবং লাইফ
# মহাকাশ গেম তৈরি করুন পর্ব ৫: স্কোরিং এবং জীবন
## প্রি-লেকচার কুইজ
## প্রাক-লেকচার কুইজ
[প্রি-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/37)
[প্রাক-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/37)
এই পাঠে, আপনি শিখবেন কীভাবে একটি গেমে স্কোর যোগ করতে হয় এবং লাইফ গণনা করতে হয়।
এই পাঠে, আপনি শিখবেন কীভাবে একটি গেমে স্কোর যোগ করতে হয় এবং জীবন গণনা করতে হয়।
## স্ক্রিনে টেক্সট আঁকা
## পর্দায় টেক্সট আঁকা
গেম স্কোর স্ক্রিনে প্রদর্শন করতে হলে, আপনাকে জানতে হবে কীভাবে স্ক্রিনে টেক্সট স্থাপন করতে হয়। এর উত্তর হলো `fillText()` মেথড ব্যবহার করা ক্যানভাস অবজেক্টে। আপনি অন্যান্য বিষয়ও নিয়ন্ত্রণ করতে পারেন যেমন কোন ফন্ট ব্যবহার করবেন, টেক্সটের রঙ এবং এমনকি এর অ্যালাইনমেন্ট (বাম, ডান, কেন্দ্র)। নিচে কিছু কোড দেওয়া হয়েছে যা স্ক্রিনে টেক্সট আঁকছে।
গেমের স্কোর পর্দায় প্রদর্শন করতে হলে, আপনাকে জানতে হবে কীভাবে পর্দায় টেক্সট স্থাপন করতে হয়। এর উত্তর হলো ক্যানভাস অবজেক্টের `fillText()` মেথড ব্যবহার করা। আপনি টেক্সটের ফন্ট, রঙ এবং এমনকি এর অ্যালাইনমেন্ট (বাম, ডান, কেন্দ্র) নিয়ন্ত্রণ করতে পারেন। নিচে কিছু কোড দেওয়া হয়েছে যা পর্দায় টেক্সট আঁকছে।
```javascript
ctx.font = "30px Arial";
@ -26,22 +26,22 @@ ctx.textAlign = "right";
ctx.fillText("show this on the screen", 0, 0);
```
✅ [ক্যানভাসে টেক্সট যোগ করার পদ্ধতি](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text) সম্পর্কে আরও পড়ুন এবং আপনারটি আরও আকর্ষণীয় দেখানোর চেষ্টা করুন!
✅ [ক্যানভাসে টেক্সট যোগ করার পদ্ধতি](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_text) সম্পর্কে আরও পড়ুন এবং আপনারটি আরও আকর্ষণীয় করে তুলুন!
## গেম কনসেপ্ট হিসেবে লাইফ
## জীবন, একটি গেম ধারণা হিসেবে
গেমে লাইফের ধারণা শুধুমাত্র একটি সংখ্যা। একটি স্পেস গেমের ক্ষেত্রে সাধারণত একটি নির্দিষ্ট সংখ্যক লাইফ দেওয়া হয় যা আপনার শিপ ক্ষতিগ্রস্ত হলে এক এক করে কমে যায়। এটি যদি একটি গ্রাফিক্যাল উপস্থাপনা হিসেবে দেখানো যায় যেমন ছোট শিপ বা হার্ট, তাহলে এটি সংখ্যার পরিবর্তে আরও আকর্ষণীয় হয়
গেমে জীবনের ধারণা কেবল একটি সংখ্যা। মহাকাশ গেমের প্রেক্ষাপটে, সাধারণত একটি নির্দিষ্ট সংখ্যক জীবন দেওয়া হয় যা আপনার জাহাজ ক্ষতিগ্রস্ত হলে এক একে কমে যায়। এটি আরও ভালো হয় যদি আপনি এটি একটি গ্রাফিক্যাল উপস্থাপনার মাধ্যমে দেখাতে পারেন, যেমন ছোট জাহাজ বা হৃদয় চিহ্নের মাধ্যমে, শুধুমাত্র একটি সংখ্যার পরিবর্তে।
## কী তৈরি করবেন
আপনার গেমে নিম্নলিখিতগুলি যোগ করুন:
- **গেম স্কোর**: প্রতিটি শত্রু শিপ ধ্বংস করার জন্য, হিরোকে কিছু পয়েন্ট দেওয়া উচিত। আমরা প্রতি শিপের জন্য ১০০ পয়েন্ট প্রস্তাব করছি। গেম স্কোরটি নিচের বাম দিকে দেখানো উচিত।
- **লাইফ**: আপনার শিপের তিনটি লাইফ থাকবে। প্রতিবার শত্রু শিপ আপনার সাথে সংঘর্ষ করলে আপনি একটি লাইফ হারাবেন। লাইফ স্কোরটি নিচের ডান দিকে প্রদর্শিত হবে এবং এটি নিম্নলিখিত গ্রাফিক দিয়ে তৈরি হবে ![life image](../../../../translated_images/life.6fb9f50d53ee0413cd91aa411f7c296e10a1a6de5c4a4197c718b49bf7d63ebf.bn.png)।
- **গেম স্কোর**: প্রতিটি শত্রু জাহাজ ধ্বংস করার জন্য, নায়ককে কিছু পয়েন্ট দেওয়া উচিত। আমরা প্রতি জাহাজের জন্য ১০০ পয়েন্ট প্রস্তাব করছি। গেম স্কোরটি নিচের বাম কোণে দেখানো উচিত।
- **জীবন**: আপনার জাহাজের তিনটি জীবন থাকবে। প্রতিবার একটি শত্রু জাহাজ আপনার সাথে সংঘর্ষ করলে একটি জীবন হারাবেন। একটি জীবন স্কোর নিচের ডান কোণে প্রদর্শিত হওয়া উচিত এবং এটি নিম্নলিখিত গ্রাফিক দিয়ে তৈরি হবে ![life image](../../../../translated_images/life.6fb9f50d53ee0413cd91aa411f7c296e10a1a6de5c4a4197c718b49bf7d63ebf.bn.png)।
## প্রস্তাবিত ধাপসমূহ
`your-work` সাব ফোল্ডারে আপনার জন্য তৈরি করা ফাইলগুলি খুঁজুন। এটি নিম্নলিখিতটি ধারণ করবে:
`your-work` সাব ফোল্ডারে আপনার জন্য তৈরি করা ফাইলগুলি খুঁজুন। এতে নিম্নলিখিতগুলি থাকা উচিত:
```bash
-| assets
@ -53,24 +53,24 @@ ctx.fillText("show this on the screen", 0, 0);
-| package.json
```
আপনার প্রকল্পটি `your_work` ফোল্ডারে শুরু করুন নিচের কমান্ড টাইপ করে:
আপনার প্রকল্পটি `your_work` ফোল্ডার থেকে শুরু করুন এই কমান্ডটি টাইপ করে:
```bash
cd your-work
npm start
```
উপরের কমান্ডটি HTTP সার্ভার চালু করবে ঠিকানা `http://localhost:5000` এ। একটি ব্রাউজার খুলুন এবং সেই ঠিকানাটি ইনপুট করুন। এখন এটি হিরো এবং সমস্ত শত্রুদের রেন্ডার করবে, এবং যখন আপনি আপনার বাম এবং ডান তীর চাপবেন, তখন হিরো চলবে এবং শত্রুদের গুলি করে ধ্বংস করতে পারবে।
উপরের কমান্ডটি `http://localhost:5000` ঠিকানায় কটি HTTP সার্ভার চালু করবে। একটি ব্রাউজার খুলুন এবং এই ঠিকানাটি প্রবেশ করান। এখন এটি নায়ক এবং সমস্ত শত্রুদের রেন্ডার করবে এবং আপনি যখন বাম এবং ডান তীর চিহ্ন চাপবেন, নায়ক চলবে এবং শত্রুদের গুলি করতে পারবে।
### কোড যোগ করুন
1. **প্রয়োজনীয় অ্যাসেটগুলি কপি করুন** `solution/assets/` ফোল্ডার থেকে `your-work` ফোল্ডারে; আপনি একটি `life.png` অ্যাসেট যোগ করবেন। `window.onload` ফাংশনে lifeImg যোগ করুন:
1. **প্রয়োজনীয় অ্যাসেট কপি করুন** `solution/assets/` ফোল্ডার থেকে `your-work` ফোল্ডারে `life.png` অ্যাসেটটি কপি করুন। `window.onload` ফাংশনে lifeImg যোগ করুন:
```javascript
lifeImg = await loadTexture("assets/life.png");
```
1. `lifeImg` কে অ্যাসেটের তালিকায় যোগ করুন:
1. `lifeImg` অ্যাসেটের তালিকায় যোগ করুন:
```javascript
let heroImg,
@ -80,7 +80,7 @@ npm start
eventEmitter = new EventEmitter();
```
2. **্যারিয়েবল যোগ করুন**। আপনার মোট স্কোর () এবং অবশিষ্ট লাইফ (৩) উপস্থাপনকারী কোড যোগ করুন, এই স্কোরগুলি স্ক্রিনে প্রদর্শন করুন।
2. **রিয়েবল যোগ করুন**। আপনার মোট স্কোর () এবং অবশিষ্ট জীবন (৩) উপস্থাপনকারী কোড যোগ করুন এবং এই স্কোরগুলি পর্দায় প্রদর্শন করুন।
3. **`updateGameObjects()` ফাংশন প্রসারিত করুন**। শত্রুদের সাথে সংঘর্ষ পরিচালনা করার জন্য `updateGameObjects()` ফাংশন প্রসারিত করুন:
@ -93,15 +93,15 @@ npm start
})
```
4. **লাইফ এবং পয়েন্ট যোগ করুন**।
1. **্যারিয়েবল ইনিশিয়ালাইজ করুন**। `Hero` ক্লাসে `this.cooldown = 0` এর নিচে লাইফ এবং পয়েন্ট সেট করুন:
4. **`life` এবং `points` যোগ করুন**।
1. **রিয়েবল ইনিশিয়ালাইজ করুন**। `Hero` ক্লাসে `this.cooldown = 0` এর নিচে life এবং points সেট করুন:
```javascript
this.life = 3;
this.points = 0;
```
1. **স্ক্রিনে ভ্যারিয়েবল আঁকুন**। এই মানগুলি স্ক্রিনে আঁকুন:
1. **পর্দায় ভেরিয়েবল আঁকুন**। এই মানগুলি পর্দায় আঁকুন:
```javascript
function drawLife() {
@ -128,18 +128,18 @@ npm start
```
1. **গেম লুপে মেথড যোগ করুন**। নিশ্চিত করুন যে আপনি এই ফাংশনগুলি `window.onload` ফাংশনে `updateGameObjects()` এর নিচে যোগ করেছেন:
1. **গেম লুপে মেথড যোগ করুন**। নিশ্চিত করুন যে আপনি এই ফাংশনগুলি `updateGameObjects()` এর নিচ`window.onload` ফাংশনে যোগ করেছেন:
```javascript
drawPoints();
drawLife();
```
1. **গেম নিয়ম বাস্তবায়ন করুন**। নিম্নলিখিত গেম নিয়ম বাস্তবায়ন করুন:
1. **গেমের নিয়ম বাস্তবায়ন করুন**। নিম্নলিখিত গেমের নিয়ম বাস্তবায়ন করুন:
1. **প্রতিটি হিরো এবং শত্রুর সংঘর্ষের জন্য**, একটি লাইফ কমান।
1. **প্রতিটি নায়ক এবং শত্রুর সংঘর্ষের জন্য**, একটি জীবন কমান।
`Hero` ক্লাস প্রসারিত করুন এই কমানোর জন্য:
`Hero` ক্লাস প্রসারিত করুন এই কাটা করার জন্য:
```javascript
decrementLife() {
@ -150,9 +150,9 @@ npm start
}
```
2. **প্রতিটি লেজার যা শত্রুকে আঘাত করে**, গেম স্কোর ১০০ পয়েন্ট বৃদ্ধি করুন।
2. **প্রতিটি লেজার যা শত্রুকে আঘাত করে**, গেম স্কোর ১০০ পয়েন্ট বাড়ান।
`Hero` ক্লাস প্রসারিত করুন এই বৃদ্ধির জন্য:
`Hero` ক্লাস প্রসারিত করুন এই বৃদ্ধি করার জন্য:
```javascript
incrementPoints() {
@ -175,15 +175,15 @@ npm start
});
```
কিছু গবেষণা করুন এবং আবিষ্কার করুন অন্যান্য গেম যা JavaScript/Canvas ব্যবহার করে তৈরি করা হয়েছে। তাদের সাধারণ বৈশিষ্ট্য কী?
✅ গবেষণা করুন এবং আবিষ্কার করুন অন্যান্য গেম যা JavaScript/Canvas ব্যবহার করে তৈরি করা হয়েছে। তাদের সাধারণ বৈশিষ্ট্য কী?
এই কাজের শেষে, আপনি ছোট 'লাইফ' শিপগুলি নিচের ডান দিকে, পয়েন্টগুলি নিচের বাম দিকে দেখতে পাবেন, এবং আপনি দেখতে পাবেন আপনার লাইফ সংখ্যা কমছে যখন আপনি শত্রুদের সাথে সংঘর্ষ করছেন এবং আপনার পয়েন্ট বাড়ছে যখন আপনি শত্রুদের গুলি করছেন। খুব ভালো! আপনার গেম প্রায় সম্পূর্ণ।
এই কাজের শেষে, আপনি নিচের ডান কোণে ছোট 'জীবন' জাহাজ, নিচের বাম কোণে পয়েন্ট এবং শত্রুদের সাথে সংঘর্ষ করলে আপনার জীবন সংখ্যা কমতে এবং শত্রুদের গুলি করলে আপনার পয়েন্ট বাড়তে দেখবেন। দারুণ কাজ! আপনার গেম প্রায় সম্পূর্ণ।
---
## 🚀 চ্যালেঞ্জ
আপনার কোড প্রায় সম্পূর্ণ। আপনি কি আপনার পরবর্তী পদক্ষেপগুলি কল্পনা করতে পারেন?
আপনার কোড প্রায় সম্পূর্ণ। আপনি কি আপনার পরবর্তী ধাপগুলি কল্পনা করতে পারেন?
## পোস্ট-লেকচার কুইজ
@ -191,11 +191,13 @@ npm start
## পর্যালোচনা এবং স্ব-অধ্যয়ন
গেম স্কোর এবং লাইফ বৃদ্ধি এবং হ্রাস করার কিছু উপায় গবেষণা করুন। [PlayFab](https://playfab.com) এর মতো কিছু আকর্ষণীয় গেম ইঞ্জিন রয়েছে। এগুলি ব্যবহার করলে কীভাবে আপনার গেম উন্নত হতে পারে?
গেম স্কোর এবং জীবন বাড়ানো এবং কমানোর কিছু উপায় গবেষণা করুন। [PlayFab](https://playfab.com) এর মতো কিছু আকর্ষণীয় গেম ইঞ্জিন রয়েছে। এগুলোর একটি ব্যবহার করলে কীভাবে আপনার গেম উন্নত হে?
## অ্যাসাইনমেন্ট
[স্কোরিং গেম তৈরি করুন](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিক অনুবাদ প্রদানের চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়বদ্ধ থাকব না।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিক অনুবাদ প্রদানের চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "01336cddd638242e99b133614111ea40",
"translation_date": "2025-08-25T22:35:17+00:00",
"original_hash": "05be6c37791668e3719c4fba94566367",
"translation_date": "2025-08-28T22:59:47+00:00",
"source_file": "6-space-game/6-end-condition/README.md",
"language_code": "bn"
}
@ -13,29 +13,29 @@ CO_OP_TRANSLATOR_METADATA:
[প্রাক-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/39)
একটি গেমে *শেষের শর্ত* প্রকাশ করার বিভিন্ন উপায় রয়েছে। গেমের নির্মাতা হিসেবে আপনাকে সিদ্ধান্ত নিতে হবে কেন গেমটি শেষ হয়েছে। এখানে কিছু কারণ উল্লেখ করা হলো, যদি আমরা ধরে নিই যে আপনি এখন পর্যন্ত যে মহাকাশ গেমটি তৈরি করেছেন তা নিয়ে আলোচনা করছি:
গেমে *শেষের শর্ত* প্রকাশ করার বিভিন্ন উপায় রয়েছে। গেমের স্রষ্টা হিসেবে, গেমটি কেন শেষ হয়েছে তা নির্ধারণ করা আপনার উপর নির্ভর করে। এখানে কিছু কারণ উল্লেখ করা হলো, যদি আমরা ধরে নিই যে আপনি এখন পর্যন্ত যে মহাকাশ গেমটি তৈরি করছেন তা নিয়ে কথা বলছি:
- **`N` শত্রু জাহাজ ধ্বংস হয়েছে**: এটি বেশ সাধারণ, যদি আপনি গেমটিকে বিভিন্ন স্তরে ভাগ করেন যেখানে একটি স্তর সম্পন্ন করতে `N` শত্রু জাহাজ ধ্বংস করতে হবে।
- **আপনার জাহাজ ধ্বংস হয়েছে**: এমন অনেক গেম রয়েছে যেখানে আপনার জাহাজ ধ্বংস হলে আপনি গেমটি হারান। আরেকটি সাধারণ পদ্ধতি হলো "জীবন" ধারণা যোগ করা। প্রতিবার আপনার জাহাজ ধ্বংস হলে একটি জীবন কমে যায়। যখন সব জীবন শেষ হয়ে যায় তখন আপনি গেমটি হারান।
- **আপনি `N` পয়েন্ট সংগ্রহ করেছেন**: আরেকটি সাধারণ শেষের শর্ত হলো পয়েন্ট সংগ্রহ করা। কীভাবে পয়েন্ট সংগ্রহ করবেন তা আপনার উপর নির্ভর করে, তবে শত্রু জাহাজ ধ্বংস করা বা ধ্বংস হওয়া আইটেম সংগ্রহ করার মতো বিভিন্ন কার্যকলাপে পয়েন্ট দেওয়া সাধারণ।
- **একটি স্তর সম্পন্ন করুন**: এটি একাধিক শর্ত অন্তর্ভুক্ত করতে পারে যেমন `X` শত্রু জাহাজ ধ্বংস, `Y` পয়েন্ট সংগ্রহ করা বা একটি নির্দিষ্ট আইটেম সংগ্রহ করা।
- **`N` শত্রু জাহাজ ধ্বংস হয়েছে**: এটি বেশ সাধারণ, যদি আপনি গেমটিকে বিভিন্ন স্তরে ভাগ করেন, যেখানে একটি স্তর সম্পন্ন করতে `N` শত্রু জাহাজ ধ্বংস করতে হবে।
- **আপনার জাহাজ ধ্বংস হয়েছে**: এমন অনেক গেম রয়েছে যেখানে আপনার জাহাজ ধ্বংস হলে আপনি গেমটি হারান। আরেকটি সাধারণ পদ্ধতি হলো জীবন ধারণার ব্যবহার। প্রতিবার আপনার জাহাজ ধ্বংস হলে একটি জীবন কমে যায়। যখন সব জীবন শেষ হয়ে যায়, তখন আপনি গেমটি হারান।
- **আপনি `N` পয়েন্ট সংগ্রহ করেছেন**: আরেকটি সাধারণ শেষের শর্ত হলো পয়েন্ট সংগ্রহ করা। আপনি কীভাবে পয়েন্ট পাবেন তা আপনার উপর নির্ভর করে, তবে শত্রু জাহাজ ধ্বংস করা বা ধ্বংস হওয়া আইটেম সংগ্রহ করার মতো বিভিন্ন কার্যকলাপে পয়েন্ট দেওয়া সাধারণ।
- **একটি স্তর সম্পন্ন করুন**: এটি বিভিন্ন শর্ত জড়িত থাকতে পারে, যেমন `X` শত্রু জাহাজ ধ্বংস, `Y` পয়েন্ট সংগ্রহ, অথবা একটি নির্দিষ্ট আইটেম সংগ্রহ করা।
## পুনরায় শুরু করা
## পুনরায় শুরু
যদি মানুষ আপনার গেমটি উপভোগ করে, তারা সম্ভবত এটি আবার খেলতে চাইবে। গেমটি যেকোনো কারণে শেষ হলে আপনি পুনরায় শুরু করার একটি বিকল্প প্রদান করবেন
যদি মানুষ আপনার গেমটি উপভোগ করে, তবে তারা এটি পুনরায় খেলতে চাইবে। যেকোনো কারণে গেমটি শেষ হলে, আপনাকে পুনরায় শুরু করার একটি বিকল্প দেওয়া উচিত
✅ চিন্তা করুন, কোন শর্তে আপনি একটি গেম শেষ করেন এবং তারপর কীভাবে আপনাকে পুনরায় শুরু করতে বলা হয়।
একটু চিন্তা করুন, কোন শর্তে আপনি মনে করেন গেমটি শেষ হয় এবং তারপর কীভাবে আপনাকে পুনরায় শুরু করার জন্য প্ররোচিত করা হয়।
## কী তৈরি করবেন
আপনার গেমে এই নিয়মগুলো যোগ করবেন:
1. **গেম জেতা**। যখন সব শত্রু জাহাজ ধ্বংস হয়ে যায়, আপনি গেমটি জিতেন। এছাড়াও একটি বিজয়ের বার্তা প্রদর্শন করুন।
1. **পুনরায় শুরু**। যখন আপনার সব জীবন শেষ হয়ে যায় বা গেমটি জিতেন, তখন গেমটি পুনরায় শুরু করার একটি উপায় প্রদান করুন। মনে রাখবেন! আপনাকে গেমটি পুনরায় আরম্ভ করতে হবে এবং পূর্ববর্তী গেমের অবস্থা মুছে ফেলতে হবে।
1. **গেম জেতা**। যখন সব শত্রু জাহাজ ধ্বংস হয়ে যায়, তখন আপনি গেমটি জিতে যান। এছাড়াও একটি বিজয়ের বার্তা প্রদর্শন করুন।
1. **পুনরায় শুরু**। যখন আপনার সব জীবন শেষ হয়ে যায় বা গেমটি জিতে যান, তখন গেমটি পুনরায় শুরু করার একটি উপায় দেওয়া উচিত। মনে রাখবেন! আপনাকে গেমটি পুনরায় আরম্ভ করতে হবে এবং পূর্ববর্তী গেমের অবস্থা মুছে ফেলতে হবে।
## সুপারিশকৃত ধাপসমূহ
## প্রস্তাবিত ধাপসমূহ
`your-work` সাব ফোল্ডারে আপনার জন্য তৈরি করা ফাইলগুলো খুঁজুন। এটি নিম্নলিখিতটি অন্তর্ভুক্ত করা উচিত:
`your-work` সাব ফোল্ডারে আপনার জন্য তৈরি করা ফাইলগুলো খুঁজে বের করুন। এতে নিম্নলিখিত ফাইলগুলো থাকা উচিত:
```bash
-| assets
@ -48,16 +48,16 @@ CO_OP_TRANSLATOR_METADATA:
-| package.json
```
আপনার প্রকল্পটি `your_work` ফোল্ডার থেকে শুরু করুন এই কমান্ডটি টাইপ করে:
আপনার প্রকল্পটি `your_work` ফোল্ডারে শুরু করুন এই কমান্ডটি টাইপ করে:
```bash
cd your-work
npm start
```
উপরের কমান্ডটি `http://localhost:5000` ঠিকানায় একটি HTTP সার্ভার চালু করবে। একটি ব্রাউজার খুলুন এবং সেই ঠিকানা লিখুন। আপনার গেমটি খেলার উপযোগী অবস্থায় থাকা উচিত।
উপরের কমান্ডটি `http://localhost:5000` ঠিকানায় একটি HTTP সার্ভার চালু করবে। একটি ব্রাউজার খুলুন এবং এই ঠিকানাটি প্রবেশ করান। আপনার গেমটি খেলার উপযোগী অবস্থায় থাকা উচিত।
> টিপ: Visual Studio Code-এ সতর্কতা এড়াতে, `window.onload` ফাংশনটি সম্পাদনা করুন যাতে এটি `gameLoopId` কল করে (যেমন আছে, `let` ছাড়া), এবং ফাইলের শীর্ষে `gameLoopId` স্বাধীনভাবে ঘোষণা করুন: `let gameLoopId;`
> টিপ: Visual Studio Code-এ সতর্কতা এড়াতে, `window.onload` ফাংশনটি সম্পাদনা কর`gameLoopId` কল করুন যেমনটি আছে (কোনো `let` ছাড়া), এবং ফাইলের শীর্ষে আলাদাভাবে `let gameLoopId;` ঘোষণা করুন।
### কোড যোগ করুন
@ -74,7 +74,7 @@ npm start
}
```
1. **বার্তা হ্যান্ডলারগুলিতে লজিক যোগ করুন**। `eventEmitter` সম্পাদনা করুন এই শর্তগুলো পরিচালনা করতে:
1. **বার্তা হ্যান্ডলারগুলিতে লজিক যোগ করুন**। এই শর্তগুলো পরিচালনা করার জন্য `eventEmitter` সম্পাদনা করুন:
```javascript
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
@ -117,7 +117,7 @@ npm start
2. **পুনরায় শুরু করার কোড যোগ করুন**। একটি নির্দিষ্ট বোতাম চাপলে গেমটি পুনরায় শুরু করার কোড যোগ করুন।
1. **কী প্রেস `Enter` শুনুন**। আপনার window-এর eventListener সম্পাদনা করুন এই প্রেসটি শুনতে:
1. **`Enter` কী প্রেস শোনার জন্য**। আপনার উইন্ডোর eventListener সম্পাদনা করুন যাতে এটি এই প্রেস শোনে:
```javascript
else if(evt.key === "Enter") {
@ -133,7 +133,7 @@ npm start
1. **গেমের নিয়ম বাস্তবায়ন করুন**। নিম্নলিখিত গেমের নিয়মগুলো বাস্তবায়ন করুন:
1. **প্লেয়ার জয়ের শর্ত**। যখন সব শত্রু জাহাজ ধ্বংস হয়ে যায়, একটি বিজয়ের বার্তা প্রদর্শন করুন।
1. **প্লেয়ার জয়ের শর্ত**। যখন সব শত্রু জাহাজ ধ্বংস হয়ে যায়, তখন একটি বিজয়ের বার্তা প্রদর্শন করুন।
1. প্রথমে একটি `displayMessage()` ফাংশন তৈরি করুন:
@ -171,9 +171,9 @@ npm start
}
```
1. **পুনরায় শুরু করার লজিক**। যখন সব জীবন শেষ হয়ে যায় বা প্লেয়ার গেমটি জিতে, তখন দেখান যে গেমটি পুনরায় শুরু করা যেতে পারে। এছাড়াও, যখন *পুনরায় শুরু* কী চাপা হয় তখন গেমটি পুনরায় শুরু করুন (আপনি সিদ্ধান্ত নিতে পারেন কোন কী পুনরায় শুরুতে ম্যাপ করা হবে)।
1. **পুনরায় শুরু লজিক**। যখন সব জীবন শেষ হয়ে যায় বা প্লেয়ার গেমটি জিতে যায়, তখন দেখান যে গেমটি পুনরায় শুরু করা যেতে পারে। এছাড়াও, *পুনরায় শুরু* কী চাপলে গেমটি পুনরায় শুরু করুন (আপনি সিদ্ধান্ত নিতে পারেন কোন কী পুনরায় শুরুতে ম্যাপ করা হবে)।
1. একটি `resetGame()` ফাংশন তৈরি করুন:
1. `resetGame()` ফাংশন তৈরি করুন:
```javascript
function resetGame() {
@ -194,7 +194,7 @@ npm start
}
```
1. `initGame()`-এ গেমটি পুনরায় সেট করার জন্য `eventEmitter`-এ একটি কল যোগ করুন:
1. `initGame()`-এ গেম রিসেট করার জন্য `eventEmitter`-এ একটি কল যোগ করুন:
```javascript
eventEmitter.on(Messages.KEY_EVENT_ENTER, () => {
@ -216,13 +216,13 @@ npm start
## 🚀 চ্যালেঞ্জ
একটি শব্দ যোগ করুন! আপনি কি শব্দ যোগ করতে পারেন যাতে আপনার গেমপ্লে আরও আকর্ষণীয় হয়, যেমন লেজার আঘাতের সময়, হিরো মারা গেলে বা জিতলে? এই [sandbox](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_play)-এ দেখুন কীভাবে JavaScript ব্যবহার করে শব্দ চালানো যায়
একটি শব্দ যোগ করুন! আপনি কি গেমপ্লে উন্নত করতে একটি শব্দ যোগ করতে পারেন, যেমন লেজার আঘাতের সময়, বা হিরো মারা গেলে বা জিতলে? এই [sandbox](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_play) দেখুন, যেখানে JavaScript ব্যবহার করে শব্দ বাজানোর পদ্ধতি শেখানো হয়েছে
## পোস্ট-লেকচার কুইজ
[পোস্ট-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/40)
## পর্যালোচনা এবং স্ব-অধ্যয়ন
## পুনরালোচনা ও স্ব-অধ্যয়ন
আপনার কাজ হলো একটি নতুন নমুনা গেম তৈরি করা, তাই কিছু আকর্ষণীয় গেম অন্বেষণ করুন এবং দেখুন আপনি কী ধরনের গেম তৈরি করতে পারেন।
@ -230,5 +230,7 @@ npm start
[একটি নমুনা গেম তৈরি করুন](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতা নিশ্চিত করার চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিক অনুবাদের চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। নথিটির মূল ভাষায় লেখা সংস্করণটিকেই প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ ব্যবহার করার পরামর্শ দেওয়া হচ্ছে। এই অনুবাদ ব্যবহারের ফলে সৃষ্ট কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যার জন্য আমরা দায়ী নই

@ -1,27 +1,27 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "8da1b5e2c63f749808858c53f37b8ce7",
"translation_date": "2025-08-26T00:31:37+00:00",
"original_hash": "8a07db14e75ac62f013b7de5df05981d",
"translation_date": "2025-08-28T22:54:22+00:00",
"source_file": "7-bank-project/1-template-route/README.md",
"language_code": "bn"
}
-->
# ব্যাংকিং অ্যাপ তৈরি করুন পার্ট ১: ওয়েব অ্যাপে HTML টেমপ্লেট এবং রুটস
# ব্যাংকিং অ্যাপ তৈরি করুন পার্ট ১: HTML টেমপ্লেট এবং ওয়েব অ্যাপে রাউটস
## প্রাক-লেকচার কুইজ
## প্রি-লেকচার কুইজ
[প্রাক-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/41)
[প্রি-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/41)
### ভূমিকা
ব্রাউজারে জাভাস্ক্রিপ্ট আসার পর থেকে, ওয়েবসাইটগুলো আগের চেয়ে অনেক বেশি ইন্টারঅ্যাকটিভ এবং জটিল হয়ে উঠেছে। এখন ওয়েব প্রযুক্তি ব্যবহার করে এমন অ্যাপ্লিকেশন তৈরি করা হয় যা সরাসরি ব্রাউজারে চলে, যাকে আমরা [ওয়েব অ্যাপ্লিকেশন](https://en.wikipedia.org/wiki/Web_application) বলি। যেহেতু ওয়েব অ্যাপগুলো অত্যন্ত ইন্টারঅ্যাকটিভ, ব্যবহারকারীরা প্রতিবার কোনো অ্যাকশন সম্পন্ন করার জন্য পুরো পেজ রিলোডের জন্য অপেক্ষা করতে চা না। এজন্য জাভাস্ক্রিপ্ট ব্যবহার করে DOM এর মাধ্যমে সরাসরি HTML আপডেট করা হয়, যা ব্যবহারকারীদের জন্য আরও মসৃণ অভিজ্ঞতা প্রদান করে।
ব্রাউজারে জাভাস্ক্রিপ্ট আসার পর থেকে ওয়েবসাইটগুলো আগের চেয়ে অনেক বেশি ইন্টারঅ্যাকটিভ এবং জটিল হয়ে উঠেছে। এখন ওয়েব প্রযুক্তি ব্যবহার করে সম্পূর্ণ কার্যকরী অ্যাপ্লিকেশন তৈরি করা হয় যা সরাসরি ব্রাউজারে চলে, যাকে আমরা [ওয়েব অ্যাপ্লিকেশন](https://en.wikipedia.org/wiki/Web_application) বলি। যেহেতু ওয়েব অ্যাপগুলো খুবই ইন্টারঅ্যাকটিভ, ব্যবহারকারীরা প্রতিবার কোনো অ্যাকশন সম্পন্ন করার সময় পুরো পেজ রিলোডের জন্য অপেক্ষা করতে চা না। এজন্য জাভাস্ক্রিপ্ট ব্যবহার করে HTML সরাসরি DOM এর মাধ্যমে আপডেট করা হয়, যা ব্যবহারকারীদের জন্য আরও মসৃণ অভিজ্ঞতা প্রদান করে।
এই পাঠে, আমরা একটি ব্যাংক ওয়েব অ্যাপ তৈরির ভিত্তি স্থাপন করব, যেখানে HTML টেমপ্লেট ব্যবহার করে একাধিক স্ক্রিন তৈরি করা হবে যা পুরো HTML পেজ রিলোড না করেই প্রদর্শিত এবং আপডেট করা যাবে।
এই পাঠে, আমরা একটি ব্যাংক ওয়েব অ্যাপ তৈরি করার ভিত্তি স্থাপন করব, যেখানে HTML টেমপ্লেট ব্যবহার করে একাধিক স্ক্রিন তৈরি করা হবে যা পুরো HTML পেজ রিলোড না করেই প্রদর্শিত এবং আপডেট করা যাবে।
### পূর্বশর্ত
এই পাঠে আমরা যে ওয়েব অ্যাপ তৈরি করব তা পরীক্ষা করার জন্য আপনার একটি লোকাল ওয়েব সার্ভার প্রয়োজন। যদি আপনার কাছে না থাকে, তাহলে আপনি [Node.js](https://nodejs.org) ইনস্টল করতে পারেন এবং আপনার প্রজেক্ট ফোল্ডার থেকে `npx lite-server` কমান্ডটি ব্যবহার করতে পারেন। এটি একটি লোকাল ওয়েব সার্ভার তৈরি করবে এবং আপনার অ্যাপটি ব্রাউজারে খুলবে।
এই পাঠে আমরা যে ওয়েব অ্যাপ তৈরি করব তা পরীক্ষা করার জন্য আপনার একটি লোকাল ওয়েব সার্ভার প্রয়োজন। যদি আপনার কাছে না থাকে, তাহলে [Node.js](https://nodejs.org) ইনস্টল করন এবং আপনার প্রজেক্ট ফোল্ডার থেকে `npx lite-server` কমান্ড ব্যবহার করুন। এটি একটি লোকাল ওয়েব সার্ভার তৈরি করবে এবং আপনার অ্যাপটি ব্রাউজারে খুলবে।
### প্রস্তুতি
@ -45,16 +45,16 @@ CO_OP_TRANSLATOR_METADATA:
## HTML টেমপ্লেট
যদি আপনি একটি ওয়েব পেজের জন্য একাধিক স্ক্রিন তৈরি করতে চান, তাহলে একটি সমাধান হতে পারে প্রতিটি স্ক্রিনের জন্য একটি HTML ফাইল তৈরি করা। তবে, এই সমাধান কিছু অসুবিধা নিয়ে আসে:
যদি আপনি একটি ওয়েব পেজের জন্য একাধিক স্ক্রিন তৈরি করতে চান, তাহলে একটি সমাধান হতে পারে প্রতিটি স্ক্রিনের জন্য আলাদা HTML ফাইল তৈরি করা। তবে, এই সমাধান কিছু অসুবিধা নিয়ে আসে:
- স্ক্রিন পরিবর্তনের সময় পুরো HTML রিলোড করতে হয়, যা ধীর হতে পারে।
- বিভিন্ন স্ক্রিনের মধ্যে ডেটা শেয়ার করা কঠিন।
আরেকটি পদ্ধতি হলো একটি মাত্র HTML ফাইল রাখা এবং `<template>` এলিমেন্ট ব্যবহার করে একাধিক [HTML টেমপ্লেট](https://developer.mozilla.org/docs/Web/HTML/Element/template) সংজ্ঞায়িত করা। একটি টেমপ্লেট হলো পুনঃব্যবহারযোগ্য HTML ব্লক যা ব্রাউজারে প্রদর্শিত হয় না এবং রানটাইমে জাভাস্ক্রিপ্ট ব্যবহার করে ইনস্ট্যান্সিয়েট করতে হয়।
আরেকটি পদ্ধতি হলো শুধুমাত্র একটি HTML ফাইল রাখা এবং `<template>` এলিমেন্ট ব্যবহার করে একাধিক [HTML টেমপ্লেট](https://developer.mozilla.org/docs/Web/HTML/Element/template) সংজ্ঞায়িত করা। একটি টেমপ্লেট হলো পুনরায় ব্যবহারযোগ্য HTML ব্লক যা ব্রাউজার দ্বারা প্রদর্শিত হয় না এবং এটি রানটাইমে জাভাস্ক্রিপ্ট ব্যবহার করে ইনস্ট্যানিয়েট করতে হয়।
### কাজ
আমরা একটি ব্যাংক অ্যাপ তৈরি করব যার দুটি স্ক্রিন থাকবে: লগইন পেজ এবং ড্যাশবোর্ড। প্রথমে, HTML বডিতে একটি প্লেসহোল্ডার এলিমেন্ট যোগ করুন যা আমাদের অ্যাপের বিভিন্ন স্ক্রিন ইনস্ট্যান্সিয়েট করতে ব্যবহার করা হবে:
আমরা একটি ব্যাংক অ্যাপ তৈরি করব যেখানে দুটি স্ক্রিন থাকবে: লগইন পেজ এবং ড্যাশবোর্ড। প্রথমে, HTML বডিতে একটি প্লেসহোল্ডার এলিমেন্ট যোগ করুন যা আমাদের অ্যাপের বিভিন্ন স্ক্রিন ইনস্ট্যানিয়েট করতে ব্যবহার করা হবে:
```html
<div id="app">Loading...</div>
@ -64,7 +64,7 @@ CO_OP_TRANSLATOR_METADATA:
> টিপ: যেহেতু এই এলিমেন্টের কন্টেন্ট প্রতিস্থাপিত হবে, আমরা এখানে একটি লোডিং মেসেজ বা ইন্ডিকেটর রাখতে পারি যা অ্যাপ লোড হওয়ার সময় দেখানো হবে।
এরপর, লগইন পেজের জন্য HTML টেমপ্লেটটি নিচে যোগ করুন। আপাতত আমরা সেখানে একটি শিরোনাম এবং একটি সেকশন রাখব যাতে একটি লিঙ্ক থাকবে যা আমরা নেভিগেশনের জন্য ব্যবহার করব।
এরপর, লগইন পেজের জন্য HTML টেমপ্লেট যোগ করুন। আপাতত আমরা খানে একটি শিরোনাম এবং একটি সেকশন রাখব যেখানে একটি লিঙ্ক থাকবে যা নেভিগেশনের জন্য ব্যবহার করা হ
```html
<template id="login">
@ -79,7 +79,7 @@ CO_OP_TRANSLATOR_METADATA:
- একটি হেডার যেখানে শিরোনাম এবং লগআউট লিঙ্ক থাকবে
- ব্যাংক অ্যাকাউন্টের বর্তমান ব্যালেন্স
- একটি টেবিলে প্রদর্শিত লেনদেনের তালিকা
- একটি টেবিলে প্রদর্শিত ট্রানজ্যাকশনের তালিকা
```html
<template id="dashboard">
@ -108,29 +108,29 @@ CO_OP_TRANSLATOR_METADATA:
> টিপ: HTML টেমপ্লেট তৈরি করার সময়, যদি আপনি দেখতে চান এটি কেমন দেখাবে, তাহলে `<template>` এবং `</template>` লাইনগুলোকে `<!-- -->` দিয়ে কমেন্ট আউট করতে পারেন।
✅ আপনি কেন মনে করেন আমরা টেমপ্লেটগুলিতে `id` অ্যাট্রিবিউট ব্যবহার করি? আমরা কি এর পরিবর্তে ক্লাস ব্যবহার করতে পারতাম?
✅ আপনি কেন মনে করেন আমরা টেমপ্লেটগুলোর উপর `id` অ্যাট্রিবিউট ব্যবহার করি? আমরা কি এর পরিবর্তে ক্লাস ব্যবহার করতে পারতাম?
## জাভাস্ক্রিপ্ট দিয়ে টেমপ্লেট প্রদর্শন
যদি আপনি আপনার বর্তমান HTML ফাইলটি ব্রাউজারে চেষ্টা করেন, তাহলে দেখবেন এটি `Loading...` দেখিয়ে আটকে আছে। এর কারণ হলো আমাদের কিছু জাভাস্ক্রিপ্ট কোড যোগ করতে হবে টেমপ্লেট ইনস্ট্যান্সিয়েট এবং প্রদর্শন করার জন্য
যদি আপনি আপনার বর্তমান HTML ফাইলটি ব্রাউজারে চেষ্টা করেন, তাহলে দেখবেন এটি `Loading...` দেখিয়ে আটকে আছে। এর কারণ হলো আমাদের কিছু জাভাস্ক্রিপ্ট কোড যোগ করতে হবে যা HTML টেমপ্লেট ইনস্ট্যানশিয়েট এবং প্রদর্শন করবে
টেমপ্লেট ইনস্ট্যান্সিয়েট সাধারণত ৩টি ধাপে করা হয়:
টেমপ্লেট ইনস্ট্যানশিয়েট সাধারণত তিনটি ধাপে করা হয়:
1. DOM-এ টেমপ্লেট এলিমেন্টটি খুঁজে বের করা, উদাহরণস্বরূপ [`document.getElementById`](https://developer.mozilla.org/docs/Web/API/Document/getElementById) ব্যবহার করে।
1. DOM-এ টেমপ্লেট এলিমেন্টটি খুঁজে বের করা, যেমন [`document.getElementById`](https://developer.mozilla.org/docs/Web/API/Document/getElementById) ব্যবহার করে।
2. টেমপ্লেট এলিমেন্টটি ক্লোন করা, [`cloneNode`](https://developer.mozilla.org/docs/Web/API/Node/cloneNode) ব্যবহার করে।
3. এটি একটি দৃশ্যমান এলিমেন্টের অধীনে DOM-এ সংযুক্ত করা, উদাহরণস্বরূপ [`appendChild`](https://developer.mozilla.org/docs/Web/API/Node/appendChild) ব্যবহার করে।
3. এটি দৃশ্যমান এলিমেন্টের নিচে DOM-এ সংযুক্ত করা, যেমন [`appendChild`](https://developer.mozilla.org/docs/Web/API/Node/appendChild) ব্যবহার করে।
✅ আমরা কেন টেমপ্লেট ক্লোন করার প্রয়োজন হয় DOM-এ সংযুক্ত করার আগে? যদি আমরা এই ধাপটি বাদ দিই তাহলে কী হতে পারে?
✅ আমরা কেন টেমপ্লেট ক্লোন করার প্রয়োজন হয় DOM-এ সংযুক্ত করার আগে? যদি আমরা এই ধাপটি বাদ দই তাহলে কী হতে পারে?
### কাজ
আপনার প্রজেক্ট ফোল্ডারে `app.js` নামে একটি নতুন ফাইল তৈরি করুন এবং এটি আপনার HTML এর `<head>` সেকশনে ইমপোর্ট করুন:
আপনার প্রজেক্ট ফোল্ডারে `app.js` নামে একটি নতুন ফাইল তৈরি করুন এবং HTML এর `<head>` সেকশনে সেই ফাইলটি ইমপোর্ট করুন:
```html
<script src="app.js" defer></script>
```
এখন `app.js`-এ, আমরা একটি নতুন ফাংশন `updateRoute` তৈরি করব:
এখন `app.js`-এ আমরা একটি নতুন ফাংশন `updateRoute` তৈরি করব:
```js
function updateRoute(templateId) {
@ -142,7 +142,7 @@ function updateRoute(templateId) {
}
```
এখানে আমরা ঠিক উপরে বর্ণিত ৩টি ধাপ অনুসরণ করেছি। আমরা `templateId` এর টেমপ্লেট ইনস্ট্যান্সিয়েট করেছি এবং এর ক্লোন করা কন্টেন্ট আমাদের অ্যাপের প্লেসহোল্ডারে রেখেছি। লক্ষ্য করুন যে আমরা `cloneNode(true)` ব্যবহার করেছি পুরো সাবট্রি কপি করার জন্য।
এখানে আমরা ঠিক তিনটি ধাপ অনুসরণ করেছি যা আগে উল্লেখ করা হয়েছে। আমরা `templateId` এর টেমপ্লেট ইনস্ট্যানশিয়েট করি এবং এর ক্লোন করা কন্টেন্ট আমাদের অ্যাপের প্লেসহোল্ডারে রাখি। লক্ষ্য করুন যে আমরা `cloneNode(true)` ব্যবহার করেছি পুরো সাবট্রি কপি করার জন্য।
এখন এই ফাংশনটি একটি টেমপ্লেট দিয়ে কল করুন এবং ফলাফল দেখুন।
@ -150,11 +150,11 @@ function updateRoute(templateId) {
updateRoute('login');
```
✅ এই কোডের উদ্দেশ্য কী `app.innerHTML = '';`? এটি ছাড়া কী ঘটে?
✅ এই কোডের উদ্দেশ্য কী `app.innerHTML = '';`? এটি ছাড়া কী ঘটে?
## রট তৈরি করা
## রাউট তৈরি করা
যখন একটি ওয়েব অ্যাপের কথা বলা হয়, তখন *রাউটিং* বলতে বোঝায় **URL**-কে নির্দিষ্ট স্ক্রিনের সাথে ম্যাপ করা যা প্রদর্শিত হওয়া উচিত। একাধিক HTML ফাইল সহ একটি ওয়েবসাইটে, এটি স্বয়ংক্রিয়ভাবে ঘটে কারণ ফাইল পাথগুলো URL-এ প্রতিফলিত হয়। উদাহরণস্বরূপ, আপনার প্রজেক্ট ফোল্ডারে এই ফাইলগুলো থাকলে:
যখন একটি ওয়েব অ্যাপের কথা বলা হয়, তখন আমরা *Routing* বলতে বুঝি **URLs**-কে নির্দিষ্ট স্ক্রিনের সাথে ম্যাপ করা যা প্রদর্শিত হওয়া উচিত। একাধিক HTML ফাইল সহ একটি ওয়েবসাইটে, এটি স্বয়ংক্রিয়ভাবে করা হয় কারণ ফাইল পাথগুলো URL-এ প্রতিফলিত হয়। উদাহরণস্বরূপ, আপনার প্রজেক্ট ফোল্ডারে এই ফাইলগুলো থাকলে:
```
mywebsite/index.html
@ -162,7 +162,7 @@ mywebsite/login.html
mywebsite/admin/index.html
```
যদি আপনি `mywebsite` কে রুট হিসেবে একটি ওয়েব সার্ভার তৈরি করেন, তাহলে URL ম্যাপিং হবে:
যদি আপনি `mywebsite` কে রুট হিসেবে ব্যবহার করে একটি ওয়েব সার্ভার তৈরি করেন, তাহলে URL ম্যাপিং হবে:
```
https://site.com --> mywebsite/index.html
@ -170,11 +170,11 @@ https://site.com/login.html --> mywebsite/login.html
https://site.com/admin/ --> mywebsite/admin/index.html
```
তবে, আমাদের ওয়েব অ্যাপের জন্য আমরা একটি মাত্র HTML ফাইল ব্যবহার করছি যাতে সব স্ক্রিন রয়েছে, তাই এই ডিফল্ট আচরণ আমাদের সাহায্য করবে না। আমাদের এই ম্যাপটি ম্যানুয়ালি তৈরি করতে হবে এবং জাভাস্ক্রিপ্ট ব্যবহার করে প্রদর্শিত টেমপ্লেট আপডেট করতে হবে।
তবে, আমাদের ওয়েব অ্যাপের জন্য আমরা একটি HTML ফাইল ব্যবহার করছি যেখানে সব স্ক্রিন রয়েছে, তাই এই ডিফল্ট আচরণ আমাদের সাহায্য করবে না। আমাদের এই ম্যাপটি ম্যানুয়ালি তৈরি করতে হবে এবং জাভাস্ক্রিপ্ট ব্যবহার করে প্রদর্শিত টেমপ্লেট আপডেট করতে হবে।
### কাজ
আমরা একটি সাধারণ অবজেক্ট ব্যবহার করব একটি [ম্যাপ](https://en.wikipedia.org/wiki/Associative_array) বাস্তবায়ন করতে যা URL পাথ এবং আমাদের টেমপ্লেটগুলোর মধ্যে সম্পর্ক স্থাপন করবে। এই অবজেক্টটি আপনার `app.js` ফাইলের শীর্ষে যোগ করুন:
আমরা একটি সাধারণ অবজেক্ট ব্যবহার করব একটি [ম্যাপ](https://en.wikipedia.org/wiki/Associative_array) বাস্তবায়ন করতে যা URL পাথ এবং আমাদের টেমপ্লেটগুলোর মধ্যে সংযোগ স্থাপন করবে। এই অবজেক্টটি `app.js` ফাইলের শীর্ষে যোগ করুন
```js
const routes = {
@ -198,26 +198,26 @@ function updateRoute() {
}
```
এখানে আমরা ঘোষিত রুটগুলোকে সংশ্লিষ্ট টেমপ্লেটের সাথে ম্যাপ করেছি। এটি সঠিকভাবে কাজ করছে কিনা তা পরীক্ষা করতে ব্রাউজারে ম্যানুয়ালি URL পরিবর্তন করুন।
এখানে আমরা আমাদের ঘোষিত রাউটগুলোকে সংশ্লিষ্ট টেমপ্লেটের সাথে ম্যাপ করেছি। এটি সঠিকভাবে কাজ করছে কিনা পরীক্ষা করতে আপনার ব্রাউজারে URL ম্যানুয়ালি পরিবর্তন করুন।
✅ যদি আপনি URL-এ একটি অজানা পাথ প্রবেশ করেন তাহলে কী ঘটে? আমরা কীভাবে এটি সমাধান করতে পারি?
## নেভিগেশন যোগ করা
আমাদের অ্যাপের পরবর্তী ধাপ হলো পেজগুলোর মধ্যে নেভিগেশনের সম্ভাবনা যোগ করা, যাতে ম্যানুয়ালি URL পরিবর্তন করতে না হয়। এটি দুটি বিষয় জড়িত:
আমাদের অ্যাপের পরবর্তী ধাপ হলো পেজগুলোর মধ্যে নেভিগেট করার সুবিধা যোগ করা, যাতে URL ম্যানুয়ালি পরিবর্তন করতে না হয়। এটি দুটি জিনিসকে অন্তর্ভুক্ত করে:
1. বর্তমান URL আপডেট করা
2. নতুন URL এর উপর ভিত্তি করে প্রদর্শিত টেমপ্লেট আপডেট করা
আমরা ইতিমধ্যে `updateRoute` ফাংশনের মাধ্যমে দ্বিতীয় অংশটি সম্পন্ন করেছি, তাই আমাদের বর্তমান URL আপডেট করার উপায় বের করতে হবে।
আমরা ইতিমধ্যে `updateRoute` ফাংশন দিয়ে দ্বিতীয় অংশটি সম্পন্ন করেছি, তাই আমাদের বর্তমান URL আপডেট করার উপায় বের করতে হবে।
আমাদের জাভাস্ক্রিপ্ট ব্যবহার করতে হবে এবং বিশেষ করে [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState) ব্যবহার করতে হবে যা URL আপডেট করতে এবং ব্রাউজিং হিস্টরিতে একটি নতুন এন্ট্রি তৈরি করতে দেয়, HTML রিলোড না করেই।
আমাদের জাভাস্ক্রিপ্ট ব্যবহার করতে হবে এবং বিশেষভাবে [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState) ব্যবহার করতে হবে যা URL আপডেট করতে এবং ব্রাউজিং হিস্টরিতে একটি নতুন এন্ট্রি তৈরি করতে সাহায্য করে, HTML রিলোড না করেই।
> নোট: HTML অ্যাঙ্কর এলিমেন্ট [`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a) নিজে থেকেই বিভিন্ন URL-এ হাইপারলিঙ্ক তৈরি করতে ব্যবহার করা যেতে পারে, তবে এটি ডিফল্টভাবে ব্রাউজারকে HTML রিলোড করতে বাধ্য করবে। কাস্টম জাভাস্ক্রিপ্ট দিয়ে রাউটিং পরিচালনা করার সময় এই আচরণটি প্রতিরোধ করা প্রয়োজন, ক্লিক ইভেন্টে `preventDefault()` ফাংশন ব্যবহার করে।
> নোট: HTML অ্যাঙ্কর এলিমেন্ট [`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a) নিজে থেকেই বিভিন্ন URL-এ হাইপারলিঙ্ক তৈরি করতে ব্যবহার করা যেতে পারে, তবে এটি ডিফল্টভাবে HTML রিলোড করবে। কাস্টম জাভাস্ক্রিপ্ট দিয়ে রাউটিং পরিচালনা করার সময় এই আচরণটি প্রতিরোধ করা প্রয়োজন, যা `preventDefault()` ফাংশন ব্যবহার করে ক্লিক ইভেন্টে করা যায়
### কাজ
আমাদের অ্যাপে নেভিগেট করার জন্য একটি নতুন ফাংশন তৈরি করুন:
আমাদের অ্যাপে নেভিগেট করার জন্য একটি নতুন ফাংশন তৈরি করি:
```js
function navigate(path) {
@ -226,9 +226,9 @@ function navigate(path) {
}
```
এই মেথডটি প্রথমে প্রদত্ত পাথের উপর ভিত্তি করে বর্তমান URL আপডেট করে, তারপর টেমপ্লেট আপডেট করে। `window.location.origin` প্রপার্টি URL রুট রিটার্ন করে, যা আমাদের একটি প্রদত্ত পাথ থেকে একটি সম্পূর্ণ URL পুনর্গঠন করতে দেয়
এই মেথড প্রথমে প্রদত্ত পাথের উপর ভিত্তি করে বর্তমান URL আপডেট করে, তারপর টেমপ্লেট আপডেট করে। `window.location.origin` প্রপার্টি URL রুট প্রদান করে, যা আমাদের একটি প্রদত্ত পাথ থেকে সম্পূর্ণ URL পুনর্গঠন করতে সাহায্য করে
এখন যেহেতু আমাদের এই ফাংশনটি আছে, আমরা যদি কোনো পাথ কোনো সংজ্ঞায়িত রুটের সাথে মেলে না তাহলে যে সমস্যাটি হয় তা সমাধান করতে পারি। আমরা `updateRoute` ফাংশনটি পরিবর্তন করব এবং কোনো ম্যাচ না পেলে বিদ্যমান রুটগুলোর একটিতে ফিরে যাব
এখন আমাদের এই ফাংশনটি আছে, আমরা যদি কোনো পাথ কোনো সংজ্ঞায়িত রাউটের সাথে মিলে না যায় তাহলে কী করব সেই সমস্যাটি সমাধান করতে পারি। আমরা `updateRoute` ফাংশনটি পরিবর্তন করব এবং একটি বিদ্যমান রাউটে ফিরে যাওয়ার ব্যবস্থা করব যদি কোনো ম্যাচ না পাওয়া যায়
```js
function updateRoute() {
@ -242,9 +242,9 @@ function updateRoute() {
...
```
যদি কোনো রুট খুঁজে না পাওয়া যায়, আমরা এখন `login` পেজে রিডাইরেক্ট করব।
যদি কোনো রাউট খুঁজে পাওয়া না যায়, তাহলে আমরা এখন `login` পেজে রিডাইরেক্ট করব।
এখন একটি ফাংশন তৈরি করুন যা একটি লিঙ্ক ক্লিক করার সময় URL পায় এবং ব্রাউজারের ডিফল্ট লিঙ্ক আচরণ প্রতিরোধ করে:
এখন একটি ফাংশন তৈরি করি যা একটি লিঙ্ক ক্লিক করার সময় URL পায় এবং ব্রাউজারের ডিফল্ট লিঙ্ক আচরণ প্রতিরোধ করে:
```js
function onLinkClick(event) {
@ -253,7 +253,7 @@ function onLinkClick(event) {
}
```
আমাদের নেভিগেশন সিস্টেম সম্পূর্ণ করতে আমাদের HTML এর *লগইন* এবং *লগআউট* লিঙ্কগুলোর সাথে বাইন্ডিং যোগ করুন:
আমাদের নেভিগেশন সিস্টেম সম্পূর্ণ করতে আমাদের HTML-এ *Login* এবং *Logout* লিঙ্কগুলোর জন্য বাইন্ডিং যোগ করতে হবে।
```html
<a href="/dashboard" onclick="onLinkClick(event)">Login</a>
@ -261,60 +261,62 @@ function onLinkClick(event) {
<a href="/login" onclick="onLinkClick(event)">Logout</a>
```
উপরের `event` অবজেক্টটি `click` ইভেন্টটি ক্যাপচার করে এবং আমাদের `onLinkClick` ফাংশনে পাস করে।
উপরের `event` অবজেক্টটি `click` ইভেন্ট ক্যাপচার করে এবং আমাদের `onLinkClick` ফাংশনে পাস করে।
[`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) অ্যাট্রিবিউট ব্যবহার করে `click` ইভেন্টটি জাভাস্ক্রিপ্ট কোডের সাথে বাইন্ড করুন, এখানে `navigate()` ফাংশন কল।
[`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) অ্যাট্রিবিউট ব্যবহার করে `click` ইভেন্টকে জাভাস্ক্রিপ্ট কোডের সাথে বাইন্ড করুন, এখানে `navigate()` ফাংশন কল।
এই লিঙ্কগুলোতে ক্লিক করে দেখুন, এখন আপনি আপনার অ্যাপের বিভিন্ন স্ক্রিনের মধ্যে নেভিগেট করতে সক্ষম হবেন
এই লিঙ্কগুলোতে ক্লিক করে দেখুন, এখন আপনি আপনার অ্যাপের বিভিন্ন স্ক্রিনে নেভিগেট করতে সক্ষম হওয়া উচিত
`history.pushState` মেথডটি HTML5 স্ট্যান্ডার্ডের অংশ এবং [সব আধুনিক ব্রাউজারে](https://caniuse.com/?search=pushState) ইমপ্লিমেন্ট করা হয়েছে। যদি আপনি পুরনো ব্রাউজারের জন্য একটি ওয়েব অ্যাপ তৈরি করেন, তাহলে এই API এর পরিবর্তে একটি কৌশল ব্যবহার করতে পারেন: পাথের আগে একটি [হ্যাশ (`#`)](https://en.wikipedia.org/wiki/URI_fragment) ব্যবহার করে আপনি এমন রাউটিং বাস্তবায়ন করতে পারেন যা সাধারণ অ্যাঙ্কর নেভিগেশনের সাথে কাজ করে এবং পেজ রিলোড করে না, কারণ এর উদ্দেশ্য ছিল একটি পেজের মধ্যে অভ্যন্তরীণ লিঙ্ক তৈরি করা।
`history.pushState` মেথড HTML5 স্ট্যান্ডার্ডের অংশ এবং [সব আধুনিক ব্রাউজারে](https://caniuse.com/?search=pushState) ইমপ্লিমেন্ট করা হয়েছে। যদি আপনি পুরনো ব্রাউজারের জন্য একটি ওয়েব অ্যাপ তৈরি করেন, তাহলে এই API-এর পরিবর্তে একটি কৌশল ব্যবহার করতে পারেন: একটি [হ্যাশ (`#`)](https://en.wikipedia.org/wiki/URI_fragment) ব্যবহার করে পাথের আগে আপনি এমন রাউটিং বাস্তবায়ন করতে পারেন যা নিয়মিত অ্যাঙ্কর নেভিগেশনের সাথে কাজ করে এবং পেজ রিলোড করে না, কারণ এর উদ্দেশ্য ছিল একটি পেজের মধ্যে অভ্যন্তরীণ লিঙ্ক তৈরি করা।
## ব্রাউজারের ব্যাক এবং ফরোয়ার্ড বোতাম পরিচালনা করা
## ব্রাউজারের ব্যাক এবং ফরওয়ার্ড বাটন পরিচালনা করা
`history.pushState` ব্যবহার করে ব্রাউজারের নেভিগেশন হিস্টরিতে নতুন এন্ট্রি তৈরি হয়। আপনি ব্রাউজারের *ব্যাক বোতাম* ধরে রাখলে এটি এমন কিছু দেখাবে:
`history.pushState` ব্যবহার করে ব্রাউজারের নেভিগেশন হিস্টরিতে নতুন এন্ট্রি তৈরি করা হয়। আপনি যদি ব্রাউজারের *ব্যাক বাটন* ধরে রাখেন, তাহলে এটি কিছুটা এরকম দেখাবে:
![নেভিগেশন হিস্টরির স্ক্রিনশট](../../../../translated_images/history.7fdabbafa521e06455b738d3dafa3ff41d3071deae60ead8c7e0844b9ed987d8.bn.png)
![নেভিগেশন হিস্টরির স্ক্রিনশট](../../../../translated_images/history.7fdabbafa521e06455b738d3dafa3ff41d3071deae60ead8c7e0844b9ed987d8.bn.png)
যদি আপনি কয়েকবার ব্যাক বোতামে ক্লিক করেন, তাহলে দেখবেন বর্তমান URL পরিবর্তিত হচ্ছে এবং হিস্টরি আপডেট হচ্ছে, কিন্তু একই টেমপ্লেট প্রদর্শিত হচ্ছে।
আপনি যদি কয়েকবার ব্যাক বাটনে ক্লিক করেন, তাহলে দেখবেন বর্তমান URL পরিবর্তিত হচ্ছে এবং হিস্টরি আপডেট হচ্ছে, কিন্তু একই টেমপ্লেট প্রদর্শিত হচ্ছে।
এর কারণ হলো অ্যাপ্লিকেশনটি জানে না যে প্রতিবার হিস্টরি পরিবর্তিত হলে আমাদের `updateRoute()` কল করতে হবে। যদি আপনি [`history.pushState` ডকুমেন্টেশন](https://developer.mozilla.org/docs/Web/API/History/pushState) দেখেন, তাহলে দেখতে পাবেন যে যদি স্টেট পরিবর্তিত হয় - অর্থাৎ আমরা একটি ভিন্ন URL-এ চলে যাই - তাহলে [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event) ইভেন্ট ট্রিগার হয়। আমরা এটি ব্যবহার করে সমস্যাটি সমাধান করব।
এর কারণ হলো অ্যাপ্লিকেশন জানে না যে আমাদের প্রতিবার হিস্টোরি পরিবর্তন হলে `updateRoute()` কল করতে হবে। যদি আপনি [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState) ডকুমেন্টেশন দেখেন, তাহলে দেখতে পাবেন যে যদি স্টেট পরিবর্ত হয় - অর্থাৎ আমরা একটি ভিন্ন URL-এ চলে যাই - তাহলে [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event) ইভেন্ট ট্রিগার হয়। আমরা এটি ব্যবহার করে এই সমস্যাটি ঠিক করব।
### কাজ
যখন ব্রাউজারের হিস্টরি পরিবর্তিত হয় তখন প্রদর্শিত টেমপ্লেট আপডেট নিশ্চিত করতে, আমরা একটি নতুন ফাংশন সংযুক্ত করব যা `updateRoute()` কল করে। আমরা এটি `app.js` ফাইলের নিচে করব:
যখন ব্রাউজারের হিস্টোরি পরিবর্তন হয় তখন প্রদর্শিত টেমপ্লেট আপডেট নিশ্চিত করতে, আমরা একটি নতুন ফাংশন সংযুক্ত করব যা `updateRoute()` কল করে। আমরা এটি `app.js` ফাইলের নিচে করব:
```js
window.onpopstate = () => updateRoute();
updateRoute();
```
> নোট: আমরা এখানে আমাদের `popstate` ইভেন্ট হ্যান্ডলার ঘোষণা করার জন্য [অ্যারো ফাংশন](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) ব্যবহার করেছি সংক্ষিপ্ততার জন্য, তবে একটি সাধারণ ফাংশনও একইভাবে কাজ করবে।
> নোট: আমরা এখানে আমাদের `popstate` ইভেন্ট হ্যান্ডলার ঘোষণা করার জন্য [arrow function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) ব্যবহার করেছি সংক্ষিপ্ততার জন্য, তবে একটি সাধারণ ফাংশনও একইভাবে কাজ করবে।
অ্যারো ফাংশনের উপর একটি রিফ্রেশার ভিডিও:
এখানে arrow functions নিয়ে একটি রিফ্রেশার ভিডিও:
[![অ্যারো ফাংশন](https://img.youtube.com/vi/OP6eEbOj2sc/0.jpg)](https://youtube.com/watch?v=OP6eEbOj2sc "অ্যারো ফাংশন")
[![Arrow Functions](https://img.youtube.com/vi/OP6eEbOj2sc/0.jpg)](https://youtube.com/watch?v=OP6eEbOj2sc "Arrow Functions")
> 🎥 উপরের ছবিতে ক্লিক করুন অ্যারো ফাংশনের ভিডিও দেখার জন্য
> 🎥 উপরের ছবিতে ক্লিক করুন arrow functions সম্পর্কে একটি ভিডিও দেখতে
এখন ব্রাউজারের ব্যাক এবং ফরোয়ার্ড বোতাম ব্যবহার করে দেখুন, এবং নিশ্চিত করুন যে এইবার প্রদর্শিত রুট সঠিকভাবে আপডেট হচ্ছে।
এখন ব্রাউজারের ব্যাক এবং ফরওয়ার্ড বাটন ব্যবহার করে দেখুন, এবং নিশ্চিত করুন যে প্রদর্শিত রাউট এবার সঠিকভাবে আপডেট হচ্ছে।
---
## 🚀 চ্যালেঞ্জ
এই অ্যাপের জন্য ক্রেডিট দেখানোর জন্য একটি তৃতীয় পেজের জন্য একটি নতুন টেমপ্লেট এবং রট যোগ করুন।
এই অ্যাপের ক্রেডিট দেখানোর জন্য একটি তৃতীয় পেজের জন্য একটি নতুন টেমপ্লেট এবং রাউট যোগ করুন।
## পোস্ট-লেকচার কুইজ
[পোস্ট-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/42)
## পর্যালোচনা ও স্ব-অধ্যয়ন
## রিভিউ এবং সেলফ স্টাডি
রাউটিং হলো ওয়েব ডেভেলপমেন্টের একটি আশ্চর্যজনকভাবে জটিল অংশ, বিশেষ করে যখন ওয়েব পেজ রিফ্রেশ আচরণ থেকে সিঙ্গেল পেজ অ্যাপ্লিকেশন পেজ রিফ্রেশে চলে যায়। [Azure Static Web App সার্ভিস](https://docs.microsoft.com/azure/static-web-apps/routes/?WT.mc_id=academic-77807-sagibbon) কীভাবে রাউটিং পরিচালনা করে সে সম্পর্কে একটু পড়ুন। আপনি কি ব্যাখ্যা করতে পারেন কেন এই ডকুমেন্টে বর্ণিত কিছু সিদ্ধান্ত প্রয়োজনীয়?
রাউটিং ওয়েব ডেভেলপমেন্টের একটি আশ্চর্যজনকভাবে জটিল অংশ, বিশেষ করে যখন ওয়েব পেজ রিফ্রেশ আচরণ থেকে সিঙ্গেল পেজ অ্যাপ্লিকেশন পেজ রিফ্রেশে চলে যায়। [Azure Static Web App সার্ভিস](https://docs.microsoft.com/azure/static-web-apps/routes/?WT.mc_id=academic-77807-sagibbon) কীভাবে রাউটিং পরিচালনা করে তা সম্পর্কে একটু পড়ুন। আপনি কি ব্যাখ্যা করতে পারেন কেন এই ডকুমেন্টে বর্ণিত কিছু সিদ্ধান্ত প্রয়োজনীয়?
## অ্যাসাইনমেন্ট
[রাউটিং উন্নত করুন](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতা নিশ্চিত করার চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়বদ্ধ নই।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিক অনুবাদের চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। নথিটির মূল ভাষায় লেখা সংস্করণটিকেই প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ ব্যবহার করার পরামর্শ দেওয়া হচ্ছে। এই অনুবাদ ব্যবহারের ফলে সৃষ্ট কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যার জন্য আমরা দায়ী নই।

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "b667b7d601e2ee19acb5aa9d102dc9f3",
"translation_date": "2025-08-26T00:09:20+00:00",
"original_hash": "8baca047d77a5f43fa4099c0578afa42",
"translation_date": "2025-08-28T22:52:39+00:00",
"source_file": "7-bank-project/2-forms/README.md",
"language_code": "bn"
}
@ -15,22 +15,22 @@ CO_OP_TRANSLATOR_METADATA:
### ভূমিকা
প্রায় সব আধুনিক ওয়েব অ্যাপে, আপনি একটি অ্যাকাউন্ট তৈরি করতে পারেন যা আপনার ব্যক্তিগত জায়গা হিসেবে কাজ করে। যেহেতু একাধিক ব্যবহারকারী একই সময়ে একটি ওয়েব অ্যাপ অ্যাক্সেস করতে পারে, তাই প্রতিটি ব্যবহারকারীর ব্যক্তিগত ডেটা আলাদাভাবে সংরক্ষণ করার এবং কোন তথ্য প্রদর্শন করতে হবে তা নির্বাচন করার একটি পদ্ধতি প্রয়োজন। আমরা [ব্যবহারকারীর পরিচয় নিরাপদে পরিচালনা](https://en.wikipedia.org/wiki/Authentication) করার বিষয়ে আলোচনা করব না কারণ এটি নিজেই একটি বিস্তৃত বিষয়, তবে আমরা নিশ্চিত করব যে প্রতিটি ব্যবহারকারী আমাদের অ্যাপে একটি (বা একাধিক) ব্যাংক অ্যাকাউন্ট তৈরি করতে সক্ষম।
প্রায় সব আধুনিক ওয়েব অ্যাপে, আপনি একটি অ্যাকাউন্ট তৈরি করতে পারেন যা আপনার ব্যক্তিগত জায়গা হিসেবে কাজ করে। যেহেতু একাধিক ব্যবহারকারী একই সময়ে একটি ওয়েব অ্যাপ অ্যাক্সেস করতে পারে, তাই প্রতিটি ব্যবহারকারীর ব্যক্তিগত ডেটা আলাদাভাবে সংরক্ষণ করার এবং কোন তথ্য প্রদর্শন করতে হবে তা নির্বাচন করার একটি পদ্ধতি প্রয়োজন। আমরা [ব্যবহারকারীর পরিচয় নিরাপদে পরিচালনা](https://en.wikipedia.org/wiki/Authentication) করার বিষয়ে আলোচনা করব না কারণ এটি নিজেই একটি বিস্তৃত বিষয়, তবে আমরা নিশ্চিত করব যে প্রতিটি ব্যবহারকারী আমাদের অ্যাপে একটি (বা একাধিক) ব্যাংক অ্যাকাউন্ট তৈরি করতে সক্ষম।
এই অংশে আমরা HTML ফর্ম ব্যবহার করে আমাদের ওয়েব অ্যাপে লগইন এবং রেজিস্ট্রেশন যোগ করব। আমরা দেখব কীভাবে প্রোগ্রাম্যাটিকভাবে সার্ভার API-তে ডেটা পাঠানো যায় এবং শেষ পর্যন্ত ব্যবহারকারীর ইনপুটের জন্য মৌলিক যাচাইকরণ নিয়ম সংজ্ঞায়িত করা যায়।
এই অংশে আমরা HTML ফর্ম ব্যবহার করে আমাদের ওয়েব অ্যাপে লগইন এবং রেজিস্ট্রেশন যোগ করব। আমরা দেখব কীভাবে সার্ভার API-তে প্রোগ্রাম্যাটিকভাবে ডেটা পাঠানো যায় এবং শেষ পর্যন্ত কীভাবে ব্যবহারকারীর ইনপুটের জন্য মৌলিক যাচাইকরণ নিয়ম সংজ্ঞায়িত করা যায়।
### পূর্বশর্ত
এই পাঠের জন্য আপনাকে ওয়েব অ্যাপের [HTML টেমপ্লেট এবং রাউটিং](../1-template-route/README.md) সম্পন্ন করতে হবে। আপনাকে [Node.js](https://nodejs.org) ইনস্টল করতে হবে এবং [সার্ভার API চালাতে হবে](../api/README.md) স্থানীয়ভাবে যাতে আপনি অ্যাকাউন্ট তৈরি করার জন্য ডেটা পাঠাতে পারেন।
এই পাঠের জন্য আপনাকে [HTML টেমপ্লেট এবং রাউটিং](../1-template-route/README.md) সম্পন্ন করতে হবে। এছাড়াও আপনাকে [Node.js](https://nodejs.org) ইনস্টল করতে হবে এবং [সার্ভার API চালাতে হবে](../api/README.md) যাতে আপনি অ্যাকাউন্ট তৈরি করার জন্য ডেটা পাঠাতে পারেন।
**মনে রাখুন**
আপনার দুটি টার্মিনাল একসাথে চালু থাকবে, যা নিচে তালিকাভুক্ত:
1. প্রধান ব্যাংক অ্যাপের জন্য যা আমরা [HTML টেমপ্লেট এবং রাউটিং](../1-template-route/README.md) পাঠে তৈরি করেছি।
2. [Bank APP server API](../api/README.md) এর জন্য যা আমরা উপরে সেটআপ করেছি।
1. মূল ব্যাংক অ্যাপের জন্য যা আমরা [HTML টেমপ্লেট এবং রাউটিং](../1-template-route/README.md) পাঠে তৈরি করেছি।
2. [ব্যাংক অ্যাপ সার্ভার API](../api/README.md) যা আমরা উপরে সেটআপ করেছি।
পাঠের বাকি অংশ অনুসরণ করতে আপনার দুটি সার্ভার চালু এবং চলমান থাকতে হবে। এগুল বিভিন্ন পোর্টে (পোর্ট `3000` এবং পোর্ট `5000`) শুনছে, তাই সবকিছু ঠিকঠাক কাজ করবে।
পাঠের বাকি অংশ অনুসরণ করতে আপনার দুটি সার্ভার চালু এবং চলমান থাকতে হবে। এগুলি বিভিন্ন পোর্টে (পোর্ট `3000` এবং পোর্ট `5000`) শুনছে, তাই সবকিছু ঠিকঠাক কাজ করবে।
আপনি টার্মিনালে এই কমান্ডটি চালিয়ে সার্ভারটি সঠিকভাবে চলছে কিনা পরীক্ষা করতে পারেন:
আপনি টার্মিনালে এই কমান্ডটি চালিয়ে পরীক্ষা করতে পারেন যে সার্ভার সঠিকভাবে চলছে কিনা:
```sh
curl http://localhost:5000/api
@ -41,25 +41,25 @@ curl http://localhost:5000/api
## ফর্ম এবং কন্ট্রোল
`<form>` উপাদানটি একটি HTML ডকুমেন্টের একটি অংশকে ঘিরে রাখে যেখানে ব্যবহারকারী ইন্টারক্টিভ কন্ট্রোল ব্যবহার করে ডেটা ইনপুট এবং জমা দিতে পারে। ফর্মের মধ্যে বিভিন্ন ধরনের ব্যবহারকারী ইন্টারফেস (UI) কন্ট্রোল ব্যবহা করা যায়, যার মধ্যে সবচেয়ে সাধারণ `<input>` এবং `<button>` উপাদান
`<form>` এলিমেন্টটি একটি HTML ডকুমেন্টের একটি অংশকে ঘিরে রাখে যেখানে ব্যবহারকারী ইন্টারঅ্যাক্টিভ কন্ট্রোল ব্যবহার করে ডেটা ইনপুট এবং জমা দিতে পারে। ফর্মের মধ্যে ব্যবহার করার জন্য বিভিন্ন ধরনের ইউজার ইন্টারফেস (UI) কন্ট্রোল রয়েছে, যার মধ্যে সবচেয়ে সাধারণ `<input>` এবং `<button>` এলিমেন্ট
`<input>` এর বিভিন্ন [ধরন](https://developer.mozilla.org/docs/Web/HTML/Element/input) রয়েছে। উদাহরণস্বরূপ, ব্যবহারকারীর নাম ইনপুট করার জন্য আপনি ব্যবহার করতে পারেন:
`<input>`-এর বিভিন্ন [ধরন](https://developer.mozilla.org/docs/Web/HTML/Element/input) রয়েছে। উদাহরণস্বরূপ, ব্যবহারকারীর ইউজারনেম ইনপুট করার জন্য আপনি ব্যবহার করতে পারেন:
```html
<input id="username" name="username" type="text">
```
`name` অ্যাট্রিবিউটটি ফর্ম ডেটা পাঠানোর সময় প্রপার্টি নাম হিসেবে ব্যবহৃত হবে। `id` অ্যাট্রিবিউটটি `<label>` এর সাথে ফর্ম কন্ট্রোলকে সংযুক্ত করতে ব্যবহৃত হয়।
`name` অ্যাট্রিবিউটটি ফর্ম ডেটা পাঠানোর সময় প্রপার্টি নাম হিসেবে ব্যবহৃত হবে। `id` অ্যাট্রিবিউটটি `<label>`-কে ফর্ম কন্ট্রোলের সাথে যুক্ত করতে ব্যবহৃত হয়।
> [`<input>` এর ধরনগুলোর সম্পূর্ণ তালিকা](https://developer.mozilla.org/docs/Web/HTML/Element/input) এবং [অন্যান্য ফর্ম কন্ট্রোল](https://developer.mozilla.org/docs/Learn/Forms/Other_form_controls) দেখুন যাতে আপনি UI তৈরি করার সময় সমস্ত নেটিভ UI উপাদান সম্পর্কে ধারণা পেতে পারেন।
> [`<input>`-এর ধরনগুলির সম্পূর্ণ তালিকা](https://developer.mozilla.org/docs/Web/HTML/Element/input) এবং [অন্যান্য ফর্ম কন্ট্রোল](https://developer.mozilla.org/docs/Learn/Forms/Other_form_controls) দেখুন যাতে আপনি আপনার UI তৈরি করার সময় সমস্ত নেটিভ UI এলিমেন্ট সম্পর্কে ধারণা পেতে পারেন।
✅ লক্ষ্য করুন `<input>` একটি [ফাঁকা উপাদান](https://developer.mozilla.org/docs/Glossary/Empty_element) যার সাথে আপনি *মিলানো বন্ধ ট্যাগ* যোগ করবেন না। তবে আপনি স্ব-বন্ধ `<input/>` নোটেশন ব্যবহার করতে পারেন, যদিও এটি বাধ্যতামূলক নয়।
✅ লক্ষ্য করুন যে `<input>` একটি [ফাঁকা এলিমেন্ট](https://developer.mozilla.org/docs/Glossary/Empty_element) যার জন্য আপনাকে *মিলানো বন্ধ ট্যাগ* যোগ করা উচিত নয়। তবে আপনি স্ব-বন্ধ `<input/>` নোটেশন ব্যবহার করতে পারেন, তবে এটি বাধ্যতামূলক নয়।
ফর্মের মধ্যে `<button>` উপাদানটি একটু বিশেষ। যদি আপনি এর `type` অ্যাট্রিবিউট নির্দিষ্ট না করেন, এটি চাপলে স্বয়ংক্রিয়ভাবে ফর্ম ডেটা সার্ভারে জমা দেবে। এখানে সম্ভাব্য `type` মানগুল:
ফর্মের মধ্যে `<button>` এলিমেন্টটি একটু বিশেষ। যদি আপনি এর `type` অ্যাট্রিবিউট নির্দিষ্ট না করেন, এটি চাপলে স্বয়ংক্রিয়ভাবে ফর্ম ডেটা সার্ভারে জমা দেবে। এখানে সম্ভাব্য `type` মানগুলি রয়েছে:
- `submit`: ফর্মের মধ্যে ডিফল্ট, এটি ফর্ম জমা দেওয়ার ক্রিয়াটি ট্রিগার করে।
- `reset`: টি সমস্ত ফর্ম কন্ট্রোলকে তাদের প্রাথমিক মানে রিসেট করে।
- `button`: যখন বোতামটি চাপা হয় তখন কোনো ডিফল্ট আচরণ বরাদ্দ করে না। আপনি পরে JavaScript ব্যবহার করে কাস্টম ক্রিয়াগুলি বরাদ্দ করতে পারেন।
- `reset`: বোতামটি সমস্ত ফর্ম কন্ট্রোলকে তাদের প্রাথমিক মানে রিসেট করে।
- `button`: বোতামটি চাপলে কোনো ডিফল্ট আচরণ বরাদ্দ করে না। আপনি পরে JavaScript ব্যবহার করে কাস্টম ক্রিয়া বরাদ্দ করতে পারেন।
### কাজ
@ -79,12 +79,12 @@ curl http://localhost:5000/api
</template>
```
যদি আপনি ভালোভাবে লক্ষ্য করেন, আপনি দেখতে পাবেন আমরা এখানে একটি `<label>` উপাদানও যোগ করেছি। `<label>` উপাদানগুলো UI কন্ট্রোলের জন্য নাম যোগ করতে ব্যবহৃত হয়, যেমন আমাদের username ফিল্ড। লেবেলগুলো আপনার ফর্মের পাঠযোগ্যতার জন্য গুরুত্বপূর্ণ, তবে এগুলো অতিরিক্ত সুবিধাও নিয়ে আসে:
যদি আপনি ভালোভাবে লক্ষ্য করেন, আপনি দেখতে পাবেন যে আমরা এখানে একটি `<label>` এলিমেন্টও যোগ করেছি। `<label>` এলিমেন্টগুলি UI কন্ট্রোলগুলিতে নাম যোগ করতে ব্যবহৃত হয়, যেমন আমাদের ইউজারনেম ফিল্ড। লেবেলগুলি আপনার ফর্মের পাঠযোগ্যতার জন্য গুরুত্বপূর্ণ, তবে এটি অতিরিক্ত সুবিধাও নিয়ে আসে:
- একটি লেবেলকে ফর্ম কন্ট্রোলের সাথে সংযুক্ত করে এটি সহায়ক প্রযুক্তি ব্যবহারকারী (যেমন স্ক্রিন রিডার) কে বুঝতে সাহায্য করে যে তারা কী ডেটা প্রদান করতে যাচ্ছে।
- আপনি লেবেলে ক্লিক করে সরাসরি সংশ্লিষ্ট ইনপুটে ফোকাস দিতে পারেন, যা টাচ-স্ক্রিন ভিত্তিক ডিভাইসে সহজে পৌঁছানো জন্ সহায়
- একটি লেবেলকে ফর্ম কন্ট্রোলের সাথে যুক্ত করে, এটি সহায়ক প্রযুক্তি ব্যবহারকারী (যেমন স্ক্রিন রিডার) ব্যবহারারীদ বুঝতে সাহায্য করে যে তারা কী ডেটা প্রদান করতে আশা করা হচ্ছে।
- আপনি লেবেলে ক্লিক করে সরাসরি সংশ্লিষ্ট ইনপুটে ফোকাস দিতে পারেন, যা টাচ-স্ক্রিন ভিত্তিক ডিভাইসে সহজে পৌঁছানো যায়।
> [ওয়েব অ্যাক্সেসিবিলিটি](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility) একটি খুব গুরুত্বপূর্ণ বিষয় যা প্রায়ই উপেক্ষা করা হয়। [সেমান্টিক HTML উপাদান](https://developer.mozilla.org/docs/Learn/Accessibility/HTML) সঠিকভাবে ব্যবহার করলে অ্যাক্সেসযোগ্য কন্টেন্ট তৈরি করা কঠিন নয়। আপনি [অ্যাক্সেসিবিলিটি সম্পর্কে আরও পড়তে পারেন](https://developer.mozilla.org/docs/Web/Accessibility) সাধারণ ভুল এড়াতে এবং একজন দায়িত্বশীল ডেভেলপার হতে।
> [ওয়েব অ্যাক্সেসিবিলিটি](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility) একটি খুব গুরুত্বপূর্ণ বিষয় যা প্রায়ই উপেক্ষা করা হয়। [সেমান্টিক HTML এলিমেন্ট](https://developer.mozilla.org/docs/Learn/Accessibility/HTML) ব্যবহার করে সঠিকভাবে ব্যবহার করলে অ্যাক্সেসযোগ্য কন্টেন্ট তৈরি করা কঠিন নয়। আপনি [অ্যাক্সেসিবিলিটি সম্পর্কে আরও পড়তে পারেন](https://developer.mozilla.org/docs/Web/Accessibility) সাধারণ ভুল এড়াতে এবং একজন দায়িত্বশীল ডেভেলপার হতে।
এখন আমরা রেজিস্ট্রেশনের জন্য একটি দ্বিতীয় ফর্ম যোগ করব, আগেরটির ঠিক নিচে:
@ -104,9 +104,9 @@ curl http://localhost:5000/api
</form>
```
`value` অ্যাট্রিবিউট ব্যবহার করে আমরা একটি ইনপুটের জন্য ডিফল্ট মান সংজ্ঞায়িত করতে পারি। লক্ষ্য করুন যে `balance` এর ইনপুটে `number` টাইপ রয়েছে। এটি কি অন্য ইনপুটগুলর চেয়ে আলাদা দেখাচ্ছে? এটি ইন্টারঅ্যাক্ট করে দেখুন।
`value` অ্যাট্রিবিউট ব্যবহার করে আমরা একটি ইনপুটের জন্য একটি ডিফল্ট মান সংজ্ঞায়িত করতে পারি। লক্ষ্য করুন যে `balance` ইনপুটটির `number` টাইপ রয়েছে। এটি কি অন্য ইনপুটগুলির চেয়ে আলাদা দেখাচ্ছে? এটি ইন্টারঅ্যাক্ট করে দেখুন।
✅ আপনি কি শুধুমাত্র কীবোর্ড ব্যবহার করে ফর্মগুলোতে নেভিগেট এবং ইন্টারঅ্যাক্ট করতে পারেন? আপনি কীভাবে এটি করবেন?
✅ আপনি কি শুধুমাত্র কীবোর্ড ব্যবহার করে ফর্মগুলি নেভিগেট এবং ইন্টারঅ্যাক্ট করতে পারেন? আপনি কীভাবে এটি করবেন?
## সার্ভারে ডেটা জমা দেওয়া
@ -114,15 +114,15 @@ curl http://localhost:5000/api
আপনার ব্রাউজারের URL সেকশনে পরিবর্তন লক্ষ্য করেছেন?
![Register বোতামে ক্লিক করার পর ব্রাউজারের URL পরিবর্তনের স্ক্রিনশট](../../../../translated_images/click-register.e89a30bf0d4bc9ca867dc537c4cea679a7c26368bd790969082f524fed2355bc.bn.png)
![রেজিস্টার বোতামে ক্লিক করার পর ব্রাউজারের URL পরিবর্তনের স্ক্রিনশট](../../../../translated_images/click-register.e89a30bf0d4bc9ca867dc537c4cea679a7c26368bd790969082f524fed2355bc.bn.png)
ডিফল্টভাবে `<form>` একটি [GET পদ্ধতি](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3) ব্যবহার করে বর্তমান সার্ভার URL-এ ফর্ম জমা দেয়, ফর্ম ডেটা সরাসরি URL-এ যোগ করে। তবে এই পদ্ধতির কিছু সীমাবদ্ধতা রয়েছে:
একটি `<form>`-এর জন্য ডিফল্ট ক্রিয়া হল বর্তমান সার্ভার URL-এ ফর্ম জমা দেওয়া [GET পদ্ধতি](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3) ব্যবহার করে, ফর্ম ডেটা সরাসরি URL-এ যোগ করে। তবে এই পদ্ধতির কিছু সীমাবদ্ধতা রয়েছে:
- পাঠানো ডেটার আকার খুব সীমিত (প্রায় ২০০০ অক্ষর)
- ডেটা URL-এ সরাসরি দৃশ্যমান (পাসওয়ার্ডের জন্য ভালো নয়)
- এটি ফাইল আপলোডের সাথে কাজ করে না
তাই আপনি এটি পরিবর্তন করে [POST পদ্ধতি](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5) ব্যবহার করতে পারেন যা ফর্ম ডেটা HTTP অনুরোধের বডিতে সার্ভারে পাঠায়, পূর্বের সীমাবদ্ধতাগুল ছাড়াই।
তাই আপনি এটি পরিবর্তন করে [POST পদ্ধতি](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5) ব্যবহার করতে পারেন যা ফর্ম ডেটা HTTP অনুরোধের বডিতে সার্ভারে পাঠায়, পূর্বের সীমাবদ্ধতাগুলি ছাড়াই।
> যদিও POST ডেটা পাঠানোর জন্য সবচেয়ে সাধারণভাবে ব্যবহৃত পদ্ধতি, [কিছু নির্দিষ্ট পরিস্থিতিতে](https://www.w3.org/2001/tag/doc/whenToUseGet.html) GET পদ্ধতি ব্যবহার করা ভালো, যেমন একটি সার্চ ফিল্ড বাস্তবায়নের সময়।
@ -136,21 +136,21 @@ curl http://localhost:5000/api
এখন আপনার নাম দিয়ে একটি নতুন অ্যাকাউন্ট রেজিস্টার করার চেষ্টা করুন। *Register* বোতামে ক্লিক করার পর আপনি এরকম কিছু দেখতে পাবেন:
![localhost:5000/api/accounts ঠিকানায় একটি ব্রাউজার উইন্ডো, যেখানে JSON স্ট্রিং সহ ব্যবহারকারীর ডেটা দেখানো হয়েছে](../../../../translated_images/form-post.61de4ca1b964d91a9e338416e19f218504dd0af5f762fbebabfe7ae80edf885f.bn.png)
![একটি ব্রাউজার উইন্ডো localhost:5000/api/accounts ঠিকানায়, যেখানে একটি JSON স্ট্রিং ব্যবহারকারীর ডেটা দেখাচ্ছে](../../../../translated_images/form-post.61de4ca1b964d91a9e338416e19f218504dd0af5f762fbebabfe7ae80edf885f.bn.png)
যদি সবকিছু ঠিকঠাক হয়, সার্ভার আপনার অনুরোধের উত্তর JSON রেসপন্স দিয়ে দেবে যেখনে তৈরি করা অ্যাকাউন্টের ডেটা থাকবে।
যদি সবকিছু ঠিকঠাক হয়, সার্ভার আপনার অনুরোধের উত্তর JSON রেসপন্স দিয়ে দেবে যা তৈরি করা অ্যাকাউন্ট ডেটা ধারণ করে।
✅ একই নাম দিয়ে আবার রেজিস্টার করার চেষ্টা করুন। কী ঘটে?
✅ একই নাম দিয়ে আবার রেজিস্টার করার চেষ্টা করুন। কী ঘটে?
## পেজ রিলোড ছাড়াই ডেটা জমা দেওয়া
আপনি সম্ভবত লক্ষ্য করেছেন, আমরা যে পদ্ধতি ব্যবহার করেছি তাতে একটি ছোট সমস্যা রয়েছে: ফর্ম জমা দেওয়ার সময় আমরা আমাদের অ্যাপ থেকে বের হয়ে সার্ভার URL-এ ব্রাউজার রিডাইরেক্ট করি। আমরা আমাদের ওয়েব অ্যাপের সাথে সমস্ত পেজ রিলোড এড়াতে চাই, কারণ আমরা একটি [Single-page application (SPA)](https://en.wikipedia.org/wiki/Single-page_application) তৈরি করছি।
যেমনটি আপনি লক্ষ্য করেছেন, আমরা যে পদ্ধতি ব্যবহার করেছি তা একটি ছোট সমস্যা রয়েছে: ফর্ম জমা দেওয়ার সময়, আমরা আমাদের অ্যাপ থেকে বেরিয়ে যাই এবং ব্রাউজারটি সার্ভার URL-এ রিডাইরেক্ট করে। আমরা আমাদের ওয়েব অ্যাপের সাথে সমস্ত পেজ রিলোড এড়াতে চাই, কারণ আমরা একটি [সিঙ্গেল-পেজ অ্যাপ্লিকেশন (SPA)](https://en.wikipedia.org/wiki/Single-page_application) তৈরি করছি।
পেজ রিলোড না করেই ফর্ম ডেটা সার্ভারে পাঠানোর জন্য আমাদের JavaScript কোড ব্যবহার করতে হবে। `<form>` উপাদানের `action` প্রপার্টিতে একটি URL দেওয়ার পরিবর্তে, আপনি `javascript:` স্ট্রিং দিয়ে শুরু করে যেকোনো JavaScript কোড ব্যবহার করতে পারেন কাস্টম অ্যাকশন সম্পাদন করতে। এটি ব্যবহার করার অর্থ হল আপনাকে ব্রাউজার দ্বারা স্বয়ংক্রিয়ভাবে সম্পাদিত কিছু কাজ বাস্তবায়ন করতে হবে:
ফর্ম ডেটা সার্ভারে পাঠানোর জন্য পেজ রিলোড এড়াতে, আমাদের JavaScript কোড ব্যবহার করতে হবে। `<form>` এলিমেন্টের `action` প্রপার্টিতে একটি URL দেওয়ার পরিবর্তে, আপনি `javascript:` স্ট্রিং দিয়ে শুরু করে যেকোনো JavaScript কোড ব্যবহার করতে পারেন কাস্টম ক্রিয়া সম্পাদন করতে। এটি ব্যবহার করার অর্থ হল আপনাকে ব্রাউজার দ্বারা স্বয়ংক্রিয়ভাবে সম্পন্ন কিছু কাজ বাস্তবায়ন করতে হবে:
- ফর্ম ডেটা পুনরুদ্ধার করা
- ফর্ম ডেটাকে উপযুক্ত ফরম্যাটে রূপান্তর এবং এনকোড করা
- HTTP অনুরোধ তৈরি করা এবং এটি সার্ভারে পাঠানো
- ফর্ম ডেটা একটি উপযুক্ত ফরম্যাটে রূপান্তর এবং এনকোড করা
- HTTP অনুরোধ তৈরি করা এবং সার্ভারে পাঠানো
### কাজ
@ -160,7 +160,7 @@ curl http://localhost:5000/api
<form id="registerForm" action="javascript:register()">
```
`app.js` খুলুন এবং `register` নামে একটি নতুন ফাংশন যোগ করুন:
`app.js` খুলুন এবং একটি নতুন ফাংশন `register` নামে যোগ করুন:
```js
function register() {
@ -171,7 +171,7 @@ function register() {
}
```
এখানে আমরা `getElementById()` ব্যবহার করে ফর্ম উপাদানটি পুনরুদ্ধার করি এবং [`FormData`](https://developer.mozilla.org/docs/Web/API/FormData) হেল্পার ব্যবহার করে ফর্ম কন্ট্রোল থেকে মানগুল কী/মান জোড়া হিসেবে বের করি। তারপর আমরা ডেটাকে একটি নিয়মিত অবজেক্টে রূপান্তর করি [`Object.fromEntries()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) ব্যবহার করে এবং শেষ পর্যন্ত ডেটাকে [JSON](https://www.json.org/json-en.html) এ সিরিয়ালাইজ করি, যা ওয়েবে ডেটা বিনিময়ের জন্য সাধারণত ব্যবহৃত একটি ফরম্যাট।
এখানে আমরা `getElementById()` ব্যবহার করে ফর্ম এলিমেন্টটি পুনরুদ্ধার করি এবং [`FormData`](https://developer.mozilla.org/docs/Web/API/FormData) হেল্পার ব্যবহার করে ফর্ম কন্ট্রোল থেকে মানগুলি কী/মান জোড়া হিসেবে বের করি। তারপর আমরা ডেটাকে একটি নিয়মিত অবজেক্টে রূপান্তর করি [`Object.fromEntries()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) ব্যবহার করে এবং শেষ পর্যন্ত ডেটাকে [JSON](https://www.json.org/json-en.html) এ সিরিয়ালাইজ করি, যা ওয়েবে ডেটা বিনিময়ের জন্য সাধারণত ব্যবহৃত একটি ফরম্যাট।
ডেটা এখন সার্ভারে পাঠানোর জন্য প্রস্তুত। `createAccount` নামে একটি নতুন ফাংশন তৈরি করুন:
@ -190,16 +190,16 @@ async function createAccount(account) {
}
```
এই ফাংশনটি কী করছে? প্রথমে, এখানে `async` কীওয়ার্ড লক্ষ্য করুন। এর অর্থ হল ফাংশনটি এমন কোড ধারণ করে যা [**অ্যাসিঙ্ক্রোনাসভাবে**](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function) কার্যকর হবে। যখন `await` কীওয়ার্ডের সাথে ব্যবহার করা হয়, এটি অ্যাসিঙ্ক্রোনাস কোড কার্যকর হওয়ার জন্য অপেক্ষা করতে দেয় - যেমন এখানে সার্ভারের উত্তর পাওয়ার জন্য অপেক্ষা করা - তারপর চালিয়ে যায়।
এই ফাংশনটি কী করছে? প্রথমে, এখানে `async` কীওয়ার্ডটি লক্ষ্য করুন। এর অর্থ হল ফাংশনটি এমন কোড ধারণ করে যা [**অ্যাসিঙ্ক্রোনাসলি**](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function) কার্যকর হবে। `await` কীওয়ার্ডের সাথে ব্যবহার করলে এটি অ্যাসিঙ্ক্রোনাস কোড কার্যকর হওয়ার জন্য অপেক্ষা করতে দেয় - যেমন এখানে সার্ভারের উত্তর পাওয়ার জন্য অপেক্ষা করা - তারপর চালিয়ে যায়।
`fetch()` API ব্যবহার করে আমরা JSON ডেটা সার্ভারে পাঠাই। এই পদ্ধতি দুটি প্যারামিটার নেয়:
`fetch()` API ব্যবহার করে আমরা JSON ডেটা সার্ভারে পাঠাই। এই পদ্ধতিটি দুটি প্যারামিটার নেয়:
- সার্ভারের URL, তাই আমরা এখানে `//localhost:5000/api/accounts` ব্যবহার করি।
- অনুরোধের সেটিংস। এখানে আমরা পদ্ধতিকে `POST` সেট করি এবং অনুরোধের জন্য `body` প্রদান করি। যেহেতু আমরা JSON ডেটা সার্ভারে পাঠাচ্ছি, তাই আমাদের `Content-Type` হেডারকে `application/json` সেট করতে হবে যাতে সার্ভার বিষয়বস্তুটি কীভাবে ব্যাখ্যা করবে তা জানে।
- অনুরোধের সেটিংস। এখানে আমরা পদ্ধতিটি `POST` সেট করি এবং অনুরোধের জন্য `body` প্রদান করি। যেহেতু আমরা JSON ডেটা সার্ভারে পাঠাচ্ছি, তাই আমাদের `Content-Type` হেডারটি `application/json` সেট করতে হবে যাতে সার্ভার বিষয়বস্তুটি কীভাবে ব্যাখ্যা করবে তা জানে।
যেহেতু সার্ভার অনুরোধের উত্তর JSON দিয়ে দেবে, আমরা `await response.json()` ব্যবহার করে JSON বিষয়বস্তু পার্স করতে পারি এবং ফলাফল অবজেক্টটি ফেরত দিতে পারি। লক্ষ্য করুন যে এই পদ্ধতিটি অ্যাসিঙ্ক্রোনাস, তাই আমরা এখানে `await` কীওয়ার্ড ব্যবহার করি যাতে পার্সিংয়ের সময় কোনো ত্রুটি ধরা পড়ে।
এখন `register` ফাংশনে কিছু কোড যোগ করুন `createAccount()` কল করার জন্য:
এখন `register` ফাংশনে কিছু কোড যোগ করুন `createAccount()` কল করতে:
```js
const result = await createAccount(jsonData);
@ -236,7 +236,7 @@ async function register() {
## ডেটা যাচাইকরণ
যদি আপনি প্রথমে একটি username সেট না করে একটি নতুন অ্যাকাউন্ট রেজিস্টার করার চেষ্টা করেন, আপনি দেখতে পাবেন যে সার্ভার [400 (Bad Request)](https://developer.mozilla.org/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).) স্ট্যাটাস কোড সহ একটি ত্রুটি ফেরত দেয়
যদি আপনি প্রথমে একটি ইউজারনেম সেট না করে একটি নতুন অ্যাকাউন্ট রেজিস্টার করার চেষ্টা করেন, আপনি দেখতে পাবেন যে সার্ভার একটি ত্রুটি ফেরত দেয় যার স্ট্যাটাস কোড [400 (Bad Request)](https://developer.mozilla.org/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).)।
সার্ভারে ডেটা পাঠানোর আগে এটি যাচাই করা একটি ভালো অভ্যাস, যখন সম্ভব, যাতে আপনি একটি বৈধ অনুরোধ পাঠান। HTML5 ফর্ম কন্ট্রোল বিভিন্ন অ্যাট্রিবিউট ব্যবহার করে বিল্ট-ইন যাচাইকরণ প্রদান করে:
@ -244,11 +244,11 @@ async function register() {
- `minlength` এবং `maxlength`: টেক্সট ফিল্ডে অক্ষরের সর্বনিম্ন এবং সর্বাধিক সংখ্যা সংজ্ঞায়িত করে।
- `min` এবং `max`: সংখ্যাসূচক ফিল্ডের সর্বনিম্ন এবং সর্বাধিক মান সংজ্ঞায়িত করে।
- `type`: প্রত্যাশিত ডেটার ধরণ সংজ্ঞায়িত করে, যেমন `number`, `email`, `file` বা [অন্যান্য বিল্ট-ইন টাইপ](https://developer.mozilla.org/docs/Web/HTML/Element/input)। এই অ্যাট্রিবিউটটি ফর্ম কন্ট্রোলের ভিজ্যুয়াল রেন্ডারিংও পরিবর্তন করতে পারে।
- `pattern`: একটি [রেগুলার এক্সপ্রেশন](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions) প্যাটার্ন সংজ্ঞায়িত করতে দেয় যা পরীক্ষা করে ইনপুটকৃত ডেটা বৈধ কিনা
রামর্শ: আপনি আপনার ফর্ম কন্ট্রোলগুলোর চেহারা কাস্টমাইজ করতে পারেন, সেগুলো বৈধ কিনা বা অবৈধ কিনা তা নির্ভর করে, `:valid` এবং `:invalid` CSS পসুডো-ক্লাস ব্যবহার করে।
- `pattern`: একটি [রেগুলার এক্সপ্রেশন](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions) প্যাটার্ন সংজ্ঞায়িত করতে দেয় যাতে প্রবেশ করা ডেটা বৈধ কিনা তা পরীক্ষা করা যায়
টিপ: আপনি আপনার ফর্ম কন্ট্রোলগুলোর চেহারা কাস্টমাইজ করতে পারেন, সেগুলো বৈধ বা অবৈধ কিনা তার উপর ভিত্তি করে, `:valid` এবং `:invalid` CSS পসুডো-ক্লাস ব্যবহার করে।
### কাজ
একটি বৈধ নতুন অ্যাকাউন্ট তৈরি করতে দুটি প্রয়োজনীয় ক্ষেত্র রয়েছে: ব্যবহারকারীর নাম এবং মুদ্রা। বাকি ক্ষেত্রগুলো ঐচ্ছিক। ফর্মের HTML আপডেট করুন, `required` অ্যাট্রিবিউট এবং ক্ষেত্রের লেবেলে টেক্সট ব্যবহার করে যাতে:
একটি বৈধ নতুন অ্যাকাউন্ট তৈরি করতে দুটি প্রয়োজনীয় ক্ষেত্র রয়েছে: ব্যবহারকারীর নাম এবং মুদ্রা। অন্যান্য ক্ষেত্রগুলো ঐচ্ছিক। ফর্মের HTML আপডেট করুন, `required` অ্যাট্রিবিউট এবং ক্ষেত্রের লেবেলে টেক্সট ব্যবহার করে যাতে:
```html
<label for="user">Username (required)</label>
@ -258,7 +258,7 @@ async function register() {
<input id="currency" name="currency" type="text" value="$" required>
```
যদিও এই নির্দিষ্ট সার্ভার ইমপ্লিমেন্টেশন ক্ষেত্রগুলোর সর্বোচ্চ দৈর্ঘ্যের উপর নির্দিষ্ট সীমা আরোপ করে না, তবুও ব্যবহারকারীর টেক্সট এন্ট্রির জন্য যুক্তিসঙ্গত সীমা নির্ধারণ করা সবসময়ই একটি ভালো অভ্যাস।
যদিও এই নির্দিষ্ট সার্ভার ইমপ্লিমেন্টেশন ক্ষেত্রগুলোর সর্বোচ্চ দৈর্ঘ্যের উপর নির্দিষ্ট সীমা আরোপ করে না, তবুও ব্যবহারকারীর টেক্সট এন্ট্রির জন্য যুক্তিসঙ্গত সীমা নির্ধারণ করা সর্বদা একটি ভালো অভ্যাস।
টেক্সট ক্ষেত্রগুলোতে একটি `maxlength` অ্যাট্রিবিউট যোগ করুন:
@ -270,23 +270,23 @@ async function register() {
<input id="description" name="description" type="text" maxlength="100">
```
এখন যদি আপনি *Register* বোতামটি চাপেন এবং কোনো ক্ষেত্র আমাদের সংজ্ঞায়িত করা ভ্যালিডেশন নিয়ম মেনে না চলে, তাহলে আপনি এরকম কিছু দেখতে পাবেন:
এখন যদি আপনি *Register* বোতামটি চাপেন এবং কোনো ক্ষেত্র আমাদের সংজ্ঞায়িত করা যাচাইয়ের নিয়ম মেনে না চলে, তবে আপনি এরকম কিছু দেখতে পাবেন:
![ফর্ম জমা দেওয়ার চেষ্টা করার সময় ভ্যালিডেশন ত্রুটি দেখানো একটি স্ক্রিনশট](../../../../translated_images/validation-error.8bd23e98d416c22f80076d04829a4bb718e0e550fd622862ef59008ccf0d5dce.bn.png)
![ফর্ম জমা দেওয়ার সময় যাচাইয়ের ত্রুটি দেখানোর স্ক্রিনশট](../../../../translated_images/validation-error.8bd23e98d416c22f80076d04829a4bb718e0e550fd622862ef59008ccf0d5dce.bn.png)
এই ধরনের ভ্যালিডেশন, যা কোনো ডেটা সার্ভারে পাঠানোর *আগে* সম্পন্ন হয়, তাকে **ক্লায়েন্ট-সাইড** ভ্যালিডেশন বলা হয়। তবে মনে রাখবেন, সব চেক করা সবসময় ডেটা না পাঠিয়েও সম্ভব নয়। উদাহরণস্বরূপ, আমরা এখানে চেক করতে পারি না যে একই ব্যবহারকারীর নাম দিয়ে একটি অ্যাকাউন্ট ইতিমধ্যেই বিদ্যমান কিনা, সার্ভারে একটি অনুরোধ না পাঠিয়ে। অতিরিক্ত ভ্যালিডেশন যা সার্ভারে সম্পন্ন হয়, তাকে **সার্ভার-সাইড** ভ্যালিডেশন বলা হয়।
এই ধরনের যাচাই, যা কোনো ডেটা সার্ভারে পাঠানোর *আগে* সম্পন্ন হয়, তাকে **ক্লায়েন্ট-সাইড** যাচাই বলা হয়। তবে মনে রাখবেন, কিছু যাচাই ডেটা না পাঠিয়ে সম্পন্ন করা সবসময় সম্ভব নয়। উদাহরণস্বরূপ, আমরা এখানে যাচাই করতে পারি না যে একই ব্যবহারকারীর নাম সহ একটি অ্যাকাউন্ট ইতিমধ্যেই বিদ্যমান কিনা, সার্ভারে একটি অনুরোধ না পাঠিয়ে। সার্ভারে সম্পন্ন হওয়া অতিরিক্ত যাচাইকে **সার্ভার-সাইড** যাচাই বলা হয়।
সাধারণত উভয়ই বাস্তবায়ন করা প্রয়োজন, এবং ক্লায়েন্ট-সাইড ভ্যালিডেশন ব্যবহারকারীর অভিজ্ঞতা উন্নত করে তাৎক্ষণিক প্রতিক্রিয়া প্রদান করে, তবে সার্ভার-সাইড ভ্যালিডেশন অত্যন্ত গুরুত্বপূর্ণ যাতে আপনি যে ব্যবহারকারীর ডেটা পরিচালনা করছেন তা সঠিক এবং নিরাপদ হয়
সাধারণত উভয়ই বাস্তবায়ন করা প্রয়োজন, এবং ক্লায়েন্ট-সাইড যাচাই ব্যবহারকারীর অভিজ্ঞতা উন্নত করে তাৎক্ষণিক প্রতিক্রিয়া প্রদান করে, তবে সার্ভার-সাইড যাচাই নিশ্চিত করে যে আপনি যে ব্যবহারকারীর ডেটা পরিচালনা করছেন তা সঠিক এবং নিরাপদ।
---
## 🚀 চ্যালেঞ্জ
যদি ব্যবহারকারী ইতিমধ্যেই বিদ্যমান থাকে, তাহলে HTML-এ একটি ত্রুটির বার্তা দেখান।
যদি ব্যবহারকারী ইতিমধ্যেই বিদ্যমান থাকে, তবে HTML-এ একটি ত্রুটি বার্তা দেখান।
এখানে একটি উদাহরণ দেওয়া হলো, যেখানে কিছু স্টাইলিং করার পর চূড়ান্ত লগইন পৃষ্ঠাটি দেখতে এরকম হতে পারে:
স্টাইলিং যোগ করার পর চূড়ান্ত লগইন পৃষ্ঠাটি দেখতে এরকম হতে পারে:
![CSS স্টাইল যোগ করার পর লগইন পৃষ্ঠার একটি স্ক্রিনশট](../../../../translated_images/result.96ef01f607bf856aa9789078633e94a4f7664d912f235efce2657299becca483.bn.png)
![CSS স্টাইল যোগ করার পর লগইন পৃষ্ঠার স্ক্রিনশট](../../../../translated_images/result.96ef01f607bf856aa9789078633e94a4f7664d912f235efce2657299becca483.bn.png)
## পোস্ট-লেকচার কুইজ
@ -294,11 +294,13 @@ async function register() {
## পর্যালোচনা ও স্ব-অধ্যয়ন
ডেভেলপাররা তাদের ফর্ম তৈরির প্রচেষ্টায়, বিশেষ করে ভ্যালিডেশন কৌশলগুলোর ক্ষেত্রে, খুবই সৃজনশীল হয়ে উঠেছে। [CodePen](https://codepen.com) ঘেঁটে বিভিন্ন ফর্ম ফ্লো সম্পর্কে জানুন; আপনি কি কিছু আকর্ষণীয় এবং অনুপ্রেরণামূলক ফর্ম খুঁজে পেতে পারেন?
ডেভেলপাররা তাদের ফর্ম তৈরির প্রচেষ্টায়, বিশেষ করে যাচাই কৌশলগুলোর ক্ষেত্রে, খুবই সৃজনশীল হয়ে উঠেছে। [CodePen](https://codepen.com) ঘেঁটে বিভিন্ন ফর্ম ফ্লো সম্পর্কে জানুন; আপনি কি কিছু আকর্ষণীয় এবং অনুপ্রেরণামূলক ফর্ম খুঁজে পেতে পারেন?
## অ্যাসাইনমেন্ট
[আপনার ব্যাংক অ্যাপ স্টাইল করুন](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়ী থাকব না।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিক অনুবাদ প্রদানের চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।

@ -1,13 +1,13 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "f587e913e3f7c0b1c549a05dd74ee8e5",
"translation_date": "2025-08-26T00:21:10+00:00",
"original_hash": "89d0df9854ed020f155e94882ae88d4c",
"translation_date": "2025-08-28T22:51:42+00:00",
"source_file": "7-bank-project/3-data/README.md",
"language_code": "bn"
}
-->
# ব্যাংকিং অ্যাপ তৈরি করুন পার্ট ৩: ডেটা সংগ্রহ এবং ব্যবহার করার পদ্ধতি
# ব্যাংকিং অ্যাপ তৈরি করুন পার্ট ৩: ডেটা আনার এবং ব্যবহারের পদ্ধতি
## প্রাক-লেকচার কুইজ
@ -15,15 +15,15 @@ CO_OP_TRANSLATOR_METADATA:
### ভূমিকা
প্রতিটি ওয়েব অ্যাপ্লিকেশনের কেন্দ্রে থাকে *ডেটা*। ডেটা বিভিন্ন রূপ নিতে পারে, তবে এর প্রধান উদ্দেশ্য হল ব্যবহারকারীর কাছে তথ্য প্রদর্শন করা। ওয়েব অ্যাপ্লিকেশনগুলি ক্রমশ ইন্টারঅ্যাকটিভ এবং জটিল হয়ে উঠছে, তাই ব্যবহারকারী কীভাবে তথ্য অ্যাক্সেস করে এবং এর সাথে ইন্টারঅ্যাক্ট করে তা এখন ওয়েব ডেভেলপমেন্টের একটি গুরুত্বপূর্ণ অংশ।
প্রতিটি ওয়েব অ্যাপ্লিকেশনের কেন্দ্রে থাকে *ডেটা*। ডেটা বিভিন্ন রূপ নিতে পারে, তবে এর প্রধান উদ্দেশ্য হল ব্যবহারকারীর কাছে তথ্য প্রদর্শন করা। ওয়েব অ্যাপ্লিকেশনগুলি ক্রমশ আরও ইন্টারেক্টিভ এবং জটিল হয়ে উঠছে, তাই ব্যবহারকারী কীভাবে তথ্য অ্যাক্সেস করে এবং এর সাথে ইন্টারঅ্যাক্ট করে তা এখন ওয়েব ডেভেলপমেন্টের একটি গুরুত্বপূর্ণ অংশ।
এই পাঠে, আমরা দেখব কীভাবে সার্ভার থেকে ডেটা অ্যাসিঙ্ক্রোনাসভাবে সংগ্রহ করা যায় এবং এই ডেটা ব্যবহার করে HTML পুনরায় লোড না করেই ওয়েব পেজে তথ্য প্রদর্শন করা যায়।
এই পাঠে, আমরা দেখব কীভাবে সার্ভার থেকে অ্যাসিঙ্ক্রোনাসভাবে ডেটা আনা যায় এবং এই ডেটা ব্যবহার করে HTML রিলোড না করেই ওয়েব পেজে তথ্য প্রদর্শন করা যায়।
### পূর্বশর্ত
এই পাঠের জন্য আপনাকে [লগইন এবং রেজিস্ট্রেশন ফর্ম](../2-forms/README.md) অংশটি তৈরি করতে হবে। এছাড়াও আপনাকে [Node.js](https://nodejs.org) ইনস্টল করতে হবে এবং [সার্ভার API চালাতে হবে](../api/README.md) লোকালভাবে যাতে আপনি অ্যাকাউন্ট ডেটা পেতে পারেন।
এই পাঠের জন্য আপনাকে ওয়েব অ্যাপের [লগইন এবং রেজিস্ট্রেশন ফর্ম](../2-forms/README.md) অংশটি তৈরি করতে হবে। আপনাকে [Node.js](https://nodejs.org) ইনস্টল করতে হবে এবং [সার্ভার API চালাতে হবে](../api/README.md) লোকালভাবে যাতে আপনি অ্যাকাউন্ট ডেটা পেতে পারেন।
আপনি টার্মিনালে এই কমান্ডটি চালিয়ে সার্ভারটি সঠিকভাবে চলছে কিনা পরীক্ষা করতে পারেন:
আপনার সার্ভার সঠিকভাবে চলছে কিনা তা পরীক্ষা করতে, টার্মিনালে এই কমান্ডটি চালান:
```sh
curl http://localhost:5000/api
@ -32,23 +32,23 @@ curl http://localhost:5000/api
---
## AJAX এবং ডেটা সংগ্রহ
## AJAX এবং ডেটা আনা
প্রথাগত ওয়েব সাইটগুলি ব্যবহারকারী যখন একটি লিঙ্ক নির্বাচন করে বা একটি ফর্ম ব্যবহার করে ডেটা জমা দেয় তখন প্রদর্শিত বিষয়বস্তু আপডেট করে, সম্পূর্ণ HTML পেজ পুনরায় লোড করে। নতুন ডেটা লোড করার প্রতিবার, ওয়েব সার্ভার একটি সম্পূর্ণ নতুন HTML পেজ ফেরত দেয় যা ব্রাউজার দ্বারা প্রক্রিয়াকরণ করতে হয়, বর্তমান ব্যবহারকারীর ক্রিয়াকে বাধাগ্রস্ত করে এবং পুনরায় লোডের সময় ইন্টারঅ্যাকশন সীমিত করে। এই ওয়ার্কফ্লোকে *মাল্টি-পেজ অ্যাপ্লিকেশন* বা *MPA* বলা হয়।
প্রথাগত ওয়েবসাইটে, ব্যবহারকারী একটি লিঙ্ক নির্বাচন করলে বা ফর্মের মাধ্যমে ডেটা জমা দিলে পুরো HTML পেজ রিলোড হয়। নতুন ডেটা লোড করার সময়, ওয়েব সার্ভার একটি সম্পূর্ণ নতুন HTML পেজ ফেরত পাঠায়, যা ব্রাউজার দ্বারা প্রক্রিয়াকৃত হয়। এটি ব্যবহারকারীর বর্তমান ক্রিয়াকলাপকে বাধাগ্রস্ত করে এবং রিলোডের সময় ইন্টারঅ্যাকশন সীমিত করে। এই ওয়ার্কফ্লোকে *মাল্টি-পেজ অ্যাপ্লিকেশন* বা *MPA* বলা হয়।
![মাল্টি-পেজ অ্যাপ্লিকেশনে আপডেট ওয়ার্কফ্লো](../../../../translated_images/mpa.7f7375a1a2d4aa779d3f928a2aaaf9ad76bcdeb05cfce2dc27ab126024050f51.bn.png)
যখন ওয়েব অ্যাপ্লিকেশনগুলি আরও জটিল এবং ইন্টারঅ্যাকটিভ হতে শুরু করে, তখন একটি নতুন কৌশল [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)) উদ্ভূত হয়। এই কৌশলটি ওয়েব অ্যাপগুলিকে জাভাস্ক্রিপ্ট ব্যবহার করে সার্ভার থেকে অ্যাসিঙ্ক্রোনাসভাবে ডেটা পাঠাতে এবং সংগ্রহ করতে দেয়, HTML পেজ পুনরায় লোড না করেই, যা দ্রুত আপডেট এবং মসৃণ ব্যবহারকারীর ইন্টারঅ্যাকশন প্রদান করে। যখন সার্ভার থেকে নতুন ডেটা পাওয়া যায়, তখন বর্তমান HTML পেজটি জাভাস্ক্রিপ্ট ব্যবহার করে [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) API এর মাধ্যমে আপডেট করা যায়। সময়ের সাথে সাথে, এই পদ্ধতিটি এখন [*সিঙ্গেল-পেজ অ্যাপ্লিকেশন* বা *SPA*](https://en.wikipedia.org/wiki/Single-page_application) নামে পরিচিত হয়েছে।
যখন ওয়েব অ্যাপ্লিকেশন আরও জটিল এবং ইন্টারেক্টিভ হতে শুরু করে, তখন [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)) নামে একটি নতুন কৌশল উদ্ভাবিত হয়। এই কৌশলটি ওয়েব অ্যাপ্লিকেশনগুলিকে জাভাস্ক্রিপ্ট ব্যবহার করে সার্ভার থেকে অ্যাসিঙ্ক্রোনাসভাবে ডেটা পাঠাতে এবং আনতে দেয়, HTML পেজ রিলোড না করেই। এর ফলে দ্রুত আপডেট এবং মসৃণ ব্যবহারকারীর ইন্টারঅ্যাকশন সম্ভব হয়। সার্ভার থেকে নতুন ডেটা পাওয়ার পর, বর্তমান HTML পেজটি জাভাস্ক্রিপ্ট ব্যবহার করে [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) API এর মাধ্যমে আপডেট করা যায়। সময়ের সাথে সাথে, এই পদ্ধতিটি [*সিঙ্গেল-পেজ অ্যাপ্লিকেশন* বা *SPA*](https://en.wikipedia.org/wiki/Single-page_application) নামে পরিচিত হয়েছে।
![সিঙ্গেল-পেজ অ্যাপ্লিকেশনে আপডেট ওয়ার্কফ্লো](../../../../translated_images/spa.268ec73b41f992c2a21ef9294235c6ae597b3c37e2c03f0494c2d8857325cc57.bn.png)
যখন AJAX প্রথম চালু হয়েছিল, তখন অ্যাসিঙ্ক্রোনাসভাবে ডেটা সংগ্রহ করার জন্য একমাত্র API ছিল [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest)। তবে আধুনিক ব্রাউজারগুলি এখন আরও সুবিধাজনক এবং শক্তিশালী [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API) বাস্তবায়ন করে, যা প্রমি ব্যবহার করে এবং JSON ডেটা পরিচালনার জন্য আরও উপযুক্ত।
যখন AJAX প্রথম চালু হয়েছিল, তখন অ্যাসিঙ্ক্রোনাসভাবে ডেটা আনার জন্য একমাত্র API ছিল [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest)। তবে আধুনিক ব্রাউজারগুলি এখন আরও সুবিধাজনক এবং শক্তিশালী [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API) বাস্তবায়ন করে, যা প্রমি ব্যবহার করে এবং JSON ডেটা পরিচালনার জন্য আরও উপযুক্ত।
> যদিও সমস্ত আধুনিক ব্রাউজার `Fetch API` সমর্থন করে, যদি আপনি চান আপনার ওয়েব অ্যাপ্লিকেশন পুরানো বা লিগ্যাসি ব্রাউজারে কাজ করুক, তাহলে প্রথমে [caniuse.com এ সামঞ্জস্যতার টেবিল](https://caniuse.com/fetch) পরীক্ষা করা সবসময়ই ভালো ধারণা।
> যদিও সমস্ত আধুনিক ব্রাউজার `Fetch API` সমর্থন করে, যদি আপনি চান আপনার ওয়েব অ্যাপ্লিকেশন পুরানো বা লিগ্যাসি ব্রাউজারে কাজ করুক, তে [caniuse.com এ সামঞ্জস্যতার টেবিল](https://caniuse.com/fetch) পরীক্ষা করা সবসময়ই একটি ভালো ধারণা।
### কাজ
[পূর্ববর্তী পাঠে](../2-forms/README.md) আমরা একটি অ্যাকাউন্ট তৈরি করতে রেজিস্ট্রেশন ফর্ম বাস্তবায়ন করেছি। এখন আমরা একটি বিদ্যমান অ্যাকাউন্ট ব্যবহার করে লগইন করার জন্য কোড যোগ করব এবং এর ডেটা সংগ্রহ করব। `app.js` ফাইলটি খুলুন এবং একটি নতুন `login` ফাংশন যোগ করুন:
[পূর্ববর্তী পাঠে](../2-forms/README.md) আমরা একটি অ্যাকাউন্ট তৈরি করার জন্য রেজিস্ট্রেশন ফর্ম বাস্তবায়ন করেছি। এখন আমরা একটি বিদ্যমান অ্যাকাউন্ট ব্যবহার করে লগইন করার এবং এর ডেটা আনার জন্য কোড যোগ করব। `app.js` ফাইলটি খুলুন এবং একটি নতুন `login` ফাংশন যোগ করুন:
```js
async function login() {
@ -57,9 +57,9 @@ async function login() {
}
```
এখানে আমরা প্রথমে `getElementById()` ব্যবহার করে ফর্ম এলিমেন্টটি সংগ্রহ করি এবং তারপর `loginForm.user.value` ব্যবহার করে ইনপুট থেকে ব্যবহারকারীর নাম সংগ্রহ করি। প্রতিটি ফর্ম কন্ট্রোলকে HTML-এ `name` অ্যাট্রিবিউট ব্যবহার করে ফর্মের একটি প্রপার্টি হিসেবে অ্যাক্সেস করা যায়।
এখানে আমরা প্রথমে `getElementById()` ব্যবহার করে ফর্ম এলিমেন্টটি আনছি এবং তারপর `loginForm.user.value` এর মাধ্যমে ইনপুট থেকে ইউজারনেমটি নিচ্ছি। প্রতিটি ফর্ম কন্ট্রোলকে তার নাম (HTML-এ `name` অ্যাট্রিবিউট ব্যবহার করে সেট করা) দ্বারা ফর্মের একটি প্রপার্টি হিসেবে অ্যাক্সেস করা যায়।
রেজিস্ট্রেশনের জন্য আমরা যা করেছি তার অনুরূপ, আমরা একটি নতুন ফাংশন তৈরি করব যা সার্ভার অনুরোধ সম্পাদন করবে, তবে এইবার অ্যাকাউন্ট ডেটা সংগ্রহ করার জন্য:
রেজিস্ট্রেশনের জন্য আমরা যা করেছি তার অনুরূপ, আমরা সার্ভার রিকোয়েস্ট করার জন্য আরেকটি ফাংশন তৈরি করব, তবে এবার অ্যাকাউন্ট ডেটা আনার জন্য:
```js
async function getAccount(user) {
@ -72,9 +72,9 @@ async function getAccount(user) {
}
```
আমরা `fetch` API ব্যবহার করে সার্ভার থেকে অ্যাসিঙ্ক্রোনাসভাবে ডেটা সংগ্রহ করি, তবে এইবার আমাদের শুধুমাত্র URL ছাড়া অন্য কোনো অতিরিক্ত প্যারামিটার দরকার নেই, কারণ আমরা শুধুমাত্র ডেটা অনুসন্ধান করছি। ডিফল্টভাবে, `fetch` একটি [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) HTTP অনুরোধ তৈরি করে, যা এখানে আমাদের প্রয়োজন।
আমরা `fetch` API ব্যবহার করে সার্ভার থেকে অ্যাসিঙ্ক্রোনাসভাবে ডেটা রিকোয়েস্ট করছি, তবে এবার আমাদের শুধুমাত্র URL ছাড়া অন্য কোনো অতিরিক্ত প্যারামিটার প্রয়োজন নেই, কারণ আমরা কেবল ডেটা কুয়েরি করছি। ডিফল্টভাবে, `fetch` একটি [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) HTTP রিকোয়েস্ট তৈরি করে, যা এখানে আমাদের প্রয়োজন।
`encodeURIComponent()` একটি ফাংশন যা URL এর জন্য বিশেষ অক্ষর এড়িয়ে যায়। যদি আমরা এই ফাংশনটি না ডাকি এবং সরাসরি `user` মানটি URL-এ ব্যবহার করি, তাহলে কী সমস্যা হতে পারে?
`encodeURIComponent()` একটি ফাংশন যা URL এর জন্য বিশেষ অক্ষরগুলোকে এস্কেপ করে। আমরা যদি এই ফাংশনটি না ডাকি এবং সরাসরি `user` ভ্যালুটি URL-এ ব্যবহার করি, তাহলে কী ধরনের সমস্যা হতে পারে?
এখন আমাদের `login` ফাংশনটি `getAccount` ব্যবহার করার জন্য আপডেট করা যাক:
@ -93,23 +93,23 @@ async function login() {
}
```
প্রথমে, যেহেতু `getAccount` একটি অ্যাসিঙ্ক্রোনাস ফাংশন, তাই আমাদের এটি `await` কীওয়ার্ড দিয়ে মেলাতে হবে যাতে সার্ভার ফলাফলের জন্য অপেক্ষা করা যায়। যেকোনো সার্ভার অনুরোধের মতো, আমাদের ত্রুটি ক্ষেত্রগুলি পরিচালনা করতে হবে। আপাতত আমরা শুধুমাত্র একটি লগ বার্তা যোগ করব ত্রুটি প্রদর্শনের জন্য এবং পরে এটি নিয়ে ফিরে আসব।
প্রথমে, যেহেতু `getAccount` একটি অ্যাসিঙ্ক্রোনাস ফাংশন, তাই সার্ভার রেজাল্টের জন্য অপেক্ষা করতে আমাদের `await` কীওয়ার্ড ব্যবহার করতে হবে। যেকোনো সার্ভার রিকোয়েস্টের মতো, আমাদের ত্রুটির ক্ষেত্রেও ডিল করতে হবে। আপাতত আমরা কেবল একটি লগ মেসেজ যোগ করব ত্রুটি প্রদর্শনের জন্য এবং পরে এটি নিয়ে ফিরে আসব।
তারপর আমাদের কোথাও ডেটা সংরক্ষণ করতে হবে যাতে আমরা পরে এটি ব্যবহার করে ড্যাশবোর্ড তথ্য প্রদর্শন করতে পারি। যেহেতু `account`েরিয়েবলটি এখনও বিদ্যমান নেই, আমরা আমাদের ফাইলের শীর্ষে একটি গ্লোবাল ভেরিয়েবল তৈরি করব:
এরপর আমাদের ডেটা কোথাও সংরক্ষণ করতে হবে যাতে আমরা পরে এটি ব্যবহার করে ড্যাশবোর্ডের তথ্য প্রদর্শন করতে পারি। যেহেতু `account`্যারিয়েবলটি এখনও বিদ্যমান নয়, আমরা এটি আমাদের ফাইলের শীর্ষে একটি গ্লোবাল ভ্যারিয়েবল হিসেবে তৈরি করব:
```js
let account = null;
```
ব্যবহারকারীর ডেটা একটি ভরিয়েবলে সংরক্ষণ করার পরে আমরা `navigate()` ফাংশন ব্যবহার করে *লগইন* পেজ থেকে *ড্যাশবোর্ড* এ যেতে পারি।
ব্যবহারকারীর ডেটা একটি ভ্যারিয়েবলে সংরক্ষণ করার পরে, আমরা *লগইন* পেজ থেকে *ড্যাশবোর্ড* এ যেতে পারি আমাদের বিদ্যমান `navigate()` ফাংশন ব্যবহার করে
অবশেষে, আমাদের লগইন ফর্মটি জমা দেওয়া হলে আমাদের `login` ফাংশনটি কল করতে হবে, HTML পরিবর্তন করে:
অবশেষে, আমাদের `login` ফাংশনটি লগইন ফর্ম জমা দেওয়ার সময় কল করতে হবে, HTML পরিবর্তন করে:
```html
<form id="loginForm" action="javascript:login()">
```
একটি নতুন অ্যাকাউন্ট নিবন্ধন করে এবং একই অ্যাকাউন্ট ব্যবহার করে লগইন করার চেষ্টা করে সবকিছু সঠিকভাবে কাজ করছে কিনা পরীক্ষা করুন
একটি নতুন অ্যাকাউন্ট রেজিস্টার করে এবং একই অ্যাকাউন্ট ব্যবহার করে লগইন করার চেষ্টা করে যাচাই করুন যে সবকিছু সঠিকভাবে কাজ করছে।
পরবর্তী অংশে যাওয়ার আগে, আমরা `register` ফাংশনটি সম্পূর্ণ করতে পারি ফাংশনের শেষে এটি যোগ করে:
@ -118,25 +118,25 @@ account = result;
navigate('/dashboard');
```
✅ আপনি কি জানেন যে ডিফল্টভাবে, আপনি শুধুমাত্র *একই ডোমেইন এবং পোর্ট* থেকে সার্ভার API কল করতে পারেন যা আপনি দেখছেন? এটি ব্রাউজার দ্বারা প্রয়োগ করা একটি নিরাপত্তা ব্যবস্থা। কিন্তু আমাদের ওয়েব অ্যাপ `localhost:3000` এ চলছে, যেখানে সার্ভার API `localhost:5000` চলছে, এটি কীভাবে কাজ করছে? [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS) নাম একটি কৌশল ব্যবহার করে, যদি সার্ভার প্রতিক্রিয়ায় বিশেষ হেডার যোগ করে নির্দিষ্ট ডোমেইনের জন্য ব্যতিক্রম অনুমতি দেয়, তাহলে ক্রস-অরিজিন HTTP অনুরোধ করা সম্ভব।
✅ আপনি কি জানেন যে ডিফল্টভাবে, আপনি কেবলমাত্র *একই ডোমেইন এবং পোর্ট* থেকে সার্ভার API কল করতে পারেন যেখন থেকে আপনি ওয়েব পেজটি দেখছেন? এটি ব্রাউজার দ্বারা প্রয়োগ করা একটি নিরাপত্তা ব্যবস্থা। কিন্তু আমাদের ওয়েব অ্যাপ `localhost:3000` এ চলছে, যেখানে সার্ভার API চলছে `localhost:5000` এ, এটি কীভাবে কাজ করছে? [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS) নাম একটি কৌশল ব্যবহার করে, যদি সার্ভার প্রতিক্রিয়ায় নির্দিষ্ট ডোমেইনের জন্য বিশেষ হেডার যোগ করে, তাহলে ক্রস-অরিজিন HTTP রিকোয়েস্ট করা সম্ভব।
> API সম্পর্কে আরও জানুন এই [পাঠটি](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon) নিয়ে।
## HTML আপডেট করে ডেটা প্রদর্শন
এখন আমাদের কাছে ব্যবহারকারীর ডেটা রয়েছে, আমাদের বিদ্যমান HTML আপডেট করতে হবে এটি প্রদর্শন করার জন্য। আমরা ইতিমধ্যে জানি কীভাবে DOM থেকে একটি এলিমেন্ট সংগ্রহ করতে হয়, উদাহরণস্বরূপ `document.getElementById()` ব্যবহার করে। একটি বেস এলিমেন্ট পাওয়ার পরে, এখানে কিছু API রয়েছে যা আপনি এটি পরিবর্তন করতে বা এর মধ্যে নতুন চাইল্ড এলিমেন্ট যোগ করতে ব্যবহার করতে পারেন:
এখন যেহেতু আমাদের কাছে ব্যবহারকারীর ডেটা রয়েছে, আমাদের বিদ্যমান HTML আপডেট করতে হবে এটি প্রদর্শনর জন্য। আমরা ইতিমধ্যে জানি কীভাবে DOM থেকে একটি এলিমেন্ট আনতে হয়, উদাহরণস্বরূপ `document.getElementById()` ব্যবহার করে। একটি বেস এলিমেন্ট পাওয়ার পরে, এখানে কিছু API রয়েছে যা আপনি এটি পরিবর্তন করতে বা এর সাথে নতুন চাইল্ড এলিমেন্ট যোগ করতে ব্যবহার করতে পারেন:
- [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) প্রপার্টি ব্যবহার করে আপনি একটি এলিমেন্টের টেক্সট পরিবর্তন করতে পারেন। মনে রাখবেন যে এই মানটি পরিবর্তন করলে এলিমেন্টের সমস্ত চাইল্ড (যদি থাকে) সরিয়ে ফেলা হয় এবং প্রদত্ত টেক্সট দিয়ে প্রতিস্থাপিত হয়। সুতরাং, এটি একটি নির্দিষ্ট এলিমেন্টের সমস্ত চাইল্ড সরিয়ে ফেলার জন্য একটি কার্যকর পদ্ধতি, একটি খালি স্ট্রিং `''` বরাদ্দ করে।
- [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) প্রপার্টি ব্যবহার করে আপনি একটি এলিমেন্টের টেক্সট পরিবর্তন করতে পারেন। মনে রাখবেন, এই মানটি পরিবর্তন করলে এলিমেন্টের সমস্ত চাইল্ড (যদি থাকে) সরিয়ে ফেলে এবং এটি প্রদত্ত টেক্সট দিয়ে প্রতিস্থাপন করে। সুতরাং, এটি একটি নির্দিষ্ট এলিমেন্টের সমস্ত চাইল্ড সরানোর জন্য একটি কার্যকর পদ্ধতি, একটি খালি স্ট্রিং `''` বরাদ্দ করে।
- [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) এবং [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append) পদ্ধতি ব্যবহার করে আপনি একটি বা একাধিক নতুন চাইল্ড এলিমেন্ট তৈরি এবং সংযুক্ত করতে পারেন।
- [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) এবং [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append) মেথড ব্যবহার করে আপনি একটি বা একাধিক নতুন চাইল্ড এলিমেন্ট তৈরি এবং সংযুক্ত করতে পারেন।
✅ একটি এলিমেন্টের [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) প্রপার্টি ব্যবহার করে এর HTML বিষয়বস্তু পরিবর্তন করাও সম্ভব, তবে এটি এড়িয়ে যাওয়া উচিত কারণ এটি [ক্রস-সাইট স্ক্রিপ্টিং (XSS)](https://developer.mozilla.org/docs/Glossary/Cross-site_scripting) আক্রমণের জন্য ঝুঁকিপূর্ণ।
✅ একটি এলিমেন্টের [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) প্রপার্টি ব্যবহার করে এর HTML কন্টেন্ট পরিবর্তন করাও সম্ভব, তবে এটি এড়িয়ে চলা উচিত কারণ এটি [ক্রস-সাইট স্ক্রিপ্টিং (XSS)](https://developer.mozilla.org/docs/Glossary/Cross-site_scripting) আক্রমণের জন্য ঝুঁকিপূর্ণ।
### কাজ
ড্যাশবোর্ড স্ক্রিনে যাওয়ার আগে, *লগইন* পেজে আমাদের একটি কাজ করতে হবে। বর্তমানে, আপনি যদি এমন একটি ব্যবহারকারীর নাম দিয়ে লগইন করার চেষ্টা করেন যা বিদ্যমান নয়, একটি বার্তা কনসোলে দেখানো হয়, তবে একজন সাধারণ ব্যবহারকারীর জন্য কিছুই পরিবর্তন হয় না এবং আপনি জানেন না কী ঘটছে।
ড্যাশবোর্ড স্ক্রিনে যাওয়ার আগে, *লগইন* পেজে আমাদের আরেকটি কাজ করা উচিত। বর্তমানে, আপনি যদি এমন একটি ইউজারনেম দিয়ে লগইন করার চেষ্টা করেন যা বিদ্যমান নয়, একটি মেসেজ কনসোলে দেখানো হয়, কিন্তু একজন সাধারণ ব্যবহারকারীর জন্য কিছুই পরিবর্তন হয় না এবং আপনি জানেন না কী ঘটছে।
চলুন লগইন ফর্মে একটি প্লেসহোল্ডার এলিমেন্ট যোগ করি যেখানে প্রয়োজনে একটি ত্রুটি বার্তা প্রদর্শন করা যেতে পারে। একটি ভালো জায়গা হে লগইন `<button>` এর ঠিক আগে:
চলুন লগইন ফর্মে একটি প্লেসহোল্ডার এলিমেন্ট যোগ করি যেখানে প্রয়োজনে একটি ত্রুটি বার্তা প্রদর্শন করা যেতে পারে। একটি ভালো জায়গা হতে পারে লগইন `<button>` এর ঠিক আগে:
```html
...
@ -145,7 +145,7 @@ navigate('/dashboard');
...
```
এই `<div>` এলিমেন্টটি খালি, যার অর্থ স্ক্রিনে কিছুই প্রদর্শিত হবে না যতক্ষণ না আমরা এতে কিছু বিষয়বস্তু যোগ করি। আমরা এটিকে একটি `id` দিই যাতে আমরা এটি সহজেই জাভাস্ক্রিপ্ট দিয়ে সংগ্রহ করতে পারি
এই `<div>` এলিমেন্টটি খালি, যার মানে স্ক্রিনে কিছুই প্রদর্শিত হবে না যতক্ষণ না আমরা এতে কিছু কন্টেন্ট যোগ করি। আমরা এটিকে একটি `id` দিই যাতে এটি সহজেই জাভাস্ক্রিপ্ট দিয়ে আনা যায়
`app.js` ফাইলে ফিরে যান এবং একটি নতুন হেল্পার ফাংশন `updateElement` তৈরি করুন:
@ -156,7 +156,7 @@ function updateElement(id, text) {
}
```
এই ফাংশনটি বেশ সহজ: একটি এলিমেন্ট *id* এবং *text* দেওয়া হলে, এটি মিলে যাওয়া `id` সহ DOM এলিমেন্টের টেক্সট বিষয়বস্তু আপডেট করবে। চলুন এই পদ্ধতিটি আগের ত্রুটি বার্তার পরিবর্ত`login` ফাংশনে ব্যবহার করি:
এই ফাংশনটি বেশ সহজ: একটি এলিমেন্ট *id* এবং *text* দেওয়া হলে, এটি মিলে যাওয়া `id` সহ DOM এলিমেন্টের টেক্সট কন্টেন্ট আপডেট করবে। চলুন এই পদ্ধতিটি `login` ফাংশনে আগের ত্রুটি বার্তার পরিবর্তে ব্যবহার করি:
```js
if (data.error) {
@ -166,9 +166,9 @@ if (data.error) {
এখন আপনি যদি একটি অবৈধ অ্যাকাউন্ট দিয়ে লগইন করার চেষ্টা করেন, আপনি এরকম কিছু দেখতে পাবেন:
![লগইন চলাকালীন প্রদর্শিত ত্রুটি বার্তা দেখানো স্ক্রিনশট](../../../../translated_images/login-error.416fe019b36a63276764c2349df5d99e04ebda54fefe60c715ee87a28d5d4ad0.bn.png)
![লগইনের সময় ত্রুটির বার্তা প্রদর্শন করা হচ্ছে এমন স্ক্রিনশট](../../../../translated_images/login-error.416fe019b36a63276764c2349df5d99e04ebda54fefe60c715ee87a28d5d4ad0.bn.png)
এখন আমাদের একটি ত্রুটি টেক্সট রয়েছে যা দৃশ্যমানভাবে প্রদর্শিত হয়, তবে আপনি যদি এটি একটি স্ক্রিন রিডার দিয়ে চেষ্টা করেন, আপনি লক্ষ্য করবেন যে কিছুই ঘোষণা করা হয় না। একটি পেজে গতিশীলভাবে যোগ করা টেক্সট স্ক্রিন রিডার দ্বারা ঘোষণা করার জন্য, এটি একটি [লাইভ রিজিয়ন](https://developer.mozilla.org/docs/Web/Accessibility/ARIA/ARIA_Live_Regions) ব্যবহার করতে হবে। এখানে আমরা একটি নির্দিষ্ট ধরনের লাইভ রিজিয়ন ব্যবহার করব যাকে একটি লার্ট বলা হয়:
এখন আমাদের কাছে একটি ত্রুটির টেক্সট রয়েছে যা ভিজ্যুয়ালি প্রদর্শিত হয়, কিন্তু আপনি যদি এটি একটি স্ক্রিন রিডার দিয়ে চেষ্টা করেন, আপনি লক্ষ্য করবেন যে কিছুই ঘোষণা করা হয় না। একটি পৃষ্ঠায় গতিশীলভাবে যোগ করা টেক্সট স্ক্রিন রিডার দ্বারা ঘোষণা করার জন্য, এটি একটি [লাইভ রিজিয়ন](https://developer.mozilla.org/docs/Web/Accessibility/ARIA/ARIA_Live_Regions) ব্যবহার করতে হবে। এখানে আমরা একটি নির্দিষ্ট ধরনের লাইভ রিজিয়ন ব্যবহার করব যাকে একটি অ্যালার্ট বলা হয়:
```html
<div id="loginError" role="alert"></div>
@ -178,7 +178,7 @@ if (data.error) {
## ড্যাশবোর্ডে তথ্য প্রদর্শন
আমরা যে কৌশলগুলি দেখেছি সেগুলি ব্যবহার করে, আমরা ড্যাশবোর্ড পেজে অ্যাকাউন্ট তথ্য প্রদর্শন করার দায়িত্বও নেব।
আমরা যে কৌশলগুলি দেখেছি সেগুলি ব্যবহার করে, আমরা ড্যাশবোর্ড পেজে অ্যাকাউন্টের তথ্য প্রদর্শনের কাজও করব।
এটি একটি অ্যাকাউন্ট অবজেক্ট যা সার্ভার থেকে প্রাপ্ত হয়:
@ -196,7 +196,7 @@ if (data.error) {
}
```
> নোট: আপনার কাজ সহজ করতে, আপনি পূর্ব-বিদ্যমান `test` অ্যাকাউন্ট ব্যবহার করতে পারেন যা ইতিমধ্যে ডেটা দিয়ে পূর্ণ।
> নোট: আপনার কাজ সহজ করতে, আপনি পূর্ববিদ্যমান `test` অ্যাকাউন্ট ব্যবহার করতে পারেন যা ইতিমধ্যে ডেটা দিয়ে পূর্ণ।
### কাজ
@ -208,15 +208,15 @@ if (data.error) {
</section>
```
আমরা অ্যাকাউন্টের বিবরণ প্রদর্শনের জন্য এর ঠিক নিচে একটি নতুন সেকশন যোগ করব:
আমরা ড্যাশবোর্ড টেমপ্লেটের নিচে একটি নতুন সেকশন যোগ করব অ্যাকাউন্টের বিবরণ প্রদর্শনের জন্য:
```html
<h2 id="description"></h2>
```
✅ যেহেতু অ্যাকাউন্টের বিবরণ এর নিচের বিষয়বস্তুর জন্য একটি শিরোনাম হিসেবে কাজ করে, এটি সেমান্টিকভাবে একটি হেডিং হিসেবে চিহ্নিত করা হয়েছে। [হেডিং স্ট্রাকচার](https://www.nomensa.com/blog/2017/how-structure-headings-web-accessibility) কেন গুরুত্বপূর্ণ তা সম্পর্কে আরও জানুন এবং পেজটি সমালোচনামূলকভাবে দেখুন এটি নির্ধারণ করতে যে আর কী কী হেডিং হতে পারে।
✅ যেহেতু অ্যাকাউন্টের বিবরণ এর নিচের কন্টেন্টের জন্য একটি শিরোনাম হিসেবে কাজ করে, এটি শিরোনাম হিসেবে সেমান্টিকভাবে মার্কআপ করা হয়েছে। [শিরোনাম কাঠামো](https://www.nomensa.com/blog/2017/how-structure-headings-web-accessibility) কেন অ্যাক্সেসিবিলিটির জন্য গুরুত্বপূর্ণ তা জানুন এবং পৃষ্ঠাটি সমালোচনামূলকভাবে দেখুন অন্য কী কী শিরোনাম হতে পারে তা নির্ধারণ করতে।
এরপর, আমরা `app.js` এ একটি নতুন ফাংশন তৈরি করব প্লেসহোল্ডার পূরণ করতে:
এরপর, আমরা `app.js`-এ একটি নতুন ফাংশন তৈরি করব প্লেসহোল্ডার পূরণের জন্য:
```js
function updateDashboard() {
@ -230,11 +230,11 @@ function updateDashboard() {
}
```
প্রথমে, আমরা যাচাই করি যে আমাদের প্রয়োজনীয় অ্যাকাউন্ট ডেটা রয়েছে কিনা। তারপর আমরা পূর্বে তৈরি করা `updateElement()` ফাংশন ব্যবহার করে HTML আপডেট করি।
প্রথমে, আমরা যাচাই করি যে আমাদের প্রয়োজনীয় অ্যাকাউন্ট ডেটা ছে কিনা। তারপর আমরা পূর্বে তৈরি করা `updateElement()` ফাংশন ব্যবহার করে HTML আপডেট করি।
> ব্যালেন্স প্রদর্শনকে আরও সুন্দর করতে, আমরা [`toFixed(2)`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) পদ্ধতি ব্যবহার করি যা মানটি দশমিক বিন্দুর পরে ২ ডিজিট সহ প্রদর্শন করতে বাধ্য করে।
> ব্যালেন্স প্রদর্শন আরও সুন্দর করতে, আমরা [`toFixed(2)`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) মেথড ব্যবহার করি যা মানটি দশমিকের পরে ২ ডিজিট সহ প্রদর্শন করতে বাধ্য করে।
এখন আমাদের `updateDashboard()` ফাংশনটি প্রতিবার ড্যাশবোর্ড লোড হলে কল করতে হবে। আপনি যদি ইতিমধ্যে [পাঠ ১ এর অ্যাসাইনমেন্ট](../1-template-route/assignment.md) শেষ করে থাকেন তবে এটি সহজ হওয়া উচিত, অন্যথায় আপনি নিম্নলিখিত বাস্তবায়ন ব্যবহার করতে পারেন।
এখন আমাদের `updateDashboard()` ফাংশনটি প্রতিবার ড্যাশবোর্ড লোড হওয়ার সময় কল করতে হবে। আপনি যদি ইতিমধ্যে [পাঠ ১ এর অ্যাসাইনমেন্ট](../1-template-route/assignment.md) শেষ করে থাকেন তবে এটি সহজ হওয়া উচিত, অন্যথায় আপনি নিম্নলিখিত বাস্তবায়নটি ব্যবহার করতে পারেন।
`updateRoute()` ফাংশনের শেষে এই কোডটি যোগ করুন:
@ -244,7 +244,7 @@ if (typeof route.init === 'function') {
}
```
এবং রুট সংজ্ঞা আপডেট করুন:
এবং রুট সংজ্ঞাগুলি আপডেট করুন:
```js
const routes = {
@ -255,15 +255,15 @@ const routes = {
এই পরিবর্তনের সাথে, প্রতিবার ড্যাশবোর্ড পেজ প্রদর্শিত হলে, `updateDashboard()` ফাংশনটি কল করা হয়। লগইনের পরে, আপনি অ্যাকাউন্ট ব্যালেন্স, মুদ্রা এবং বিবরণ দেখতে সক্ষম হওয়া উচিত।
## HTML টেমপ্লেট দিয়ে টেবিল রো ডাইনামিকভাবে তৈরি করুন
## HTML টেমপ্লেট দিয়ে টেবিলের সারি ডায়নামিকভাবে তৈরি করা
[প্রথম পাঠে](../1-template-route/README.md) আমরা HTML টেমপ্লেট ব্যবহার করেছি এবং [`appendChild()`](https://developer.mozilla.org/docs/Web/API/Node/appendChild) পদ্ধতি ব্যবহার করে আমাদের অ্যাপের নেভিগেশন বাস্তবায়ন করেছি। টেমপ্লেটগুলি ছোটও হতে পারে এবং একটি পেজের পুনরাবৃত্ত অংশগুলি ডাইনামিকভাবে পূরণ করতে ব্যবহার করা যেতে পারে।
[প্রথম পাঠে](../1-template-route/README.md) আমরা HTML টেমপ্লেট এবং [`appendChild()`](https://developer.mozilla.org/docs/Web/API/Node/appendChild) মেথড ব্যবহার করে আমাদের অ্যাপের নেভিগেশন বাস্তবায়ন করেছি। টেমপ্লেটগুলি ছোটও হতে পারে এবং একটি পৃষ্ঠার পুনরাবৃত্ত অংশগুলি ডায়নামিকভাবে পূরণ করতে ব্যবহার করা যেতে পারে।
আমরা HTML টেবিলে লেনদেনের তালিকা প্রদর্শন করতে একই পদ্ধতি ব্যবহার করব
আমরা একটি অনুরূপ পদ্ধতি ব্যবহার করব HTML টেবিলে লেনদেনের তালিকা প্রদর্শনের জন্য
### কাজ
HTML `<body>` এ একটি নতুন টেমপ্লেট যোগ করুন:
HTML `<body>`-এ একটি নতুন টেমপ্লেট যোগ করুন:
```html
<template id="transaction">
@ -275,9 +275,9 @@ HTML `<body>` এ একটি নতুন টেমপ্লেট যোগ
</template>
```
এই টেমপ্লেটটি একটি একক টেবিল রো উপস্থাপন করে, যেখানে আমরা পূরণ করতে চাই এমন ৩টি কলাম রয়েছে: একটি লেনদেনের *তারিখ*, *বস্তু* এবং *পরিমাণ*
এই টেমপ্লেটটি একটি একক টেবিল সারি উপস্থাপন করে, যেখানে আমরা পূরণ করতে চাই এমন ৩টি কলাম রয়েছে: একটি লেনদেনের *তারিখ*, *অবজেক্ট* এবং *পরিমাণ*
তারপর, ড্যাশবোর্ড টেমপ্লেটের টেবিলের `<tbody>` এলিমেন্টে এই `id` প্রপার্টি যোগ করুন যাতে এটি জাভাস্ক্রিপ্ট ব্যবহার করে সহজে খুঁজে পাওয়া যায়:
তারপর, টেবিলের `<tbody>` এলিমেন্টে এই `id` প্রপার্টি যোগ করুন যাতে এটি জাভাস্ক্রিপ্ট ব্যবহার করে সহজে খুঁজে পাওয়া যায়:
```html
<tbody id="transactions"></tbody>
@ -297,7 +297,7 @@ function createTransactionRow(transaction) {
}
```
এই ফাংশনটি ঠিক তার নাম অনুসারে কাজ করে: আমরা পূর্বে তৈরি করা টেমপ্লেট ব্যবহার করে একটি নতুন টেবিল রো তৈরি করি এবং লেনদেনের ডেটা ব্যবহার করে এর বিষয়বস্তু পূরণ করি। আমরা এটি আমাদের `updateDashboard()` ফাংশনে ব্যবহার করব টেবিলটি পূরণ করতে:
এই ফাংশনটি তার নাম অনুসারে কাজ করে: আমরা পূর্বে তৈরি করা টেমপ্লেটটি ব্যবহার করে একটি নতুন টেবিল সারি তৈরি করি এবং লেনদেনের ডেটা ব্যবহার করে এর কন্টেন্ট পূরণ করি। আমরা এটি আমাদের `updateDashboard()` ফাংশনে ব্যবহার করব টেবিলটি পূরণ করতে:
```js
const transactionsRows = document.createDocumentFragment();
@ -308,28 +308,30 @@ for (const transaction of account.transactions) {
updateElement('transactions', transactionsRows);
```
এখানে আমরা [`document.createDocumentFragment()`](https://developer.mozilla.org/docs/Web/API/Document/createDocumentFragment) পদ্ধতি ব্যবহার করি যা একটি নতুন DOM ফ্রাগমেন্ট তৈরি করে যার উপর আমরা কাজ করতে পারি, অবশেষে এটি আমাদের HTML টেবিলে সংযুক্ত করার আগে
এখানে আমরা [`document.createDocumentFragment()`](https://developer.mozilla.org/docs/Web/API/Document/createDocumentFragment) মেথড ব্যবহার করি যা একটি নতুন DOM ফ্র্যাগমেন্ট তৈরি করে, যার উপর আমরা কাজ করতে পারি এবং অবশেষে এটি আমাদের HTML টেবিলে সংযুক্ত করি
এই কোডটি কাজ করার আগে আমাদের এখনও একটি কাজ করতে হবে, কারণ আমাদের `updateElement()` ফাংশন বর্তমানে শুধুমাত্র টেক্সট বিষয়বস্তু সমর্থন করে
এই কোডটি কাজ করার আগে আমাদের আরেকটি কাজ করতে হবে, কারণ আমাদের `updateElement()`
যদি আপনি `test` অ্যাকাউন্ট ব্যবহার করে লগইন করেন, তাহলে এখন ড্যাশবোর্ডে একটি লেনদেন তালিকা দেখতে পাবেন 🎉।
---
## 🚀 চ্যালেঞ্জ
একসাথে কাজ করে ড্যাশবোর্ড পেজটিকে একটি বাস্তব ব্যাংকিং অ্যাপের মতো দেখানোর চেষ্টা করুন। যদি আপনি ইতিমধ্যেই আপনার অ্যাপটি স্টাইল করে থাকেন, তাহলে [মিডিয়া কোয়েরি](https://developer.mozilla.org/docs/Web/CSS/Media_Queries) ব্যবহার করে [রেসপন্সিভ ডিজাইন](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks) তৈরি করার চেষ্টা করুন, যা ডেস্কটপ এবং মোবাইল ডিভাইসে সুন্দরভাবে কাজ করবে।
একসাথে কাজ করে ড্যাশবোর্ড পেজটিকে একটি বাস্তব ব্যাংকিং অ্যাপের মতো দেখানোর চেষ্টা করুন। যদি আপনি ইতিমধ্যেই আপনার অ্যাপটি স্টাইল করেছেন, তাহলে [মিডিয়া কুয়েরি](https://developer.mozilla.org/docs/Web/CSS/Media_Queries) ব্যবহার করে একটি [রেসপন্সিভ ডিজাইন](https://developer.mozilla.org/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks) তৈরি করার চেষ্টা করুন, যা ডেস্কটপ এবং মোবাইল ডিভাইসে সুন্দরভাবে কাজ করবে।
এখানে একটি স্টাইল করা ড্যাশবোর্ড পেজের উদাহরণ দেওয়া হলো:
এখানে একটি স্টাইল করা ড্যাশবোর্ড পেজের উদাহরণ দেওয়া হয়েছে:
![ড্যাশবোর্ড স্টাইল করার পরের উদাহরণের স্ক্রিনশট](../../../../translated_images/screen2.123c82a831a1d14ab2061994be2fa5de9cec1ce651047217d326d4773a6348e4.bn.png)
![স্টাইল করার পর ড্যাশবোর্ডের একটি উদাহরণ ফলাফলের স্ক্রিনশট](../../../../translated_images/screen2.123c82a831a1d14ab2061994be2fa5de9cec1ce651047217d326d4773a6348e4.bn.png)
## লেকচার-পরবর্তী কুইজ
## পোস্ট-লেকচার কুইজ
[লেকচার-পরবর্তী কুইজ](https://ff-quizzes.netlify.app/web/quiz/46)
[পোস্ট-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/46)
## অ্যাসাইনমেন্ট
[আপনার কোড পুনর্গঠন এবং মন্তব্য যোগ করুন](assignment.md)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতা নিশ্চিত করার চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিক অনুবাদ প্রদানের চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "4fa20c513e367e9cdd401bf49ae16e33",
"translation_date": "2025-08-26T00:42:59+00:00",
"original_hash": "5d2efabbc8f94d89f4317ee8646c3ce9",
"translation_date": "2025-08-28T22:53:36+00:00",
"source_file": "7-bank-project/4-state-management/README.md",
"language_code": "bn"
}
@ -15,15 +15,15 @@ CO_OP_TRANSLATOR_METADATA:
### ভূমিকা
যখন একটি ওয়েব অ্যাপ্লিকেশন বড় হয়, তখন সমস্ত ডেটা প্রবাহ ট্র্যাক করা একটি চ্যালেঞ্জ হয়ে দাঁড়ায়। কোন কোড ডেটা পায়, কোন পৃষ্ঠা এটি ব্যবহার করে, কোথায় এবং কখন এটি আপডেট করতে হবে...এটি সহজেই জটিল কোডে পরিণত হতে পারে যা রক্ষণাবেক্ষণ করা কঠিন। এটি বিশেষভাবে সত্য যখন আপনার অ্যাপের বিভিন্ন পৃষ্ঠার মধ্যে ডেটা শেয়ার করতে হয়, যেমন ব্যবহারকারীর তথ্য। *স্টেট ম্যানেজমেন্ট* ধারণাটি সব ধরনের প্রোগ্রামে সবসময়ই বিদ্যমান ছিল, কিন্তু ওয়েব অ্যাপগুলো ক্রমাগত জটিল হয়ে উঠছে, এটি এখন উন্নয়নের সময় একটি গুরুত্বপূর্ণ বিষয় হয়ে উঠেছে।
যখন একটি ওয়েব অ্যাপ্লিকেশন বড় হয়, তখন সমস্ত ডেটা প্রবাহ ট্র্যাক করা একটি চ্যালেঞ্জ হয়ে দাঁড়ায়। কোন কোড ডেটা পায়, কোন পৃষ্ঠা এটি ব্যবহার করে, কোথায় এবং কখন এটি আপডেট করতে হবে...এটি সহজেই জটিল কোডে পরিণত হতে পারে যা রক্ষণাবেক্ষণ করা কঠিন। এটি বিশেষভাবে সত্য যখন আপনার অ্যাপের বিভিন্ন পৃষ্ঠার মধ্যে ডেটা শেয়ার করতে হয়, যেমন ব্যবহারকারীর তথ্য। *স্টেট ম্যানেজমেন্ট* ধারণাটি সব ধরনের প্রোগ্রামে সবসময়ই বিদ্যমান ছিল, কিন্তু ওয়েব অ্যাপগুলো ক্রমাগত জটিল হয়ে উঠার সাথে সাথে এটি এখন উন্নয়নের সময় একটি গুরুত্বপূর্ণ বিষয় হয়ে উঠেছে।
এই চূড়ান্ত অংশে, আমরা আমাদের তৈরি করা অ্যাপটি পুনর্বিবেচনা করব কিভাবে স্টেট পরিচালিত হয়, ব্রাউজার রিফ্রেশের জন্য যেকোনো সময় সমর্থন প্রদান করে এবং ব্যবহারকারীর সেশনের মধ্যে ডেটা সংরক্ষণ করে।
### পূর্বশর্ত
এই পাঠের জন্য আপনাকে ওয়েব অ্যাপের [ডেটা ফেচিং](../3-data/README.md) অংশ সম্পন্ন করতে হবে। আপনাকে [Node.js](https://nodejs.org) ইনস্টল করতে হবে এবং [সার্ভার API চালাতে হবে](../api/README.md) স্থানীয়ভাবে যাতে আপনি অ্যাকাউন্ট ডেটা পরিচালনা করতে পারেন।
এই পাঠের জন্য আপনাকে ওয়েব অ্যাপের [ডেটা ফেচিং](../3-data/README.md) অংশ সম্পন্ন করতে হবে। আপনাকে [Node.js](https://nodejs.org) ইনস্টল করতে হবে এবং [সার্ভার API চালাতে হবে](../api/README.md) লোকালভাবে যাতে আপনি অ্যাকাউন্ট ডেটা পরিচালনা করতে পারেন।
আপনি টার্মিনালে এই কমান্ডটি চালিয়ে পরীক্ষা করতে পারেন যে সার্ভারটি সঠিকভাবে চলছে কিনা:
আপনি টার্মিনালে এই কমান্ডটি চালিয়ে নিশ্চিত করতে পারেন যে সার্ভার সঠিকভাবে চলছে:
```sh
curl http://localhost:5000/api
@ -34,30 +34,30 @@ curl http://localhost:5000/api
## স্টেট ম্যানেজমেন্ট পুনর্বিবেচনা করুন
[পূর্ববর্তী পাঠে](../3-data/README.md), আমরা আমাদের অ্যাপে একটি মৌলিক স্টেট ধারণা প্রবর্তন করেছি `account` নামক একটি গ্লোবাল ভেরিয়েবল দিয়ে, যা বর্তমানে লগ ইন করা ব্যবহারকারীর ব্যাংক ডেটা ধারণ করে। তবে, আমাদের বর্তমান বাস্তবায়নে কিছু ত্রুটি রয়েছে। ড্যাশবোর্ডে থাকাকালীন পৃষ্ঠাটি রিফ্রেশ করার চেষ্টা করুন। কী ঘটে?
[পূর্ববর্তী পাঠে](../3-data/README.md), আমরা আমাদের অ্যাপে একটি মৌলিক স্টেট ধারণা প্রবর্তন করেছি `account` গ্লোবাল ভেরিয়েবল দিয়ে, যা বর্তমানে লগ ইন করা ব্যবহারকারীর ব্যাংক ডেটা ধারণ করে। তবে, আমাদের বর্তমান বাস্তবায়নে কিছু ত্রুটি রয়েছে। ড্যাশবোর্ডে থাকাকালীন পৃষ্ঠা রিফ্রেশ করার চেষ্টা করুন। কী ঘটে?
বর্তমান কোডে তিনটি সমস্যা রয়েছে:
- স্টেট সংরক্ষিত নয়, কারণ ব্রাউজার রিফ্রেশ আপনাকে লগইন পৃষ্ঠায় ফিরিয়ে নিয়ে যায়।
- স্টেট পরিবর্তন করার জন্য একাধিক ফাংশন রয়েছে। অ্যাপটি বড় হলে এটি পরিবর্তনগুলো ট্র্যাক করা কঠিন করে তুলতে পারে এবং একটি আপডেট করতে ভুলে যাওয়া সহজ।
- স্টেট পরিষ্কার করা হয় না, তাই যখন আপনি *লগআউট* ক্লিক করেন তখন অ্যাকাউন্ট ডেটা এখনও সেখানে থাকে যদিও আপনি লগইন পৃষ্ঠায় রয়েছেন।
- স্টেট পরিবর্তন করার জন্য একাধিক ফাংশন রয়েছে। অ্যাপটি বড় হলে এটি পরিবর্তনগুলো ট্র্যাক করা কঠিন করে তুলতে পারে এবং একটি আপডেট করতে ভুলওয়া সহজ।
- স্টেট পরিষ্কার করা হয় না, তাই যখন আপনি *লগআউট* ক্লিক করেন তখন অ্যাকাউন্ট ডেটা এখনও থাকে যদিও আপনি লগইন পৃষ্ঠায় রয়েছেন।
আমরা একে একে এই সমস্যাগুলো মোকাবেলা করার জন্য আমাদের কোড আপডেট করতে পারি, তবে এটি আরও কোড ডুপ্লিকেশন তৈরি করবে এবং অ্যাপটিকে আরও জটিল এবং রক্ষণাবেক্ষণ করা কঠিন করে তুলবে। অথবা আমরা কয়েক মিনিটের জন্য বিরতি নিতে পারি এবং আমাদের কৌশল পুনর্বিবেচনা করতে পারি।
আমরা এই সমস্যাগুলো একে একে সমাধান করতে আমাদের কোড আপডেট করতে পারি, তবে এটি আরও কোড ডুপ্লিকেশন তৈরি করবে এবং অ্যাপটিকে আরও জটিল এবং রক্ষণাবেক্ষণ করা কঠিন করে তুলবে। অথবা আমরা কয়েক মিনিটের জন্য বিরতি নিতে পারি এবং আমাদের কৌশল পুনর্বিবেচনা করতে পারি।
> আমরা এখানে আসলে কোন সমস্যাগুলো সমাধান করার চেষ্টা করছি?
[স্টেট ম্যানেজমেন্ট](https://en.wikipedia.org/wiki/State_management) হলো এই দুটি নির্দিষ্ট সমস্যার সমাধানের জন্য একটি ভালো পদ্ধতি খুঁজে বের করা:
[স্টেট ম্যানেজমেন্ট](https://en.wikipedia.org/wiki/State_management) হলো এই দুটি নির্দিষ্ট সমস্যার জন্য একটি ভালো পদ্ধতি খুঁজে বের করার বিষয়ে:
- কীভাবে একটি অ্যাপে ডেটা প্রবাহগুলোকে বোধগম্য রাখা যায়?
- কীভাবে স্টেট ডেটাকে সর্বদা ব্যবহারকারীর ইন্টারফেসের সাথে (এবং এর বিপরীতে) সিঙ্কে রাখা যায়?
- কীভাবে একটি অ্যাপে ডেটা প্রবাহগুলোকে বোধগম্য রাখা যায়?
- কীভাবে স্টেট ডেটাকে সবসময় ব্যবহারকারীর ইন্টারফেসের সাথে সিঙ্কে রাখা যায় (এবং এর বিপরীত)?
আপনি যখন এগুলো যত্ন সহকারে পরিচালনা করবেন, তখন আপনার যে কোনো অন্যান্য সমস্যা হয়তো ইতিমধ্যেই সমাধান হয়ে যেতে পারে অথবা সমাধান করা সহজ হয়ে যেতে পারে। এই সমস্যাগুলো সমাধানের জন্য অনেক সম্ভাব্য পদ্ধতি রয়েছে, তবে আমরা একটি সাধারণ সমাধান গ্রহণ করব যা **ডেটা এবং এটি পরিবর্তনের উপায়গুলোকে কেন্দ্রীভূত করার** ধারণার উপর ভিত্তি করে। ডেটা প্রবাহগুলো এইভাবে চলবে:
আপনি যখন এগুলো যত্ন সহকারে পরিচালনা করবেন, তখন আপনার যে কোনো অন্যান্য সমস্যা হয়তো ইতিমধ্যেই সমাধান হয়ে যাবে বা সমাধান করা সহজ হয়ে যাবে। এই সমস্যাগুলো সমাধানের জন্য অনেক সম্ভাব্য পদ্ধতি রয়েছে, তবে আমরা একটি সাধারণ সমাধান গ্রহণ করব যা **ডেটা এবং এটি পরিবর্তনের উপায়গুলো কেন্দ্রীভূত করার** ধারণা নিয়ে কাজ করে। ডেটা প্রবাহগুলো এইভাবে চলবে:
![HTML, ব্যবহারকারীর ক্রিয়া এবং স্টেটের মধ্যে ডেটা প্রবাহ দেখানো স্কিমা](../../../../translated_images/data-flow.fa2354e0908fecc89b488010dedf4871418a992edffa17e73441d257add18da4.bn.png)
![HTML, ব্যবহারকারীর ক্রিয়া এবং স্টেটের মধ্যে ডেটা প্রবাহের স্কিমা](../../../../translated_images/data-flow.fa2354e0908fecc89b488010dedf4871418a992edffa17e73441d257add18da4.bn.png)
> আমরা এখানে সেই অংশটি কভার করব না যেখানে ডেটা স্বয়ংক্রিয়ভাবে ভিউ আপডেটকে ট্রিগার করে, কারণ এটি [Reactive Programming](https://en.wikipedia.org/wiki/Reactive_programming)-এর আরও উন্নত ধারণার সাথে সম্পর্কিত। এটি একটি গভীর ডাইভের জন্য একটি ভালো অনুসরণ বিষয়।
✅ স্টেট ম্যানেজমেন্টের জন্য বিভিন্ন পদ্ধতির সাথে অনেক লাইব্রেরি রয়েছে, [Redux](https://redux.js.org) একটি জনপ্রিয় বিকল্প। এর ধারণা এবং প্যাটার্নগুলো দেখুন কারণ এটি প্রায়ই বড় ওয়েব অ্যাপগুলোতে আপনি যে সম্ভাব্য সমস্যাগুলো সম্মুখীন হতে পারেন এবং কীভাবে এটি সমাধান করা যায় তা শেখার একটি ভালো উপায়।
✅ স্টেট ম্যানেজমেন্টের জন্য অনেক লাইব্রেরি রয়েছে, [Redux](https://redux.js.org) একটি জনপ্রিয় অপশন। এর ধারণা এবং প্যাটার্নগুলো দেখুন কারণ এটি প্রায়ই বড় ওয়েব অ্যাপগুলোতে সম্ভাব্য সমস্যাগুলো এবং কীভাবে সেগুলো সমাধান করা যায় তা শেখার একটি ভালো উপায়।
### কাজ
@ -75,7 +75,7 @@ let state = {
};
```
ধারণাটি হলো আমাদের অ্যাপের সমস্ত ডেটাকে একটি একক স্টেট অবজেক্টে *কেন্দ্রীভূত* করা। বর্তমানে স্টেটে শুধুমাত্র `account` রয়েছে, তাই এটি খুব বেশি পরিবর্তন করে না, তবে এটি ভবিষ্যতের জন্য একটি পথ তৈরি করে।
ধারণাটি হলো আমাদের অ্যাপের সমস্ত ডেটাকে একটি একক স্টেট অবজেক্টে *কেন্দ্রীভূত* করা। আমাদের স্টেটে এখন শুধুমাত্র `account` রয়েছে, তাই এটি খুব বেশি পরিবর্তন করে না, তবে এটি ভবিষ্যতের জন্য একটি পথ তৈরি করে।
আমাদের এটি ব্যবহারকারী ফাংশনগুলোও আপডেট করতে হবে। `register()` এবং `login()` ফাংশনে, `account = ...` প্রতিস্থাপন করুন `state.account = ...`;
@ -89,9 +89,9 @@ const account = state.account;
## ডেটা পরিবর্তন ট্র্যাক করুন
এখন আমরা আমাদের ডেটা সংরক্ষণর জন্য `state` অবজেক্টটি স্থাপন করেছি, পরবর্তী ধাপ হলো আপডেটগুলো কেন্দ্রীভূত করা। লক্ষ্য হলো যে কোনো পরিবর্তন এবং কখন তা ঘটে তা ট্র্যাক করা সহজ করা।
এখন আমরা আমাদের ডেটা সংরক্ষণ করার জন্য `state` অবজেক্টটি স্থাপন করেছি, পরবর্তী ধাপ হলো আপডেটগুলো কেন্দ্রীভূত করা। লক্ষ্য হলো যে কোনো পরিবর্তন এবং কখন তা ঘটে তা ট্র্যাক করা সহজ করা।
`state` অবজেক্টে পরিবর্তন করা এড়াতে, এটিকে [*immutable*](https://en.wikipedia.org/wiki/Immutable_object) বিবেচনা করাও একটি ভালো অভ্যাস, যার অর্থ এটি মোটেও পরিবর্তন করা যাবে না। এর অর্থ হলো আপনি যদি এতে কিছু পরিবর্তন করতে চান তবে আপনাকে একটি নতুন স্টেট অবজেক্ট তৈরি করতে হবে। এটি করে, আপনি সম্ভাব্য অনাকাঙ্ক্ষিত [side effects](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) সম্পর্কে একটি সুরক্ষা তৈরি করেন এবং আপনার অ্যাপে নতুন বৈশিষ্ট্য বাস্তবায়নের জন্য সম্ভাবনা খুলে দেন যেমন undo/redo বাস্তবায়ন করা, পাশাপাশি এটি ডিবাগ করা সহজ করে তোলে। উদাহরণস্বরূপ, আপনি স্টেটে করা প্রতিটি পরিবর্তন লগ করতে পারেন এবং একটি বাগের উৎস বুঝতে পরিবর্তনের একটি ইতিহাস রাখতে পারেন।
`state` অবজেক্টে পরিবর্তনগুলো এড়াতে, এটিকে [*immutable*](https://en.wikipedia.org/wiki/Immutable_object) বিবেচনা করাও একটি ভালো অভ্যাস, যার অর্থ এটি মোটেও পরিবর্তন করা যাবে না। এর অর্থ হলো আপনি যদি এতে কিছু পরিবর্তন করতে চান তবে আপনাকে একটি নতুন স্টেট অবজেক্ট তৈরি করতে হবে। এটি করে আপনি সম্ভাব্য অনাকাঙ্ক্ষিত [side effects](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) সম্পর্কে সুরক্ষা তৈরি করেন এবং আপনার অ্যাপে নতুন বৈশিষ্ট্য বাস্তবায়নের জন্য সম্ভাবনা খুলে দেন যেমন undo/redo বাস্তবায়ন করা, পাশাপাশি এটি ডিবাগ করা সহজ করে তোলে। উদাহরণস্বরূপ, আপনি স্টেটে করা প্রতিটি পরিবর্তন লগ করতে পারেন এবং একটি বাগের উৎস বুঝতে পরিবর্তনের ইতিহাস রাখতে পারেন।
জাভাস্ক্রিপ্টে, আপনি [`Object.freeze()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) ব্যবহার করতে পারেন একটি অবজেক্টের অপরিবর্তনীয় সংস্করণ তৈরি করতে। আপনি যদি একটি অপরিবর্তনীয় অবজেক্টে পরিবর্তন করার চেষ্টা করেন, তবে একটি ব্যতিক্রম উত্থাপিত হবে।
@ -110,9 +110,9 @@ function updateState(property, newData) {
}
```
এই ফাংশনে, আমরা একটি নতুন স্টেট অবজেক্ট তৈরি করছি এবং পূর্ববর্তী স্টেট থেকে ডেটা কপি করছি [*spread (`...`) operator*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals) ব্যবহার করে। তারপর আমরা একটি নির্দিষ্ট প্রপার্টি স্টেট অবজেক্টে নতুন ডেটা দিয়ে ওভাররাইড করি [bracket notation](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` ব্যবহার করে। অবশেষে, আমরা `Object.freeze()` ব্যবহার করে অবজেক্টটি লক করি যাতে পরিবর্তন প্রতিরোধ করা যায়। বর্তমানে স্টেটে শুধুমাত্র `account` প্রপার্টি সংরক্ষিত আছে, তবে এই পদ্ধতির মাধ্যমে আপনি স্টেটে যত প্রপার্টি প্রয়োজন যোগ করতে পারেন।
এই ফাংশনে, আমরা একটি নতুন স্টেট অবজেক্ট তৈরি করছি এবং পূর্ববর্তী স্টেট থেকে ডেটা কপি করছি [*spread (`...`) operator*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals) ব্যবহার করে। তারপর আমরা একটি নির্দিষ্ট প্রপার্টি স্টেট অবজেক্টে নতুন ডেটা দিয়ে ওভাররাইড করি [bracket notation](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` ব্যবহার করে। অবশেষে, আমরা `Object.freeze()` ব্যবহার করে অবজেক্টটি লক করি যাতে পরিবর্তনগুলো প্রতিরোধ করা যায়। আমাদের স্টেটে বর্তমানে শুধুমাত্র `account` প্রপার্টি সংরক্ষিত আছে, তবে এই পদ্ধতির মাধ্যমে আপনি স্টেটে যত প্রপার্টি প্রয়োজন যোগ করতে পারেন।
আমরা নিশ্চিত করতে `state` initialization আপডেট করব যাতে প্রাথমিক স্টেটও ফ্রোজেন থাকে:
আমরা নিশ্চিত করতে `state` ইনিশিয়ালাইজেশনও আপডেট করব যাতে প্রাথমিক স্টেটও ফ্রিজ করা হয়:
```js
let state = Object.freeze({
@ -132,7 +132,7 @@ updateState('account', result);
updateState('account', data);
```
আমরা এখন *Logout* ক্লিক করার সময় অ্যাকাউন্ট ডেটা পরিষ্কার না হওয়ার সমস্যাটি সমাধান করার সুযোগ নেব।
আমরা এখন *লগআউট* ক্লিক করার সময় অ্যাকাউন্ট ডেটা পরিষ্কার না হওয়ার সমস্যাটি সমাধান করার সুযোগ নেব।
একটি নতুন `logout()` ফাংশন তৈরি করুন:
@ -145,33 +145,33 @@ function logout() {
`updateDashboard()`-এ, `return navigate('/login');` রিডিরেকশনটি প্রতিস্থাপন করুন `return logout();` দিয়ে;
একটি নতুন অ্যাকাউন্ট নিবন্ধন করুন, লগআউট করুন এবং আবার লগইন করুন এটি এখনও সঠিকভাবে কাজ করছে কিনা তা পরীক্ষা করতে
একটি নতুন অ্যাকাউন্ট রেজিস্টার করার চেষ্টা করুন, লগআউট করুন এবং আবার লগইন করুন যাতে সবকিছু এখনও সঠিকভাবে কাজ করছে কিনা তা পরীক্ষা করা যায়
> টিপ: আপনি ব্রাউজারের ডেভেলপমেন্ট টুলসের কনসোলে `updateState()`-এর নিচে `console.log(state)` যোগ করে সমস্ত স্টেট পরিবর্তন দেখতে পারেন।
## স্টেট সংরক্ষণ করুন
বেশিরভাগ ওয়েব অ্যাপ সঠিকভাবে কাজ করতে ডেটা সংরক্ষণ করতে হয়। সমস্ত গুরুত্বপূর্ণ ডেটা সাধারণত একটি ডাটাবেসে সংরক্ষণ করা হয় এবং একটি সার্ভার API এর মাধ্যমে অ্যাক্সেস করা হয়, যেমন আমাদের ক্ষেত্রে ব্যবহারকারীর অ্যাকাউন্ট ডেটা। তবে কখনও কখনও, ব্রাউজারে চলমান ক্লায়েন্ট অ্যাপে কিছু ডেটা সংরক্ষণ করাও আকর্ষণীয় হতে পারে, একটি ভালো ব্যবহারকারীর অভিজ্ঞতার জন্য বা লোডিং পারফরম্যান্স উন্নত করতে
বেশিরভাগ ওয়েব অ্যাপ সঠিকভাবে কাজ করতে ডেটা সংরক্ষণ করতে হয়। সমস্ত গুরুত্বপূর্ণ ডেটা সাধারণত একটি ডাটাবেসে সংরক্ষণ করা হয় এবং একটি সার্ভার API এর মাধ্যমে অ্যাক্সেস করা হয়, যেমন আমাদের ক্ষেত্রে ব্যবহারকারীর অ্যাকাউন্ট ডেটা। তবে কখনও কখনও, ব্রাউজারে চলমান ক্লায়েন্ট অ্যাপে কিছু ডেটা সংরক্ষণ করাও আকর্ষণীয় হতে পারে, একটি ভালো ব্যবহারকারীর অভিজ্ঞতা বা লোডিং পারফরম্যান্স উন্নত করার জন্য
যখন আপনি আপনার ব্রাউজারে ডেটা সংরক্ষণ করতে চান, তখন কয়েকটি গুরুত্বপূর্ণ প্রশ্ন জিজ্ঞাসা করা উচিত:
- *ডেটা কি সংবেদনশীল?* আপনি ক্লায়েন্টে কোনো সংবেদনশীল ডেটা সংরক্ষণ এড়ানো উচিত, যেমন ব্যবহারকারীর পাসওয়ার্ড।
- *আপনার এই ডেটা কতক্ষণ ধরে রাখতে হবে?* আপনি কি এই ডেটা শুধুমাত্র বর্তমান সেশনের জন্য অ্যাক্সেস করার পরিকল্পনা করছেন নাকি আপনি এটি চিরতরে সংরক্ষণ করতে চান?
- *ডেটা কি সংবেদনশীল?* আপনি ক্লায়েন্টে কোনো সংবেদনশীল ডেটা সংরক্ষণ এড়িয়ে চলা উচিত, যেমন ব্যবহারকারীর পাসওয়ার্ড।
- *আপনার এই ডেটা কতক্ষণ ধরে রাখতে হবে?* আপনি কি এই ডেটা শুধুমাত্র বর্তমান সেশনের জন্য অ্যাক্সেস করতে চান নাকি এটি চিরতরে সংরক্ষণ করতে চান?
ওয়েব অ্যাপের ভিতরে তথ্য সংরক্ষণের জন্য বিভিন্ন উপায় রয়েছে, আপনি যা অর্জন করতে চান তার উপর নির্ভর করে। উদাহরণস্বরূপ, আপনি একটি সার্চ কোয়েরি সংরক্ষণ করতে URL ব্যবহার করতে পারেন এবং এটি ব্যবহারকারীদের মধ্যে শেয়ারযোগ্য করতে পারেন। আপনি [HTTP cookies](https://developer.mozilla.org/docs/Web/HTTP/Cookies) ব্যবহার করতে পারেন যদি ডেটা সার্ভারের সাথে শেয়ার করতে হয়, যেমন [authentication](https://en.wikipedia.org/wiki/Authentication) তথ্য।
ওয়েব অ্যাপের ভিতরে তথ্য সংরক্ষণের জন্য বিভিন্ন উপায় রয়েছে, আপনি যা অর্জন করতে চান তার উপর নির্ভর করে। উদাহরণস্বরূপ, আপনি একটি সার্চ কোয়েরি সংরক্ষণ করতে URL ব্যবহার করতে পারেন এবং এটি ব্যবহারকারীদের মধ্যে শেয়ারযোগ্য করতে পারেন। আপনি [HTTP কুকিজ](https://developer.mozilla.org/docs/Web/HTTP/Cookies) ব্যবহার করতে পারেন যদি ডেটা সার্ভারের সাথে শেয়ার করতে হয়, যেমন [authentication](https://en.wikipedia.org/wiki/Authentication) তথ্য।
আরেকটি বিকল্প হলো ডেটা সংরক্ষণের জন্য ব্রাউজারের অনেক API-এর মধ্যে একটি ব্যবহার করা। দুটি বিশেষভাবে আকর্ষণীয়:
আরেকটি অপশন হলো ডেটা সংরক্ষণের জন্য ব্রাউজারের অনেক API এর মধ্যে একটি ব্যবহার করা। দুটি বিশেষভাবে আকর্ষণীয়:
- [`localStorage`](https://developer.mozilla.org/docs/Web/API/Window/localStorage): একটি [Key/Value store](https://en.wikipedia.org/wiki/Key%E2%80%93value_database) যা বিভিন্ন সেশনের মধ্যে নির্দিষ্ট ওয়েব সাইটের ডেটা সংরক্ষণ করতে দেয়। এতে সংরক্ষিত ডেটা কখনোই মেয়াদোত্তীর্ণ হয় না।
- [`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage): এটি `localStorage` এর মতো কাজ করে তবে এতে সংরক্ষিত ডেটা সেশনের শেষে (যখন ব্রাউজার বন্ধ হয়) মুছে ফেলা হয়।
- [`localStorage`](https://developer.mozilla.org/docs/Web/API/Window/localStorage): একটি [Key/Value store](https://en.wikipedia.org/wiki/Key%E2%80%93value_database) যা বিভিন্ন সেশনের মধ্যে বর্তমান ওয়েব সাইটের জন্য নির্দিষ্ট ডেটা সংরক্ষণ করতে দেয়। এতে সংরক্ষিত ডেটা কখনোই মেয়াদোত্তীর্ণ হয় না।
- [`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage): এটি `localStorage` এর মতো কাজ করে তবে এতে সংরক্ষিত ডেটা সেশন শেষ হলে (যখন ব্রাউজার বন্ধ হয়) মুছে ফেলা হয়।
উল্লেখ্য যে এই দুটি API শুধুমাত্র [strings](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) সংরক্ষণ করতে দেয়। আপনি যদি জটিল অবজেক্ট সংরক্ষণ করতে চান, তবে আপনাকে এটি [JSON](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON) ফরম্যাটে সিরিয়ালাইজ করতে হবে [`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) ব্যবহার করে।
✅ আপনি যদি এমন একটি ওয়েব অ্যাপ তৈরি করতে চান যা সার্ভার ছাড়াই কাজ করে, তবে [`IndexedDB` API](https://developer.mozilla.org/docs/Web/API/IndexedDB_API) ব্যবহার করে ক্লায়েন্টে একটি ডাটাবেস তৈরি করাও সম্ভব। এটি উন্নত ব্যবহারের ক্ষেত্রে বা যদি উল্লেখযোগ্য পরিমাণ ডেটা সংরক্ষণ করতে হয়, তবে এটি ব্যবহার করা আরও জটিল।
✅ আপনি যদি একটি ওয়েব অ্যাপ তৈরি করতে চান যা সার্ভার ছাড়াই কাজ করে, তবে এটি [`IndexedDB` API](https://developer.mozilla.org/docs/Web/API/IndexedDB_API) ব্যবহার করে ক্লায়েন্টে একটি ডাটাবেস তৈরি করাও সম্ভব। এটি উন্নত ব্যবহারের ক্ষেত্রে বা যদি আপনি উল্লেখযোগ্য পরিমাণ ডেটা সংরক্ষণ করতে চান তবে সংরক্ষিত, কারণ এটি ব্যবহার করা আরও জটিল।
### কাজ
আমরা চাই আমাদের ব্যবহারকারীরা *Logout* বোতামে স্পষ্টভাবে ক্লিক না করা পর্যন্ত লগ ইন অবস্থায় থাকুক, তাই আমরা `localStorage` ব্যবহার করব অ্যাকাউন্ট ডেটা সংরক্ষণ করতে। প্রথমে, আসুন একটি key সংজ্ঞায়িত করি যা আমরা আমাদের ডেটা সংরক্ষণের জন্য ব্যবহার করব।
আমরা চাই আমাদের ব্যবহারকারীরা *লগআউট* বোতামে স্পষ্টভাবে ক্লিক না করা পর্যন্ত লগ ইন অবস্থায় থাকুক, তাই আমরা `localStorage` ব্যবহার করব অ্যাকাউন্ট ডেটা সংরক্ষণ করতে। প্রথমে, আসুন একটি কী সংজ্ঞায়িত করি যা আমরা আমাদের ডেটা সংরক্ষণের জন্য ব্যবহার করব।
```js
const storageKey = 'savedAccount';
@ -183,9 +183,9 @@ const storageKey = 'savedAccount';
localStorage.setItem(storageKey, JSON.stringify(state.account));
```
এর মাধ্যমে, ব্যবহারকারীর অ্যাকাউন্ট ডেটা সংরক্ষিত থাকবে এবং আমরা পূর্বে কেন্দ্রীভূত করা সমস্ত স্টেট আপডেটের জন্য সর্বদা আপ-টু-ডেট থাকবে। এটি হলো যেখানে আমরা আমাদের পূর্ববর্তী রিফ্যাক্টরগুলো থেকে উপকৃত হতে শুরু করি 🙂।
এর মাধ্যমে, ব্যবহারকারীর অ্যাকাউন্ট ডেটা সংরক্ষিত থাকবে এবং আমরা পূর্বে কেন্দ্রীভূত সমস্ত স্টেট আপডেটের জন্য সর্বদা আপ-টু-ডেট থাকবে। এটি হলো যেখানে আমরা আমাদের পূর্ববর্তী রিফ্যাক্টরগুলো থেকে উপকৃত হতে শুরু করি 🙂।
ডেটা সংরক্ষিত হওয়ার কারণে, অ্যাপটি লোড হওয়ার সময় এটি পুনরুদ্ধার করাও আমাদের যত্ন নিতে হবে। যেহেতু আমরা আরও initialization কোড শুরু করতে যাচ্ছি, এটি একটি নতুন `init` ফাংশন তৈরি করার জন্য একটি ভালো ধারণা হতে পারে, যা `app.js`-এর নিচে আমাদের পূর্ববর্তী কোডও অন্তর্ভুক্ত করে:
ডেটা সংরক্ষিত হওয়ার কারণে, আমাদের অ্যাপ লোড হওয়ার সময় এটি পুনরুদ্ধার করার যত্ন নিতে হবে। যেহেতু আমরা আরও ইনিশিয়ালাইজেশন কোড পেতে শুরু করব, এটি একটি নতুন `init` ফাংশন তৈরি করার জন্য একটি ভালো ধারণা হতে পারে, যা `app.js`-এর নিচে আমাদের পূর্ববর্তী কোডও অন্তর্ভুক্ত করে:
```js
function init() {
@ -202,17 +202,17 @@ function init() {
init();
```
এখানে আমরা সংরক্ষিত ডেটা পুনরুদ্ধার করি, এবং যদি কোনো ডেটা থাকে তবে আমরা স্টেটটি অনুযায়ী আপডেট করি। এটি *route* আপডেট করার *আগে* করা গুরুত্বপূর্ণ, কারণ পৃষ্ঠা আপডেটের সময় স্টেটের উপর নির্ভরশীল কোড থাকতে পারে।
এখানে আমরা সংরক্ষিত ডেটা পুনরুদ্ধার করি, এবং যদি কোনো ডেটা থাকে তবে আমরা স্টেট অনুযায়ী আপডেট করি। এটি *রুট* আপডেট করার *আগে* করা গুরুত্বপূর্ণ, কারণ পৃষ্ঠা আপডেটের সময় স্টেটের উপর নির্ভরশীল কোড থাকতে পারে।
আমরা আমাদের অ্যাপ্লিকেশনের ডিফল্ট পৃষ্ঠা *Dashboard* পৃষ্ঠা করতে পারি, কারণ আমরা এখন অ্যাকাউন্ট ডেটা সংরক্ষণ করছি। যদি কোনো ডেটা না পাওয়া যায়, তাহলে ড্যাশবোর্ড যেকোনোভাবে *Login* পৃষ্ঠায় রিডিরেক্ট করার যত্ন নেয়। `updateRoute()`-এ, `return navigate('/login');` ফallback প্রতিস্থাপন করুন `return navigate('/dashboard');` দিয়ে।
আমরা *ড্যাশবোর্ড* পৃষ্ঠাকে আমাদের অ্যাপ্লিকেশনের ডিফল্ট পৃষ্ঠা করতে পারি, কারণ আমরা এখন অ্যাকাউন্ট ডেটা সংরক্ষণ করছি। যদি কোনো ডেটা পাওয়া না যায়, ড্যাশবোর্ড যেকোনোভাবে *লগইন* পৃষ্ঠায় রিডিরেক্ট করার যত্ন নেয়। `updateRoute()`-এ, `return navigate('/login');` ফallback প্রতিস্থাপন করুন `return navigate('/dashboard');` দিয়ে।
এখন অ্যাপে লগইন করুন এবং পৃষ্ঠাটি রিফ্রেশ করার চেষ্টা করুন। আপনি ড্যাশবোর্ডে থাকা উচিত। এই আপডেটের মাধ্যমে আমরা আমাদের সমস্ত প্রাথমিক সমস্যার যত্ন নিয়েছি...
এখন অ্যাপে লগইন করুন এবং পৃষ্ঠা রিফ্রেশ করার চেষ্টা করুন। আপনি ড্যাশবোর্ডে থাকা উচিত। এই আপডেটের মাধ্যমে আমরা আমাদের সমস্ত প্রাথমিক সমস্যার যত্ন নিয়েছি...
## ডেটা রিফ্রেশ করুন
...কিন্তু আমরা হয়তো একটি নতুন সমস্যা তৈরি করেছি। ওহ!
`test` অ্যাকাউন্ট ব্যবহার করে ড্যাশবোর্ডে যান, তারপর একটি নতুন লেনদেন তৈরি করতে একটি টার্মিনালে এই কমান্ডটি চালান:
`test` অ্যাকাউন্ট ব্যবহার করে ড্যাশবোর্ডে যান, তারপর একটি নতুন লেনদেন তৈরি করতে টার্মিনালে এই কমান্ডটি চালান:
```sh
curl --request POST \
@ -221,11 +221,11 @@ curl --request POST \
http://localhost:5000/api/accounts/test/transactions
```
এখন ব্রাউজারে ড্যাশবোর্ড পৃষ্ঠাটি রিফ্রেশ করার চেষ্টা করুন। কী ঘটে? আপনি কি নতুন লেনদেনটি দেখতে পাচ্ছেন?
এখন ব্রাউজারে ড্যাশবোর্ড পৃষ্ঠা রিফ্রেশ করার চেষ্টা করুন। কী ঘটে? আপনি কি নতুন লেনদেনটি দেখতে পাচ্ছেন?
স্টেটটি `localStorage` এর মাধ্যমে অনির্দিষ্টকালের জন্য সংরক্ষিত থাকে, তবে এর অর্থ হলো এটি কখনোই আপডেট হয় না যতক্ষণ না আপনি অ্যাপ থেকে লগ আউট করেন এবং আবার লগ ইন করেন!
এটি ঠিক করার একটি সম্ভাব্য কৌশল হলো ড্যাশবোর্ড লোড হওয়ার সময় প্রতিবার অ্যাকাউন্ট ডেটা পুনরায় লোড করা, স্থবির ডেটা এড়াতে
এটি ঠিক করার একটি সম্ভাব্য কৌশল হলো ড্যাশবোর্ড লোড হওয়ার প্রতিবার অ্যাকাউন্ট ডেটা পুনরায় লোড করা, স্থবির ডেটা এড়ানোর জন্য
### কাজ
@ -247,7 +247,7 @@ async function updateAccountData() {
}
```
এই পদ্ধতিটি পরীক্ষা করে যে আমরা বর্তমানে লগ ইন অবস্থায় আছি, তারপর সার্ভার থেকে অ্যাকাউন্ট ডেটা পুনরায় লোড করে।
এই মেথডটি পরীক্ষা করে যে আমরা বর্তমানে লগ ইন অবস্থায় আছি, তারপর সার্ভার থেকে অ্যাকাউন্ট ডেটা পুনরায় লোড করে।
`refresh` নামে আরেকটি ফাংশন তৈরি করুন:
@ -258,7 +258,7 @@ async function refresh() {
}
```
এটি অ্যাকাউন্ট ডেটা আপডেট করে, তারপর ড্যাশবোর্ড পৃষ্ঠার HTML আপডেট করার যত্ন নেয়। এটি হলো যা আমরা ড্যাশবোর্ড route লোড করার সময় কল করতে চাই। route সংজ্ঞা আপডেট করুন:
এটি অ্যাকাউন্ট ডেটা আপডেট করে, তারপর ড্যাশবোর্ড পৃষ্ঠার HTML আপডেট করার যত্ন নেয়। এটি হলো যা আমরা ড্যাশবোর্ড রুট লোড হওয়ার সময় কল করতে চাই। রুট সংজ্ঞা আপডেট করুন:
```js
const routes = {
@ -273,20 +273,20 @@ const routes = {
## 🚀 চ্যালেঞ্জ
এখন আমরা প্রতিবার ড্যাশবোর্ড লোড করার সময় অ্যাকাউন্ট ডেটা পুনরায় লোড করি, আপনি কি মনে করেন আমরা এখনও *সমস্ত অ্যাকাউন্ট* ডেটা সংরক্ষণ করতে হবে?
এখন আমরা ড্যাশবোর্ড লোড হওয়ার প্রতিবার অ্যাকাউন্ট ডেটা পুনরায় লোড করি, আপনি কি মনে করেন আমরা এখনও *সমস্ত অ্যাকাউন্ট* ডেটা সংরক্ষণ করতে হবে?
একসাথে কাজ করে `localStorage` থেকে কী সংরক্ষণ করা এবং লোড করা উচিত তা পরিবর্তন করার চেষ্টা করুন যাতে অ্যাপটি কাজ করার জন্য শুধুমাত্র যা একেবারে প্রয়োজন তা অন্তর্ভুক্ত থাকে
একসাথে কাজ করার চষ্টা করুন `localStorage` থেকে কী সংরক্ষণ এবং লোড করা হয় তা পরিবর্তন করতে যাতে অ্যাপটি কাজ করার জন্য শুধুমাত্র যা একেবারে প্রয়োজন তা অন্তর্ভুক্ত করা হয়
## পোস্ট-লেকচার কুইজ
[পোস্ট-লেকচার কুইজ](https://ff-quizzes.netlify.app/web/quiz/48)
## অ্যাসাইনমেন্ট
[পোস্ট-লেকচার কুইজ](https://ff-quizzes.netlify.app/web
[লেনদেন যোগ করার ডায়ালগ বাস্তবায়ন করুন](assignment.md)
["Add transaction" ডায়ালগ বাস্তবায়ন করুন](assignment.md)
এখানে একটি উদাহরণ ফলাফল রয়েছে যা অ্যাসাইনমেন্ট সম্পন্ন করার পরে দেখা যাবে:
অ্যাসাইনমেন্ট সম্পন্ন করার পর একটি উদাহরণ ফলাফল এখানে দেওয়া হলো:
![স্ক্রিনশট যেখানে "লেনদেন যোগ করুন" ডায়ালগের একটি উদাহরণ দেখানো হয়েছে](../../../../translated_images/dialog.93bba104afeb79f12f65ebf8f521c5d64e179c40b791c49c242cf15f7e7fab15.bn.png)
!["Add transaction" ডায়ালগের একটি উদাহরণ স্ক্রিনশট](../../../../translated_images/dialog.93bba104afeb79f12f65ebf8f521c5d64e179c40b791c49c242cf15f7e7fab15.bn.png)
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতা নিশ্চিত করার চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।

@ -1,23 +1,23 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "7aa6e4f270d38d9cb17f2b5bd86b863d",
"translation_date": "2025-08-25T23:17:03+00:00",
"original_hash": "1ba61d96a11309a2a6ea507496dcf7e5",
"translation_date": "2025-08-28T23:04:54+00:00",
"source_file": "8-code-editor/1-using-a-code-editor/README.md",
"language_code": "bn"
}
-->
# কোড এডিটর ব্যবহার করা
এই পাঠে [VSCode.dev](https://vscode.dev) নামক একটি ওয়েব-ভিত্তিক কোড এডিটর ব্যবহারের মৌলিক বিষয়গুলো আলোচনা করা হয়েছে, যাতে আপনি আপনার কোডে পরিবর্তন আনতে এবং কোনো প্রকল্পে অবদান রাখতে পারেন, আপনার কম্পিউটারে কিছু ইনস্টল না করেই।
এই পাঠে [VSCode.dev](https://vscode.dev) নামক একটি ওয়েব-ভিত্তিক কোড এডিটর ব্যবহারের মৌলিক বিষয়গুলো আলোচনা করা হয়েছে, যাতে আপনি আপনার কোডে পরিবর্তন আনতে এবং কোনো প্রজেক্টে অবদান রাখতে পারেন, আপনার কম্পিউটারে কিছু ইনস্টল না করেই।
## শেখার লক্ষ্যসমূহ
এই পাঠে আপনি শিখবেন কীভাবে:
এই পাঠে আপনি শিখবেন:
- কোড প্রকল্পে একটি কোড এডিটর ব্যবহার করবেন
- ভার্সন কন্ট্রোলের মাধ্যমে পরিবর্তনগুলো ট্র্যাক করবেন
- ডেভেলপমেন্টের জন্য এডিটর কাস্টমাইজ করবেন
- কোড প্রজেক্টে কোড এডিটর ব্যবহার করা
- ভার্সন কন্ট্রোলের মাধ্যমে পরিবর্তনগুলো ট্র্যাক কর
- ডেভেলপমেন্টের জন্য এডিটর কাস্টমাইজ কর
### পূর্বশর্ত
@ -25,11 +25,11 @@ CO_OP_TRANSLATOR_METADATA:
### ভূমিকা
কোড এডিটর হলো প্রোগ্রাম লেখার এবং বিদ্যমান কোডিং প্রকল্পে সহযোগিতা করার জন্য একটি অপরিহার্য টুল। একবার আপনি এডিটরের মৌলিক বিষয়গুলো এবং এর বৈশিষ্ট্যগুলো কীভাবে ব্যবহার করবেন তা বুঝতে পারলে, আপনি এগুলো কোড লেখার সময় প্রয়োগ করতে পারবেন।
কোড এডিটর হলো প্রোগ্রাম লেখার এবং বিদ্যমান কোডিং প্রজেক্টে সহযোগিতা করার জন্য একটি অপরিহার্য টুল। একবার আপনি এডিটরের মৌলিক বিষয়গুলো এবং এর বৈশিষ্ট্যগুলো কীভাবে ব্যবহার করবেন তা বুঝে গেলে, আপনি এগুলো কোড লেখার সময় প্রয়োগ করতে পারবেন।
## VSCode.dev দিয়ে শুরু করা
[VSCode.dev](https://vscode.dev) হলো একটি ওয়েব-ভিত্তিক কোড এডিটর। এটি ব্যবহার করতে কিছু ইনস্টল করার প্রয়োজন নেই, এটি ঠিক অন্য কোনো ওয়েবসাইট খোলার মতো। এডিটরটি শুরু করতে, এই লিঙ্কটি খুলুন: [https://vscode.dev](https://vscode.dev)। যদি আপনি [GitHub](https://github.com/) এ সাইন ইন না করেন, তাহলে সাইন ইন করার বা নতুন অ্যাকাউন্ট তৈরি করার জন্য প্রম্পট অনুসরণ করুন এবং তারপর সাইন ইন করুন।
[VSCode.dev](https://vscode.dev) হলো একটি ওয়েব-ভিত্তিক কোড এডিটর। এটি ব্যবহার করতে আপনাকে কিছু ইনস্টল করার প্রয়োজন নেই, এটি ঠিক অন্য কোনো ওয়েবসাইট খোলার মতো। এডিটরটি শুরু করতে, এই লিঙ্কটি খুলুন: [https://vscode.dev](https://vscode.dev)। যদি আপনি [GitHub](https://github.com/) এ সাইন ইন না করে থাকেন, তাহলে সাইন ইন করার বা নতুন অ্যাকাউন্ট তৈরি করার জন্য প্রম্পট অনুসরণ করুন এবং তারপর সাইন ইন করুন।
লোড হওয়ার পর, এটি নিচের ছবির মতো দেখতে হবে:
@ -38,12 +38,12 @@ CO_OP_TRANSLATOR_METADATA:
এখানে তিনটি প্রধান অংশ রয়েছে, বাম থেকে ডানে:
1. _অ্যাক্টিভিটি বার_, যেখানে কিছু আইকন রয়েছে, যেমন ম্যাগনিফাইং গ্লাস 🔎, গিয়ার ⚙️, এবং আরও কিছু।
1. অ্যাক্টিভিটি বারটি প্রসারিত হয়ে _এক্সপ্লোরার_ নামে পরিচিত _সাইড বার_
1. এবং শেষের দিকে, ডানদিকে কোডের এলাকা।
2. _সাইড বার_, যা ডিফল্টভাবে _এক্সপ্লোরার_ এ সেট করা থাকে
3. এবং শেষের দিকে কোডের জন্য জায়গা।
প্রতিটি আইকনে ক্লিক করে বিভিন্ন মেনু প্রদর্শন করুন। কাজ শেষ হলে, _এক্সপ্লোরার_ এ ক্লিক করুন যাতে আপনি আবার শুরুতে ফিরে আসেন।
যখন আপনি কোড তৈরি করা শুরু করবেন বা বিদ্যমান কোড পরিবর্তন করবেন, এটি ডানদিকে সবচেয়ে বড় এলাকাতে ঘটবে। আপনি এই এলাকাটি বিদ্যমান কোড দেখতে ব্যবহার করবেন, যা আপনি পরবর্তী ধাপে করবেন।
যখন আপনি কোড তৈরি করা বা বিদ্যমান কোড পরিবর্তন করা শুরু করবেন, এটি ডানপাশের সবচেয়ে বড় জায়গায় হবে। এই জায়গাটি ব্যবহার করে আপনি বিদ্যমান কোডও দেখতে পারবেন, যা আপনি পরবর্তী ধাপে করবেন।
## একটি GitHub রিপোজিটরি খুলুন
@ -55,11 +55,11 @@ CO_OP_TRANSLATOR_METADATA:
![Open remote repository](../../../../translated_images/open-remote-repository.bd9c2598b8949e7fc283cdfc8f4050c6205a7c7c6d3f78c4b135115d037d6fa2.bn.png)
আপনি কমান্ড প্যালেটও ব্যবহার করতে পারেন। কমান্ড প্যালেট হলো একটি ইনপুট বক্স যেখানে আপনি কোনো কমান্ড বা অ্যাকশনের অংশ হিসেবে কোনো শব্দ টাইপ করতে পারেন সঠিক কমান্ডটি খুঁজে বের করার জন্য। মেনুতে যান, তারপর _View_ নির্বাচন করুন, এবং তারপর _Command Palette_ নির্বাচন করুন, অথবা এই কিবোর্ড শর্টকাট ব্যবহার করুন: Ctrl-Shift-P (MacOS এ এটি Command-Shift-P হবে)।
আপনি কমান্ড প্যালেটও ব্যবহার করতে পারেন। কমান্ড প্যালেট হলো একটি ইনপুট বক্স যেখানে আপনি কোনো কমান্ড বা অ্যাকশনের অংশ হিসেবে কোনো শব্দ টাইপ করতে পারেন সঠিক কমান্ডটি খুঁজে বের করার জন্য। উপরের বাম মেনুতে যান, তারপর _View_ নির্বাচন করুন, এবং তারপর _Command Palette_ নির্বাচন করুন, অথবা এই কিবোর্ড শর্টকাট ব্যবহার করুন: Ctrl-Shift-P (MacOS এ এটি Command-Shift-P হবে)।
![Palette Menu](../../../../translated_images/palette-menu.4946174e07f426226afcdad707d19b8d5150e41591c751c45b5dee213affef91.bn.png)
মেনু খোলার পর, _open remote repository_ টাইপ করুন এবং তারপর প্রথম অপশনটি নির্বাচন করুন। আপনি অংশগ্রহণ করা বা সম্প্রতি খোলা রিপোজিটরিগুলোর তালিকা দেখতে পাবেন। আপনি একটি সম্পূর্ণ GitHub URL ব্যবহার করেও একটি রিপোজিটরি নির্বাচন করতে পারেন। নিচের URL টি ব্যবহার করুন এবং বক্সে পেস্ট করুন:
মেনু খুললে, _open remote repository_ টাইপ করুন এবং তারপর প্রথম অপশনটি নির্বাচন করুন। আপনি যে রিপোজিটরিগুলোর অংশ বা সম্প্রতি খুলেছেন সেগুলো দেখাবে। আপনি একটি সম্পূর্ণ GitHub URL ব্যবহার করেও একটি নির্বাচন করতে পারেন। নিচের URL ব্যবহার করুন এবং বক্সে পেস্ট করুন:
```
https://github.com/microsoft/Web-Dev-For-Beginners
@ -69,83 +69,92 @@ https://github.com/microsoft/Web-Dev-For-Beginners
### ২. URL ব্যবহার করে
আপনি সরাসরি একটি URL ব্যবহার করেও রিপোজিটরি লোড করতে পারেন। উদাহরণস্বরূপ, বর্তমান রিপোজিটরির সম্পূর্ণ URL হলো [https://github.com/microsoft/Web-Dev-For-Beginners](https://github.com/microsoft/Web-Dev-For-Beginners), তবে আপনি GitHub ডোমেইনটি `VSCode.dev/github` দিয়ে পরিবর্তন করে সরাসরি রিপোজিটরি লোড করতে পারেন। ফলাফল URL হবে [https://vscode.dev/github/microsoft/Web-Dev-For-Beginners](https://vscode.dev/github/microsoft/Web-Dev-For-Beginners)।
আপনি সরাসরি একটি URL ব্যবহার করেও রিপোজিটরি লোড করতে পারেন। উদাহরণস্বরূপ, বর্তমান রিপোজিটরির সম্পূর্ণ URL হলো [https://github.com/microsoft/Web-Dev-For-Beginners](https://github.com/microsoft/Web-Dev-For-Beginners), তবে আপনি GitHub ডোমেইনটি `VSCode.dev/github` দিয়ে পরিবর্তন করে রিপোজিটরি সরাসরি লোড করতে পারেন। ফলাফল URL হবে [https://vscode.dev/github/microsoft/Web-Dev-For-Beginners](https://vscode.dev/github/microsoft/Web-Dev-For-Beginners)।
## ফাইল সম্পাদনা করুন
একবার আপনি ব্রাউজারে বা vscode.dev এ রিপোজিটরি খুলে ফেললে, পরবর্তী ধাপ হবে প্রকল্পে আপডেট বা পরিবর্তন করা।
একবার আপনি ব্রাউজারে বা vscode.dev এ রিপোজিটরি খুলে ফেললে, পরবর্তী ধাপ হবে প্রজেক্টে আপডেট বা পরিবর্তন করা।
### ১. একটি নতুন ফাইল তৈরি করুন
আপনি বিদ্যমান ফোল্ডারের ভিতরে একটি ফাইল তৈরি করতে পারেন, অথবা মূল ডিরেক্টরি/ফোল্ডারে এটি তৈরি করতে পারেন। একটি নতুন ফাইল তৈরি করতে, সেই অবস্থান/ডিরেক্টরি খুলুন যেখানে আপনি ফাইলটি সংরক্ষণ করতে চান এবং _'New file ...'_ আইকনটি অ্যাক্টিভিটি বারে _(বামে)_ নির্বাচন করুন, একটি নাম দিন এবং এন্টার চাপুন।
আপনি বিদ্যমান ফোল্ডারের ভিতরে একটি ফাইল তৈরি করতে পারেন, অথবা রুট ডিরেক্টরি/ফোল্ডারে এটি তৈরি করতে পারেন। একটি নতুন ফাইল তৈরি করতে, সেই লোকেশন/ডিরেক্টরি খুলুন যেখানে আপনি ফাইলটি সংরক্ষণ করতে চান এবং _'New file ...'_ আইকনটি নির্বাচন করুন, একটি নাম দিন এবং এন্টার চাপুন।
![Create a new file](../../../../translated_images/create-new-file.2814e609c2af9aeb6c6fd53156c503ac91c3d538f9cac63073b2dd4a7631f183.bn.png)
### ২. রিপোজিটরিতে একটি ফাইল সম্পাদনা এবং সংরক্ষণ করুন
vscode.dev ব্যবহার করা সুবিধাজনক যখন আপনি আপনার প্রকল্পে দ্রুত আপডেট করতে চান, কোনো সফটওয়্যার লোকালি লোড না করেই। আপনার কোড আপডেট করতে, অ্যাক্টিভিটি বারে থাকা 'Explorer' আইকনে ক্লিক করুন যাতে রিপোজিটরিতে থাকা ফাইল ও ফোল্ডারগুলো দেখতে পারেন। একটি ফাইল নির্বাচন করুন যাতে এটি কোড এলাকায় খুলে যায়, আপনার পরিবর্তনগুলো করুন এবং সংরক্ষণ করুন।
vscode.dev ব্যবহার করা সুবিধাজনক যখন আপনি আপনার প্রজেক্টে দ্রুত আপডেট করতে চান এবং কোনো সফটওয়্যার লোকালি লোড করতে চান না।
আপনার কোড আপডেট করতে, 'Explorer' আইকনে ক্লিক করুন, যা অ্যাক্টিভিটি বারে অবস্থিত, রিপোজিটরির ফাইল ও ফোল্ডার দেখতে।
একটি ফাইল নির্বাচন করুন যাতে এটি কোড এলাকায় খুলে যায়, পরিবর্তন করুন এবং সংরক্ষণ করুন।
![Edit a file](../../../../translated_images/edit-a-file.52c0ee665ef19f08119d62d63f395dfefddc0a4deb9268d73bfe791f52c5807a.bn.png)
আপনার প্রকল্প আপডেট করা শেষ হলে, _`source control`_ আইকনটি নির্বাচন করুন যেখানে আপনি আপনার রিপোজিটরিতে করা নতুন পরিবর্তনগুলো দেখতে পাবেন।
আপনার প্রজেক্ট আপডেট করা শেষ হলে, _`source control`_ আইকনটি নির্বাচন করুন যেখানে আপনি আপনার রিপোজিটরিতে করা নতুন পরিবর্তনগুলো দেখতে পাবেন।
আপনার প্রকল্পে করা পরিবর্তনগুলো দেখতে, প্রসারিত অ্যাক্টিভিটি বারে `Changes` ফোল্ডারে থাকা ফাইলগুলো নির্বাচন করুন। এটি একটি 'Working Tree' খুলবে যেখানে আপনি ফাইলের পরিবর্তনগুলো ভিজ্যুয়ালি দেখতে পারবেন। লাল রঙ প্রকল্প থেকে কিছু বাদ পড়া নির্দেশ করে, আর সবুজ রঙ যোগ করা নির্দেশ করে।
আপনার প্রজেক্টে করা পরিবর্তনগুলো দেখতে, _Changes_ ফোল্ডারে থাকা ফাইলগুলো নির্বাচন করুন যা এক্সপ্যান্ডেড অ্যাক্টিভিটি বারে রয়েছে। এটি একটি 'Working Tree' খুলবে যেখানে আপনি ভিজ্যুয়ালি দেখতে পারবেন ফাইলের পরিবর্তনগুলো। লাল রঙ প্রজেক্ট থেকে কিছু বাদ পড়া নির্দেশ করে, আর সবুজ রঙ যোগ করা নির্দেশ করে।
![View changes](../../../../translated_images/working-tree.c58eec08e6335c79cc708c0c220c0b7fea61514bd3c7fb7471905a864aceac7c.bn.png)
যদি আপনি আপনার করা পরিবর্তনগুলো নিয়ে সন্তুষ্ট হন, তাহলে `Changes` ফোল্ডারে হোভার করুন এবং পরিবর্তনগুলো স্টেজ করতে `+` বোতামে ক্লিক করুন। স্টেজিং মানে হলো আপনার পরিবর্তনগুলো GitHub এ কমিট করার জন্য প্রস্তুত করা।
যদি আপনি আপনার করা পরিবর্তনগুলো নিয়ে সন্তুষ্ট হন, তাহলে _Changes_ ফোল্ডারে হোভার করুন এবং পরিবর্তনগুলো স্টেজ করতে _`+`_ বোতামে ক্লিক করুন। স্টেজিং মানে হলো আপনার পরিবর্তনগুলো GitHub এ কমিট করার জন্য প্রস্তুত করা।
যদি আপনি কিছু পরিবর্তন নিয়ে স্বাচ্ছন্দ্যবোধ না করেন এবং সেগুলো বাতিল করতে চান, তাহলে `Changes` ফোল্ডারে হোভার করুন এবং `undo` আইকনটি নির্বাচন করুন।
যদি আপনি কিছু পরিবর্তন নিয়ে সন্তুষ্ট না হন এবং সেগুলো বাতিল করতে চান, তাহলে _Changes_ ফোল্ডারে হোভার করুন এবং _`undo`_ আইকনটি নির্বাচন করুন।
তারপর একটি `commit message` টাইপ করুন _(আপনার প্রকল্পে করা পরিবর্তনের একটি বিবরণ)_, এবং পরিবর্তনগুলো কমিট ও পুশ করতে `check icon` এ ক্লিক করুন।
তারপর একটি _commit message_ টাইপ করুন _(আপনার প্রজেক্টে করা পরিবর্তনের বর্ণনা)_, এবং পরিবর্তনগুলো কমিট ও পুশ করতে _check icon_ এ ক্লিক করুন।
আপনার প্রকল্পে কাজ শেষ হলে, উপরের বাম দিকে থাকা `hamburger menu icon` নির্বাচন করুন যাতে github.com এ রিপোজিটরিতে ফিরে যেতে পারেন।
আপনার প্রজেক্টে কাজ শেষ হলে, উপরের বাম দিকে থাকা _hamburger menu icon_ নির্বাচন করুন যাতে আপনি github.com এ রিপোজিটরিতে ফিরে যেতে পারেন।
![Stage & commit changes](../../../../8-code-editor/images/edit-vscode.dev.gif)
## এক্সটেনশন ব্যবহার করা
VSCode এ এক্সটেনশন ইনস্টল করলে আপনি নতুন বৈশিষ্ট্য যোগ করতে পারেন এবং আপনার এডিটরে কাস্টমাইজড ডেভেলপমেন্ট এনভায়রনমেন্ট অপশন যোগ করতে পারেন যা আপনার ডেভেলপমেন্ট ওয়ার্কফ্লো উন্নত করে। এই এক্সটেনশনগুলো আপনাকে একাধিক প্রোগ্রামিং ভাষার জন্য সাপোর্ট যোগ করতে সাহায্য করে এবং সাধারণত জেনেরিক এক্সটেনশন বা ভাষা-ভিত্তিক এক্সটেনশন হয়ে থাকে।
VSCode এ এক্সটেনশন ইনস্টল করলে আপনি আপনার এডিটরে নতুন বৈশিষ্ট্য যোগ করতে এবং ডেভেলপমেন্ট পরিবেশ কাস্টমাইজ করতে পারেন যা আপনার ডেভেলপমেন্ট ওয়ার্কফ্লো উন্নত করে। এই এক্সটেনশনগুলো আপনাকে একাধিক প্রোগ্রামিং ভাষার জন্য সাপোর্ট যোগ করতে সাহায্য করে এবং সাধারণত জেনেরিক এক্সটেনশন বা ভাষা-ভিত্তিক এক্সটেনশন হয়ে থাকে।
সব উপলব্ধ এক্সটেনশনের তালিকা দেখতে, অ্যাক্টিভিটি বারে _`Extensions icon`_ এ ক্লিক করুন এবং _'Search Extensions in Marketplace'_ লেবেলযুক্ত টেক্সট ফিল্ডে এক্সটেনশনের নাম টাইপ করা শুরু করুন। আপনি এক্সটেনশনের একটি তালিকা দেখতে পাবেন, প্রতিটিতে **এক্সটেনশনের নাম, প্রকাশকের নাম, একটি বাক্য বিবরণ, ডাউনলোড সংখ্যা** এবং **একটি তারকা রেটিং** থাকবে।
সব উপলব্ধ এক্সটেনশনের তালিকা দেখতে, অ্যাক্টিভিটি বারে _`Extensions icon`_ এ ক্লিক করুন এবং _'Search Extensions in Marketplace'_ লেবেলযুক্ত টেক্সট ফিল্ডে এক্সটেনশনের নাম টাইপ করুন।
আপনি এক্সটেনশনের একটি তালিকা দেখতে পাবেন, যেখানে থাকবে **এক্সটেনশনের নাম, প্রকাশকের নাম, এক বাক্যের বিবরণ, ডাউনলোড সংখ্যা** এবং **স্টার রেটিং**।
![Extension details](../../../../translated_images/extension-details.9f8f1fd4e9eb2de5069ae413119eb8ee43172776383ebe2f7cf640e11df2e106.bn.png)
আপনি পূর্বে ইনস্টল করা সব এক্সটেনশন _`Installed folder`_ এ, অধিকাংশ ডেভেলপারদের ব্যবহৃত জনপ্রিয় এক্সটেনশন _`Popular folder`_ এ এবং আপনার জন্য সুপারিশকৃত এক্সটেনশন _`recommended folder`_ এ দেখতে পারেন, যা একই ওয়ার্কস্পেসে থাকা ্যবহারকারীদর দ্বারা বা আপার সম্প্রতি খোলা ফাইলের ভিত্তিতে সুপারিশ করা হয়
আপনি পূর্বে ইনস্টল করা সব এক্সটেনশন _Installed folder_ এ, বেশিরভাগ ডেভেলপারদের ব্যবহৃত জনপ্রিয় এক্সটেনশন _Popular folder_ এ এবং আপনার জন্য সুপারিশকৃত এক্সটেনশন _recommended folder_ এ দেখতে পারবেন।
![View extensions](../../../../translated_images/extensions.eca0e0c7f59a10b5c88be7fe24b3e32cca6b6058b35a49026c3a9d80b1813b7c.bn.png)
### ১. এক্সটেনশন ইনস্টল করুন
একটি এক্সটেনশন ইনস্টল করতে, সার্চ ফিল্ডে এক্সটেনশনের নাম টাইপ করুন এবং এটি প্রসারিত অ্যাক্টিভিটি বারে প্রদর্শিত হলে অতিরিক্ত তথ্য দেখতে ক্লিক করুন। আপনি প্রসারিত অ্যাক্টিভিটি বারে থাকা _নীল ইনস্টল বোতাম_ ব্যবহার করে ইনস্টল করতে পারেন অথবা কোড এলাকায় এক্সটেনশনটি নির্বাচন করলে প্রদর্শিত ইনস্টল বোতাম ব্যবহার করতে পারেন।
একটি এক্সটেনশন ইনস্টল করতে, সার্চ ফিল্ডে এক্সটেনশনের নাম টাইপ করুন এবং এক্সটেনশনটি এক্সপ্যান্ডেড অ্যাক্টিভিটি বারে প্রদর্শিত হলে এটি নির্বাচন করুন।
এক্সটেনশন সম্পর্কে অতিরিক্ত তথ্য দেখতে কোড এলাকায় এটি লোড করুন।
আপনি এক্সপ্যান্ডেড অ্যাক্টিভিটি বারে থাকা _নীল ইনস্টল বোতাম_ ব্যবহার করে অথবা কোড এলাকায় থাকা ইনস্টল বোতাম ব্যবহার করে এক্সটেনশনটি ইনস্টল করতে পারেন।
![Install extensions](../../../../8-code-editor/images/install-extension.gif)
### ২. এক্সটেনশন কাস্টমাইজ করুন
এক্সটেনশন ইনস্টল করার পর, আপনি এর আচরণ পরিবর্তন করতে এবং আপনার পছন্দ অনুযায়ী কাস্টমাইজ করতে পারেন। এটি করতে, Extensions আইকন নির্বাচন করুন, এবং এবার আপনার এক্সটেনশনটি _Installed folder_ এ প্রদর্শিত হবে। _**Gear icon**_ এ ক্লিক করুন এবং _Extensions Setting_ এ যান।
এক্সটেনশন ইনস্টল করার পর, আপনি এর আচরণ পরিবর্তন করতে এবং আপনার পছন্দ অনুযায়ী কাস্টমাইজ করতে পারেন।
এটি করতে, _Extensions icon_ নির্বাচন করুন, এবং এবার আপনার এক্সটেনশন _Installed folder_ এ প্রদর্শিত হবে।
_**Gear icon**_ এ ক্লিক করুন এবং _Extensions Setting_ এ যান।
![Modify extension settings](../../../../translated_images/extension-settings.21c752ae4f4cdb78a867f140ccd0680e04619d0c44bb4afb26373e54b829d934.bn.png)
### ৩. এক্সটেনশন ম্যানেজ করুন
এক্সটেনশন ইনস্টল এবং ব্যবহার করার পর, vscode.dev বিভিন্ন প্রয়োজন অনুযায়ী আপনার এক্সটেনশন ম্যানেজ করার অপশন প্রদান করে। উদাহরণস্বরূপ, আপনি নিম্নলিখিত কাজ করতে পারেন:
এক্সটেনশন ইনস্টল এবং ব্যবহার করার পর, vscode.dev বিভিন্ন প্রয়োজন অনুযায়ী এক্সটেনশন ম্যানেজ করার অপশন প্রদান করে। উদাহরণস্বরূপ, আপনি হয়তো:
- **ডিসেবল:** _(যখন আপনি একটি এক্সটেনশন সাময়িকভাবে ব্যবহার করতে চান না কিন্তু সম্পূর্ণভাবে আনইনস্টল করতে চান না)_
- **ডিসেবল:** _(আপনি যখন কোনো এক্সটেনশন সাময়িকভাবে ব্যবহার করতে চান না কিন্তু সম্পূর্ণ আনইনস্টল করতে চান না)_
প্রসারিত অ্যাক্টিভিটি বারে ইনস্টল করা এক্সটেনশন নির্বাচন করুন > Gear আইকনে ক্লিক করুন > 'Disable' বা 'Disable (Workspace)' নির্বাচন করুন **অথবা** কোড এলাকায় এক্সটেনশন খুলুন এবং নীল Disable বোতামে ক্লিক করুন।
এক্সপ্যান্ডেড অ্যাক্টিভিটি বারে ইনস্টল করা এক্সটেনশন নির্বাচন করুন > Gear icon এ ক্লিক করুন > 'Disable' বা 'Disable (Workspace)' নির্বাচন করুন **অথবা** কোড এলাকায় এক্সটেনশন খুলুন এবং নীল Disable বোতামে ক্লিক করুন।
- **আনইনস্টল:** প্রসারিত অ্যাক্টিভিটি বারে ইনস্টল করা এক্সটেনশন নির্বাচন করুন > Gear আইকনে ক্লিক করুন > 'Uninstall' নির্বাচন করুন **অথবা** কোড এলাকায় এক্সটেনশন খুলুন এবং নীল Uninstall বোতামে ক্লিক করুন।
- **আনইনস্টল:** এক্সপ্যান্ডেড অ্যাক্টিভিটি বারে ইনস্টল করা এক্সটেনশন নির্বাচন করুন > Gear icon এ ক্লিক করুন > 'Uninstall' নির্বাচন করুন **অথবা** কোড এলাকায় এক্সটেনশন খুলুন এবং নীল Uninstall বোতামে ক্লিক করুন।
---
## অ্যাসাইনমেন্ট
[vscode.dev ব্যবহার করে একটি রিজিউম ওয়েবসাইট তৈরি করুন](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/8-code-editor/1-using-a-code-editor/assignment.md)
[VSCode.dev ব্যবহার করে একটি রিজিউম ওয়েবসাইট তৈরি করুন](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/8-code-editor/1-using-a-code-editor/assignment.md)
## পর্যালোচনা ও স্ব-অধ্যয়ন
## রিভিউ এবং স্ব-অধ্যয়ন
[VSCode.dev](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza) এবং এর অন্যান্য বৈশিষ্ট্য সম্পর্কে আরও পড়ুন।
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতা নিশ্চিত করার চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়বদ্ধ নই।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "2fcb983b8dbadadb1bc2e97f8c12dac5",
"translation_date": "2025-08-25T23:22:25+00:00",
"original_hash": "bd3aa6d2b879c30ea496c43aec1c49ed",
"translation_date": "2025-08-28T23:05:26+00:00",
"source_file": "8-code-editor/1-using-a-code-editor/assignment.md",
"language_code": "bn"
}
@ -29,13 +29,13 @@ _কতটা চমৎকার হবে যদি কোনো রিক্
`creating a new file` লিঙ্কে ক্লিক করুন, `index.html` নাম টাইপ করুন এবং `Commit new file` বোতামটি নির্বাচন করুন।
![github.com-এ একটি নতুন ফাইল তৈরি করুন](../../../../translated_images/new-file-github.com.c886796d800e8056561829a181be1382c5303da9d902d8b2dd82b68a4806e21f.bn.png)
![github.com-এ নতুন ফাইল তৈরি করুন](../../../../translated_images/new-file-github.com.c886796d800e8056561829a181be1382c5303da9d902d8b2dd82b68a4806e21f.bn.png)
**ধাপ ৩:** [VSCode.dev](https://vscode.dev) খুলুন এবং `Open Remote Repository` বোতামটি নির্বাচন করুন।
আপনার রিজিউম সাইটের জন্য আপনি যে রিপোজিটরি তৈরি করেছেন তার URL কপি করুন এবং ইনপুট বক্সে পেস্ট করুন:
_আপনার github ব্যবহারকারীর নামের জায়গায় `your-username` লিখুন।_
_`your-username` আপনার GitHub ব্যবহারকারীর নাম দিয়ে প্রতিস্থাপন করুন_
```
https://github.com/your-username/my-resume
@ -43,7 +43,7 @@ https://github.com/your-username/my-resume
✅ সফল হলে, আপনি আপনার প্রকল্প এবং `index.html` ফাইলটি ব্রাউজারের টেক্সট এডিটরে খুলতে দেখতে পাবেন।
![একটি নতুন ফাইল তৈরি করুন](../../../../translated_images/project-on-vscode.dev.e79815a9a95ee7feac72ebe5c941c91279716be37c575dbdbf2f43bea2c7d8b6.bn.png)
![নতুন ফাইল তৈরি করুন](../../../../translated_images/project-on-vscode.dev.e79815a9a95ee7feac72ebe5c941c91279716be37c575dbdbf2f43bea2c7d8b6.bn.png)
**ধাপ :** `index.html` ফাইলটি খুলুন, নিচের কোডটি আপনার কোড এলাকায় পেস্ট করুন এবং সংরক্ষণ করুন।
@ -59,7 +59,7 @@ https://github.com/your-username/my-resume
</head>
<body>
<header id="header">
<!-- রিজিউমের হেডার যেখানে আপনার নাম এবং টাইটেল থাকবে -->
<!-- রিজিউম হেডার আপনার নাম এবং টাইটেল সহ -->
<h1>আপনার নাম এখানে লিখুন!</h1>
<hr>
আপনার ভূমিকা!
@ -112,11 +112,11 @@ https://github.com/your-username/my-resume
<p>আপনার সম্পর্কে একটি সংক্ষিপ্ত বিবরণ লিখুন!</p>
</section>
<section>
<h2>কর্মজীবনের অভিজ্ঞতা</h2>
<!-- আপনার কর্মজীবনের অভিজ্ঞতা -->
<h2>কর্ম অভিজ্ঞতা</h2>
<!-- আপনার কর্ম অভিজ্ঞতা -->
<h3>পদবী</h3>
<p>
প্রতিষ্ঠানের নাম এখানে লিখুন | শুরুর মাস শেষ মাস
প্রতিষ্ঠান নাম এখানে লিখুন | শুরুর মাস শেষ মাস
</p>
<ul>
<li>কাজ ১ - আপনি কী করেছেন তা লিখুন!</li>
@ -126,7 +126,7 @@ https://github.com/your-username/my-resume
</ul>
<h3>পদবী ২</h3>
<p>
প্রতিষ্ঠানের নাম এখানে লিখুন | শুরুর মাস শেষ মাস
প্রতিষ্ঠান নাম এখানে লিখুন | শুরুর মাস শেষ মাস
</p>
<ul>
<li>কাজ ১ - আপনি কী করেছেন তা লিখুন!</li>
@ -141,7 +141,7 @@ https://github.com/your-username/my-resume
</html>
</details>
HTML কোডে _placeholder text_ পরিবর্তন করে আপনার রিজিউমের তথ্য যোগ করুন।
HTML কোডে _প্লেসহোল্ডার টেক্সট_ পরিবর্তন করে আপনার রিজিউমের তথ্য যোগ করুন।
**ধাপ ৫:** My-Resume ফোল্ডারের উপর মাউস রাখুন, `New File ...` আইকনে ক্লিক করুন এবং আপনার প্রকল্পে দুটি নতুন ফাইল তৈরি করুন: `style.css` এবং `codeswing.json`
@ -219,15 +219,15 @@ HTML কোডে _placeholder text_ পরিবর্তন করে আপ
**ধাপ :** `Codeswing extension` ইনস্টল করুন যাতে কোড এলাকায় রিজিউম ওয়েবসাইটটি দেখতে পারেন।
Activity bar-এ _`Extensions`_ আইকনে ক্লিক করুন এবং Codeswing টাইপ করুন। _ব্লু ইনস্টল বোতাম_ বা কোড এলাকায় প্রদর্শিত ইনস্টল বোতাম ব্যবহার করে এক্সটেনশনটি ইনস্টল করুন। এক্সটেনশন ইনস্টল করার পরপরই আপনার প্রকল্পে পরিবর্তনগুলি লক্ষ্য করুন 😃
Activity bar-এ _`Extensions`_ আইকনে ক্লিক করুন এবং Codeswing টাইপ করুন। Expanded activity bar-এ _নীল ইনস্টল বোতাম_ বা কোড এলাকায় প্রদর্শিত ইনস্টল বোতাম ব্যবহার করে এক্সটেনশনটি ইনস্টল করুন। এক্সটেনশন ইনস্টল করার পরপরই আপনার প্রকল্পে পরিবর্তনগুলি লক্ষ্য করুন 😃
![এক্সটেনশন ইনস্টল করুন](../../../../8-code-editor/images/install-extension.gif)
এক্সটেনশন ইনস্টল করার পর আপনার স্ক্রিনে এটি দেখতে পাবেন।
![Codeswing এক্সটেনশন কার্যকর](../../../../translated_images/after-codeswing-extension-pb.0ebddddcf73b550994947a9084e35e2836c713ae13839d49628e3c764c1cfe83.bn.png)
![Codeswing extension কার্যক্রমে](../../../../translated_images/after-codeswing-extension-pb.0ebddddcf73b550994947a9084e35e2836c713ae13839d49628e3c764c1cfe83.bn.png)
যদি আপনি আপনার পরিবর্তনে সন্তুষ্ট হন, `Changes` ফোল্ডারের উপর মাউস রাখুন এবং `+` বোতামে ক্লিক করে পরিবর্তনগুলি স্টেজ করুন।
যদি আপনি আপনার পরিবর্তনে সন্তুষ্ট হন, `Changes` ফোল্ডারের উপর মাউস রাখুন এবং পরিবর্তনগুলি স্টেজ করতে `+` বোতামে ক্লিক করুন।
একটি কমিট বার্তা টাইপ করুন _(আপনার প্রকল্পে করা পরিবর্তনের বিবরণ)_ এবং `check` ক্লিক করে আপনার পরিবর্তনগুলি কমিট করুন। আপনার প্রকল্পে কাজ শেষ হলে, উপরের বাম দিকে থাকা হ্যামবার্গার মেনু আইকন নির্বাচন করে GitHub-এ রিপোজিটরিতে ফিরে যান।
@ -241,5 +241,7 @@ Activity bar-এ _`Extensions`_ আইকনে ক্লিক করুন এ
[VSCode.dev](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza) এবং এর অন্যান্য বৈশিষ্ট্য সম্পর্কে আরও পড়ুন।
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতা নিশ্চিত করার চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়ী থাকব না।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতার জন্য চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।

@ -0,0 +1,389 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "cf15ff7770c5a484349383bb27d1131f",
"translation_date": "2025-08-29T01:24:22+00:00",
"source_file": "9-chat-project/README.md",
"language_code": "bn"
}
-->
# চ্যাট প্রকল্প
এই চ্যাট প্রকল্পটি দেখায় কীভাবে GitHub Models ব্যবহার করে একটি চ্যাট অ্যাসিস্ট্যান্ট তৈরি করা যায়।
এখানে চূড়ান্ত প্রকল্পটি দেখতে কেমন হবে:
<div>
<img src="./assets/screenshot.png" alt="চ্যাট অ্যাপ" width="600">
</div>
কিছু প্রেক্ষাপট, জেনারেটিভ AI ব্যবহার করে চ্যাট অ্যাসিস্ট্যান্ট তৈরি করা AI সম্পর্কে শেখার একটি চমৎকার উপায়। এই পাঠে আপনি শিখবেন কীভাবে জেনারেটিভ AI-কে একটি ওয়েব অ্যাপে সংযুক্ত করতে হয়। চলুন শুরু করি।
## জেনারেটিভ AI-তে সংযোগ স্থাপন
ব্যাকএন্ডের জন্য, আমরা GitHub Models ব্যবহার করছি। এটি একটি চমৎকার পরিষেবা যা আপনাকে বিনামূল্যে AI ব্যবহার করতে দেয়। এর প্লেগ্রাউন্ডে যান এবং আপনার পছন্দের ব্যাকএন্ড ভাষার সাথে সম্পর্কিত কোডটি নিন। এটি দেখতে কেমন তা এখানে দেখুন: [GitHub Models Playground](https://github.com/marketplace/models/azure-openai/gpt-4o-mini/playground)
<div>
<img src="./assets/playground.png" alt="GitHub Models AI Playground" with="600">
</div>
যেমন বলা হয়েছে, "Code" ট্যাব এবং আপনার পছন্দের রানটাইম নির্বাচন করুন।
<div>
<img src="./assets/playground-choice.png" alt="playground choice" with="600">
</div>
এই ক্ষেত্রে আমরা Python নির্বাচন করি, যার অর্থ আমরা এই কোডটি বেছে নেব:
```python
"""Run this model in Python
> pip install openai
"""
import os
from openai import OpenAI
# To authenticate with the model you will need to generate a personal access token (PAT) in your GitHub settings.
# Create your PAT token by following instructions here: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
client = OpenAI(
base_url="https://models.github.ai/inference",
api_key=os.environ["GITHUB_TOKEN"],
)
response = client.chat.completions.create(
messages=[
{
"role": "system",
"content": "",
},
{
"role": "user",
"content": "What is the capital of France?",
}
],
model="openai/gpt-4o-mini",
temperature=1,
max_tokens=4096,
top_p=1
)
print(response.choices[0].message.content)
```
এই কোডটি একটু পরিষ্কার করি যাতে এটি পুনরায় ব্যবহারযোগ্য হয়:
```python
def call_llm(prompt: str, system_message: str):
response = client.chat.completions.create(
messages=[
{
"role": "system",
"content": system_message,
},
{
"role": "user",
"content": prompt,
}
],
model="openai/gpt-4o-mini",
temperature=1,
max_tokens=4096,
top_p=1
)
return response.choices[0].message.content
```
এই `call_llm` ফাংশনটি ব্যবহার করে আমরা এখন একটি প্রম্পট এবং একটি সিস্টেম প্রম্পট নিতে পারি এবং ফাংশনটি ফলাফল ফেরত দেয়।
### AI অ্যাসিস্ট্যান্ট কাস্টমাইজ করুন
আপনি যদি AI অ্যাসিস্ট্যান্ট কাস্টমাইজ করতে চান, তাহলে সিস্টেম প্রম্পটটি এভাবে পূরণ করে তার আচরণ নির্ধারণ করতে পারেন:
```python
call_llm("Tell me about you", "You're Albert Einstein, you only know of things in the time you were alive")
```
## এটি একটি ওয়েব API এর মাধ্যমে প্রকাশ করুন
চমৎকার, আমাদের AI অংশটি সম্পন্ন হয়েছে, এখন দেখি কীভাবে এটি একটি ওয়েব API-তে সংযুক্ত করা যায়। ওয়েব API-এর জন্য, আমরা Flask ব্যবহার করছি, তবে যেকোনো ওয়েব ফ্রেমওয়ার্কই ভালো হবে। এর কোডটি এখানে দেখুন:
```python
# api.py
from flask import Flask, request, jsonify
from llm import call_llm
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # * example.com
@app.route("/", methods=["GET"])
def index():
return "Welcome to this API. Call POST /hello with 'message': 'my message' as JSON payload"
@app.route("/hello", methods=["POST"])
def hello():
# get message from request body { "message": "do this taks for me" }
data = request.get_json()
message = data.get("message", "")
response = call_llm(message, "You are a helpful assistant.")
return jsonify({
"response": response
})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
```
এখানে, আমরা একটি Flask API তৈরি করি এবং "/" এবং "/chat" নামে দুটি রুট সংজ্ঞায়িত করি। দ্বিতীয়টি আমাদের ফ্রন্টএন্ডের মাধ্যমে প্রশ্ন পাঠানোর জন্য ব্যবহৃত হয়।
*llm.py* সংযুক্ত করতে আমাদের যা করতে হবে তা হলো:
- `call_llm` ফাংশনটি ইমপোর্ট করুন:
```python
from llm import call_llm
from flask import Flask, request
```
- "/chat" রুট থেকে এটি কল করুন:
```python
@app.route("/hello", methods=["POST"])
def hello():
# get message from request body { "message": "do this taks for me" }
data = request.get_json()
message = data.get("message", "")
response = call_llm(message, "You are a helpful assistant.")
return jsonify({
"response": response
})
```
এখানে আমরা ইনকামিং রিকোয়েস্টটি পার্স করি এবং JSON বডি থেকে `message` প্রপার্টি পুনরুদ্ধার করি। এরপর আমরা এই কল দিয়ে LLM-কে কল করি:
```python
response = call_llm(message, "You are a helpful assistant")
# return the response as JSON
return jsonify({
"response": response
})
```
চমৎকার, এখন আমরা যা দরকার তা সম্পন্ন করেছি।
### Cors কনফিগার করুন
আমাদের উল্লেখ করা উচিত যে আমরা Cors, অর্থাৎ ক্রস-অরিজিন রিসোর্স শেয়ারিং সেট আপ করেছি। এর মানে হলো আমাদের ব্যাকএন্ড এবং ফ্রন্টএন্ড আলাদা পোর্টে চলবে, তাই আমাদের ব্যাকএন্ডে ফ্রন্টএন্ড কল করার অনুমতি দিতে হবে। *api.py* ফাইলের একটি কোড অংশ এটি সেট আপ করে:
```python
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # * example.com
```
এখন এটি "*" অর্থাৎ সব অরিজিনের জন্য সেট করা হয়েছে, যা কিছুটা অনিরাপদ। প্রোডাকশনে যাওয়ার সময় এটি সীমাবদ্ধ করা উচিত।
## আপনার প্রকল্প চালান
ঠিক আছে, আমাদের *llm.py* এবং *api.py* আছে, কীভাবে আমরা এটি ব্যাকএন্ডের সাথে কাজ করব? দুটি জিনিস করতে হবে:
- ডিপেনডেন্সি ইনস্টল করুন:
```sh
cd backend
python -m venv venv
source ./venv/bin/activate
pip install openai flask flask-cors openai
```
- API চালু করুন:
```sh
python api.py
```
যদি আপনি Codespaces-এ থাকেন, তাহলে আপনাকে এডিটরের নিচের অংশে Ports-এ যেতে হবে, সেখানে রাইট-ক্লিক করে "Port Visibility" নির্বাচন করতে হবে এবং "Public" নির্বাচন করতে হবে।
### ফ্রন্টএন্ডে কাজ করুন
এখন আমাদের API চালু এবং চলমান, চলুন এর জন্য একটি ফ্রন্টএন্ড তৈরি করি। একটি ন্যূনতম ফ্রন্টএন্ড যা আমরা ধাপে ধাপে উন্নত করব। একটি *frontend* ফোল্ডারে নিম্নলিখিত তৈরি করুন:
```text
backend/
frontend/
index.html
app.js
styles.css
```
চলুন শুরু করি **index.html** দিয়ে:
```html
<html>
<head>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<form>
<textarea id="messages"></textarea>
<input id="input" type="text" />
<button type="submit" id="sendBtn">Send</button>
</form>
<script src="app.js" />
</body>
</html>
```
উপরেরটি একটি চ্যাট উইন্ডো সমর্থন করার জন্য প্রয়োজনীয় ন্যূনতম জিনিস, কারণ এটি একটি textarea নিয়ে গঠিত যেখানে বার্তাগুলি রেন্ডার করা হবে, একটি ইনপুট যেখানে বার্তা টাইপ করা হবে এবং একটি বোতাম যা আপনার বার্তাটি ব্যাকএন্ডে পাঠাবে। চলুন *app.js* এ JavaScript দেখি।
**app.js**
```js
// app.js
(function(){
// 1. set up elements
const messages = document.getElementById("messages");
const form = document.getElementById("form");
const input = document.getElementById("input");
const BASE_URL = "change this";
const API_ENDPOINT = `${BASE_URL}/hello`;
// 2. create a function that talks to our backend
async function callApi(text) {
const response = await fetch(API_ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message: text })
});
let json = await response.json();
return json.response;
}
// 3. add response to our textarea
function appendMessage(text, role) {
const el = document.createElement("div");
el.className = `message ${role}`;
el.innerHTML = text;
messages.appendChild(el);
}
// 4. listen to submit events
form.addEventListener("submit", async(e) => {
e.preventDefault();
// someone clicked the button in the form
// get input
const text = input.value.trim();
appendMessage(text, "user")
// reset it
input.value = '';
const reply = await callApi(text);
// add to messages
appendMessage(reply, "assistant");
})
})();
```
চলুন কোডটি বিভাগ অনুযায়ী দেখি:
- ১) এখানে আমরা আমাদের সমস্ত এলিমেন্টের রেফারেন্স পাই যা আমরা পরে কোডে উল্লেখ করব।
- ২) এই অংশে, আমরা একটি ফাংশন তৈরি করি যা বিল্ট-ইন `fetch` মেথড ব্যবহার করে আমাদের ব্যাকএন্ডে কল করে।
- ৩) `appendMessage` ব্যবহারকারীর টাইপ করা বার্তা এবং রেসপন্স যোগ করতে সাহায্য করে।
- ) এখানে আমরা submit ইভেন্টটি শুনি এবং ইনপুট ফিল্ডটি পড়ি, ব্যবহারকারীর বার্তাটি textarea-তে রাখি, API-তে কল করি এবং রেসপন্সটি textarea-তে রেন্ডার করি।
চলুন স্টাইলিং দেখি, এখানে আপনি আপনার ইচ্ছামতো ডিজাইন করতে পারেন, তবে কিছু পরামর্শ এখানে দেওয়া হলো:
**styles.css**
```
.message {
background: #222;
box-shadow: 0 0 0 10px orange;
padding: 10px:
margin: 5px;
}
.message.user {
background: blue;
}
.message.assistant {
background: grey;
}
```
এই তিনটি ক্লাসের মাধ্যমে আপনি বার্তাগুলিকে স্টাইল করতে পারেন, এটি অ্যাসিস্ট্যান্ট বা ব্যবহারকারীর কাছ থেকে এসেছে কিনা তার উপর নির্ভর করে। অনুপ্রাণিত হতে চাইলে `solution/frontend/styles.css` ফোল্ডারটি দেখুন।
### Base Url পরিবর্তন করুন
এখানে একটি জিনিস আমরা সেট করিনি, সেটি হলো `BASE_URL`, এটি আপনার ব্যাকএন্ড শুরু না হওয়া পর্যন্ত জানা যায় না। এটি সেট করতে:
- যদি আপনি API লোকালভাবে চালান, এটি কিছুটা এরকম হওয়া উচিত: `http://localhost:5000`
- যদি Codespaces-এ চালান, এটি কিছুটা এরকম দেখাবে: "[name]app.github.dev"।
## অ্যাসাইনমেন্ট
আপনার নিজস্ব *project* ফোল্ডার তৈরি করুন যার কন্টেন্ট এরকম:
```text
project/
frontend/
index.html
app.js
styles.css
backend/
api.py
llm.py
```
উপরের নির্দেশনা থেকে কন্টেন্ট কপি করুন, তবে আপনার ইচ্ছামতো কাস্টমাইজ করতে পারেন।
## সমাধান
[Solution](./solution/README.md)
## বোনাস
AI অ্যাসিস্ট্যান্টের ব্যক্তিত্ব পরিবর্তন করার চেষ্টা করুন। যখন আপনি *api.py*-তে `call_llm` কল করেন, তখন দ্বিতীয় আর্গুমেন্টটি আপনার ইচ্ছামতো পরিবর্তন করতে পারেন, যেমন:
```python
call_llm(message, "You are Captain Picard")
```
*index.html* এবং *styles.css*-এ পরিবর্তন করে CSS এবং টেক্সটও আপনার ইচ্ছামতো পরিবর্তন করুন।
## সারসংক্ষেপ
চমৎকার, আপনি শূন্য থেকে শিখেছেন কীভাবে AI ব্যবহার করে একটি ব্যক্তিগত অ্যাসিস্ট্যান্ট তৈরি করতে হয়। আমরা এটি করেছি GitHub Models, Python ব্যাকএন্ড এবং HTML, CSS এবং JavaScript ফ্রন্টএন্ড ব্যবহার করে।
## Codespaces দিয়ে সেট আপ করুন
- নেভিগেট করুন: [Web Dev For Beginners repo](https://github.com/microsoft/Web-Dev-For-Beginners)
- টেমপ্লেট থেকে তৈরি করুন (নিশ্চিত করুন আপনি GitHub-এ লগ ইন করেছেন) উপরের ডানদিকে:
![টেমপ্লেট থেকে তৈরি করুন](../../../translated_images/template.67ad477109d29a2b04599a83c964c87fcde041256d4f04d3589cbb00c696f76c.bn.png)
- আপনার রিপোতে গেলে, একটি Codespace তৈরি করুন:
![Codespace তৈরি করুন](../../../translated_images/codespace.bcecbdf5d2747d3d17da67a78ad911c8853d68102e34748ec372cde1e9236e1d.bn.png)
এটি একটি পরিবেশ শুরু করবে যেখানে আপনি এখন কাজ করতে পারবেন।
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিকতা নিশ্চিত করার চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়ী থাকব না।

@ -0,0 +1,55 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "a7b7f54b13f9e6683a844d173ffdd766",
"translation_date": "2025-08-29T01:27:59+00:00",
"source_file": "9-chat-project/solution/README.md",
"language_code": "bn"
}
-->
# কোড চালানো
## সেটআপ
ভার্চুয়াল এনভায়রনমেন্ট তৈরি করুন
```sh
cd backend
python -m venv venv
source ./venv/bin/activate
```
## নির্ভরশীলতাগুলি ইনস্টল করুন
```sh
pip install openai flask flask-cors
```
## এপিআই চালান
```sh
python api.py
```
## ফ্রন্টএন্ড চালান
নিশ্চিত করুন যে আপনি ফ্রন্টএন্ড ফোল্ডারে অবস্থান করছেন
*app.js* ফাইলটি খুঁজুন, `BASE_URL`-কে আপনার ব্যাকএন্ড URL-এ পরিবর্তন করুন
এটি চালান
```
npx http-server -p 8000
```
চ্যাটে একটি বার্তা টাইপ করার চেষ্টা করুন, আপনি একটি উত্তর দেখতে পাবেন (যদি আপনি এটি Codespace-এ চালাচ্ছেন বা একটি অ্যাক্সেস টোকেন সেটআপ করেছেন)।
## অ্যাক্সেস টোকেন সেটআপ করুন (যদি আপনি এটি Codespace-এ চালাচ্ছেন না)
[ব্যক্তিগত অ্যাক্সেস টোকেন সেটআপ](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) দেখুন
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিক অনুবাদের চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। নথিটির মূল ভাষায় রচিত সংস্করণটিকেই প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে সৃষ্ট কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যার জন্য আমরা দায়ী নই।

@ -1,203 +1,216 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "efa251c5fc089367f0a81c572874afca",
"translation_date": "2025-08-28T02:42:55+00:00",
"original_hash": "687c62646ad5595f1ba733edc294cdae",
"translation_date": "2025-08-28T22:50:11+00:00",
"source_file": "README.md",
"language_code": "bn"
}
-->
[![GitHub license](https://img.shields.io/github/license/microsoft/Web-Dev-For-Beginners.svg)](https://github.com/microsoft/Web-Dev-For-Beginners/blob/master/LICENSE)
[![GitHub contributors](https://img.shields.io/github/contributors/microsoft/Web-Dev-For-Beginners.svg)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/graphs/contributors/)
[![GitHub issues](https://img.shields.io/github/issues/microsoft/Web-Dev-For-Beginners.svg)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/issues/)
[![GitHub pull-requests](https://img.shields.io/github/issues-pr/microsoft/Web-Dev-For-Beginners.svg)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/pulls/)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
[![GitHub license](https://img.shields.io/github/license/microsoft/Web-Dev-For-Beginners.svg)](https://github.com/microsoft/Web-Dev-For-Beginners/blob/master/LICENSE)
[![GitHub contributors](https://img.shields.io/github/contributors/microsoft/Web-Dev-For-Beginners.svg)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/graphs/contributors/)
[![GitHub issues](https://img.shields.io/github/issues/microsoft/Web-Dev-For-Beginners.svg)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/issues/)
[![GitHub pull-requests](https://img.shields.io/github/issues-pr/microsoft/Web-Dev-For-Beginners.svg)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/pulls/)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
[![GitHub watchers](https://img.shields.io/github/watchers/microsoft/Web-Dev-For-Beginners.svg?style=social&label=Watch&maxAge=2592000)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/watchers/)
[![GitHub forks](https://img.shields.io/github/forks/microsoft/Web-Dev-For-Beginners.svg?style=social&label=Fork&maxAge=2592000)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/network/)
[![GitHub stars](https://img.shields.io/github/stars/microsoft/Web-Dev-For-Beginners.svg?style=social&label=Star&maxAge=2592000)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/stargazers/)
[![GitHub watchers](https://img.shields.io/github/watchers/microsoft/Web-Dev-For-Beginners.svg?style=social&label=Watch&maxAge=2592000)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/watchers/)
[![GitHub forks](https://img.shields.io/github/forks/microsoft/Web-Dev-For-Beginners.svg?style=social&label=Fork&maxAge=2592000)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/network/)
[![GitHub stars](https://img.shields.io/github/stars/microsoft/Web-Dev-For-Beginners.svg?style=social&label=Star&maxAge=2592000)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/stargazers/)
[![](https://dcbadge.vercel.app/api/server/ByRwuEEgH4)](https://discord.gg/zxKYvhSnVp?WT.mc_id=academic-000002-leestott)
[![](https://dcbadge.vercel.app/api/server/ByRwuEEgH4)](https://discord.gg/zxKYvhSnVp?WT.mc_id=academic-000002-leestott)
[![Open in Visual Studio Code](https://img.shields.io/static/v1?logo=visualstudiocode&label=&message=Open%20in%20Visual%20Studio%20Code&labelColor=2c2c32&color=007acc&logoColor=007acc)](https://open.vscode.dev/microsoft/Web-Dev-For-Beginners)
[![Open in Visual Studio Code](https://img.shields.io/static/v1?logo=visualstudiocode&label=&message=Open%20in%20Visual%20Studio%20Code&labelColor=2c2c32&color=007acc&logoColor=007acc)](https://open.vscode.dev/microsoft/Web-Dev-For-Beginners)
[![Microsoft Azure AI Foundry Discord](https://dcbadge.limes.pink/api/server/ByRwuEEgH4)](https://discord.com/invite/ByRwuEEgH4)
[![Microsoft Azure AI Foundry Discord](https://dcbadge.limes.pink/api/server/ByRwuEEgH4)](https://discord.com/invite/ByRwuEEgH4)
এই রিসোর্সগুলো ব্যবহার শুরু করতে নিচের ধাপগুলো অনুসরণ করুন:
1. **রিপোজিটরি ফর্ক করুন**: ক্লিক করুন [![GitHub forks](https://img.shields.io/github/forks/microsoft/Web-Dev-For-beginners.svg?style=social&label=Fork)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/fork)
2. **রিপোজিটরি ক্লোন করুন**: `git clone https://github.com/microsoft/Web-Dev-For-Beginners.git`
3. [**Azure AI Foundry Discord-এ যোগ দিন এবং বিশেষজ্ঞ ও অন্যান্য ডেভেলপারদের সাথে পরিচিত হন**](https://discord.com/invite/ByRwuEEgH4)
এই রিসোর্সগুলো ব্যবহার শুরু করতে নিচের ধাপগুলো অনুসরণ করুন:
1. **রিপোজিটরি ফর্ক করুন**: ক্লিক করুন [![GitHub forks](https://img.shields.io/github/forks/microsoft/Web-Dev-For-beginners.svg?style=social&label=Fork)](https://GitHub.com/microsoft/Web-Dev-For-Beginners/fork)
2. **রিপোজিটরি ক্লোন করুন**: `git clone https://github.com/microsoft/Web-Dev-For-Beginners.git`
3. [**Azure AI Foundry Discord-এ যোগ দিন এবং বিশেষজ্ঞ ও অন্যান্য ডেভেলপারদের সাথে পরিচিত হন**](https://discord.com/invite/ByRwuEEgH4)
# ওয়েব ডেভেলপমেন্ট শেখার জন্য একটি কোর্স - শিক্ষার্থীদের জন্য
# ওয়েব ডেভেলপমেন্টের জন্য শিক্ষার্থীদের - একটি কারিকুলাম
মাইক্রোসফট ক্লাউড অ্যাডভোকেটদের ১২ সপ্তাহের এই কোর্সের মাধ্যমে ওয়েব ডেভেলপমেন্টের মৌলিক বিষয়গুলো শিখুন। ২৪টি লেসনে JavaScript, CSS এবং HTML নিয়ে কাজ করুন হাতে-কলমে প্রজেক্টের মাধ্যমে, যেমন টেরারিয়াম, ব্রাউজার এক্সটেনশন এবং স্পেস গেম। কুইজ, আলোচনা এবং প্র্যাকটিক্যাল অ্যাসাইনমেন্টের মাধ্যমে দক্ষতা বৃদ্ধি করুন। প্রজেক্ট-ভিত্তিক শিক্ষার মাধ্যমে আপনার জ্ঞানকে আরও কার্যকরভাবে ধরে রাখুন। আজই কোডিং শেখা শুরু করুন!
মাইক্রোসফট ক্লাউড অ্যাডভোকেটদের ১২-সপ্তাহের বিস্তৃত কোর্সের মাধ্যমে ওয়েব ডেভেলপমেন্টের মৌলিক বিষয়গুলো শিখুন। ২৪টি পাঠে জাভাস্ক্রিপ্ট, CSS এবং HTML নিয়ে কাজ করা প্রকল্পের মাধ্যমে শেখানো হয়, যেমন টেরারিয়াম, ব্রাউজার এক্সটেনশন এবং স্পেস গেম। কুইজ, আলোচনা এবং ব্যবহারিক অ্যাসাইনমেন্টের মাধ্যমে অংশগ্রহণ করুন। আমাদের কার্যকর প্রকল্প-ভিত্তিক শিক্ষাদান পদ্ধতির মাধ্যমে আপনার দক্ষতা বৃদ্ধি করুন এবং জ্ঞান ধরে রাখার ক্ষমতা উন্নত করুন। আজই আপনার কোডিং যাত্রা শুরু করুন!
#### 🧑‍🎓 _আপনি কি একজন শিক্ষার্থী?_
### 🌐 বহু-ভাষার সমর্থন
[**স্টুডেন্ট হাব পেজ**](https://docs.microsoft.com/learn/student-hub/?WT.mc_id=academic-77807-sagibbon) ভিজিট করুন যেখানে আপনি পাবেন শিক্ষার্থীদের জন্য রিসোর্স, স্টুডেন্ট প্যাক এবং এমনকি বিনামূল্যে সার্টিফিকেট ভাউচার পাওয়ার উপায়। এই পেজটি বুকমার্ক করুন এবং মাসিকভাবে নতুন কন্টেন্টের জন্য চেক করুন।
#### GitHub Action এর মাধ্যমে সমর্থিত (স্বয়ংক্রিয় এবং সর্বদা আপডেটেড)
### 📣 ঘোষণা - _নতুন কোর্স_ জেনারেটিভ AI এবং JavaScript নিয়ে প্রকাশিত হয়েছে
[French](../fr/README.md) | [Spanish](../es/README.md) | [German](../de/README.md) | [Russian](../ru/README.md) | [Arabic](../ar/README.md) | [Persian (Farsi)](../fa/README.md) | [Urdu](../ur/README.md) | [Chinese (Simplified)](../zh/README.md) | [Chinese (Traditional, Macau)](../mo/README.md) | [Chinese (Traditional, Hong Kong)](../hk/README.md) | [Chinese (Traditional, Taiwan)](../tw/README.md) | [Japanese](../ja/README.md) | [Korean](../ko/README.md) | [Hindi](../hi/README.md) | [Bengali](./README.md) | [Marathi](../mr/README.md) | [Nepali](../ne/README.md) | [Punjabi (Gurmukhi)](../pa/README.md) | [Portuguese (Portugal)](../pt/README.md) | [Portuguese (Brazil)](../br/README.md) | [Italian](../it/README.md) | [Polish](../pl/README.md) | [Turkish](../tr/README.md) | [Greek](../el/README.md) | [Thai](../th/README.md) | [Swedish](../sv/README.md) | [Danish](../da/README.md) | [Norwegian](../no/README.md) | [Finnish](../fi/README.md) | [Dutch](../nl/README.md) | [Hebrew](../he/README.md) | [Vietnamese](../vi/README.md) | [Indonesian](../id/README.md) | [Malay](../ms/README.md) | [Tagalog (Filipino)](../tl/README.md) | [Swahili](../sw/README.md) | [Hungarian](../hu/README.md) | [Czech](../cs/README.md) | [Slovak](../sk/README.md) | [Romanian](../ro/README.md) | [Bulgarian](../bg/README.md) | [Serbian (Cyrillic)](../sr/README.md) | [Croatian](../hr/README.md) | [Slovenian](../sl/README.md) | [Ukrainian](../uk/README.md) | [Burmese (Myanmar)](../my/README.md)
আমাদের নতুন জেনারেটিভ AI কোর্স মিস করবেন না!
**যদি আপনি অতিরিক্ত ভাষার অনুবাদ চান, সমর্থিত ভাষার তালিকা [এখানে](https://github.com/Azure/co-op-translator/blob/main/getting_started/supported-languages.md) দেওয়া আছে।**
শুরু করতে ভিজিট করুন [https://aka.ms/genai-js-course](https://aka.ms/genai-js-course)!
#### 🧑‍🎓 _আপনি কি একজন শিক্ষার্থী?_
![Background](../../translated_images/background.148a8d43afde57303419a663f50daf586681bc2fabf833f66ef6954073983c66.bn.png)
[**Student Hub পেজ**](https://docs.microsoft.com/learn/student-hub/?WT.mc_id=academic-77807-sagibbon) ভিজিট করুন যেখানে আপনি শিক্ষার্থীদের জন্য রিসোর্স, স্টুডেন্ট প্যাক এবং এমনকি বিনামূল্যে সার্টিফিকেট ভাউচার পাওয়ার উপায় খুঁজে পাবেন। এটি এমন একটি পেজ যা আপনি বুকমার্ক করতে পারেন এবং সময় সময় চেক করতে পারেন কারণ আমরা প্রতি মাসে কন্টেন্ট পরিবর্তন করি।
- বেসিক থেকে RAG পর্যন্ত লেসন।
- জেনারেটিভ AI এবং আমাদের সঙ্গী অ্যাপ ব্যবহার করে ঐতিহাসিক চরিত্রের সাথে ইন্টারঅ্যাক্ট করুন।
- মজার এবং আকর্ষণীয় গল্প, আপনি সময় ভ্রমণ করবেন!
### 📣 ঘোষণা - _জেনারেটিভ AI ব্যবহার করে নতুন প্রকল্প তৈরি করুন_
![character](../../translated_images/character.5c0dd8e067ffd693c16e2c5b7412ab075a2215ce31f998305639fa3a05e14fbe.bn.png)
নতুন AI অ্যাসিস্ট্যান্ট প্রকল্প যোগ করা হয়েছে, এটি দেখুন [প্রকল্প](./09-chat-project/README.md)
প্রতিটি লেসনে রয়েছে:
- প্রম্পটিং এবং প্রম্পট ইঞ্জিনিয়ারিং
- টেক্সট এবং ইমেজ অ্যাপ তৈরি
- সার্চ অ্যাপ
### 📣 ঘোষণা - _জেনারেটিভ AI এর নতুন কারিকুলাম_ জাভাস্ক্রিপ্টের জন্য প্রকাশিত হয়েছে
শুরু করতে ভিজিট করুন [https://aka.ms/genai-js-course](https://aka.ms/genai-js-course)!
আমাদের নতুন জেনারেটিভ AI কারিকুলাম মিস করবেন না!
## 🌱 শুরু করা
শুরু করতে ভিজিট করুন [https://aka.ms/genai-js-course](https://aka.ms/genai-js-course)!
> **শিক্ষকগণ**, আমরা [কিছু পরামর্শ](for-teachers.md) অন্তর্ভুক্ত করেছি এই কোর্সটি কীভাবে ব্যবহার করবেন। আমাদের [আলোচনা ফোরামে](https://github.com/microsoft/Web-Dev-For-Beginners/discussions/categories/teacher-corner) আপনার মতামত জানাতে পারেন!
![Background](../../translated_images/background.148a8d43afde57303419a663f50daf586681bc2fabf833f66ef6954073983c66.bn.png)
**[শিক্ষার্থীরা](https://aka.ms/student-page/?WT.mc_id=academic-77807-sagibbon)**, প্রতিটি লেসনের জন্য, প্রি-লেকচার কুইজ দিয়ে শুরু করুন এবং লেকচার মেটেরিয়াল পড়ুন, বিভিন্ন কার্যক্রম সম্পন্ন করুন এবং পোস্ট-লেকচার কুইজ দিয়ে আপনার জ্ঞান যাচাই করুন।
- বেসিক থেকে RAG পর্যন্ত সবকিছু নিয়ে পাঠ।
- GenAI এবং আমাদের সঙ্গী অ্যাপ ব্যবহার করে ঐতিহাসিক চরিত্রের সাথে ইন্টারঅ্যাক্ট করুন।
- মজাদার এবং আকর্ষণীয় গল্প, আপনি সময় ভ্রমণ করবেন!
আপনার শেখার অভিজ্ঞতা উন্নত করতে, আপনার সহপাঠীদের সাথে প্রজেক্টে কাজ করুন! আলোচনা উৎসাহিত করা হয় আমাদের [আলোচনা ফোরামে](https://github.com/microsoft/Web-Dev-For-Beginners/discussions) যেখানে আমাদের মডারেটর টিম আপনার প্রশ্নের উত্তর দিতে প্রস্তুত থাকবে।
![character](../../translated_images/character.5c0dd8e067ffd693c16e2c5b7412ab075a2215ce31f998305639fa3a05e14fbe.bn.png)
আপনার শিক্ষা আরও এগিয়ে নিতে, আমরা [Microsoft Learn](https://learn.microsoft.com/users/wirelesslife/collections/p1ddcy5jwy0jkm?WT.mc_id=academic-77807-sagibbon) এক্সপ্লোর করার পরামর্শ দিচ্ছি অতিরিক্ত স্টাডি মেটেরিয়ালের জন্য।
প্রতিটি পাঠে একটি অ্যাসাইনমেন্ট, একটি জ্ঞান যাচাই এবং একটি চ্যালেঞ্জ অন্তর্ভুক্ত থাকে যা আপনাকে শেখার বিষয়গুলোতে গাইড করবে:
- প্রম্পটিং এবং প্রম্পট ইঞ্জিনিয়ারিং
- টেক্সট এবং ইমেজ অ্যাপ জেনারেশন
- সার্চ অ্যাপস
### 📋 আপনার পরিবেশ সেটআপ করুন
শুরু করতে ভিজিট করুন [https://aka.ms/genai-js-course](../../[https:/aka.ms/genai-js-course)!
এই কোর্সের জন্য একটি ডেভেলপমেন্ট পরিবেশ প্রস্তুত রয়েছে! শুরু করার সময় আপনি [Codespace](https://github.com/features/codespaces/) (_ব্রাউজার-ভিত্তিক, কোনো ইনস্টল প্রয়োজন নেই_) অথবা আপনার কম্পিউটারে লোকালি একটি টেক্সট এডিটর ব্যবহার করতে পারেন যেমন [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)।
#### আপনার রিপোজিটরি তৈরি করুন
আপনার কাজ সহজে সংরক্ষণ করতে, আপনার নিজস্ব কপি তৈরি করার পরামর্শ দেওয়া হয়। এটি করতে পেজের উপরে **Use this template** বাটনে ক্লিক করুন। এটি আপনার GitHub অ্যাকাউন্টে একটি নতুন রিপোজিটরি তৈরি করবে।
ধাপগুলো অনুসরণ করুন:
1. **রিপোজিটরি ফর্ক করুন**: এই পেজের উপরের ডানদিকে থাকা "Fork" বাটনে ক্লিক করুন।
2. **রিপোজিটরি ক্লোন করুন**: `git clone https://github.com/microsoft/Web-Dev-For-Beginners.git`
## 🌱 শুরু করা
#### Codespace-এ কোর্স চালানো
> **শিক্ষকগণ**, আমরা [কিছু পরামর্শ](for-teachers.md) অন্তর্ভুক্ত করেছি এই কারিকুলাম কীভাবে ব্যবহার করবেন। আমাদের [আলোচনা ফোরামে](https://github.com/microsoft/Web-Dev-For-Beginners/discussions/categories/teacher-corner) আপনার মতামত জানাতে ভালো লাগবে!
আপনার তৈরি করা রিপোজিটরিতে **Code** বাটনে ক্লিক করুন এবং **Open with Codespaces** নির্বাচন করুন। এটি আপনার কাজের জন্য একটি নতুন Codespace তৈরি করবে।
**[শিক্ষার্থীরা](https://aka.ms/student-page/?WT.mc_id=academic-77807-sagibbon)**, প্রতিটি পাঠের জন্য, একটি প্রি-লেকচার কুইজ দিয়ে শুরু করুন এবং লেকচার মেটেরিয়াল পড়ুন, বিভিন্ন কার্যক্রম সম্পন্ন করুন এবং পোস্ট-লেকচার কুইজ দিয়ে আপনার জ্ঞান যাচাই করুন।
[!Codespace](./images/createcodespace.png)
আপনার শেখার অভিজ্ঞতা উন্নত করতে, আপনার সহপাঠীদের সাথে প্রকল্পগুলোতে কাজ করুন! আমাদের [আলোচনা ফোরামে](https://github.com/microsoft/Web-Dev-For-Beginners/discussions) আলোচনা উৎসাহিত করা হয় যেখানে আমাদের মডারেটর টিম আপনার প্রশ্নের উত্তর দিতে প্রস্তুত থাকবে।
#### আপনার কম্পিউটারে লোকালি কোর্স চালানো
আপনার শিক্ষা আরও এগিয়ে নিতে, আমরা [Microsoft Learn](https://learn.microsoft.com/users/wirelesslife/collections/p1ddcy5jwy0jkm?WT.mc_id=academic-77807-sagibbon) অনুসন্ধান করার জন্য অত্যন্ত সুপারিশ করি যেখানে অতিরিক্ত শিক্ষার উপকরণ পাওয়া যাবে।
আপনার কম্পিউটারে কোর্স চালানোর জন্য, একটি টেক্সট এডিটর, একটি ব্রাউজার এবং একটি কমান্ড লাইন টুল প্রয়োজন। আমাদের প্রথম লেসন, [প্রোগ্রামিং ভাষা এবং টুলসের পরিচিতি](../../1-getting-started-lessons/1-intro-to-programming-languages), আপনাকে বিভিন্ন টুলের অপশন দেখাবে যা আপনার জন্য সবচেয়ে ভালো কাজ করবে।
### 📋 আপনার পরিবেশ সেট আপ করা
আমাদের সুপারিশ হলো [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) ব্যবহার করা, যা একটি বিল্ট-ইন [Terminal](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon) সহ আসে। Visual Studio Code [এখানে](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) ডাউনলোড করুন
এই কারিকুলামের জন্য একটি ডেভেলপমেন্ট পরিবেশ প্রস্তুত রয়েছে! শুরু করার সময় আপনি [Codespace](https://github.com/features/codespaces/) (_ব্রাউজার-ভিত্তিক, কোনো ইনস্টল প্রয়োজন নেই_) অথবা আপনার কম্পিউটারে লোকালি একটি টেক্সট এডিটর ব্যবহার করতে পারেন যেমন [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)।
1. আপনার রিপোজিটরি কম্পিউটারে ক্লোন করুন। এটি করতে **Code** বাটনে ক্লিক করুন এবং URL কপি করুন:
#### আপনার রিপোজিটরি তৈরি করুন
আপনার কাজ সহজে সংরক্ষণ করার জন্য, আপনার নিজস্ব কপি তৈরি করার সুপারিশ করা হয়। আপনি পেজের উপরে **Use this template** বাটনে ক্লিক করে এটি করতে পারেন। এটি আপনার GitHub অ্যাকাউন্টে কারিকুলামের একটি কপি সহ একটি নতুন রিপোজিটরি তৈরি করবে।
[!CodeSpace](./images/createcodespace.png)
নিচের ধাপগুলো অনুসরণ করুন:
1. **রিপোজিটরি ফর্ক করুন**: এই পেজের উপরের ডানদিকে থাকা "Fork" বাটনে ক্লিক করুন।
2. **রিপোজিটরি ক্লোন করুন**: `git clone https://github.com/microsoft/Web-Dev-For-Beginners.git`
তারপর, [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)-এর [Terminal](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon) খুলুন এবং নিচের কমান্ডটি চালান, `<your-repository-url>` এর জায়গায় আপনার কপি করা URL বসান:
#### Codespace-এ কারিকুলাম চালানো
আপনার তৈরি করা এই রিপোজিটরির কপিতে, **Code** বাটনে ক্লিক করুন এবং **Open with Codespaces** নির্বাচন করুন। এটি আপনার কাজ করার জন্য একটি নতুন Codespace তৈরি করবে।
[!Codespace](../..)./images/createcodespace.png)
#### আপনার কম্পিউটারে লোকালি কারিকুলাম চালানো
আপনার কম্পিউটারে লোকালি কারিকুলাম চালানোর জন্য, একটি টেক্সট এডিটর, একটি ব্রাউজার এবং একটি কমান্ড লাইন টুল প্রয়োজন। আমাদের প্রথম পাঠ, [প্রোগ্রামিং ভাষা এবং টুলস অফ দ্য ট্রেডের পরিচিতি](../../1-getting-started-lessons/1-intro-to-programming-languages), আপনাকে এই টুলগুলোর বিভিন্ন অপশন দেখাবে যাতে আপনি আপনার জন্য সেরা অপশনটি বেছে নিতে পারেন।
আমাদের সুপারিশ হলো [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) ব্যবহার করা, যা একটি বিল্ট-ইন [Terminal](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon) সহ আসে। আপনি [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon) এখান থেকে ডাউনলোড করতে পারেন।
1. আপনার রিপোজিটরি কম্পিউটারে ক্লোন করুন। এটি করতে, **Code** বাটনে ক্লিক করুন এবং URL কপি করুন:
[!CodeSpace](./images/createcodespace.png)
তারপর, [Visual Studio Code](https://code.visualstudio.com/?WT.mc_id=academic-77807-sagibbon)-এর মধ্যে [Terminal](https://code.visualstudio.com/docs/terminal/basics/?WT.mc_id=academic-77807-sagibbon) খুলুন এবং নিচের কমান্ডটি চালান, যেখানে `<your-repository-url>` আপনার কপি করা URL দিয়ে প্রতিস্থাপন করুন:
```bash
git clone <your-repository-url>
```
2. Visual Studio Code-এ ফোল্ডারটি খুলুন। এটি করতে **File** > **Open Folder**-এ ক্লিক করুন এবং ক্লোন করা ফোল্ডারটি নির্বাচন করুন।
> Visual Studio Code-এর জন্য সুপারিশকৃত এক্সটেনশন:
>
> * [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) - HTML পেজগুলো Visual Studio Code-এর মধ্যে প্রিভিউ করার জন্য
> * [Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot&WT.mc_id=academic-77807-sagibbon) - কোড দ্রুত লেখার জন্য সাহায্য করতে
## 📂 প্রতিটি লেসনে রয়েছে:
- ঐচ্ছিক স্কেচনোট
- ঐচ্ছিক সম্পূরক ভিডিও
- প্রি-লেসন ওয়ার্মআপ কুইজ
- লিখিত লেসন
- প্রজেক্ট-ভিত্তিক লেসনের জন্য, প্রজেক্ট তৈরি করার ধাপে ধাপে গাইড
- জ্ঞান যাচাই
- একটি চ্যালেঞ্জ
- সম্পূরক পড়াশোনা
- অ্যাসাইনমেন্ট
- [পোস্ট-লেসন কুইজ](https://ff-quizzes.netlify.app/web/)
> **কুইজ সম্পর্কে একটি নোট**: সব কুইজ `Quiz-app` ফোল্ডারে রয়েছে, মোট ৪৮টি কুইজ, প্রতিটিতে তিনটি প্রশ্ন। এগুলো [এখানে](https://ff-quizzes.netlify.app/web/) পাওয়া যাবে। কুইজ অ্যাপ লোকালি চালানো বা Azure-এ ডিপ্লয় করা যাবে; `quiz-app` ফোল্ডারে নির্দেশনা অনুসরণ করুন।
## 🗃️ লেসনসমূহ
| | প্রজেক্টের নাম | শেখানো ধারণা | শেখার লক্ষ্য | লিঙ্কযুক্ত লেসন | লেখক |
| :-: | :------------------------------------------------------: | :--------------------------------------------------------------------: | ----------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------: | :---------------------: |
| 01 | শুরু করা | প্রোগ্রামিং এবং টুলসের পরিচিতি | বেশিরভাগ প্রোগ্রামিং ভাষার মৌলিক বিষয় এবং পেশাদার ডেভেলপারদের কাজে সাহায্যকারী সফটওয়্যার সম্পর্কে জানুন | [প্রোগ্রামিং ভাষা এবং টুলসের পরিচিতি](./1-getting-started-lessons/1-intro-to-programming-languages/README.md) | Jasmine |
| 02 | শুরু করা | GitHub-এর বেসিক, টিমের সাথে কাজ করা | আপনার প্রজেক্টে GitHub ব্যবহার করা, কোড বেসে অন্যদের সাথে সহযোগিতা করা | [GitHub-এর পরিচিতি](./1-getting-started-lessons/2-github-basics/README.md) | Floor |
| 03 | শুরু করা | অ্যাক্সেসিবিলিটি | ওয়েব অ্যাক্সেসিবিলিটির মৌলিক বিষয়গুলো শিখুন | [অ্যাক্সেসিবিলিটির মৌলিক বিষয়](./1-getting-started-lessons/3-accessibility/README.md) | Christopher |
| 04 | JS বেসিক | JavaScript ডেটা টাইপ | JavaScript ডেটা টাইপের মৌলিক বিষয়গুলো শিখুন | [ডেটা টাইপ](./2-js-basics/1-data-types/README.md) | Jasmine |
| 05 | JS বেসিক | ফাংশন এবং মেথড | একটি অ্যাপ্লিকেশনের লজিক প্রবাহ পরিচালনা করতে ফাংশন এবং মেথড সম্পর্কে জানুন | [ফাংশন এবং মেথড](./2-js-basics/2-functions-methods/README.md) | Jasmine এবং Christopher |
| 06 | JS বেসিক | JS দিয়ে সিদ্ধান্ত নেওয়া | সিদ্ধান্ত নেওয়ার পদ্ধতি ব্যবহার করে আপনার কোডে শর্ত তৈরি করা শিখুন | [সিদ্ধান্ত নেওয়া](./2-js-basics/3-making-decisions/README.md) | Jasmine |
| 07 | JS বেসিক | অ্যারে এবং লুপ | JavaScript-এ ডেটা নিয়ে কাজ করুন অ্যারে এবং লুপ ব্যবহার করে | [অ্যারে এবং লুপ](./2-js-basics/4-arrays-loops/README.md) | Jasmine |
| 08 | [টেরারিয়াম](./3-terrarium/solution/README.md) | HTML ব্যবহারিকভাবে | একটি অনলাইন টেরারিয়াম তৈরি করতে HTML ব্যবহার করুন, লেআউট তৈরি করার উপর ফোকাস | [HTML-এর পরিচিতি](./3-terrarium/1-intro-to-html/README.md) | Jen |
| 09 | [টেরারিয়াম](./3-terrarium/solution/README.md) | CSS ব্যবহারিকভাবে | অনলাইন টেরারিয়াম স্টাইল করতে CSS ব্যবহার করুন, CSS-এর মৌলিক বিষয়গুলো নিয়ে কাজ করুন, যেমন পেজকে রেসপন্সিভ করা | [CSS-এর পরিচিতি](./3-terrarium/2-intro-to-css/README.md) | Jen |
| 10 | [Terrarium](./3-terrarium/solution/README.md) | জাভাস্ক্রিপ্ট ক্লোজারস, DOM ম্যানিপুলেশন | টেরারিয়ামকে ড্র্যাগ/ড্রপ ইন্টারফেস হিসেবে কাজ করার জন্য জাভাস্ক্রিপ্ট তৈরি করুন, ক্লোজারস এবং DOM ম্যানিপুলেশনের উপর ফোকাস করে | [জাভাস্ক্রিপ্ট ক্লোজারস, DOM ম্যানিপুলেশন](./3-terrarium/3-intro-to-DOM-and-closures/README.md) | Jen |
| 11 | [Typing Game](./4-typing-game/solution/README.md) | একটি টাইপিং গেম তৈরি করুন | কী-বোর্ড ইভেন্ট ব্যবহার করে কীভাবে আপনার জাভাস্ক্রিপ্ট অ্যাপের লজিক চালানো যায় তা শিখুন | [ইভেন্ট-ড্রিভেন প্রোগ্রামিং](./4-typing-game/typing-game/README.md) | Christopher |
| 12 | [Green Browser Extension](./5-browser-extension/solution/README.md) | ব্রাউজার নিয়ে কাজ করা | ব্রাউজার কীভাবে কাজ করে, তাদের ইতিহাস এবং একটি ব্রাউজার এক্সটেনশনের প্রথম উপাদানগুলি কীভাবে তৈরি করতে হয় তা শিখুন | [ব্রাউজার সম্পর্কে](./5-browser-extension/1-about-browsers/README.md) | Jen |
| 13 | [Green Browser Extension](./5-browser-extension/solution/README.md) | একটি ফর্ম তৈরি করা, API কল করা এবং ভেরিয়েবল লোকাল স্টোরেজে সংরক্ষণ করা | আপনার ব্রাউজার এক্সটেনশনের জাভাস্ক্রিপ্ট উপাদান তৈরি করুন যা লোকাল স্টোরেজে সংরক্ষিত ভেরিয়েবল ব্যবহার করে API কল করে | [API, ফর্ম এবং লোকাল স্টোরেজ](./5-browser-extension/2-forms-browsers-local-storage/README.md) | Jen |
| 14 | [Green Browser Extension](./5-browser-extension/solution/README.md) | ব্রাউজারের ব্যাকগ্রাউন্ড প্রসেস, ওয়েব পারফরম্যান্স | এক্সটেনশনের আইকন পরিচালনার জন্য ব্রাউজারের ব্যাকগ্রাউন্ড প্রসেস ব্যবহার করুন; ওয়েব পারফরম্যান্স এবং কিছু অপ্টিমাইজেশন সম্পর্কে জানুন | [ব্যাকগ্রাউন্ড টাস্ক এবং পারফরম্যান্স](./5-browser-extension/3-background-tasks-and-performance/README.md) | Jen |
| 15 | [Space Game](./6-space-game/solution/README.md) | জাভাস্ক্রিপ্ট দিয়ে আরও উন্নত গেম ডেভেলপমেন্ট | ক্লাস এবং কম্পোজিশন উভয় ব্যবহার করে ইনহেরিটেন্স এবং পাব/সাব প্যাটার্ন সম্পর্কে জানুন, একটি গেম তৈরি করার প্রস্তুতি হিসেবে | [উন্নত গেম ডেভেলপমেন্টের পরিচিতি](./6-space-game/1-introduction/README.md) | Chris |
| 16 | [Space Game](./6-space-game/solution/README.md) | ক্যানভাসে আঁকা | ক্যানভাস API সম্পর্কে জানুন, যা স্ক্রিনে উপাদান আঁকতে ব্যবহৃত হয় | [ক্যানভাসে আঁকা](./6-space-game/2-drawing-to-canvas/README.md) | Chris |
| 17 | [Space Game](./6-space-game/solution/README.md) | স্ক্রিনে উপাদান সরানো | কার্টেসিয়ান কোঅর্ডিনেট এবং ক্যানভাস API ব্যবহার করে কীভাবে উপাদানগুলোকে গতি দেওয়া যায় তা আবিষ্কার করুন | [উপাদান সরানো](./6-space-game/3-moving-elements-around/README.md) | Chris |
| 18 | [Space Game](./6-space-game/solution/README.md) | সংঘর্ষ সনাক্তকরণ | কীপ্রেস ব্যবহার করে উপাদানগুলোকে একে অপরের সাথে সংঘর্ষ করান এবং প্রতিক্রিয়া জানান এবং গেমের পারফরম্যান্স নিশ্চিত করতে একটি কুলডাউন ফাংশন প্রদান করুন | [সংঘর্ষ সনাক্তকরণ](./6-space-game/4-collision-detection/README.md) | Chris |
| 19 | [Space Game](./6-space-game/solution/README.md) | স্কোর রাখা | গেমের অবস্থা এবং পারফরম্যান্সের উপর ভিত্তি করে গাণিতিক হিসাব সম্পাদন করুন | [স্কোর রাখা](./6-space-game/5-keeping-score/README.md) | Chris |
| 20 | [Space Game](./6-space-game/solution/README.md) | গেম শেষ করা এবং পুনরায় শুরু করা | গেম শেষ এবং পুনরায় শুরু করার পদ্ধতি শিখুন, যার মধ্যে অ্যাসেট পরিষ্কার করা এবং ভেরিয়েবল মান রিসেট করা অন্তর্ভুক্ত | [শেষ করার শর্ত](./6-space-game/6-end-condition/README.md) | Chris |
| 21 | [Banking App](./7-bank-project/solution/README.md) | একটি ওয়েব অ্যাপে HTML টেমপ্লেট এবং রুট | রাউটিং এবং HTML টেমপ্লেট ব্যবহার করে একটি মাল্টিপেজ ওয়েবসাইটের কাঠামো তৈরি করা শিখুন | [HTML টেমপ্লেট এবং রুট](./7-bank-project/1-template-route/README.md) | Yohan |
| 22 | [Banking App](./7-bank-project/solution/README.md) | একটি লগইন এবং রেজিস্ট্রেশন ফর্ম তৈরি করুন | ফর্ম তৈরি এবং ভ্যালিডেশন রুটিন পরিচালনা সম্পর্কে জানুন | [ফর্ম](./7-bank-project/2-forms/README.md) | Yohan |
| 23 | [Banking App](./7-bank-project/solution/README.md) | ডেটা আনার এবং ব্যবহারের পদ্ধতি | আপনার অ্যাপে ডেটা কীভাবে প্রবাহিত হয়, কীভাবে এটি আনা, সংরক্ষণ এবং নিষ্পত্তি করা যায় তা শিখুন | [ডেটা](./7-bank-project/3-data/README.md) | Yohan |
| 24 | [Banking App](./7-bank-project/solution/README.md) | স্টেট ম্যানেজমেন্টের ধারণা | আপনার অ্যাপ কীভাবে স্টেট ধরে রাখে এবং কীভাবে এটি প্রোগ্রাম্যাটিকভাবে পরিচালনা করা যায় তা শিখুন | [স্টেট ম্যানেজমেন্ট](./7-bank-project/4-state-management/README.md) | Yohan |
```
2. Visual Studio Code-এ ফোল্ডারটি খুলুন। এটি করতে **File** বাটনে ক্লিক করুন।
> **ফোল্ডার খুলুন** এবং আপনি যে ফোল্ডারটি ক্লোন করেছেন সেটি নির্বাচন করুন।
> ভিজ্যুয়াল স্টুডিও কোডের জন্য প্রস্তাবিত এক্সটেনশনসমূহ:
>
> * [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) - ভিজ্যুয়াল স্টুডিও কোডে HTML পেজ প্রিভিউ করার জন্য
> * [Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot&WT.mc_id=academic-77807-sagibbon) - কোড দ্রুত লেখার জন্য সহায়ক
## 📂 প্রতিটি পাঠে অন্তর্ভুক্ত:
- ঐচ্ছিক স্কেচনোট
- ঐচ্ছিক সম্পূরক ভিডিও
- পাঠের পূর্বে ওয়ার্মআপ কুইজ
- লিখিত পাঠ
- প্রকল্পভিত্তিক পাঠের জন্য, ধাপে ধাপে প্রকল্প তৈরির গাইড
- জ্ঞান যাচাই
- একটি চ্যালেঞ্জ
- সম্পূরক পড়াশোনা
- অ্যাসাইনমেন্ট
- [পাঠ-পরবর্তী কুইজ](https://ff-quizzes.netlify.app/web/)
> **কুইজ সম্পর্কে একটি নোট**: সব কুইজ `Quiz-app` ফোল্ডারে অন্তর্ভুক্ত, মোট ৪৮টি কুইজ, প্রতিটিতে তিনটি প্রশ্ন। এগুলো [এখানে](https://ff-quizzes.netlify.app/web/) পাওয়া যাবে। কুইজ অ্যাপটি লোকাল মেশিনে চালানো বা Azure-এ ডিপ্লয় করা যেতে পারে; `quiz-app` ফোল্ডারের নির্দেশনা অনুসরণ করুন।
## 🗃️ পাঠসমূহ
| | প্রকল্পের নাম | শেখানো ধারণাসমূহ | শেখার লক্ষ্য | লিঙ্ককৃত পাঠ | লেখক |
| :-: | :------------------------------------------------------: | :--------------------------------------------------------------------: | ----------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------: | :---------------------: |
| 01 | শুরু করা | প্রোগ্রামিং এবং প্রয়োজনীয় টুলসের পরিচিতি | বেশিরভাগ প্রোগ্রামিং ভাষার মৌলিক বিষয় এবং পেশাদার ডেভেলপারদের কাজে সহায়ক সফটওয়্যার সম্পর্কে জানুন | [প্রোগ্রামিং ভাষা এবং টুলসের পরিচিতি](./1-getting-started-lessons/1-intro-to-programming-languages/README.md) | Jasmine |
| 02 | শুরু করা | GitHub-এর বেসিকস, টিমের সাথে কাজ করা | আপনার প্রকল্পে GitHub ব্যবহার করা এবং কোডবেসে অন্যদের সাথে সহযোগিতা করা শিখুন | [GitHub-এর পরিচিতি](./1-getting-started-lessons/2-github-basics/README.md) | Floor |
| 03 | শুরু করা | অ্যাক্সেসিবিলিটি | ওয়েব অ্যাক্সেসিবিলিটির মৌলিক বিষয় শিখুন | [অ্যাক্সেসিবিলিটির মৌলিক বিষয়](./1-getting-started-lessons/3-accessibility/README.md) | Christopher |
| 04 | জাভাস্ক্রিপ্ট বেসিক | জাভাস্ক্রিপ্ট ডেটা টাইপ | জাভাস্ক্রিপ্ট ডেটা টাইপের মৌলিক বিষয় শিখুন | [ডেটা টাইপ](./2-js-basics/1-data-types/README.md) | Jasmine |
| 05 | জাভাস্ক্রিপ্ট বেসিক | ফাংশন এবং মেথড | অ্যাপ্লিকেশনের লজিক প্রবাহ পরিচালনার জন্য ফাংশন এবং মেথড সম্পর্কে জানুন | [ফাংশন এবং মেথড](./2-js-basics/2-functions-methods/README.md) | Jasmine এবং Christopher |
| 06 | জাভাস্ক্রিপ্ট বেসিক | জাভাস্ক্রিপ্ট দিয়ে সিদ্ধান্ত নেওয়া | সিদ্ধান্ত গ্রহণের পদ্ধতি ব্যবহার করে কোডে শর্ত তৈরি করা শিখুন | [সিদ্ধান্ত গ্রহণ](./2-js-basics/3-making-decisions/README.md) | Jasmine |
| 07 | জাভাস্ক্রিপ্ট বেসিক | অ্যারে এবং লুপ | জাভাস্ক্রিপ্টে অ্যারে এবং লুপ ব্যবহার করে ডেটা নিয়ে কাজ করুন | [অ্যারে এবং লুপ](./2-js-basics/4-arrays-loops/README.md) | Jasmine |
| 08 | [টেরারিয়াম](./3-terrarium/solution/README.md) | HTML অনুশীলন | একটি অনলাইন টেরারিয়াম তৈরি করতে HTML ব্যবহার করুন, লেআউট তৈরির উপর ফোকাস করুন | [HTML-এর পরিচিতি](./3-terrarium/1-intro-to-html/README.md) | Jen |
| 09 | [টেরারিয়াম](./3-terrarium/solution/README.md) | CSS অনুশীলন | অনলাইন টেরারিয়াম স্টাইল করার জন্য CSS ব্যবহার করুন, CSS-এর বেসিকস এবং পেজ রেসপন্সিভ করার উপর ফোকাস করুন | [CSS-এর পরিচিতি](./3-terrarium/2-intro-to-css/README.md) | Jen |
| 10 | [টেরারিয়াম](./3-terrarium/solution/README.md) | জাভাস্ক্রিপ্ট ক্লোজার, DOM ম্যানিপুলেশন | টেরারিয়ামকে ড্র্যাগ/ড্রপ ইন্টারফেস হিসেবে কাজ করানোর জন্য জাভাস্ক্রিপ্ট তৈরি করুন, ক্লোজার এবং DOM ম্যানিপুলেশনের উপর ফোকাস করুন | [জাভাস্ক্রিপ্ট ক্লোজার, DOM ম্যানিপুলেশন](./3-terrarium/3-intro-to-DOM-and-closures/README.md) | Jen |
| 11 | [টাইপিং গেম](./4-typing-game/solution/README.md) | টাইপিং গেম তৈরি করুন | কী-বোর্ড ইভেন্ট ব্যবহার করে আপনার জাভাস্ক্রিপ্ট অ্যাপের লজিক চালানোর পদ্ধতি শিখুন | [ইভেন্ট-চালিত প্রোগ্রামিং](./4-typing-game/typing-game/README.md) | Christopher |
| 12 | [সবুজ ব্রাউজার এক্সটেনশন](./5-browser-extension/solution/README.md) | ব্রাউজারের সাথে কাজ করা | ব্রাউজার কীভাবে কাজ করে, তাদের ইতিহাস এবং একটি ব্রাউজার এক্সটেনশনের প্রথম উপাদান তৈরি করার পদ্ধতি শিখুন | [ব্রাউজার সম্পর্কে](./5-browser-extension/1-about-browsers/README.md) | Jen |
| 13 | [সবুজ ব্রাউজার এক্সটেনশন](./5-browser-extension/solution/README.md) | একটি ফর্ম তৈরি করা, একটি API কল করা এবং স্থানীয় স্টোরেজে ভেরিয়েবল সংরক্ষণ করা | স্থানীয় স্টোরেজে সংরক্ষিত ভেরিয়েবল ব্যবহার করে একটি API কল করার জন্য আপনার ব্রাউজার এক্সটেনশনের জাভাস্ক্রিপ্ট উপাদান তৈরি করুন | [API, ফর্ম এবং স্থানীয় স্টোরেজ](./5-browser-extension/2-forms-browsers-local-storage/README.md) | Jen |
| 14 | [সবুজ ব্রাউজার এক্সটেনশন](./5-browser-extension/solution/README.md) | ব্রাউজারের ব্যাকগ্রাউন্ড প্রসেস, ওয়েব পারফরম্যান্স | এক্সটেনশনের আইকন পরিচালনার জন্য ব্রাউজারের ব্যাকগ্রাউন্ড প্রসেস ব্যবহার করুন; ওয়েব পারফরম্যান্স এবং কিছু অপ্টিমাইজেশন সম্পর্কে জানুন | [ব্যাকগ্রাউন্ড টাস্ক এবং পারফরম্যান্স](./5-browser-extension/3-background-tasks-and-performance/README.md) | Jen |
| 15 | [স্পেস গেম](./6-space-game/solution/README.md) | জাভাস্ক্রিপ্ট দিয়ে আরও উন্নত গেম ডেভেলপমেন্ট | ক্লাস এবং কম্পোজিশন ব্যবহার করে ইনহেরিটেন্স এবং পাব/সাব প্যাটার্ন সম্পর্কে জানুন, একটি গেম তৈরির প্রস্তুতি হিসেবে | [উন্নত গেম ডেভেলপমেন্টের পরিচিতি](./6-space-game/1-introduction/README.md) | Chris |
| 16 | [স্পেস গেম](./6-space-game/solution/README.md) | ক্যানভাসে আঁকা | ক্যানভাস API সম্পর্কে জানুন, যা স্ক্রিনে উপাদান আঁকতে ব্যবহৃত হয় | [ক্যানভাসে আঁকা](./6-space-game/2-drawing-to-canvas/README.md) | Chris |
| 17 | [স্পেস গেম](./6-space-game/solution/README.md) | স্ক্রিনে উপাদান সরানো | কার্টেসিয়ান কোঅর্ডিনেট এবং ক্যানভাস API ব্যবহার করে উপাদানগুলো কীভাবে গতি পায় তা আবিষ্কার করুন | [উপাদান সরানো](./6-space-game/3-moving-elements-around/README.md) | Chris |
| 18 | [স্পেস গেম](./6-space-game/solution/README.md) | সংঘর্ষ সনাক্তকরণ | কীপ্রেস ব্যবহার করে উপাদানগুলোকে একে অপরের সাথে সংঘর্ষ করানো এবং প্রতিক্রিয়া জানানো শিখুন; গেমের পারফরম্যান্স নিশ্চিত করতে কুলডাউন ফাংশন প্রদান করুন | [সংঘর্ষ সনাক্তকরণ](./6-space-game/4-collision-detection/README.md) | Chris |
| 19 | [স্পেস গেম](./6-space-game/solution/README.md) | স্কোর রাখা | গেমের অবস্থা এবং পারফরম্যান্সের উপর ভিত্তি করে গাণিতিক হিসাব করুন | [স্কোর রাখা](./6-space-game/5-keeping-score/README.md) | Chris |
| 20 | [স্পেস গেম](./6-space-game/solution/README.md) | গেম শেষ করা এবং পুনরায় শুরু করা | গেম শেষ করা এবং পুনরায় শুরু করার পদ্ধতি শিখুন, যার মধ্যে অ্যাসেট পরিষ্কার করা এবং ভেরিয়েবল মান রিসেট করা অন্তর্ভুক্ত | [শেষের শর্ত](./6-space-game/6-end-condition/README.md) | Chris |
| 21 | [ব্যাংকিং অ্যাপ](./7-bank-project/solution/README.md) | ওয়েব অ্যাপে HTML টেমপ্লেট এবং রুট | রাউটিং এবং HTML টেমপ্লেট ব্যবহার করে একটি মাল্টিপেজ ওয়েবসাইটের কাঠামো তৈরি করা শিখুন | [HTML টেমপ্লেট এবং রুট](./7-bank-project/1-template-route/README.md) | Yohan |
| 22 | [ব্যাংকিং অ্যাপ](./7-bank-project/solution/README.md) | লগইন এবং রেজিস্ট্রেশন ফর্ম তৈরি করা | ফর্ম তৈরি এবং ভ্যালিডেশন রুটিন পরিচালনা সম্পর্কে জানুন | [ফর্ম](./7-bank-project/2-forms/README.md) | Yohan |
| 23 | [ব্যাংকিং অ্যাপ](./7-bank-project/solution/README.md) | ডেটা আনার এবং ব্যবহারের পদ্ধতি | আপনার অ্যাপে ডেটা কীভাবে প্রবাহিত হয়, কীভাবে এটি আনা, সংরক্ষণ এবং নিষ্পত্তি করা হয় তা শিখুন | [ডেটা](./7-bank-project/3-data/README.md) | Yohan |
| 24 | [ব্যাংকিং অ্যাপ](./7-bank-project/solution/README.md) | স্টেট ম্যানেজমেন্টের ধারণা | আপনার অ্যাপ কীভাবে স্টেট ধরে রাখে এবং এটি প্রোগ্রাম্যাটিকভাবে কীভাবে পরিচালনা করা যায় তা শিখুন | [স্টেট ম্যানেজমেন্ট](./7-bank-project/4-state-management/README.md) | Yohan |
| 25 | [ব্রাউজার/ভিএসকোড কোড](../../8-code-editor) | ভিএসকোডের সাথে কাজ করা | কোড এডিটর ব্যবহার করা শিখুন | [ভিএসকোড কোড এডিটর ব্যবহার](./8-code-editor/1-using-a-code-editor/README.md) | Chris |
| 26 | [এআই অ্যাসিস্ট্যান্ট](./9-chat-project/README.md) | এআই নিয়ে কাজ করা | নিজের এআই অ্যাসিস্ট্যান্ট তৈরি করা শিখুন | [এআই অ্যাসিস্ট্যান্ট প্রকল্প](./9-chat-project/README.md) | Chris |
## 🏫 শিক্ষাদান পদ্ধতি
আমাদের কারিকুলাম দুটি মূল শিক্ষাদান নীতির উপর ভিত্তি করে ডিজাইন করা হয়েছে:
* প্রকল্প-ভিত্তিক শিক্ষা
আমাদের কারিকুলাম দুটি মূল শিক্ষাদান পদ্ধতির উপর ভিত্তি করে ডিজাইন করা হয়েছে:
* প্রকল্পভিত্তিক শিক্ষা
* ঘন ঘন কুইজ
এই প্রোগ্রামটি জাভাস্ক্রিপ্ট, HTML এবং CSS এর মৌলিক বিষয়গুলি শেখায়, পাশাপাশি আজকের ওয়েব ডেভেলপারদের ব্যবহৃত সর্বশেষ টুল এবং কৌশলগুলি। শিক্ষার্থীরা টাইপিং গেম, ভার্চুয়াল টেরারিয়াম, পরিবেশ-বান্ধব ব্রাউজার এক্সটেনশন, স্পেস-ইনভেডার-স্টাইল গেম এবং ব্যবসার জন্য একটি ব্যাংকিং অ্যাপ তৈরি করে হাতে-কলমে অভিজ্ঞতা অর্জনের সুযোগ পাবে। সিরিজের শেষে, শিক্ষার্থীরা ওয়েব ডেভেলপমেন্ট সম্পর্কে একটি শক্ত ভিত্তি অর্জন করবে।
এই প্রোগ্রামটি জাভাস্ক্রিপ্ট, HTML এবং CSS-এর মৌলিক বিষয় শেখায়, পাশাপাশি আজকের ওয়েব ডেভেলপারদের ব্যবহৃত সর্বশেষ টুল এবং কৌশলগুলি শেখায়। শিক্ষার্থীরা টাইপিং গেম, ভার্চুয়াল টেরারিয়াম, পরিবেশবান্ধব ব্রাউজার এক্সটেনশন, স্পেস-ইনভেডার-স্টাইল গেম এবং ব্যবসার জন্য একটি ব্যাংকিং অ্যাপ তৈরি করার মাধ্যমে হাতে-কলমে অভিজ্ঞতা অর্জনের সুযোগ পাবে। সিরিজের শেষে, শিক্ষার্থীরা ওয়েব ডেভেলপমেন্ট সম্পর্কে একটি শক্তিশালী ধারণা অর্জন করবে।
> 🎓 আপনি এই কারিকুলামের প্রথম কয়েকটি পাঠ [Microsoft Learn](https://docs.microsoft.com/learn/paths/web-development-101/?WT.mc_id=academic-77807-sagibbon) এ একটি [Learn Path] হিসেবে নিতে পারেন!
> 🎓 এই কারিকুলামের প্রথম কয়েকটি পাঠ [Microsoft Learn](https://docs.microsoft.com/learn/paths/web-development-101/?WT.mc_id=academic-77807-sagibbon)-এ একটি [Learn Path](https://docs.microsoft.com/learn/paths/web-development-101/?WT.mc_id=academic-77807-sagibbon) হিসেবে নিতে পারেন!
প্রকল্পগুলির সাথে সামঞ্জস্য রেখে বিষয়বস্তু তৈরি করার মাধ্যমে শিক্ষার্থীদের জন্য প্রক্রিয়াটি আরও আকর্ষণীয় হয়ে ওঠে এবং ধারণাগুলির ধারণক্ষমতা বৃদ্ধি পায়। আমরা জাভাস্ক্রিপ্ট বেসিকের উপর বেশ কয়েকটি স্টার্টার লেসনও লিখেছি যা ধারণাগুলি পরিচয় করিয়ে দেয়, "[Beginners Series to: JavaScript](https://channel9.msdn.com/Series/Beginners-Series-to-JavaScript/?WT.mc_id=academic-77807-sagibbon)" ভিডিও টিউটোরিয়াল সংগ্রহের একটি ভিডিওর সাথে যুক্ত, যার কিছু লেখক এই কারিকুলামে অবদান রেখেছেন।
প্রকল্পের সাথে সামঞ্জস্য রেখে বিষয়বস্তু নিশ্চিত করার মাধ্যমে শিক্ষার্থীদের জন্য প্রক্রিয়াটি আরও আকর্ষণীয় হয়ে ওঠে এবং ধারণাগুলির ধারণক্ষমতা বৃদ্ধি পায়। আমরা জাভাস্ক্রিপ্ট বেসিকের উপর কয়েকটি স্টার্টার পাঠও লিখেছি, যা "[Beginners Series to: JavaScript](https://channel9.msdn.com/Series/Beginners-Series-to-JavaScript/?WT.mc_id=academic-77807-sagibbon)" ভিডিও টিউটোরিয়াল সংগ্রহের একটি ভিডিওর সাথে যুক্ত, যার কিছু লেখক এই কারিকুলামে অবদান রেখেছেন।
এছাড়াও, একটি ক্লাসের আগে একটি কম ঝুঁকিপূর্ণ কুইজ শিক্ষার্থীর মনোযোগ একটি বিষয় শেখার দিকে স্থাপন করে, যখন ক্লাসের পরে একটি দ্বিতীয় কুইজ আরও ধারণক্ষমতা নিশ্চিত করে। এই কারিকুলামটি নমনীয় এবং মজাদার হতে ডিজাইন করা হয়েছে এবং এটি সম্পূর্ণ বা আংশিকভাবে নেওয়া যেতে পারে। প্রকল্পগুলি ছোট থেকে শুরু হয় এবং ১২-সপ্তাহের চক্রের শেষে ক্রমশ জটিল হয়ে ওঠে।
এছাড়াও, ক্লাসের আগে একটি লো-স্টেক কুইজ শিক্ষার্থীর মনোযোগ একটি বিষয় শেখার দিকে নিয়ে যায়, যখন ক্লাসের পরে একটি দ্বিতীয় কুইজ আরও ধারণক্ষমতা নিশ্চিত করে। এই কারিকুলামটি নমনীয় এবং মজাদার হতে ডিজাইন করা হয়েছে এবং এটি সম্পূর্ণ বা আংশিকভাবে নেওয়া যেতে পারে। প্রকল্পগুলি ছোট থেকে শুরু হয় এবং ১২-সপ্তাহের চক্রের শেষে ক্রমশ জটিল হয়ে ওঠে।
আমরা ইচ্ছাকৃতভাবে জাভাস্ক্রিপ্ট ফ্রেমওয়ার্কগুলি পরিচয় করানো এড়িয়ে গেছি যাতে একটি ফ্রেমওয়ার্ক গ্রহণ করার আগে একজন ওয়েব ডেভেলপার হিসাবে প্রয়োজনীয় মৌলিক দক্ষতাগুলির উপর মনোযোগ কেন্দ্রীভূত করা যায়। এই কারিকুলামটি সম্পন্ন করার একটি ভাল পরবর্তী পদক্ষেপ হবে আরেকটি ভিডিও সংগ্রহের মাধ্যমে Node.js সম্পর্কে শেখা: "[Beginner Series to: Node.js](https://channel9.msdn.com/Series/Beginners-Series-to-Nodejs/?WT.mc_id=academic-77807-sagibbon)"।
> আমাদের [Code of Conduct](CODE_OF_CONDUCT.md) এবং [Contributing](CONTRIBUTING.md) নির্দেশিকা দেখুন। আমরা আপনার গঠনমূলক প্রতিক্রিয়া স্বাগত জানাই!
যদিও আমরা জাভাস্ক্রিপ্ট ফ্রেমওয়ার্কগুলি পরিচয় করানো এড়িয়ে গেছি যাতে ওয়েব ডেভেলপার হিসেবে একটি ফ্রেমওয়ার্ক গ্রহণের আগে প্রয়োজনীয় মৌলিক দক্ষতাগুলি শেখানো যায়, এই কারিকুলামটি সম্পন্ন করার পর একটি ভালো পরবর্তী পদক্ষেপ হবে Node.js সম্পর্কে শেখা। এটি "[Beginner Series to: Node.js](https://channel9.msdn.com/Series/Beginners-Series-to-Nodejs/?WT.mc_id=academic-77807-sagibbon)" ভিডিও সংগ্রহের মাধ্যমে শেখা যেতে পারে।
> আমাদের [কোড অফ কন্ডাক্ট](CODE_OF_CONDUCT.md) এবং [অবদান](CONTRIBUTING.md) নির্দেশিকা দেখুন। আমরা আপনার গঠনমূলক প্রতিক্রিয়া স্বাগত জানাই!
## 🧭 অফলাইন অ্যাক্সেস
আপনি [Docsify](https://docsify.js.org/#/) ব্যবহার করে এই ডকুমেন্টেশনটি অফলাইনে চালাতে পারেন। এই রিপোটি ফর্ক করুন, আপনার লোকাল মেশিনে [Docsify ইনস্টল করুন](https://docsify.js.org/#/quickstart), এবং তারপর এই রিপোর রুট ফোল্ডারে `docsify serve` টাইপ করুন। ওয়েবসাইটটি আপনার লোকালহোস্টে ৩০০০ পোর্টে পরিবেশন করা হবে: `localhost:3000`
আপনি [Docsify](https://docsify.js.org/#/) ব্যবহার করে এই ডকুমেন্টেশনটি অফলাইনে চালাতে পারেন। এই রিপোটি ফর্ক করুন, আপনার লোকাল মেশিনে [Docsify ইনস্টল](https://docsify.js.org/#/quickstart) করুন, এবং তারপর এই রিপোর রুট ফোল্ডারে `docsify serve` টাইপ করুন। ওয়েবসাইটটি আপনার লোকালহোস্টে পোর্ট ৩০০০-এ পরিবেশন করা হবে: `localhost:3000`
## 📘 পিডিএফ
সমস্ত পাঠের একটি পিডিএফ [এখানে](https://microsoft.github.io/Web-Dev-For-Beginners/pdf/readme.pdf) পাওয়া যাবে।
সব পাঠের একটি পিডিএফ [এখানে](https://microsoft.github.io/Web-Dev-For-Beginners/pdf/readme.pdf) পাওয়া যাবে।
## 🎒 অন্যান্য কোর্স
আমাদের টিম অন্যান্য কোর্সও তৈরি করে! দেখুন:
- [Generative AI for Beginners](https://aka.ms/genai-beginners)
- [Generative AI for Beginners .NET](https://github.com/microsoft/Generative-AI-for-beginners-dotnet)
- [Generative AI with JavaScript](https://github.com/microsoft/generative-ai-with-javascript)
- [Generative AI with Java](https://github.com/microsoft/Generative-AI-for-beginners-java)
- [AI for Beginners](https://aka.ms/ai-beginners)
- [Data Science for Beginners](https://aka.ms/datascience-beginners)
- [ML for Beginners](https://aka.ms/ml-beginners)
- [Cybersecurity for Beginners](https://github.com/microsoft/Security-101)
- [Web Dev for Beginners](https://aka.ms/webdev-beginners)
- [IoT for Beginners](https://aka.ms/iot-beginners)
- [XR Development for Beginners](https://github.com/microsoft/xr-development-for-beginners)
- [Mastering GitHub Copilot for Agentic use](https://github.com/microsoft/Mastering-GitHub-Copilot-for-Paired-Programming)
- [Mastering GitHub Copilot for C#/.NET Developers](https://github.com/microsoft/mastering-github-copilot-for-dotnet-csharp-developers)
- [Choose Your Own Copilot Adventure](https://github.com/microsoft/CopilotAdventures)
- [শুরু করার জন্য জেনারেটিভ এআই](https://aka.ms/genai-beginners)
- [শুরু করার জন্য জেনারেটিভ এআই .NET](https://github.com/microsoft/Generative-AI-for-beginners-dotnet)
- [জাভাস্ক্রিপ্ট দিয়ে জেনারেটিভ এআই](https://github.com/microsoft/generative-ai-with-javascript)
- [জাভা দিয়ে জেনারেটিভ এআই](https://github.com/microsoft/Generative-AI-for-beginners-java)
- [শুরু করার জন্য এআই](https://aka.ms/ai-beginners)
- [ডেটা সায়েন্সের প্রাথমিক পাঠ](https://aka.ms/datascience-beginners)
- [মেশিন লার্নিংয়ের প্রাথমিক পাঠ](https://aka.ms/ml-beginners)
- [সাইবার সিকিউরিটির প্রাথমিক পাঠ](https://github.com/microsoft/Security-101)
- [ওয়েব ডেভেলপমেন্টের প্রাথমিক পাঠ](https://aka.ms/webdev-beginners)
- [ইন্টারনেট অফ থিংসের প্রাথমিক পাঠ](https://aka.ms/iot-beginners)
- [এক্সআর ডেভেলপমেন্টের প্রাথমিক পাঠ](https://github.com/microsoft/xr-development-for-beginners)
- [এজেন্টিক ব্যবহারের জন্য GitHub Copilot আয়ত্ত করা](https://github.com/microsoft/Mastering-GitHub-Copilot-for-Paired-Programming)
- [C#/.NET ডেভেলপারদের জন্য GitHub Copilot আয়ত্ত করা](https://github.com/microsoft/mastering-github-copilot-for-dotnet-csharp-developers)
- [আপনার নিজস্ব Copilot অ্যাডভেঞ্চার নির্বাচন করুন](https://github.com/microsoft/CopilotAdventures)
## লাইসেন্স
@ -206,4 +219,4 @@ CO_OP_TRANSLATOR_METADATA:
---
**অস্বীকৃতি**:
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতা নিশ্চিত করার চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা দায়বদ্ধ থাকব না।
এই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিক অনুবাদ প্রদানের চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়ী থাকব না।

@ -1,15 +1,15 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "c63675cfaf1d223b37bb9fecbfe7c252",
"translation_date": "2025-08-25T23:12:00+00:00",
"original_hash": "2dcbb9259dee4f20a4f08d9a1aa2bd4c",
"translation_date": "2025-08-28T23:58:32+00:00",
"source_file": "1-getting-started-lessons/1-intro-to-programming-languages/README.md",
"language_code": "br"
}
-->
# Introdução às Linguagens de Programação e Ferramentas do Ofício
# Introdução às Linguagens de Programação e Ferramentas Essenciais
Esta lição aborda os fundamentos das linguagens de programação. Os tópicos abordados aqui se aplicam à maioria das linguagens de programação modernas. Na seção "Ferramentas do Ofício", você aprenderá sobre softwares úteis que ajudam você como desenvolvedor.
Esta lição aborda os fundamentos das linguagens de programação. Os tópicos abordados aqui se aplicam à maioria das linguagens de programação modernas. Na seção 'Ferramentas Essenciais', você aprenderá sobre softwares úteis que ajudam você como desenvolvedor.
![Intro Programming](../../../../translated_images/webdev101-programming.d6e3f98e61ac4bff0b27dcbf1c3f16c8ed46984866f2d29988929678b0058fde.br.png)
> Sketchnote por [Tomomi Imura](https://twitter.com/girlie_mac)
@ -40,9 +40,9 @@ Um *programa* pode ser qualquer coisa escrita com código; sites, jogos e aplica
Linguagens de programação permitem que os desenvolvedores escrevam instruções para um dispositivo. Dispositivos só entendem binário (1s e 0s), e para *a maioria* dos desenvolvedores, essa não é uma forma muito eficiente de se comunicar. Linguagens de programação são o meio de comunicação entre humanos e computadores.
As linguagens de programação vêm em diferentes formatos e podem servir a diferentes propósitos. Por exemplo, JavaScript é usado principalmente para aplicativos web, enquanto Bash é usado principalmente para sistemas operacionais.
As linguagens de programação vêm em diferentes formatos e podem servir a diferentes propósitos. Por exemplo, JavaScript é usado principalmente para aplicações web, enquanto Bash é usado principalmente para sistemas operacionais.
*Linguagens de baixo nível* geralmente exigem menos etapas do que *linguagens de alto nível* para que um dispositivo interprete instruções. No entanto, o que torna as linguagens de alto nível populares é sua legibilidade e suporte. JavaScript é considerado uma linguagem de alto nível.
*Linguagens de baixo nível* geralmente requerem menos etapas do que *linguagens de alto nível* para que um dispositivo interprete as instruções. No entanto, o que torna as linguagens de alto nível populares é sua legibilidade e suporte. JavaScript é considerado uma linguagem de alto nível.
O código a seguir ilustra a diferença entre uma linguagem de alto nível, como JavaScript, e uma linguagem de baixo nível, como o código de montagem ARM.
@ -91,15 +91,15 @@ Acredite ou não, *eles estão fazendo a mesma coisa*: imprimindo uma sequência
Uma única instrução em um programa é chamada de *declaração* e geralmente terá um caractere ou espaçamento de linha que marca onde a instrução termina, ou *termina*. Como um programa termina varia de acordo com cada linguagem.
Declarações dentro de um programa podem depender de dados fornecidos por um usuário ou de outra fonte para executar instruções. Os dados podem alterar o comportamento de um programa, então as linguagens de programação vêm com uma maneira de armazenar temporariamente os dados para que possam ser usados posteriormente. Esses são chamados de *variáveis*. Variáveis são declarações que instruem um dispositivo a salvar dados em sua memória. Variáveis em programas são semelhantes às variáveis em álgebra, onde possuem um nome único e seu valor pode mudar ao longo do tempo.
Declarações dentro de um programa podem depender de dados fornecidos por um usuário ou de outro lugar para executar instruções. Os dados podem alterar o comportamento de um programa, então as linguagens de programação vêm com uma maneira de armazenar temporariamente os dados para que possam ser usados posteriormente. Esses são chamados de *variáveis*. Variáveis são declarações que instruem um dispositivo a salvar dados em sua memória. Variáveis em programas são semelhantes às variáveis em álgebra, onde m um nome único e seu valor pode mudar ao longo do tempo.
Há uma chance de que algumas declarações não sejam executadas por um dispositivo. Isso geralmente ocorre por design, quando escrito pelo desenvolvedor, ou por acidente, quando ocorre um erro inesperado. Esse tipo de controle sobre um aplicativo o torna mais robusto e fácil de manter. Normalmente, essas mudanças de controle acontecem quando certas condições são atendidas. Uma declaração comum usada na programação moderna para controlar como um programa é executado é a declaração `if..else`.
Há uma chance de que algumas declarações não sejam executadas por um dispositivo. Isso geralmente é intencional, quando escrito pelo desenvolvedor, ou por acidente, quando ocorre um erro inesperado. Esse tipo de controle sobre um aplicativo o torna mais robusto e fácil de manter. Normalmente, essas mudanças de controle acontecem quando certas condições são atendidas. Uma declaração comum usada na programação moderna para controlar como um programa é executado é a declaração `if..else`.
✅ Você aprenderá mais sobre esse tipo de declaração em lições subsequentes.
## Ferramentas do Ofício
## Ferramentas Essenciais
[![Tools of the Trade](https://img.youtube.com/vi/69WJeXGBdxg/0.jpg)](https://youtube.com/watch?v=69WJeXGBdxg "Ferramentas do Ofício")
[![Tools of the Trade](https://img.youtube.com/vi/69WJeXGBdxg/0.jpg)](https://youtube.com/watch?v=69WJeXGBdxg "Tools of the Trade")
> 🎥 Clique na imagem acima para assistir a um vídeo sobre ferramentas
@ -115,7 +115,7 @@ Os desenvolvedores dependem dos editores por alguns motivos adicionais:
- *Depuração* ajuda a identificar bugs e erros ao passar pelo código linha por linha. Alguns editores possuem recursos de depuração; eles podem ser personalizados e adicionados para linguagens de programação específicas.
- *Realce de sintaxe* adiciona cores e formatação ao texto do código, tornando-o mais fácil de ler. A maioria dos editores permite personalizar o realce de sintaxe.
- *Extensões e integrações* são ferramentas especializadas para desenvolvedores, criadas por desenvolvedores. Essas ferramentas não foram incluídas no editor base. Por exemplo, muitos desenvolvedores documentam seu código para explicar como ele funciona. Eles podem instalar uma extensão de verificação ortográfica para ajudar a encontrar erros de digitação na documentação. A maioria das extensões é destinada ao uso em um editor específico, e a maioria dos editores vem com uma maneira de pesquisar extensões disponíveis.
- *Extensões e Integrações* são ferramentas especializadas para desenvolvedores, criadas por desenvolvedores. Essas ferramentas não foram incluídas no editor base. Por exemplo, muitos desenvolvedores documentam seu código para explicar como ele funciona. Eles podem instalar uma extensão de verificação ortográfica para ajudar a encontrar erros de digitação na documentação. A maioria das extensões é destinada ao uso em um editor específico, e a maioria dos editores vem com uma maneira de pesquisar extensões disponíveis.
- *Personalização* permite que os desenvolvedores criem um ambiente de desenvolvimento único para atender às suas necessidades. A maioria dos editores é extremamente personalizável e também pode permitir que os desenvolvedores criem extensões personalizadas.
#### Editores Populares e Extensões para Desenvolvimento Web
@ -135,7 +135,7 @@ Os desenvolvedores dependem dos editores por alguns motivos adicionais:
### Navegadores
Outra ferramenta crucial é o navegador. Desenvolvedores web dependem do navegador para ver como seu código é executado na web. Ele também é usado para exibir os elementos visuais de uma página web que são escritos no editor, como HTML.
Outra ferramenta crucial é o navegador. Desenvolvedores web dependem do navegador para ver como seu código funciona na web. Ele também é usado para exibir os elementos visuais de uma página web que são escritos no editor, como HTML.
Muitos navegadores vêm com *ferramentas de desenvolvedor* (DevTools) que contêm um conjunto de recursos úteis e informações para ajudar os desenvolvedores a coletar e capturar informações importantes sobre seu aplicativo. Por exemplo: Se uma página web tiver erros, às vezes é útil saber quando eles ocorreram. As DevTools em um navegador podem ser configuradas para capturar essas informações.
@ -147,7 +147,7 @@ Muitos navegadores vêm com *ferramentas de desenvolvedor* (DevTools) que contê
### Ferramentas de Linha de Comando
Alguns desenvolvedores preferem uma visão menos gráfica para suas tarefas diárias e dependem da linha de comando para isso. Escrever código exige uma quantidade significativa de digitação, e alguns desenvolvedores preferem não interromper seu fluxo no teclado. Eles usam atalhos de teclado para alternar entre janelas do desktop, trabalhar em diferentes arquivos e usar ferramentas. A maioria das tarefas pode ser realizada com um mouse, mas um benefício da linha de comando é que muito pode ser feito com ferramentas de linha de comando sem a necessidade de alternar entre o mouse e o teclado. Outro benefício da linha de comando é que ela é configurável, permitindo salvar uma configuração personalizada, alterá-la posteriormente e importá-la para outras máquinas de desenvolvimento. Como os ambientes de desenvolvimento são tão únicos para cada desenvolvedor, alguns evitam usar a linha de comando, outros dependem dela totalmente, e alguns preferem uma mistura dos dois.
Alguns desenvolvedores preferem uma visão menos gráfica para suas tarefas diárias e dependem da linha de comando para isso. Escrever código exige uma quantidade significativa de digitação, e alguns desenvolvedores preferem não interromper seu fluxo no teclado. Eles usam atalhos de teclado para alternar entre janelas da área de trabalho, trabalhar em diferentes arquivos e usar ferramentas. A maioria das tarefas pode ser realizada com um mouse, mas um benefício da linha de comando é que muito pode ser feito com ferramentas de linha de comando sem a necessidade de alternar entre o mouse e o teclado. Outro benefício da linha de comando é que ela é configurável, permitindo salvar uma configuração personalizada, alterá-la posteriormente e importá-la para outras máquinas de desenvolvimento. Como os ambientes de desenvolvimento são tão únicos para cada desenvolvedor, alguns evitam usar a linha de comando, outros dependem dela totalmente, e alguns preferem uma mistura dos dois.
### Opções Populares de Linha de Comando
@ -182,7 +182,7 @@ As opções de linha de comando variam de acordo com o sistema operacional que v
### Documentação
Quando um desenvolvedor quer aprender algo novo, ele provavelmente recorrerá à documentação para aprender como usar. Os desenvolvedores frequentemente dependem da documentação para guiá-los sobre como usar ferramentas e linguagens corretamente, além de obter um conhecimento mais profundo de como elas funcionam.
Quando um desenvolvedor quer aprender algo novo, ele provavelmente recorrerá à documentação para aprender como usar. Desenvolvedores frequentemente dependem da documentação para guiá-los sobre como usar ferramentas e linguagens corretamente, além de obter um conhecimento mais profundo de como elas funcionam.
#### Documentação Popular sobre Desenvolvimento Web
@ -201,7 +201,7 @@ Quando um desenvolvedor quer aprender algo novo, ele provavelmente recorrerá à
Compare algumas linguagens de programação. Quais são algumas das características únicas do JavaScript em comparação ao Java? E do COBOL em relação ao Go?
## Quiz Pós-Aula
[Quiz pós-aula](https://ff-quizzes.netlify.app/web/quiz/2)
[Quiz pós-aula](https://ff-quizzes.netlify.app/web/)
## Revisão e Autoestudo
@ -211,5 +211,7 @@ Estude um pouco sobre as diferentes linguagens disponíveis para o programador.
[Lendo a Documentação](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "05666cecb8983a72cf0ce1d18932b5b7",
"translation_date": "2025-08-25T22:50:44+00:00",
"original_hash": "361249da70432ddfd4741c917d1a6f50",
"translation_date": "2025-08-28T23:59:44+00:00",
"source_file": "1-getting-started-lessons/2-github-basics/README.md",
"language_code": "br"
}
@ -15,7 +15,7 @@ Esta lição aborda os fundamentos do GitHub, uma plataforma para hospedar e ger
> Sketchnote por [Tomomi Imura](https://twitter.com/girlie_mac)
## Quiz Pré-Aula
[Quiz pré-aula](https://ff-quizzes.netlify.app/web/quiz/3)
[Quiz pré-aula](https://ff-quizzes.netlify.app)
## Introdução
@ -27,33 +27,33 @@ Nesta lição, vamos abordar:
### Pré-requisitos
Antes de começar, você precisa verificar se o Git está instalado. No terminal, digite:
Antes de começar, você precisa verificar se o Git está instalado. No terminal, digite:
`git --version`
Se o Git não estiver instalado, [baixe o Git](https://git-scm.com/downloads). Depois, configure seu perfil local do Git no terminal:
Se o Git não estiver instalado, [baixe o Git](https://git-scm.com/downloads). Em seguida, configure seu perfil local do Git no terminal:
* `git config --global user.name "seu-nome"`
* `git config --global user.email "seu-email"`
Para verificar se o Git já está configurado, você pode digitar:
`git config --list`
Você também precisará de uma conta no GitHub, um editor de código (como o Visual Studio Code) e abrir seu terminal (ou prompt de comando).
Você também precisará de uma conta no GitHub, um editor de código (como o Visual Studio Code) e deverá abrir seu terminal (ou prompt de comando).
Acesse [github.com](https://github.com/) e crie uma conta, caso ainda não tenha uma, ou faça login e preencha seu perfil.
Acesse [github.com](https://github.com/) e crie uma conta, caso ainda não tenha uma, ou faça login e preencha seu perfil.
✅ O GitHub não é o único repositório de código no mundo; existem outros, mas o GitHub é o mais conhecido.
### Preparação
Você precisará de uma pasta com um projeto de código na sua máquina local (laptop ou PC) e de um repositório público no GitHub, que servirá como exemplo de como contribuir para os projetos de outras pessoas.
Você precisará de uma pasta com um projeto de código na sua máquina local (laptop ou PC) e de um repositório público no GitHub, que servirá como exemplo de como contribuir para os projetos de outras pessoas.
---
## Gerenciamento de código
Vamos supor que você tenha uma pasta local com algum projeto de código e queira começar a rastrear seu progresso usando o Git - o sistema de controle de versão. Algumas pessoas comparam usar o Git a escrever uma carta de amor para seu futuro eu. Ao ler suas mensagens de commit dias, semanas ou meses depois, você será capaz de lembrar por que tomou uma decisão ou "reverter" uma alteração - isso, claro, quando você escreve boas "mensagens de commit".
Vamos supor que você tenha uma pasta localmente com algum projeto de código e queira começar a rastrear seu progresso usando o Git - o sistema de controle de versão. Algumas pessoas comparam usar o Git a escrever uma carta de amor para seu futuro eu. Ao ler suas mensagens de commit dias, semanas ou meses depois, você será capaz de lembrar por que tomou uma decisão ou "reverter" uma alteração - isso, claro, quando você escreve boas mensagens de commit.
### Tarefa: Criar um repositório e fazer commit do código
### Tarefa: Criar um repositório e fazer commit de código
> Confira o vídeo
>
@ -102,7 +102,7 @@ Vamos supor que você tenha uma pasta local com algum projeto de código e queir
git add .
```
O comando `git add` com o argumento `.` indica que todos os seus arquivos e alterações serão rastreados.
O argumento `git add` seguido de `.` indica que todos os seus arquivos e alterações serão rastreados.
1. **Adicionar arquivos selecionados para rastreamento**
@ -134,11 +134,11 @@ Vamos supor que você tenha uma pasta local com algum projeto de código e queir
git commit -m "first commit"
```
Isso faz commit de todos os seus arquivos, adicionando a mensagem "primeiro commit". Para mensagens de commit futuras, você vai querer ser mais descritivo na sua descrição para transmitir que tipo de alteração você fez.
Isso faz commit de todos os seus arquivos, adicionando a mensagem "primeiro commit". Para mensagens de commit futuras, você vai querer ser mais descritivo na sua descrição para transmitir o tipo de alteração que você fez.
1. **Conectar seu repositório Git local ao GitHub**. Um repositório Git é útil na sua máquina, mas em algum momento você vai querer ter um backup dos seus arquivos em algum lugar e também convidar outras pessoas para trabalhar com você no repositório. Um ótimo lugar para fazer isso é o GitHub. Lembre-se de que já criamos um repositório no GitHub, então só precisamos conectar nosso repositório Git local ao GitHub. O comando `git remote add` fará isso. Digite o seguinte comando:
1. **Conectar seu repositório Git local ao GitHub**. Um repositório Git é útil na sua máquina, mas em algum momento você vai querer ter um backup dos seus arquivos em algum lugar e também convidar outras pessoas para trabalhar com você no repositório. Um ótimo lugar para isso é o GitHub. Lembre-se de que já criamos um repositório no GitHub, então só precisamos conectar nosso repositório Git local ao GitHub. O comando `git remote add` fará isso. Digite o seguinte comando:
> Nota: antes de digitar o comando, vá até a página do seu repositório no GitHub para encontrar a URL do repositório. Você usará essa URL no comando abaixo. Substitua ```https://github.com/username/repository_name.git``` pela URL do seu GitHub.
> Nota: antes de digitar o comando, vá até a página do repositório no GitHub para encontrar a URL do repositório. Você usará essa URL no comando abaixo. Substitua ```https://github.com/username/repository_name.git``` pela URL do GitHub.
```bash
git remote add origin https://github.com/username/repository_name.git
@ -148,7 +148,7 @@ Vamos supor que você tenha uma pasta local com algum projeto de código e queir
1. **Enviar arquivos locais para o GitHub**. Até agora, você criou uma _conexão_ entre o repositório local e o repositório do GitHub. Vamos enviar esses arquivos para o GitHub com o seguinte comando `git push`, assim:
> Nota: o nome da sua branch pode ser diferente do padrão ```main```.
> Nota: o nome da sua branch pode ser diferente por padrão de ```main```.
```bash
git push -u origin main
@ -164,17 +164,17 @@ Vamos supor que você tenha uma pasta local com algum projeto de código e queir
git push
```
> Dica: você também pode querer adotar um arquivo `.gitignore` para evitar que arquivos que você não deseja rastrear apareçam no GitHub - como aquele arquivo de notas que você armazena na mesma pasta, mas que não tem lugar em um repositório público. Você pode encontrar modelos para arquivos `.gitignore` em [.gitignore templates](https://github.com/github/gitignore).
> Dica: você também pode adotar um arquivo `.gitignore` para evitar que arquivos que você não deseja rastrear apareçam no GitHub - como aquele arquivo de notas que você armazena na mesma pasta, mas que não tem lugar em um repositório público. Você pode encontrar modelos para arquivos `.gitignore` em [.gitignore templates](https://github.com/github/gitignore).
#### Mensagens de commit
Uma ótima linha de assunto para um commit do Git completa a seguinte frase:
Uma ótima linha de assunto para um commit no Git completa a seguinte frase:
Se aplicado, este commit irá <sua linha de assunto aqui>
Para o assunto, use o imperativo no presente: "alterar" e não "alterado" nem "altera".
Assim como no assunto, no corpo (opcional) também use o imperativo no presente. O corpo deve incluir a motivação para a alteração e contrastá-la com o comportamento anterior. Você está explicando o `porquê`, não o `como`.
✅ Reserve alguns minutos para navegar pelo GitHub. Você consegue encontrar uma mensagem de commit realmente boa? Consegue encontrar uma bem minimalista? Que informações você acha que são mais importantes e úteis para transmitir em uma mensagem de commit?
✅ Reserve alguns minutos para navegar pelo GitHub. Você consegue encontrar uma mensagem de commit realmente boa? Consegue encontrar uma bem minimalista? Quais informações você acha que são mais importantes e úteis para transmitir em uma mensagem de commit?
### Tarefa: Colaborar
@ -186,34 +186,33 @@ O principal motivo para colocar coisas no GitHub foi tornar possível colaborar
>
> [![Vídeo básico sobre Git e GitHub](https://img.youtube.com/vi/bFCM-PC3cu8/0.jpg)](https://www.youtube.com/watch?v=bFCM-PC3cu8)
No seu repositório, navegue até `Insights > Community` para ver como seu projeto se compara aos padrões recomendados da comunidade.
No seu repositório, navegue até `Insights > Community` para ver como seu projeto se compara aos padrões recomendados para a comunidade.
Aqui estão algumas coisas que podem melhorar seu repositório no GitHub:
- **Descrição**. Você adicionou uma descrição para seu projeto?
- **Descrição**. Você adicionou uma descrição para o seu projeto?
- **README**. Você adicionou um README? O GitHub fornece orientações para escrever um [README](https://docs.github.com/articles/about-readmes/?WT.mc_id=academic-77807-sagibbon).
- **Diretrizes de contribuição**. Seu projeto tem [diretrizes de contribuição](https://docs.github.com/articles/setting-guidelines-for-repository-contributors/?WT.mc_id=academic-77807-sagibbon)?
- **Código de Conduta**. Um [Código de Conduta](https://docs.github.com/articles/adding-a-code-of-conduct-to-your-project/).
- **Licença**. Talvez o mais importante, uma [licença](https://docs.github.com/articles/adding-a-license-to-a-repository/)?
Todos esses recursos beneficiarão a integração de novos membros da equipe. E essas são, geralmente, as coisas que novos contribuidores olham antes mesmo de olhar seu código, para descobrir se seu projeto é o lugar certo para eles investirem seu tempo.
Todos esses recursos beneficiarão a integração de novos membros da equipe. E essas são, geralmente, as coisas que novos contribuidores olham antes mesmo de olhar para o seu código, para descobrir se seu projeto é o lugar certo para eles investirem seu tempo.
✅ Arquivos README, embora levem tempo para serem preparados, são frequentemente negligenciados por mantenedores ocupados. Você consegue encontrar um exemplo de um README particularmente descritivo? Nota: existem alguns [ferramentas para ajudar a criar bons READMEs](https://www.makeareadme.com/) que você pode querer experimentar.
### Tarefa: Fazer merge de algum código
### Tarefa: Fazer merge de código
Documentos de contribuição ajudam as pessoas a contribuir para o projeto. Eles explicam quais tipos de contribuições você está procurando e como o processo funciona. Os contribuidores precisarão passar por uma série de etapas para poder contribuir para seu repositório no GitHub:
1. **Fazer fork do seu repositório**. Você provavelmente vai querer que as pessoas _façam fork_ do seu projeto. Fazer fork significa criar uma réplica do seu repositório no perfil do GitHub delas.
1. **Clonar**. A partir daí, elas irão clonar o projeto para sua máquina local.
1. **Criar uma branch**. Você vai querer pedir que elas criem uma _branch_ para o trabalho delas.
1. **Focar a alteração em uma área**. Peça aos contribuidores para concentrarem suas contribuições em uma coisa de cada vez - assim, as chances de você conseguir _fazer merge_ do trabalho deles são maiores. Imagine que eles escrevam uma correção de bug, adicionem um novo recurso e atualizem vários testes - e se você quiser, ou puder, implementar apenas 2 de 3 ou 1 de 3 alterações?
1. **Fazer fork do seu repositório**. Você provavelmente vai querer que as pessoas _façam fork_ do seu projeto. Fazer fork significa criar uma réplica do seu repositório no perfil delas no GitHub.
1. **Clonar**. A partir daí, elas irão clonar o projeto para sua máquina local.
1. **Criar uma branch**. Você vai querer pedir que elas criem uma _branch_ para o trabalho delas.
1. **Focar a alteração em uma área**. Peça aos contribuidores para concentrarem suas contribuições em uma coisa de cada vez - assim, as chances de você conseguir _fazer merge_ do trabalho deles são maiores. Imagine que eles escrevam uma correção de bug, adicionem um novo recurso e atualizem vários testes - e se você quiser ou puder implementar apenas 2 de 3 ou 1 de 3 alterações?
✅ Imagine uma situação onde branches são particularmente críticas para escrever e enviar um bom código. Que casos de uso você consegue pensar?
✅ Imagine uma situação onde branches são particularmente críticas para escrever e entregar um bom código. Quais casos de uso você consegue pensar?
> Nota: seja a mudança que você quer ver no mundo e crie branches para seu próprio trabalho também. Qualquer commit que você fizer será feito na branch que você está atualmente "checado". Use `git status` para ver em qual branch você está.
Vamos passar por um fluxo de trabalho de contribuidor. Assuma que o contribuidor já _fez fork_ e _clonou_ o repositório, então ele tem um repositório Git pronto para ser trabalhado na máquina local:
Vamos passar por um fluxo de trabalho de contribuidores. Assuma que o contribuidor já _fez fork_ e _clonou_ o repositório, então ele tem um repositório Git pronto para ser trabalhado na máquina local:
1. **Criar uma branch**. Use o comando `git branch` para criar uma branch que conterá as alterações que ele pretende contribuir:
@ -227,16 +226,16 @@ Vamos passar por um fluxo de trabalho de contribuidor. Assuma que o contribuidor
git switch [branch-name]
```
1. **Fazer alterações**. Neste ponto, você quer adicionar suas alterações. Não se esqueça de informar ao Git sobre isso com os seguintes comandos:
1. **Fazer o trabalho**. Neste ponto, você quer adicionar suas alterações. Não se esqueça de informar ao Git sobre isso com os seguintes comandos:
```bash
git add .
git commit -m "my changes"
```
Certifique-se de dar um bom nome ao seu commit, tanto para você quanto para o mantenedor do repositório que você está ajudando.
Certifique-se de dar um bom nome ao seu commit, para seu próprio benefício e para o mantenedor do repositório que você está ajudando.
1. **Combinar seu trabalho com a branch `main`**. Em algum momento, você termina de trabalhar e quer combinar seu trabalho com o da branch `main`. A branch `main` pode ter mudado enquanto isso, então certifique-se de primeiro atualizá-la para a versão mais recente com os seguintes comandos:
1. **Combinar seu trabalho com a branch `main`**. Em algum momento, você termina o trabalho e quer combinar seu trabalho com o da branch `main`. A branch `main` pode ter mudado enquanto isso, então certifique-se de primeiro atualizá-la para a versão mais recente com os seguintes comandos:
```bash
git switch main
@ -250,9 +249,9 @@ Vamos passar por um fluxo de trabalho de contribuidor. Assuma que o contribuidor
git merge main
```
Isso trará todas as alterações da `main` para sua branch e, com sorte, você poderá continuar. Se não, o VS Code mostrará onde o Git está _confuso_ e você apenas alterará os arquivos afetados para indicar qual conteúdo é mais preciso.
Isso trará todas as alterações da branch `main` para sua branch e, com sorte, você poderá continuar. Se não, o VS Code mostrará onde o Git está _confuso_ e você apenas alterará os arquivos afetados para indicar qual conteúdo é o mais preciso.
1. **Enviar seu trabalho para o GitHub**. Enviar seu trabalho para o GitHub significa duas coisas: enviar sua branch para seu repositório e depois abrir um PR, Pull Request.
1. **Enviar seu trabalho para o GitHub**. Enviar seu trabalho para o GitHub significa duas coisas: enviar sua branch para seu repositório e, em seguida, abrir um PR (Pull Request).
```bash
git push --set-upstream origin [branch-name]
@ -260,26 +259,26 @@ Vamos passar por um fluxo de trabalho de contribuidor. Assuma que o contribuidor
O comando acima cria a branch no seu repositório de fork.
1. **Abrir um PR**. Em seguida, você quer abrir um PR. Você faz isso navegando até o repositório de fork no GitHub. Você verá uma indicação no GitHub perguntando se deseja criar um novo PR, clique nisso e você será levado a uma interface onde pode alterar o título da mensagem de commit, dar uma descrição mais adequada. Agora o mantenedor do repositório que você fez fork verá este PR e _dedos cruzados_ ele apreciará e _fará merge_ do seu PR. Agora você é um contribuidor, yay :)
1. **Abrir um PR**. Em seguida, você quer abrir um PR. Você faz isso navegando até o repositório de fork no GitHub. Você verá uma indicação no GitHub perguntando se deseja criar um novo PR, clique nisso e você será levado a uma interface onde pode alterar o título da mensagem de commit, dar uma descrição mais adequada. Agora o mantenedor do repositório que você fez fork verá este PR e _dedos cruzados_ ele apreciará e _fará merge_ do seu PR. Você agora é um contribuidor, yay :)
1. **Limpar**. É considerado uma boa prática _limpar_ depois de você ter feito merge com sucesso de um PR. Você quer limpar tanto sua branch local quanto a branch que você enviou para o GitHub. Primeiro, vamos deletá-la localmente com o seguinte comando:
1. **Limpar**. É considerado uma boa prática _limpar_ após você ter feito merge com sucesso de um PR. Você quer limpar tanto sua branch local quanto a branch que você enviou para o GitHub. Primeiro, vamos deletá-la localmente com o seguinte comando:
```bash
git branch -d [branch-name]
```
Certifique-se de acessar a página do GitHub para o repositório bifurcado e remover a branch remota que você acabou de enviar para lá.
`Pull request` parece um termo meio bobo, porque na verdade você quer enviar suas alterações para o projeto. Mas o mantenedor (dono do projeto) ou a equipe principal precisa considerar suas alterações antes de mesclá-las com a branch "main" do projeto, então você está realmente solicitando uma decisão de mudança de um mantenedor.
Certifique-se de ir à página do repositório de fork no GitHub e remover a branch remota que você acabou de enviar.
`Pull request` pode parecer um termo estranho, porque na verdade você quer enviar suas alterações para o projeto. Mas o mantenedor (dono do projeto) ou a equipe principal precisa avaliar suas alterações antes de integrá-las ao branch "main" do projeto. Então, você está realmente solicitando uma decisão de mudança ao mantenedor.
Um pull request é o lugar para comparar e discutir as diferenças introduzidas em uma branch com revisões, comentários, testes integrados e mais. Um bom pull request segue aproximadamente as mesmas regras de uma mensagem de commit. Você pode adicionar uma referência a um problema no rastreador de problemas, quando seu trabalho, por exemplo, resolve um problema. Isso é feito usando um `#` seguido pelo número do problema. Por exemplo, `#97`.
Um pull request é o lugar para comparar e discutir as diferenças introduzidas em um branch, com revisões, comentários, testes integrados e mais. Um bom pull request segue aproximadamente as mesmas regras de uma mensagem de commit. Você pode adicionar uma referência a um problema no rastreador de problemas, por exemplo, quando seu trabalho resolve um problema. Isso é feito usando um `#` seguido pelo número do problema. Por exemplo, `#97`.
🤞Dedos cruzados para que todos os testes passem e o(s) dono(s) do projeto mesclem suas alterações no projeto🤞
🤞Dedos cruzados para que todos os testes passem e o(s) dono(s) do projeto integrem suas alterações ao projeto🤞
Atualize sua branch local de trabalho atual com todos os novos commits da branch remota correspondente no GitHub:
Atualize seu branch local atual com todos os novos commits do branch remoto correspondente no GitHub:
`git pull`
## Como contribuir para open source
## Como contribuir para código aberto
Primeiro, vamos encontrar um repositório (ou **repo**) no GitHub que seja do seu interesse e para o qual você gostaria de contribuir com uma alteração. Você vai querer copiar o conteúdo dele para sua máquina.
@ -287,7 +286,7 @@ Primeiro, vamos encontrar um repositório (ou **repo**) no GitHub que seja do se
![Copiar um repositório localmente](../../../../translated_images/clone_repo.5085c48d666ead57664f050d806e325d7f883be6838c821e08bc823ab7c66665.br.png)
Existem várias maneiras de copiar código. Uma delas é "clonar" o conteúdo do repositório, usando HTTPS, SSH ou utilizando o GitHub CLI (Interface de Linha de Comando).
Existem várias maneiras de copiar código. Uma delas é "clonar" o conteúdo do repositório, usando HTTPS, SSH ou a CLI (Interface de Linha de Comando) do GitHub.
Abra seu terminal e clone o repositório assim:
`git clone https://github.com/ProjectURL`
@ -295,28 +294,28 @@ Abra seu terminal e clone o repositório assim:
Para trabalhar no projeto, mude para a pasta correta:
`cd ProjectURL`
Você também pode abrir o projeto inteiro usando [Codespaces](https://github.com/features/codespaces), o editor de código integrado / ambiente de desenvolvimento em nuvem do GitHub, ou [GitHub Desktop](https://desktop.github.com/).
Você também pode abrir o projeto inteiro usando [Codespaces](https://github.com/features/codespaces), o editor de código integrado/ambiente de desenvolvimento em nuvem do GitHub, ou [GitHub Desktop](https://desktop.github.com/).
Por fim, você pode baixar o código em uma pasta compactada.
### Algumas coisas interessantes sobre o GitHub
Você pode dar estrela, seguir e/ou "forkar" qualquer repositório público no GitHub. Você pode encontrar seus repositórios estrelados no menu suspenso no canto superior direito. É como salvar nos favoritos, mas para código.
Você pode dar estrela, seguir ou "forkar" qualquer repositório público no GitHub. Você encontra seus repositórios com estrela no menu suspenso no canto superior direito. É como salvar nos favoritos, mas para código.
Os projetos têm um rastreador de problemas, geralmente no GitHub na aba "Issues", a menos que indicado de outra forma, onde as pessoas discutem problemas relacionados ao projeto. E a aba Pull Requests é onde as pessoas discutem e revisam alterações que estão em andamento.
Os projetos também podem ter discussões em fóruns, listas de e-mails ou canais de chat como Slack, Discord ou IRC.
Dê uma olhada no seu novo repositório do GitHub e experimente algumas coisas, como editar configurações, adicionar informações ao seu repositório e criar um projeto (como um quadro Kanban). Há muito o que explorar!
Explore seu novo repositório no GitHub e experimente algumas coisas, como editar configurações, adicionar informações ao repositório e criar um projeto (como um quadro Kanban). Há muito o que fazer!
---
## 🚀 Desafio
Trabalhe em parceria com um amigo no código um do outro. Crie um projeto colaborativamente, faça fork do código, crie branches e mescle alterações.
Trabalhe em parceria com um amigo para trabalhar no código um do outro. Crie um projeto colaborativo, faça fork do código, crie branches e integre alterações.
## Quiz Pós-Aula
[Quiz pós-aula](https://ff-quizzes.netlify.app/web/quiz/4)
[Quiz pós-aula](https://ff-quizzes.netlify.app/web/en/)
## Revisão & Autoestudo
@ -334,5 +333,7 @@ Você também encontrará cursos mais avançados.
Complete [o curso Primeira Semana no GitHub](https://skills.github.com/#first-week-on-github)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte oficial. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,23 +1,23 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e4cd5b1faed4adab5acf720f82798003",
"translation_date": "2025-08-25T23:02:11+00:00",
"original_hash": "f0c88c3e2cefa8952d356f802b1e47ca",
"translation_date": "2025-08-28T23:59:06+00:00",
"source_file": "1-getting-started-lessons/3-accessibility/README.md",
"language_code": "br"
}
-->
# Criando Páginas Web Acessíveis
![Tudo Sobre Acessibilidade](../../../../translated_images/webdev101-a11y.8ef3025c858d897a403a1a42c0897c76e11b724d9a8a0c0578dd4316f7507622.br.png)
![Tudo Sobre Acessibilidade](../../../../translated_images/webdev101-a11y.8ef3025c858d897a403a1a42c0897c76e11b724d9a8a0c0578dd4316f7507622.br.png)
> Sketchnote por [Tomomi Imura](https://twitter.com/girlie_mac)
## Quiz Pré-Aula
[Quiz pré-aula](https://ff-quizzes.netlify.app/web/quiz/5)
## Quiz Pré-Aula
[Quiz pré-aula](https://ff-quizzes.netlify.app/web/)
> O poder da Web está em sua universalidade. O acesso por todos, independentemente de deficiência, é um aspecto essencial.
>
> \- Sir Timothy Berners-Lee, Diretor do W3C e inventor da World Wide Web
> O poder da Web está em sua universalidade. O acesso por todos, independentemente de deficiência, é um aspecto essencial.
>
> \- Sir Timothy Berners-Lee, Diretor do W3C e inventor da World Wide Web
Essa citação destaca perfeitamente a importância de criar sites acessíveis. Um aplicativo que não pode ser acessado por todos é, por definição, excludente. Como desenvolvedores web, devemos sempre ter a acessibilidade em mente. Ao focar nisso desde o início, você estará no caminho certo para garantir que todos possam acessar as páginas que você cria. Nesta lição, você aprenderá sobre as ferramentas que podem ajudar a garantir que seus recursos web sejam acessíveis e como construir com acessibilidade em mente.
@ -29,21 +29,21 @@ Essa citação destaca perfeitamente a importância de criar sites acessíveis.
Uma das ferramentas de acessibilidade mais conhecidas são os leitores de tela.
[Leitores de tela](https://en.wikipedia.org/wiki/Screen_reader) são clientes comumente usados por pessoas com deficiência visual. Assim como nos preocupamos em garantir que um navegador transmita corretamente as informações que queremos compartilhar, também devemos garantir que um leitor de tela faça o mesmo.
[Leitores de tela](https://en.wikipedia.org/wiki/Screen_reader) são clientes comumente usados por pessoas com deficiência visual. Assim como dedicamos tempo para garantir que um navegador transmita corretamente as informações que desejamos compartilhar, também devemos garantir que um leitor de tela faça o mesmo.
De forma básica, um leitor de tela lê uma página de cima para baixo de forma audível. Se sua página for composta apenas por texto, o leitor transmitirá as informações de maneira semelhante a um navegador. No entanto, páginas web raramente são apenas texto; elas contêm links, gráficos, cores e outros componentes visuais. É necessário cuidado para garantir que essas informações sejam lidas corretamente por um leitor de tela.
Todo desenvolvedor web deve se familiarizar com um leitor de tela. Como mencionado acima, é o cliente que seus usuários utilizarão. Da mesma forma que você conhece o funcionamento de um navegador, deve aprender como um leitor de tela opera. Felizmente, leitores de tela estão integrados na maioria dos sistemas operacionais.
Todo desenvolvedor web deve se familiarizar com um leitor de tela. Como destacado acima, é o cliente que seus usuários utilizarão. Da mesma forma que você conhece o funcionamento de um navegador, deve aprender como um leitor de tela opera. Felizmente, leitores de tela estão integrados na maioria dos sistemas operacionais.
Alguns navegadores também possuem ferramentas integradas e extensões que podem ler texto em voz alta ou até mesmo fornecer alguns recursos básicos de navegação, como [essas ferramentas de acessibilidade do navegador Edge](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features). Essas ferramentas também são importantes para acessibilidade, mas funcionam de maneira muito diferente dos leitores de tela e não devem ser confundidas com ferramentas de teste de leitores de tela.
Alguns navegadores também possuem ferramentas integradas e extensões que podem ler texto em voz alta ou até mesmo fornecer alguns recursos básicos de navegação, como [essas ferramentas focadas em acessibilidade do navegador Edge](https://support.microsoft.com/help/4000734/microsoft-edge-accessibility-features). Essas ferramentas também são importantes para acessibilidade, mas funcionam de maneira muito diferente dos leitores de tela e não devem ser confundidas com ferramentas de teste de leitores de tela.
✅ Experimente um leitor de tela e um leitor de texto do navegador. No Windows, o [Narrador](https://support.microsoft.com/windows/complete-guide-to-narrator-e4397a0d-ef4f-b386-d8ae-c172f109bdb1/?WT.mc_id=academic-77807-sagibbon) está incluído por padrão, e [JAWS](https://webaim.org/articles/jaws/) e [NVDA](https://www.nvaccess.org/about-nvda/) também podem ser instalados. No macOS e iOS, o [VoiceOver](https://support.apple.com/guide/voiceover/welcome/10) está instalado por padrão.
### Zoom
Outra ferramenta comumente usada por pessoas com deficiência visual é o zoom. O tipo mais básico de zoom é o zoom estático, controlado por `Control + sinal de mais (+)` ou pela diminuição da resolução da tela. Esse tipo de zoom faz com que toda a página seja redimensionada, então usar [design responsivo](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Responsive_Design) é importante para proporcionar uma boa experiência ao usuário em níveis de zoom aumentados.
Outra ferramenta comumente usada por pessoas com deficiência visual é o zoom. O tipo mais básico de zoom é o zoom estático, controlado por `Control + sinal de mais (+)` ou pela redução da resolução da tela. Esse tipo de zoom faz com que toda a página seja redimensionada, então usar [design responsivo](https://developer.mozilla.org/docs/Learn/CSS/CSS_layout/Responsive_Design) é importante para proporcionar uma boa experiência ao usuário em níveis de zoom aumentados.
Outro tipo de zoom depende de softwares especializados para ampliar uma área específica da tela e mover-se, como se estivesse usando uma lupa real. No Windows, o [Lupa](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198) está integrado, e o [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) é um software de ampliação de terceiros com mais recursos e uma base de usuários maior. Tanto o macOS quanto o iOS possuem um software de ampliação integrado chamado [Zoom](https://www.apple.com/accessibility/mac/vision/).
Outro tipo de zoom depende de softwares especializados para ampliar uma área da tela e mover-se, como usar uma lupa real. No Windows, o [Lupa](https://support.microsoft.com/windows/use-magnifier-to-make-things-on-the-screen-easier-to-see-414948ba-8b1c-d3bd-8615-0e5e32204198) está integrado, e o [ZoomText](https://www.freedomscientific.com/training/zoomtext/getting-started/) é um software de ampliação de terceiros com mais recursos e uma base de usuários maior. Tanto o macOS quanto o iOS possuem um software de ampliação integrado chamado [Zoom](https://www.apple.com/accessibility/mac/vision/).
### Verificadores de contraste
@ -77,7 +77,7 @@ As pessoas enxergam o mundo de maneiras diferentes, e isso inclui as cores. Ao s
Com CSS e JavaScript, é possível fazer qualquer elemento parecer qualquer tipo de controle. `<span>` pode ser usado para criar um `<button>`, e `<b>` pode se tornar um hiperlink. Embora isso possa ser considerado mais fácil de estilizar, não transmite nada para um leitor de tela. Use o HTML apropriado ao criar controles em uma página. Se você quiser um hiperlink, use `<a>`. Usar o HTML correto para o controle correto é chamado de uso de HTML Semântico.
✅ Acesse qualquer site e veja se os designers e desenvolvedores estão usando HTML corretamente. Você consegue encontrar um botão que deveria ser um link? Dica: clique com o botão direito e escolha 'Exibir código-fonte da página' no seu navegador para ver o código subjacente.
✅ Acesse qualquer site e veja se os designers e desenvolvedores estão usando HTML corretamente. Você consegue encontrar um botão que deveria ser um link? Dica: clique com o botão direito e escolha 'Exibir código-fonte da página' no seu navegador para olhar o código subjacente.
### Crie uma hierarquia de cabeçalhos descritiva
@ -89,7 +89,7 @@ O CSS oferece controle total sobre a aparência de qualquer elemento em uma pág
## A importância do texto de links
Hiperlinks são essenciais para navegar na web. Como resultado, garantir que um leitor de tela possa ler links corretamente permite que todos os usuários naveguem pelo seu site.
Hiperlinks são fundamentais para navegar na web. Como resultado, garantir que um leitor de tela possa ler links corretamente permite que todos os usuários naveguem pelo seu site.
### Leitores de tela e links
@ -127,14 +127,14 @@ Como um bônus adicional por garantir que seu site seja acessível para todos, v
Imagine a seguinte página:
| Produto | Descrição | Pedido |
| ------------ | ------------------ | ------------ |
| Widget | [Descrição](../../../../1-getting-started-lessons/3-accessibility/') | [Pedido](../../../../1-getting-started-lessons/3-accessibility/') |
| Super widget | [Descrição](../../../../1-getting-started-lessons/3-accessibility/') | [Pedido](../../../../1-getting-started-lessons/3-accessibility/') |
| Produto | Descrição | Pedido |
| ------------ | ------------------ | ------------ |
| Widget | [Descrição](../../../../1-getting-started-lessons/3-accessibility/') | [Pedido](../../../../1-getting-started-lessons/3-accessibility/') |
| Super widget | [Descrição](../../../../1-getting-started-lessons/3-accessibility/') | [Pedido](../../../../1-getting-started-lessons/3-accessibility/') |
Neste exemplo, duplicar o texto de descrição e pedido faz sentido para alguém usando um navegador. No entanto, alguém usando um leitor de tela ouviria apenas as palavras *descrição* e *pedido* repetidas sem contexto.
Para apoiar esses tipos de cenários, o HTML suporta um conjunto de atributos conhecidos como [Aplicações Ricas para Internet Acessíveis (ARIA)](https://developer.mozilla.org/docs/Web/Accessibility/ARIA). Esses atributos permitem fornecer informações adicionais para leitores de tela.
Para apoiar esses tipos de cenários, o HTML suporta um conjunto de atributos conhecidos como [Aplicações Ricas de Internet Acessíveis (ARIA)](https://developer.mozilla.org/docs/Web/Accessibility/ARIA). Esses atributos permitem que você forneça informações adicionais para leitores de tela.
> **NOTE**: Como muitos aspectos do HTML, o suporte de navegadores e leitores de tela pode variar. No entanto, a maioria dos clientes principais suporta atributos ARIA.
@ -155,26 +155,26 @@ Você pode usar `aria-label` para descrever o link quando o formato da página n
## Imagens
É evidente que leitores de tela não conseguem ler automaticamente o que está em uma imagem. Garantir que as imagens sejam acessíveis não exige muito trabalho - é para isso que serve o atributo `alt`. Todas as imagens significativas devem ter um `alt` para descrever o que são.
É óbvio que leitores de tela não conseguem ler automaticamente o que está em uma imagem. Garantir que as imagens sejam acessíveis não exige muito trabalho - é para isso que serve o atributo `alt`. Todas as imagens significativas devem ter um `alt` para descrever o que são.
Imagens que são puramente decorativas devem ter seu atributo `alt` configurado como uma string vazia: `alt=""`. Isso impede que leitores de tela anunciem desnecessariamente a imagem decorativa.
✅ Como você pode imaginar, mecanismos de busca também não conseguem entender o que está em uma imagem. Eles também usam o texto alternativo. Então, mais uma vez, garantir que sua página seja acessível traz benefícios adicionais!
✅ Como você pode imaginar, mecanismos de busca também não conseguem entender o que está em uma imagem. Eles também usam o texto alternativo. Então, mais uma vez, garantir que sua página seja acessível traz bônus adicionais!
## O teclado
Alguns usuários não conseguem usar um mouse ou trackpad, dependendo exclusivamente de interações com o teclado para navegar de um elemento para outro. É importante que seu site apresente seu conteúdo em uma ordem lógica para que um usuário de teclado possa acessar cada elemento interativo enquanto avança pelo documento. Se você construir suas páginas web com marcação semântica e usar CSS para estilizar seu layout visual, seu site deve ser navegável por teclado, mas é importante testar esse aspecto manualmente. Saiba mais sobre [estratégias de navegação por teclado](https://webaim.org/techniques/keyboard/).
Alguns usuários não conseguem usar um mouse ou trackpad, dependendo exclusivamente de interações com o teclado para navegar de um elemento ao próximo. É importante que seu site apresente seu conteúdo em uma ordem lógica para que um usuário de teclado possa acessar cada elemento interativo enquanto avança pelo documento. Se você construir suas páginas web com marcação semântica e usar CSS para estilizar seu layout visual, seu site deve ser navegável por teclado, mas é importante testar esse aspecto manualmente. Saiba mais sobre [estratégias de navegação por teclado](https://webaim.org/techniques/keyboard/).
✅ Acesse qualquer site e tente navegar por ele usando apenas o teclado. O que funciona, o que não funciona? Por quê?
## Resumo
Uma web acessível para alguns não é uma verdadeira 'world-wide web'. A melhor maneira de garantir que os sites que você cria sejam acessíveis é incorporar as melhores práticas de acessibilidade desde o início. Embora envolvam etapas extras, incorporar essas habilidades ao seu fluxo de trabalho agora garantirá que todas as páginas que você criar sejam acessíveis.
Uma web acessível para alguns não é uma verdadeira 'world-wide web'. A melhor maneira de garantir que os sites que você cria sejam acessíveis é incorporar as melhores práticas de acessibilidade desde o início. Embora envolva etapas extras, incorporar essas habilidades ao seu fluxo de trabalho agora garantirá que todas as páginas que você criar sejam acessíveis.
---
## 🚀 Desafio
Pegue este HTML e reescreva-o para torná-lo o mais acessível possível, usando as estratégias que você aprendeu.
Pegue este HTML e reescreva-o para torná-lo o mais acessível possível, dado as estratégias que você aprendeu.
```html
<!DOCTYPE html>
@ -220,16 +220,16 @@ Pegue este HTML e reescreva-o para torná-lo o mais acessível possível, usando
<p class="nav-item nav-item-bull"><a href="../semantic">Semantic Example</a></p>
</div>
</div>
<p class="footer-copyright">&copy; 2016 Instrument</span>
<p class="footer-copyright">&copy; 2016 Instrument</p>
</div>
</body>
</html>
```
## Quiz Pós-Aula
[Quiz pós-aula](https://ff-quizzes.netlify.app/web/quiz/6)
## Quiz Pós-Aula
[Quiz pós-aula](https://ff-quizzes.netlify.app/web/en/)
## Revisão e Autoestudo
## Revisão & Autoestudo
Muitos governos possuem leis relacionadas a requisitos de acessibilidade. Pesquise sobre as leis de acessibilidade do seu país. O que está coberto e o que não está? Um exemplo é [este site do governo](https://accessibility.blog.gov.uk/).
## Tarefa
@ -238,5 +238,7 @@ Muitos governos possuem leis relacionadas a requisitos de acessibilidade. Pesqui
Créditos: [Turtle Ipsum](https://github.com/Instrument/semantic-html-sample) por Instrument
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "fc6aef8ecfdd5b0ad2afa6e6ba52bfde",
"translation_date": "2025-08-25T21:55:47+00:00",
"original_hash": "b95fdd8310ef467305015ece1b0f9411",
"translation_date": "2025-08-28T23:54:48+00:00",
"source_file": "2-js-basics/1-data-types/README.md",
"language_code": "br"
}
@ -13,9 +13,9 @@ CO_OP_TRANSLATOR_METADATA:
> Sketchnote por [Tomomi Imura](https://twitter.com/girlie_mac)
## Quiz Pré-Aula
[Quiz pré-aula](https://ff-quizzes.netlify.app/web/quiz/7)
[Quiz pré-aula](https://ff-quizzes.netlify.app/web/)
Esta lição aborda os fundamentos do JavaScript, a linguagem que proporciona interatividade na web.
Esta lição aborda os fundamentos do JavaScript, a linguagem que traz interatividade para a web.
> Você pode fazer esta lição no [Microsoft Learn](https://docs.microsoft.com/learn/modules/web-development-101-variables/?WT.mc_id=academic-77807-sagibbon)!
@ -36,7 +36,7 @@ Criar e **declarar** uma variável segue a seguinte sintaxe **[palavra-chave] [n
- **Palavra-chave**. As palavras-chave podem ser `let` ou `var`.
✅ A palavra-chave `let` foi introduzida no ES6 e dá à sua variável um chamado _escopo de bloco_. É recomendado usar `let` em vez de `var`. Vamos abordar escopos de bloco mais detalhadamente em partes futuras.
- **O nome da variável**, que é um nome que você escolhe.
- **O nome da variável**, que é um nome escolhido por você.
### Tarefa - Trabalhando com variáveis
@ -46,7 +46,7 @@ Criar e **declarar** uma variável segue a seguinte sintaxe **[palavra-chave] [n
let myVariable;
```
`myVariable` foi declarada agora usando a palavra-chave `let`. Atualmente, ela não possui um valor.
`myVariable` foi declarada usando a palavra-chave `let`. Atualmente, ela não possui um valor.
1. **Atribua um valor**. Armazene um valor em uma variável com o operador `=`, seguido do valor esperado.
@ -64,7 +64,7 @@ Criar e **declarar** uma variável segue a seguinte sintaxe **[palavra-chave] [n
let myVariable = 123;
```
O exemplo acima é chamado de _inicialização explícita_ quando uma variável é declarada e recebe um valor ao mesmo tempo.
O exemplo acima é chamado de _inicialização explícita_, quando uma variável é declarada e recebe um valor ao mesmo tempo.
1. **Altere o valor da variável**. Altere o valor da variável da seguinte forma:
@ -74,7 +74,7 @@ Criar e **declarar** uma variável segue a seguinte sintaxe **[palavra-chave] [n
Uma vez que uma variável é declarada, você pode alterar seu valor a qualquer momento no seu código com o operador `=` e o novo valor.
✅ Experimente! Você pode escrever JavaScript diretamente no seu navegador. Abra uma janela do navegador e acesse as Ferramentas de Desenvolvedor. No console, você encontrará um prompt; digite `let myVariable = 123`, pressione Enter, e depois digite `myVariable`. O que acontece? Observe que você aprenderá mais sobre esses conceitos em lições subsequentes.
✅ Experimente! Você pode escrever JavaScript diretamente no seu navegador. Abra uma janela do navegador e vá para as Ferramentas de Desenvolvedor. No console, você encontrará um prompt; digite `let myVariable = 123`, pressione Enter, depois digite `myVariable`. O que acontece? Observe que você aprenderá mais sobre esses conceitos em lições subsequentes.
## Constantes
@ -86,8 +86,8 @@ const MY_VARIABLE = 123;
Constantes são semelhantes às variáveis, com duas exceções:
- **Devem ter um valor**. Constantes devem ser inicializadas, ou ocorrerá um erro ao executar o código.
- **A referência não pode ser alterada**. A referência de uma constante não pode ser alterada após ser inicializada, ou ocorrerá um erro ao executar o código. Vamos analisar dois exemplos:
- **Devem ter um valor**. Constantes precisam ser inicializadas, ou um erro ocorrerá ao executar o código.
- **A referência não pode ser alterada**. A referência de uma constante não pode ser alterada após ser inicializada, ou um erro ocorrerá ao executar o código. Vamos ver dois exemplos:
- **Valor simples**. O seguinte NÃO é permitido:
```javascript
@ -132,12 +132,12 @@ Variáveis podem armazenar todos os tipos de números, incluindo decimais ou nú
Existem vários tipos de operadores para usar ao realizar funções aritméticas, e alguns estão listados aqui:
| Símbolo | Descrição | Exemplo |
| ------ | ---------------------------------------------------------------------- | -------------------------------- |
| `+` | **Adição**: Calcula a soma de dois números | `1 + 2 //resposta esperada é 3` |
| `-` | **Subtração**: Calcula a diferença entre dois números | `1 - 2 //resposta esperada é -1` |
| `*` | **Multiplicação**: Calcula o produto de dois números | `1 * 2 //resposta esperada é 2` |
| `/` | **Divisão**: Calcula o quociente de dois números | `1 / 2 //resposta esperada é 0.5` |
| `%` | **Resto**: Calcula o resto da divisão de dois números | `1 % 2 //resposta esperada é 1` |
| ------- | ---------------------------------------------------------------------- | -------------------------------- |
| `+` | **Adição**: Calcula a soma de dois números | `1 + 2 //resposta esperada é 3` |
| `-` | **Subtração**: Calcula a diferença entre dois números | `1 - 2 //resposta esperada é -1` |
| `*` | **Multiplicação**: Calcula o produto de dois números | `1 * 2 //resposta esperada é 2` |
| `/` | **Divisão**: Calcula o quociente de dois números | `1 / 2 //resposta esperada é 0.5`|
| `%` | **Resto**: Calcula o resto da divisão de dois números | `1 % 2 //resposta esperada é 1` |
✅ Experimente! Tente uma operação aritmética no console do seu navegador. Os resultados te surpreendem?
@ -167,7 +167,7 @@ myString1 + ", " + myString2 + "!"; //Hello, World!
```
✅ Por que `1 + 1 = 2` em JavaScript, mas `'1' + '1' = 11?` Pense nisso. E `'1' + 1`?
✅ Por que `1 + 1 = 2` em JavaScript, mas `'1' + '1' = 11`? Pense nisso. E `'1' + 1`?
**Template literals** são outra forma de formatar strings, mas, em vez de aspas, usa-se o acento grave. Qualquer coisa que não seja texto simples deve ser colocada dentro de placeholders `${ }`. Isso inclui quaisquer variáveis que possam ser strings.
@ -196,12 +196,12 @@ Booleanos podem ter apenas dois valores: `true` ou `false`. Booleanos ajudam a t
## 🚀 Desafio
JavaScript é notório por suas formas surpreendentes de lidar com tipos de dados ocasionalmente. Faça uma pesquisa sobre esses 'pegadinhas'. Por exemplo: a sensibilidade a maiúsculas e minúsculas pode te pegar! Experimente isso no seu console: `let age = 1; let Age = 2; age == Age` (resolve como `false` -- por quê?). Que outras pegadinhas você consegue encontrar?
JavaScript é famoso por suas maneiras surpreendentes de lidar com tipos de dados ocasionalmente. Faça uma pesquisa sobre esses 'pegadinhas'. Por exemplo: a sensibilidade a maiúsculas e minúsculas pode te pegar! Experimente isso no seu console: `let age = 1; let Age = 2; age == Age` (resolve para `false` -- por quê?). Que outras pegadinhas você consegue encontrar?
## Quiz Pós-Aula
[Quiz pós-aula](https://ff-quizzes.netlify.app/web/quiz/8)
[Quiz pós-aula](https://ff-quizzes.netlify.app)
## Revisão e Autoestudo
## Revisão & Autoestudo
Dê uma olhada nesta [lista de exercícios de JavaScript](https://css-tricks.com/snippets/javascript/) e tente um. O que você aprendeu?
@ -209,5 +209,7 @@ Dê uma olhada nesta [lista de exercícios de JavaScript](https://css-tricks.com
[Prática de Tipos de Dados](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,19 +1,19 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "b4612bbb9ace984f374fcc80e3e035ad",
"translation_date": "2025-08-25T21:43:21+00:00",
"original_hash": "92e136090efc4341b1d51c37924c1802",
"translation_date": "2025-08-28T23:54:01+00:00",
"source_file": "2-js-basics/2-functions-methods/README.md",
"language_code": "br"
}
-->
# Fundamentos de JavaScript: Métodos e Funções
# Noções Básicas de JavaScript: Métodos e Funções
![Fundamentos de JavaScript - Funções](../../../../translated_images/webdev101-js-functions.be049c4726e94f8b7605c36330ac42eeb5cd8ed02bcdd60fdac778174d6cb865.br.png)
![Noções Básicas de JavaScript - Funções](../../../../translated_images/webdev101-js-functions.be049c4726e94f8b7605c36330ac42eeb5cd8ed02bcdd60fdac778174d6cb865.br.png)
> Sketchnote por [Tomomi Imura](https://twitter.com/girlie_mac)
## Quiz Pré-Aula
[Quiz pré-aula](https://ff-quizzes.netlify.app/web/quiz/9)
[Quiz pré-aula](https://ff-quizzes.netlify.app)
Quando pensamos em escrever código, sempre queremos garantir que ele seja legível. Embora isso possa parecer contraintuitivo, o código é lido muitas mais vezes do que é escrito. Uma ferramenta essencial no arsenal de um desenvolvedor para garantir um código sustentável é a **função**.
@ -27,11 +27,11 @@ Quando pensamos em escrever código, sempre queremos garantir que ele seja legí
No seu núcleo, uma função é um bloco de código que podemos executar sob demanda. Isso é perfeito para cenários em que precisamos realizar a mesma tarefa várias vezes; em vez de duplicar a lógica em vários locais (o que tornaria difícil atualizá-la no futuro), podemos centralizá-la em um único local e chamá-la sempre que precisarmos realizar a operação - você pode até chamar funções dentro de outras funções!
Igualmente importante é a capacidade de nomear uma função. Embora isso possa parecer trivial, o nome fornece uma maneira rápida de documentar uma seção de código. Você pode pensar nisso como um rótulo em um botão. Se eu clicar em um botão que diz "Cancelar temporizador", sei que ele vai parar o relógio.
Igualmente importante é a capacidade de nomear uma função. Embora isso possa parecer trivial, o nome fornece uma maneira rápida de documentar uma seção do código. Você pode pensar nisso como um rótulo em um botão. Se eu clicar em um botão que diz "Cancelar temporizador", sei que ele vai parar o relógio.
## Criando e chamando uma função
A sintaxe para uma função é a seguinte:
A sintaxe para uma função é assim:
```javascript
function nameOfFunction() { // function definition
@ -54,7 +54,7 @@ Sempre que quisermos chamar (ou invocar) nossa função, usamos o nome da funç
displayGreeting();
```
> **NOTE:** Existe um tipo especial de função conhecido como **método**, que você já está usando! Na verdade, vimos isso no nosso exemplo acima quando usamos `console.log`. O que diferencia um método de uma função é que um método está associado a um objeto (`console` no nosso exemplo), enquanto uma função é independente. Você ouvirá muitos desenvolvedores usarem esses termos de forma intercambiável.
> **NOTE:** Existe um tipo especial de função conhecido como **método**, que você já está usando! Na verdade, vimos isso no nosso exemplo acima quando usamos `console.log`. O que diferencia um método de uma função é que um método está anexado a um objeto (`console` no nosso exemplo), enquanto uma função é independente. Muitos desenvolvedores usam esses termos de forma intercambiável.
### Melhores práticas para funções
@ -94,7 +94,7 @@ displayGreeting('Christopher');
## Valores padrão
Podemos tornar nossa função ainda mais flexível adicionando mais parâmetros. Mas e se não quisermos exigir que todos os valores sejam especificados? Continuando com nosso exemplo de saudação, poderíamos deixar o nome como obrigatório (precisamos saber quem estamos saudando), mas queremos permitir que a saudação em si seja personalizada, se desejado. Se alguém não quiser personalizá-la, fornecemos um valor padrão. Para fornecer um valor padrão a um parâmetro, configuramos isso da mesma forma que configuramos um valor para uma variável - `parameterName = 'defaultValue'`. Para ver um exemplo completo:
Podemos tornar nossa função ainda mais flexível adicionando mais parâmetros. Mas e se não quisermos exigir que todos os valores sejam especificados? Mantendo nosso exemplo de saudação, poderíamos deixar o nome como obrigatório (precisamos saber quem estamos saudando), mas queremos permitir que a saudação em si seja personalizada conforme desejado. Se alguém não quiser personalizá-la, fornecemos um valor padrão. Para fornecer um valor padrão a um parâmetro, configuramos isso da mesma forma que configuramos um valor para uma variável - `parameterName = 'defaultValue'`. Para ver um exemplo completo:
```javascript
function displayGreeting(name, salutation='Hello') {
@ -102,7 +102,7 @@ function displayGreeting(name, salutation='Hello') {
}
```
Quando chamamos a função, podemos decidir se queremos definir um valor para `salutation`.
Quando chamarmos a função, podemos decidir se queremos definir um valor para `salutation`.
```javascript
displayGreeting('Christopher');
@ -133,7 +133,7 @@ function createGreetingMessage(name) {
}
```
Ao chamar essa função, armazenaremos o valor em uma variável. Isso é muito semelhante à forma como definiríamos uma variável para um valor estático (como `const name = 'Christopher'`).
Ao chamar essa função, armazenaremos o valor em uma variável. Isso é muito semelhante a como definiríamos uma variável para um valor estático (como `const name = 'Christopher'`).
```javascript
const greetingMessage = createGreetingMessage('Christopher');
@ -141,7 +141,7 @@ const greetingMessage = createGreetingMessage('Christopher');
## Funções como parâmetros para funções
À medida que você avança em sua carreira de programação, encontrará funções que aceitam outras funções como parâmetros. Esse truque interessante é comumente usado quando não sabemos quando algo vai ocorrer ou ser concluído, mas sabemos que precisamos realizar uma operação em resposta.
À medida que você avança na sua carreira de programação, encontrará funções que aceitam outras funções como parâmetros. Esse truque interessante é comumente usado quando não sabemos quando algo vai ocorrer ou ser concluído, mas sabemos que precisamos realizar uma operação em resposta.
Como exemplo, considere [setTimeout](https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), que inicia um temporizador e executará o código quando ele for concluído. Precisamos dizer a ele qual código queremos executar. Parece um trabalho perfeito para uma função!
@ -157,7 +157,7 @@ setTimeout(displayDone, 3000);
### Funções anônimas
Vamos dar outra olhada no que construímos. Estamos criando uma função com um nome que será usado uma única vez. À medida que nossa aplicação se torna mais complexa, podemos nos ver criando muitas funções que serão chamadas apenas uma vez. Isso não é ideal. Acontece que nem sempre precisamos fornecer um nome!
Vamos dar outra olhada no que construímos. Estamos criando uma função com um nome que será usado apenas uma vez. À medida que nosso aplicativo se torna mais complexo, podemos nos ver criando muitas funções que serão chamadas apenas uma vez. Isso não é ideal. Acontece que nem sempre precisamos fornecer um nome!
Quando passamos uma função como parâmetro, podemos evitar criá-la com antecedência e, em vez disso, construí-la como parte do parâmetro. Usamos a mesma palavra-chave `function`, mas a construímos como um parâmetro.
@ -169,7 +169,7 @@ setTimeout(function() {
}, 3000);
```
Se você executar nosso novo código, notará que obtemos os mesmos resultados. Criamos uma função, mas não tivemos que dar um nome a ela!
Se você executar nosso novo código, notará que obtemos os mesmos resultados. Criamos uma função, mas não precisamos dar um nome a ela!
### Funções de seta (fat arrow)
@ -185,7 +185,7 @@ setTimeout(() => {
### Quando usar cada estratégia
Agora você viu que temos três maneiras de passar uma função como parâmetro e pode estar se perguntando quando usar cada uma. Se você sabe que usará a função mais de uma vez, crie-a normalmente. Se você a usará apenas em um local, geralmente é melhor usar uma função anônima. Se você usará uma função de seta ou a sintaxe mais tradicional com `function` é uma escolha sua, mas você notará que a maioria dos desenvolvedores modernos prefere `=>`.
Agora você viu que temos três maneiras de passar uma função como parâmetro e pode estar se perguntando quando usar cada uma. Se você sabe que usará a função mais de uma vez, crie-a normalmente. Se for usá-la apenas em um local, geralmente é melhor usar uma função anônima. Se você usará uma função de seta ou a sintaxe mais tradicional `function` é uma escolha sua, mas notará que a maioria dos desenvolvedores modernos prefere `=>`.
---
@ -194,15 +194,17 @@ Agora você viu que temos três maneiras de passar uma função como parâmetro
Você consegue articular em uma frase a diferença entre funções e métodos? Tente!
## Quiz Pós-Aula
[Quiz pós-aula](https://ff-quizzes.netlify.app/web/quiz/10)
[Quiz pós-aula](https://ff-quizzes.netlify.app)
## Revisão e Autoestudo
Vale a pena [ler um pouco mais sobre funções de seta](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions), já que elas estão sendo cada vez mais usadas em bases de código. Pratique escrever uma função e, em seguida, reescrevê-la com essa sintaxe.
Vale a pena [ler um pouco mais sobre funções de seta](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions), já que elas estão sendo cada vez mais usadas em bases de código. Pratique escrever uma função e depois reescrevê-la com essa sintaxe.
## Tarefa
[Divirta-se com Funções](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte oficial. Para informações críticas, recomenda-se a tradução profissional feita por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "888609c48329c280ca2477d2df40f2e5",
"translation_date": "2025-08-25T21:36:23+00:00",
"original_hash": "f7009631b73556168ca435120a231c98",
"translation_date": "2025-08-28T23:54:29+00:00",
"source_file": "2-js-basics/3-making-decisions/README.md",
"language_code": "br"
}
@ -17,7 +17,7 @@ CO_OP_TRANSLATOR_METADATA:
[Quiz pré-aula](https://ff-quizzes.netlify.app/web/quiz/11)
Tomar decisões e controlar a ordem em que seu código é executado torna seu código reutilizável e robusto. Esta seção aborda a sintaxe para controlar o fluxo de dados em JavaScript e sua importância ao ser usada com tipos de dados Booleanos.
Tomar decisões e controlar a ordem em que seu código é executado torna seu código reutilizável e robusto. Esta seção aborda a sintaxe para controlar o fluxo de dados em JavaScript e sua importância ao ser usado com tipos de dados Booleanos.
[![Tomando Decisões](https://img.youtube.com/vi/SxTp8j-fMMY/0.jpg)](https://youtube.com/watch?v=SxTp8j-fMMY "Tomando Decisões")
@ -34,7 +34,7 @@ Defina seu booleano como verdadeiro ou falso assim:
`let myTrueBool = true`
`let myFalseBool = false`
✅ Booleanos são nomeados em homenagem ao matemático, filósofo e lógico inglês George Boole (18151864).
✅ Booleanos foram nomeados em homenagem ao matemático, filósofo e lógico inglês George Boole (18151864).
## Operadores de Comparação e Booleanos
@ -46,7 +46,7 @@ Operadores são usados para avaliar condições fazendo comparações que geram
| `<=` | **Menor ou igual a**: Compara dois valores e retorna o tipo de dado Booleano `true` se o valor do lado esquerdo for menor ou igual ao do lado direito | `5 <= 6 // true` |
| `>` | **Maior que**: Compara dois valores e retorna o tipo de dado Booleano `true` se o valor do lado esquerdo for maior que o do lado direito | `5 > 6 // false` |
| `>=` | **Maior ou igual a**: Compara dois valores e retorna o tipo de dado Booleano `true` se o valor do lado esquerdo for maior ou igual ao do lado direito | `5 >= 6 // false` |
| `===` | **Igualdade estrita**: Compara dois valores e retorna o tipo de dado Booleano `true` se os valores do lado direito e esquerdo forem iguais E do mesmo tipo | `5 === 6 // false` |
| `===` | **Igualdade estrita**: Compara dois valores e retorna o tipo de dado Booleano `true` se os valores do lado direito e esquerdo forem iguais E do mesmo tipo. | `5 === 6 // false` |
| `!==` | **Desigualdade**: Compara dois valores e retorna o valor Booleano oposto ao que um operador de igualdade estrita retornaria | `5 !== 6 // true` |
✅ Teste seu conhecimento escrevendo algumas comparações no console do navegador. Algum dado retornado te surpreendeu?
@ -141,7 +141,7 @@ Decisões podem exigir mais de uma comparação e podem ser encadeadas com opera
## Condições e Decisões com Operadores Lógicos
Operadores lógicos podem ser usados para formar condições em declarações `if..else`.
Operadores lógicos podem ser usados para formar condições em declarações if..else.
```javascript
let currentMoney;
@ -159,7 +159,7 @@ if (currentMoney >= laptopPrice || currentMoney >= laptopDiscountPrice) {
### Operador de Negação
Você já viu até agora como usar uma declaração `if...else` para criar lógica condicional. Qualquer coisa que vá dentro de um `if` precisa ser avaliada como verdadeiro ou falso. Usando o operador `!`, você pode _negar_ a expressão. Ficaria assim:
Você já viu como usar uma declaração `if...else` para criar lógica condicional. Qualquer coisa que vá dentro de um `if` precisa ser avaliada como verdadeiro/falso. Usando o operador `!`, você pode _negar_ a expressão. Ficaria assim:
```javascript
if (!condition) {
@ -226,5 +226,7 @@ Explore o incrível [guia de operadores](https://joshwcomeau.com/operator-lookup
[Operadores](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,21 +1,21 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "3f7f87871312cf6cc12662da7d973182",
"translation_date": "2025-08-25T21:49:00+00:00",
"original_hash": "9029f96b0e034839c1799f4595e4bb66",
"translation_date": "2025-08-28T23:55:17+00:00",
"source_file": "2-js-basics/4-arrays-loops/README.md",
"language_code": "br"
}
-->
# Noções Básicas de JavaScript: Arrays e Loops
# Fundamentos de JavaScript: Arrays e Loops
![Noções Básicas de JavaScript - Arrays](../../../../translated_images/webdev101-js-arrays.439d7528b8a294558d0e4302e448d193f8ad7495cc407539cc81f1afe904b470.br.png)
![Fundamentos de JavaScript - Arrays](../../../../translated_images/webdev101-js-arrays.439d7528b8a294558d0e4302e448d193f8ad7495cc407539cc81f1afe904b470.br.png)
> Sketchnote por [Tomomi Imura](https://twitter.com/girlie_mac)
## Quiz Pré-Aula
[Quiz pré-aula](https://ff-quizzes.netlify.app/web/quiz/13)
## Questionário Pré-Aula
[Questionário pré-aula](https://ff-quizzes.netlify.app/web/quiz/13)
Esta lição aborda os fundamentos do JavaScript, a linguagem que proporciona interatividade na web. Nesta lição, você aprenderá sobre arrays e loops, que são usados para manipular dados.
Esta lição aborda os fundamentos do JavaScript, a linguagem que traz interatividade para a web. Nesta lição, você aprenderá sobre arrays e loops, que são usados para manipular dados.
[![Arrays](https://img.youtube.com/vi/1U4qTyq02Xw/0.jpg)](https://youtube.com/watch?v=1U4qTyq02Xw "Arrays")
@ -27,7 +27,7 @@ Esta lição aborda os fundamentos do JavaScript, a linguagem que proporciona in
## Arrays
Trabalhar com dados é uma tarefa comum em qualquer linguagem, e essa tarefa se torna muito mais fácil quando os dados estão organizados em um formato estrutural, como arrays. Com arrays, os dados são armazenados em uma estrutura semelhante a uma lista. Um grande benefício dos arrays é que você pode armazenar diferentes tipos de dados em um único array.
Trabalhar com dados é uma tarefa comum em qualquer linguagem, e fica muito mais fácil quando os dados estão organizados em um formato estrutural, como arrays. Com arrays, os dados são armazenados em uma estrutura semelhante a uma lista. Uma grande vantagem dos arrays é que você pode armazenar diferentes tipos de dados em um único array.
✅ Arrays estão por toda parte! Consegue pensar em um exemplo da vida real de um array, como um conjunto de painéis solares?
@ -37,13 +37,13 @@ A sintaxe de um array é um par de colchetes.
let myArray = [];
```
Este é um array vazio, mas os arrays podem ser declarados já preenchidos com dados. Vários valores em um array são separados por uma vírgula.
Este é um array vazio, mas arrays podem ser declarados já preenchidos com dados. Vários valores em um array são separados por vírgulas.
```javascript
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
```
Os valores do array recebem um valor único chamado **índice**, um número inteiro atribuído com base na sua posição a partir do início do array. No exemplo acima, o valor de string "Chocolate" tem um índice de 0, e o índice de "Rocky Road" é 4. Use o índice com colchetes para recuperar, alterar ou inserir valores no array.
Os valores do array recebem um valor único chamado **índice**, um número inteiro atribuído com base na sua posição a partir do início do array. No exemplo acima, o valor de string "Chocolate" tem o índice 0, e o índice de "Rocky Road" é 4. Use o índice com colchetes para recuperar, alterar ou inserir valores no array.
✅ Você se surpreendeu ao saber que os arrays começam no índice zero? Em algumas linguagens de programação, os índices começam em 1. Há uma história interessante sobre isso, que você pode [ler na Wikipedia](https://en.wikipedia.org/wiki/Zero-based_numbering).
@ -64,7 +64,7 @@ E pode inserir um novo valor em um índice específico assim:
iceCreamFlavors[5] = "Cookie Dough"; //Added "Cookie Dough"
```
✅ Uma maneira mais comum de adicionar valores a um array é usando operadores de array, como array.push().
✅ Uma maneira mais comum de adicionar valores a um array é usando operadores como array.push().
Para descobrir quantos itens há em um array, use a propriedade `length`.
@ -73,18 +73,18 @@ let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky
iceCreamFlavors.length; //5
```
✅ Experimente você mesmo! Use o console do navegador para criar e manipular um array de sua própria criação.
✅ Experimente você mesmo! Use o console do seu navegador para criar e manipular um array de sua própria criação.
## Loops
Loops nos permitem realizar tarefas repetitivas ou **iterativas**, economizando muito tempo e código. Cada iteração pode variar em suas variáveis, valores e condições. Existem diferentes tipos de loops em JavaScript, e todos têm pequenas diferenças, mas essencialmente fazem a mesma coisa: iterar sobre dados.
Loops permitem realizar tarefas repetitivas ou **iterativas**, economizando muito tempo e código. Cada iteração pode variar em suas variáveis, valores e condições. Existem diferentes tipos de loops em JavaScript, e todos têm pequenas diferenças, mas essencialmente fazem a mesma coisa: iterar sobre dados.
### Loop For
### For Loop
O loop `for` requer 3 partes para iterar:
- `counter` Uma variável que geralmente é inicializada com um número que conta o número de iterações
- `condition` Expressão que usa operadores de comparação para fazer o loop parar quando for `false`
- `iteration-expression` Executada no final de cada iteração, geralmente usada para alterar o valor do contador
O loop `for` requer 3 partes para iterar:
- `counter` Uma variável que geralmente é inicializada com um número que conta o número de iterações
- `condition` Expressão que usa operadores de comparação para fazer o loop parar quando for `false`
- `iteration-expression` Executada no final de cada iteração, geralmente usada para alterar o valor do contador
```javascript
// Counting up to 10
@ -95,7 +95,7 @@ for (let i = 0; i < 10; i++) {
✅ Execute este código no console do navegador. O que acontece quando você faz pequenas alterações no contador, na condição ou na expressão de iteração? Consegue fazer o loop rodar ao contrário, criando uma contagem regressiva?
### Loop While
### While Loop
Diferente da sintaxe do loop `for`, os loops `while` exigem apenas uma condição que fará o loop parar quando a condição se tornar `false`. As condições nos loops geralmente dependem de outros valores, como contadores, e devem ser gerenciadas durante o loop. Os valores iniciais dos contadores devem ser criados fora do loop, e quaisquer expressões para atender a uma condição, incluindo a alteração do contador, devem ser mantidas dentro do loop.
@ -108,11 +108,11 @@ while (i < 10) {
}
```
✅ Por que você escolheria um loop for em vez de um loop while? 17 mil pessoas tiveram a mesma dúvida no StackOverflow, e algumas das opiniões [podem ser interessantes para você](https://stackoverflow.com/questions/39969145/while-loops-vs-for-loops-in-javascript).
✅ Por que você escolheria um loop for em vez de um while? 17 mil pessoas tiveram a mesma dúvida no StackOverflow, e algumas das opiniões [podem ser interessantes para você](https://stackoverflow.com/questions/39969145/while-loops-vs-for-loops-in-javascript).
## Loops e Arrays
Os arrays são frequentemente usados com loops porque a maioria das condições requer o comprimento do array para parar o loop, e o índice também pode ser o valor do contador.
Arrays são frequentemente usados com loops porque a maioria das condições requer o comprimento do array para parar o loop, e o índice também pode ser o valor do contador.
```javascript
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
@ -130,8 +130,8 @@ for (let i = 0; i < iceCreamFlavors.length; i++) {
Existem outras maneiras de iterar sobre arrays além dos loops for e while. Há [forEach](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach), [for-of](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/for...of) e [map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map). Reescreva seu loop de array usando uma dessas técnicas.
## Quiz Pós-Aula
[Quiz pós-aula](https://ff-quizzes.netlify.app/web/quiz/14)
## Questionário Pós-Aula
[Questionário pós-aula](https://ff-quizzes.netlify.app/web/quiz/14)
## Revisão e Autoestudo
@ -141,5 +141,7 @@ Os arrays em JavaScript possuem muitos métodos associados a eles, que são extr
[Iterar um Array](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "46a0639e719b9cf1dfd062aa24cad639",
"translation_date": "2025-08-25T21:09:56+00:00",
"original_hash": "89f7f9f800ce7c9f149e98baaae8491a",
"translation_date": "2025-08-28T23:55:37+00:00",
"source_file": "3-terrarium/1-intro-to-html/README.md",
"language_code": "br"
}
@ -12,9 +12,10 @@ CO_OP_TRANSLATOR_METADATA:
![Introdução ao HTML](../../../../translated_images/webdev101-html.4389c2067af68e98280c1bde52b6c6269f399eaae3659b7c846018d8a7b0bbd9.br.png)
> Sketchnote por [Tomomi Imura](https://twitter.com/girlie_mac)
## Quiz Pré-Aula
## Questionário Pré-Aula
[Questionário pré-aula](https://ff-quizzes.netlify.app/web/quiz/15)
[Quiz pré-aula](https://ff-quizzes.netlify.app/web/quiz/15)
> Assista ao vídeo
@ -25,17 +26,17 @@ CO_OP_TRANSLATOR_METADATA:
HTML, ou HyperText Markup Language, é o 'esqueleto' da web. Se o CSS 'veste' seu HTML e o JavaScript dá vida a ele, o HTML é o corpo da sua aplicação web. A sintaxe do HTML reflete essa ideia, pois inclui tags como "head", "body" e "footer".
Nesta lição, vamos usar HTML para estruturar o 'esqueleto' da interface do nosso terrário virtual. Ele terá um título e três colunas: uma coluna à direita e outra à esquerda onde as plantas arrastáveis estarão, e uma área central que será o terrário com aparência de vidro. Ao final desta lição, você poderá ver as plantas nas colunas, mas a interface parecerá um pouco estranha; não se preocupe, na próxima seção você adicionará estilos CSS para melhorar a aparência da interface.
Nesta lição, vamos usar HTML para estruturar o 'esqueleto' da interface do nosso terrário virtual. Ele terá um título e três colunas: uma coluna à direita e outra à esquerda onde ficarão as plantas arrastáveis, e uma área central que será o terrário com aparência de vidro. Ao final desta lição, você será capaz de ver as plantas nas colunas, mas a interface ainda parecerá um pouco estranha; não se preocupe, na próxima seção você adicionará estilos CSS para melhorar a aparência da interface.
### Tarefa
No seu computador, crie uma pasta chamada 'terrarium' e, dentro dela, um arquivo chamado 'index.html'. Você pode fazer isso no Visual Studio Code após criar a pasta do terrário, abrindo uma nova janela do VS Code, clicando em 'abrir pasta' e navegando até sua nova pasta. Clique no pequeno botão 'arquivo' no painel Explorer e crie o novo arquivo:
No seu computador, crie uma pasta chamada 'terrarium' e, dentro dela, um arquivo chamado 'index.html'. Você pode fazer isso no Visual Studio Code após criar a pasta do terrário, abrindo uma nova janela do VS Code, clicando em 'abrir pasta' e navegando até sua nova pasta. Clique no pequeno botão 'arquivo' no painel do Explorer e crie o novo arquivo:
![explorer no VS Code](../../../../translated_images/vs-code-index.e2986cf919471eb984a0afef231380c8b132b000635105f2397bd2754d1b689c.br.png)
Ou
Use estes comandos no seu git bash:
Use estes comandos no seu Git Bash:
* `mkdir terrarium`
* `cd terrarium`
* `touch index.html`
@ -47,32 +48,32 @@ Use estes comandos no seu git bash:
## O DocType e as tags html
A primeira linha de um arquivo HTML é seu doctype. É um pouco surpreendente que você precise ter essa linha no topo do arquivo, mas ela informa aos navegadores mais antigos que a página deve ser renderizada em modo padrão, seguindo a especificação atual do HTML.
A primeira linha de um arquivo HTML é o seu doctype. É um pouco surpreendente que você precise ter essa linha no topo do arquivo, mas ela informa aos navegadores mais antigos que a página deve ser renderizada em modo padrão, seguindo a especificação atual do HTML.
> Dica: no VS Code, você pode passar o mouse sobre uma tag e obter informações sobre seu uso nos guias de referência do MDN.
> Dica: no VS Code, você pode passar o mouse sobre uma tag e obter informações sobre seu uso a partir dos guias de referência do MDN.
A segunda linha deve ser a tag de abertura `<html>`, seguida agora pela sua tag de fechamento `</html>`. Essas tags são os elementos raiz da sua interface.
A segunda linha deve ser a tag de abertura `<html>`, seguida imediatamente pela sua tag de fechamento `</html>`. Essas tags são os elementos raiz da sua interface.
### Tarefa
Adicione essas linhas no topo do seu arquivo `index.html`:
Adicione estas linhas no topo do seu arquivo `index.html`:
```HTML
<!DOCTYPE html>
<html></html>
```
✅ Existem alguns modos diferentes que podem ser determinados configurando o DocType com uma string de consulta: [Modo Quirks e Modo Padrão](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode). Esses modos costumavam suportar navegadores muito antigos que não são normalmente usados hoje em dia (Netscape Navigator 4 e Internet Explorer 5). Você pode usar a declaração padrão do doctype.
✅ Existem alguns modos diferentes que podem ser determinados configurando o DocType com uma string de consulta: [Modo Quirks e Modo Padrão](https://developer.mozilla.org/docs/Web/HTML/Quirks_Mode_and_Standards_Mode). Esses modos eram usados para suportar navegadores muito antigos que não são mais usados atualmente (Netscape Navigator 4 e Internet Explorer 5). Você pode usar a declaração padrão do doctype.
---
## O 'head' do documento
A área 'head' do documento HTML inclui informações cruciais sobre sua página web, também conhecidas como [metadados](https://developer.mozilla.org/docs/Web/HTML/Element/meta). No nosso caso, informamos ao servidor web para o qual esta página será enviada para renderização, estas quatro coisas:
A área 'head' do documento HTML inclui informações cruciais sobre sua página web, também conhecidas como [metadados](https://developer.mozilla.org/docs/Web/HTML/Element/meta). No nosso caso, informamos ao servidor web, que renderizará esta página, as seguintes quatro coisas:
- o título da página
- metadados da página, incluindo:
- o 'conjunto de caracteres', que informa sobre qual codificação de caracteres é usada na página
- o 'conjunto de caracteres', que informa qual codificação de caracteres é usada na página
- informações do navegador, incluindo `x-ua-compatible`, que indica que o navegador IE=edge é suportado
- informações sobre como o viewport deve se comportar ao ser carregado. Configurar o viewport para ter uma escala inicial de 1 controla o nível de zoom quando a página é carregada pela primeira vez.
@ -97,7 +98,7 @@ Adicione um bloco 'head' ao seu documento entre as tags de abertura e fechamento
### Tags HTML
No HTML, você adiciona tags ao seu arquivo .html para criar elementos de uma página web. Cada tag geralmente tem uma tag de abertura e fechamento, como esta: `<p>olá</p>` para indicar um parágrafo. Crie o corpo da sua interface adicionando um conjunto de tags `<body>` dentro do par de tags `<html>`; sua marcação agora ficará assim:
No HTML, você adiciona tags ao seu arquivo .html para criar elementos de uma página web. Cada tag geralmente tem uma tag de abertura e uma de fechamento, como esta: `<p>olá</p>` para indicar um parágrafo. Crie o corpo da sua interface adicionando um conjunto de tags `<body>` dentro do par de tags `<html>`; seu código agora ficará assim:
### Tarefa
@ -118,9 +119,9 @@ Agora, você pode começar a construir sua página. Normalmente, você usa tags
### Imagens
Uma tag HTML que não precisa de uma tag de fechamento é a `<img>`, porque ela tem um elemento `src` que contém todas as informações que a página precisa para renderizar o item.
Uma tag HTML que não precisa de uma tag de fechamento é a `<img>`, porque ela possui um elemento `src` que contém todas as informações necessárias para renderizar o item na página.
Crie uma pasta no seu aplicativo chamada `images` e, dentro dela, adicione todas as imagens na [pasta de código fonte](../../../../3-terrarium/solution/images); (são 14 imagens de plantas).
Crie uma pasta no seu aplicativo chamada `images` e, dentro dela, adicione todas as imagens da [pasta de código-fonte](../../../../3-terrarium/solution/images); (são 14 imagens de plantas).
### Tarefa
@ -177,19 +178,19 @@ Adicione essas imagens de plantas em duas colunas entre as tags `<body></body>`:
</div>
```
> Nota: Spans vs. Divs. Divs são considerados elementos 'block', e Spans são 'inline'. O que aconteceria se você transformasse esses divs em spans?
> Nota: Spans vs. Divs. Divs são considerados elementos 'block', enquanto Spans são 'inline'. O que aconteceria se você transformasse esses divs em spans?
Com essa marcação, as plantas agora aparecem na tela. Parece bem ruim, porque ainda não foram estilizadas usando CSS, e faremos isso na próxima lição.
Com esse código, as plantas agora aparecem na tela. A aparência ainda está ruim, porque elas ainda não foram estilizadas com CSS, e faremos isso na próxima lição.
Cada imagem tem um texto alternativo que aparecerá mesmo que você não consiga ver ou renderizar uma imagem. Este é um atributo importante para incluir para acessibilidade. Aprenda mais sobre acessibilidade em lições futuras; por enquanto, lembre-se de que o atributo alt fornece informações alternativas para uma imagem caso um usuário, por algum motivo, não consiga visualizá-la (por causa de conexão lenta, um erro no atributo src ou se o usuário usar um leitor de tela).
Cada imagem possui um texto alternativo (alt) que aparecerá mesmo que você não consiga ver ou renderizar uma imagem. Esse é um atributo importante para acessibilidade. Aprenda mais sobre acessibilidade em lições futuras; por enquanto, lembre-se de que o atributo alt fornece informações alternativas para uma imagem caso um usuário, por algum motivo, não consiga visualizá-la (devido a uma conexão lenta, um erro no atributo src ou se o usuário usar um leitor de tela).
✅ Você percebeu que cada imagem tem o mesmo texto alternativo? Isso é uma boa prática? Por que ou por que não? Você pode melhorar este código?
✅ Você percebeu que cada imagem tem o mesmo texto alternativo? Isso é uma boa prática? Por quê? Você pode melhorar esse código?
---
## Marcação semântica
Em geral, é preferível usar 'semântica' significativa ao escrever HTML. O que isso significa? Significa que você usa tags HTML para representar o tipo de dado ou interação para os quais foram projetadas. Por exemplo, o texto principal de título em uma página deve usar uma tag `<h1>`.
Em geral, é preferível usar 'semântica' significativa ao escrever HTML. O que isso significa? Significa usar tags HTML para representar o tipo de dado ou interação para o qual foram projetadas. Por exemplo, o texto principal de um título em uma página deve usar uma tag `<h1>`.
Adicione a seguinte linha logo abaixo da sua tag de abertura `<body>`:
@ -197,13 +198,13 @@ Adicione a seguinte linha logo abaixo da sua tag de abertura `<body>`:
<h1>My Terrarium</h1>
```
Usar marcação semântica, como ter cabeçalhos como `<h1>` e listas não ordenadas renderizadas como `<ul>`, ajuda leitores de tela a navegar por uma página. Em geral, botões devem ser escritos como `<button>` e listas como `<li>`. Embora seja _possível_ usar elementos `<span>` especialmente estilizados com manipuladores de clique para simular botões, é melhor para usuários com deficiência usar tecnologias para determinar onde em uma página um botão está localizado e interagir com ele, se o elemento aparecer como um botão. Por essa razão, tente usar marcação semântica sempre que possível.
Usar marcação semântica, como ter cabeçalhos como `<h1>` e listas não ordenadas como `<ul>`, ajuda leitores de tela a navegar por uma página. Em geral, botões devem ser escritos como `<button>` e listas como `<li>`. Embora seja _possível_ usar elementos `<span>` especialmente estilizados com manipuladores de clique para simular botões, é melhor para usuários com deficiência que usam tecnologias assistivas determinar onde está um botão em uma página e interagir com ele, se o elemento aparecer como um botão. Por essa razão, tente usar marcação semântica sempre que possível.
✅ Dê uma olhada em um leitor de tela e [como ele interage com uma página web](https://www.youtube.com/watch?v=OUDV1gqs9GA). Você consegue entender por que ter marcação não semântica pode frustrar o usuário?
✅ Dê uma olhada em um leitor de tela e [como ele interage com uma página web](https://www.youtube.com/watch?v=OUDV1gqs9GA). Você consegue perceber por que uma marcação não semântica pode frustrar o usuário?
## O terrário
A última parte desta interface envolve criar marcação que será estilizada para criar um terrário.
A última parte desta interface envolve criar uma marcação que será estilizada para criar um terrário.
### Tarefa:
@ -221,27 +222,29 @@ Adicione esta marcação acima da última tag `</div>`:
</div>
```
✅ Mesmo que você tenha adicionado esta marcação à tela, você não vê absolutamente nada sendo renderizado. Por quê?
✅ Mesmo que você tenha adicionado essa marcação à tela, nada aparece. Por quê?
---
## 🚀Desafio
Existem algumas tags 'antigas' no HTML que ainda são divertidas de usar, embora você não deva usar tags obsoletas como [estas tags](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) na sua marcação. Ainda assim, você consegue usar a antiga tag `<marquee>` para fazer o título h1 rolar horizontalmente? (se fizer isso, não se esqueça de removê-la depois)
Existem algumas tags 'antigas' no HTML que ainda são divertidas de usar, embora você não deva usar tags obsoletas como [essas tags](https://developer.mozilla.org/docs/Web/HTML/Element#Obsolete_and_deprecated_elements) no seu código. Ainda assim, você consegue usar a antiga tag `<marquee>` para fazer o título `<h1>` rolar horizontalmente? (se fizer isso, não se esqueça de removê-la depois)
## Quiz Pós-Aula
## Questionário Pós-Aula
[Quiz pós-aula](https://ff-quizzes.netlify.app/web/quiz/16)
[Questionário pós-aula](https://ff-quizzes.netlify.app/web/quiz/16)
## Revisão & Autoestudo
## Revisão e Autoestudo
HTML é o sistema de blocos de construção 'testado e comprovado' que ajudou a construir a web como ela é hoje. Aprenda um pouco sobre sua história estudando algumas tags antigas e novas. Você consegue descobrir por que algumas tags foram descontinuadas e outras adicionadas? Que tags podem ser introduzidas no futuro?
HTML é o sistema de construção 'testado e aprovado' que ajudou a construir a web como a conhecemos hoje. Aprenda um pouco sobre sua história estudando algumas tags antigas e novas. Você consegue descobrir por que algumas tags foram descontinuadas e outras adicionadas? Que tags podem ser introduzidas no futuro?
Saiba mais sobre como construir sites para a web e dispositivos móveis em [Microsoft Learn](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=academic-77807-sagibbon).
Saiba mais sobre como criar sites para a web e dispositivos móveis em [Microsoft Learn](https://docs.microsoft.com/learn/modules/build-simple-website/?WT.mc_id=academic-77807-sagibbon).
## Tarefa
[Pratique seu HTML: Crie um mockup de blog](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e375c2aeb94e2407f2667633d39580bd",
"translation_date": "2025-08-25T21:27:25+00:00",
"original_hash": "acb5ae00cde004304296bb97da8ff4c3",
"translation_date": "2025-08-28T23:56:00+00:00",
"source_file": "3-terrarium/2-intro-to-css/README.md",
"language_code": "br"
}
@ -12,23 +12,23 @@ CO_OP_TRANSLATOR_METADATA:
![Introdução ao CSS](../../../../translated_images/webdev101-css.3f7af5991bf53a200d79e7257e5e450408d8ea97f5b531d31b2e3976317338ee.br.png)
> Sketchnote por [Tomomi Imura](https://twitter.com/girlie_mac)
## Questionário Pré-Aula
## Quiz Pré-Aula
[Questionário pré-aula](https://ff-quizzes.netlify.app/web/quiz/17)
[Quiz pré-aula](https://ff-quizzes.netlify.app/web/quiz/17)
### Introdução
CSS, ou Cascading Style Sheets, resolve um problema importante no desenvolvimento web: como fazer seu site ficar bonito. Estilizar seus aplicativos os torna mais utilizáveis e visualmente agradáveis; você também pode usar CSS para criar um Design Responsivo (RWD) - permitindo que seus aplicativos fiquem bem em qualquer tamanho de tela. CSS não é apenas sobre aparência; sua especificação inclui animações e transformações que possibilitam interações sofisticadas para seus aplicativos. O CSS Working Group ajuda a manter as especificações atuais do CSS; você pode acompanhar o trabalho deles no [site do World Wide Web Consortium](https://www.w3.org/Style/CSS/members).
CSS, ou Cascading Style Sheets, resolve um problema importante no desenvolvimento web: como fazer seu site ter uma aparência agradável. Estilizar seus aplicativos os torna mais utilizáveis e visualmente atraentes; você também pode usar CSS para criar um Design Responsivo (RWD) - permitindo que seus aplicativos fiquem bem em qualquer tamanho de tela. CSS não é apenas sobre aparência; sua especificação inclui animações e transformações que podem habilitar interações sofisticadas para seus aplicativos. O Grupo de Trabalho de CSS ajuda a manter as especificações atuais do CSS; você pode acompanhar o trabalho deles no [site do World Wide Web Consortium](https://www.w3.org/Style/CSS/members).
> Nota: o CSS é uma linguagem que evolui, como tudo na web, e nem todos os navegadores suportam as partes mais recentes da especificação. Sempre verifique suas implementações consultando o [CanIUse.com](https://caniuse.com).
> Nota: CSS é uma linguagem que evolui, como tudo na web, e nem todos os navegadores suportam as partes mais recentes da especificação. Sempre verifique suas implementações consultando [CanIUse.com](https://caniuse.com).
Nesta lição, vamos adicionar estilos ao nosso terrário online e aprender mais sobre vários conceitos do CSS: a cascata, herança, uso de seletores, posicionamento e como usar CSS para criar layouts. Durante o processo, vamos organizar o layout do terrário e criar o próprio terrário.
Nesta lição, vamos adicionar estilos ao nosso terrário online e aprender mais sobre vários conceitos de CSS: a cascata, herança, uso de seletores, posicionamento e como usar CSS para construir layouts. Durante o processo, vamos organizar o layout do terrário e criar o próprio terrário.
### Pré-requisito
Você deve ter o HTML do seu terrário pronto para ser estilizado.
Você deve ter o HTML do seu terrário construído e pronto para ser estilizado.
> Assista ao vídeo
> Confira o vídeo
>
> [![Vídeo básico sobre Git e GitHub](https://img.youtube.com/vi/6yIdOIV9p1I/0.jpg)](https://www.youtube.com/watch?v=6yIdOIV9p1I)
@ -45,7 +45,7 @@ Na pasta do seu terrário, crie um novo arquivo chamado `style.css`. Importe ess
## A Cascata
As Cascading Style Sheets incorporam a ideia de que os estilos 'cascateiam', de forma que a aplicação de um estilo é guiada por sua prioridade. Estilos definidos pelo autor de um site têm prioridade sobre aqueles definidos pelo navegador. Estilos definidos 'inline' têm prioridade sobre aqueles definidos em uma folha de estilo externa.
Cascading Style Sheets incorporam a ideia de que os estilos 'cascateiam', de forma que a aplicação de um estilo é guiada por sua prioridade. Estilos definidos pelo autor de um site têm prioridade sobre aqueles definidos por um navegador. Estilos definidos 'inline' têm prioridade sobre aqueles definidos em uma folha de estilo externa.
### Tarefa
@ -55,7 +55,7 @@ Adicione o estilo inline "color: red" à sua tag `<h1>`:
<h1 style="color: red">My Terrarium</h1>
```
Depois, adicione o seguinte código ao seu arquivo `style.css`:
Em seguida, adicione o seguinte código ao seu arquivo `style.css`:
```CSS
h1 {
@ -63,17 +63,17 @@ h1 {
}
```
✅ Qual cor é exibida no seu aplicativo web? Por quê? Você consegue encontrar uma maneira de sobrescrever estilos? Quando você gostaria de fazer isso, ou por que não?
✅ Qual cor aparece no seu aplicativo web? Por quê? Você consegue encontrar uma maneira de sobrescrever estilos? Quando você gostaria de fazer isso, ou por que não?
---
## Herança
Os estilos são herdados de um estilo ancestral para um descendente, de forma que elementos aninhados herdam os estilos de seus pais.
Estilos são herdados de um estilo ancestral para um descendente, de forma que elementos aninhados herdam os estilos de seus pais.
### Tarefa
Defina a fonte do corpo para uma fonte específica e verifique se um elemento aninhado herda essa fonte:
Defina a fonte do corpo para uma fonte específica e verifique a fonte de um elemento aninhado:
```CSS
body {
@ -81,7 +81,7 @@ body {
}
```
Abra o console do seu navegador na aba 'Elements' e observe a fonte do H1. Ele herda sua fonte do corpo, conforme indicado no navegador:
Abra o console do seu navegador na aba 'Elements' e observe a fonte do H1. Ele herda sua fonte do corpo, conforme indicado pelo navegador:
![fonte herdada](../../../../translated_images/1.cc07a5cbe114ad1d4728c35134584ac1b87db688eff83cf75985cf31fe0ed95c.br.png)
@ -106,11 +106,11 @@ h1 {
}
```
Esse método de estilizar uma tag dá controle sobre elementos únicos, mas você precisa controlar os estilos de várias plantas no seu terrário. Para isso, você precisa aproveitar os seletores CSS.
Esse método de estilizar uma tag dá controle sobre elementos únicos, mas você precisa controlar os estilos de muitas plantas no seu terrário. Para isso, você precisa aproveitar os seletores CSS.
### Ids
Adicione algum estilo para organizar os contêineres esquerdo e direito. Como há apenas um contêiner esquerdo e um direito, eles recebem ids no markup. Para estilizar, use `#`:
Adicione algum estilo para organizar os contêineres esquerdo e direito. Como há apenas um contêiner esquerdo e um contêiner direito, eles recebem ids no markup. Para estilizá-los, use `#`:
```CSS
#left-container {
@ -134,9 +134,9 @@ Adicione algum estilo para organizar os contêineres esquerdo e direito. Como h
}
```
Aqui, você posicionou esses contêineres com posicionamento absoluto nas extremidades esquerda e direita da tela, e usou porcentagens para a largura deles, para que possam se ajustar a telas pequenas de dispositivos móveis.
Aqui, você posicionou esses contêineres com posicionamento absoluto nas extremidades esquerda e direita da tela e usou porcentagens para sua largura, permitindo que eles se ajustem a telas pequenas de dispositivos móveis.
✅ Esse código está bastante repetitivo, portanto não segue o princípio "DRY" (Don't Repeat Yourself). Você consegue encontrar uma maneira melhor de estilizar esses ids, talvez usando um id e uma classe? Você precisaria alterar o markup e refatorar o CSS:
✅ Este código está bastante repetitivo, portanto não segue o princípio "DRY" (Don't Repeat Yourself); você consegue encontrar uma maneira melhor de estilizar esses ids, talvez usando um id e uma classe? Você precisaria alterar o markup e refatorar o CSS:
```html
<div id="left-container" class="container"></div>
@ -144,7 +144,7 @@ Aqui, você posicionou esses contêineres com posicionamento absoluto nas extrem
### Classes
No exemplo acima, você estilizou dois elementos únicos na tela. Se quiser aplicar estilos a vários elementos na tela, pode usar classes CSS. Faça isso para organizar as plantas nos contêineres esquerdo e direito.
No exemplo acima, você estilizou dois elementos únicos na tela. Se quiser que os estilos se apliquem a muitos elementos na tela, você pode usar classes CSS. Faça isso para organizar as plantas nos contêineres esquerdo e direito.
Observe que cada planta no markup HTML tem uma combinação de ids e classes. Os ids aqui são usados pelo JavaScript que você adicionará mais tarde para manipular o posicionamento das plantas no terrário. As classes, no entanto, dão a todas as plantas um estilo específico.
@ -171,35 +171,35 @@ Adicione o seguinte ao seu arquivo `style.css`:
}
```
Notável neste trecho é a mistura de posicionamento relativo e absoluto, que abordaremos na próxima seção. Observe como as alturas são tratadas com porcentagens:
Notável neste trecho é a mistura de posicionamento relativo e absoluto, que abordaremos na próxima seção. Observe como as alturas são tratadas por porcentagens:
Você definiu a altura do suporte das plantas como 13%, um bom número para garantir que todas as plantas sejam exibidas em cada contêiner vertical sem necessidade de rolagem.
Você definiu a altura do suporte da planta como 13%, um bom número para garantir que todas as plantas sejam exibidas em cada contêiner vertical sem necessidade de rolagem.
Você ajustou o suporte das plantas para a esquerda para que as plantas fiquem mais centralizadas dentro do contêiner. As imagens têm uma grande quantidade de fundo transparente para torná-las mais arrastáveis, então precisam ser ajustadas para a esquerda para se encaixarem melhor na tela.
Você ajustou o suporte da planta para mover-se para a esquerda, permitindo que as plantas fiquem mais centralizadas dentro de seu contêiner. As imagens têm uma grande quantidade de fundo transparente para torná-las mais arrastáveis, então precisam ser empurradas para a esquerda para se encaixar melhor na tela.
Depois, a própria planta recebeu uma largura máxima de 150%. Isso permite que ela seja redimensionada à medida que o navegador é redimensionado. Experimente redimensionar seu navegador; as plantas permanecem nos contêineres, mas se ajustam para caber.
Depois, a própria planta recebeu um max-width de 150%. Isso permite que ela seja redimensionada conforme o navegador é redimensionado. Experimente ajustar o tamanho do seu navegador; as plantas permanecem em seus contêineres, mas se ajustam para caber.
Também é notável o uso de z-index, que controla a altitude relativa de um elemento (para que as plantas fiquem acima do contêiner e pareçam estar dentro do terrário).
✅ Por que você precisa de um seletor CSS para o suporte das plantas e outro para a planta?
✅ Por que você precisa de um seletor CSS para o suporte da planta e outro para a planta?
## Posicionamento CSS
Misturar propriedades de posicionamento (existem posições estática, relativa, fixa, absoluta e sticky) pode ser um pouco complicado, mas quando feito corretamente, dá um bom controle sobre os elementos nas suas páginas.
Misturar propriedades de posicionamento (existem posições estática, relativa, fixa, absoluta e sticky) pode ser um pouco complicado, mas quando feito corretamente, oferece bom controle sobre os elementos nas suas páginas.
Elementos com posicionamento absoluto são posicionados em relação ao seu ancestral posicionado mais próximo, e se não houver nenhum, são posicionados em relação ao corpo do documento.
Elementos posicionados de forma absoluta são posicionados em relação aos seus ancestrais mais próximos que possuem posicionamento, e se não houver nenhum, são posicionados em relação ao corpo do documento.
Elementos com posicionamento relativo são posicionados com base nas direções do CSS para ajustar seu posicionamento em relação à sua posição inicial.
Elementos posicionados de forma relativa são posicionados com base nas direções do CSS para ajustar seu posicionamento em relação à sua posição inicial.
No nosso exemplo, o `plant-holder` é um elemento com posicionamento relativo que está posicionado dentro de um contêiner com posicionamento absoluto. O comportamento resultante é que os contêineres laterais são fixados à esquerda e à direita, e o `plant-holder` é aninhado, ajustando-se dentro das barras laterais, dando espaço para que as plantas sejam organizadas em uma linha vertical.
No nosso exemplo, o `plant-holder` é um elemento posicionado de forma relativa dentro de um contêiner posicionado de forma absoluta. O comportamento resultante é que os contêineres laterais são fixados à esquerda e à direita, e o `plant-holder` é aninhado, ajustando-se dentro dos contêineres laterais, dando espaço para as plantas serem colocadas em uma fileira vertical.
> A própria `plant` também tem posicionamento absoluto, necessário para torná-la arrastável, como você descobrirá na próxima lição.
✅ Experimente trocar os tipos de posicionamento dos contêineres laterais e do `plant-holder`. O que acontece?
✅ Experimente alternar os tipos de posicionamento dos contêineres laterais e do `plant-holder`. O que acontece?
## Layouts CSS
Agora você usará o que aprendeu para construir o terrário em si, tudo usando CSS!
Agora você usará o que aprendeu para construir o próprio terrário, tudo usando CSS!
Primeiro, estilize os filhos da div `.terrarium` como um retângulo arredondado usando CSS:
@ -250,33 +250,35 @@ Primeiro, estilize os filhos da div `.terrarium` como um retângulo arredondado
}
```
Observe o uso de porcentagens aqui. Se você redimensionar seu navegador, verá como o jarro também se ajusta. Note também as porcentagens de largura e altura dos elementos do jarro e como cada elemento é posicionado absolutamente no centro, fixado na parte inferior da janela de visualização.
Observe o uso de porcentagens aqui. Se você reduzir o tamanho do navegador, verá como o jarro também se ajusta. Também observe as porcentagens de largura e altura dos elementos do jarro e como cada elemento é posicionado absolutamente no centro, fixado na parte inferior da janela de visualização.
Também estamos usando `rem` para o border-radius, uma medida relativa à fonte. Leia mais sobre esse tipo de medida relativa na [especificação CSS](https://www.w3.org/TR/css-values-3/#font-relative-lengths).
✅ Experimente mudar as cores e a opacidade do jarro em comparação com as da terra. O que acontece? Por quê?
✅ Experimente alterar as cores e a opacidade do jarro em comparação com as da terra. O que acontece? Por quê?
---
## 🚀Desafio
Adicione um brilho de 'bolha' na área inferior esquerda do jarro para fazê-lo parecer mais vítreo. Você estilizará `.jar-glossy-long` e `.jar-glossy-short` para parecerem um reflexo. Veja como ficaria:
Adicione um brilho de 'bolha' na área inferior esquerda do jarro para fazê-lo parecer mais vítreo. Você estará estilizando `.jar-glossy-long` e `.jar-glossy-short` para parecerem um brilho refletido. Veja como ficaria:
![terrário finalizado](../../../../translated_images/terrarium-final.2f07047ffc597d0a06b06cab28a77801a10dd12fdb6c7fc630e9c40665491c53.br.png)
Para completar o questionário pós-aula, passe por este módulo do Learn: [Estilize seu aplicativo HTML com CSS](https://docs.microsoft.com/learn/modules/build-simple-website/4-css-basics/?WT.mc_id=academic-77807-sagibbon)
Para completar o quiz pós-aula, passe por este módulo do Learn: [Estilize seu aplicativo HTML com CSS](https://docs.microsoft.com/learn/modules/build-simple-website/4-css-basics/?WT.mc_id=academic-77807-sagibbon)
## Questionário Pós-Aula
## Quiz Pós-Aula
[Questionário pós-aula](https://ff-quizzes.netlify.app/web/quiz/18)
[Quiz pós-aula](https://ff-quizzes.netlify.app/web/quiz/18)
## Revisão e Autoestudo
CSS parece ser simples à primeira vista, mas há muitos desafios ao tentar estilizar um aplicativo perfeitamente para todos os navegadores e tamanhos de tela. CSS-Grid e Flexbox são ferramentas desenvolvidas para tornar o trabalho um pouco mais estruturado e confiável. Aprenda sobre essas ferramentas jogando [Flexbox Froggy](https://flexboxfroggy.com/) e [Grid Garden](https://codepip.com/games/grid-garden/).
CSS parece enganosamente simples, mas há muitos desafios ao tentar estilizar um aplicativo perfeitamente para todos os navegadores e tamanhos de tela. CSS-Grid e Flexbox são ferramentas desenvolvidas para tornar o trabalho um pouco mais estruturado e confiável. Aprenda sobre essas ferramentas jogando [Flexbox Froggy](https://flexboxfroggy.com/) e [Grid Garden](https://codepip.com/games/grid-garden/).
## Tarefa
[Refatoração de CSS](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "30f8903a1f290e3d438dc2c70fe60259",
"translation_date": "2025-08-25T21:20:16+00:00",
"original_hash": "61c14b27044861e5e69db35dd52c4403",
"translation_date": "2025-08-28T23:56:23+00:00",
"source_file": "3-terrarium/3-intro-to-DOM-and-closures/README.md",
"language_code": "br"
}
@ -12,23 +12,23 @@ CO_OP_TRANSLATOR_METADATA:
![DOM e um closure](../../../../translated_images/webdev101-js.10280393044d7eaaec7e847574946add7ddae6be2b2194567d848b61d849334a.br.png)
> Sketchnote por [Tomomi Imura](https://twitter.com/girlie_mac)
## Quiz Pré-Aula
## Questionário Pré-Aula
[Quiz pré-aula](https://ff-quizzes.netlify.app/web/quiz/19)
[Questionário pré-aula](https://ff-quizzes.netlify.app/web/quiz/19)
### Introdução
Manipular o DOM, ou "Document Object Model", é um aspecto fundamental do desenvolvimento web. De acordo com [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction), "O Document Object Model (DOM) é a representação de dados dos objetos que compõem a estrutura e o conteúdo de um documento na web." Os desafios em torno da manipulação do DOM na web frequentemente motivaram o uso de frameworks JavaScript em vez de JavaScript puro para gerenciar o DOM, mas aqui vamos fazer isso por conta própria!
Manipular o DOM, ou "Document Object Model", é um aspecto fundamental do desenvolvimento web. De acordo com a [MDN](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction), "O Document Object Model (DOM) é a representação de dados dos objetos que compõem a estrutura e o conteúdo de um documento na web." Os desafios em torno da manipulação do DOM na web frequentemente motivaram o uso de frameworks JavaScript em vez de JavaScript puro para gerenciar o DOM, mas aqui faremos isso por conta própria!
Além disso, esta lição introduzirá a ideia de um [closure em JavaScript](https://developer.mozilla.org/docs/Web/JavaScript/Closures), que você pode pensar como uma função encapsulada por outra função, permitindo que a função interna tenha acesso ao escopo da função externa.
Além disso, esta lição introduzirá a ideia de um [closure em JavaScript](https://developer.mozilla.org/docs/Web/JavaScript/Closures), que você pode imaginar como uma função encapsulada por outra função, permitindo que a função interna tenha acesso ao escopo da função externa.
> Closures em JavaScript são um tópico vasto e complexo. Esta lição aborda a ideia mais básica: no código deste terrário, você encontrará um closure: uma função interna e uma função externa construídas de forma a permitir que a função interna acesse o escopo da função externa. Para muito mais informações sobre como isso funciona, visite a [documentação detalhada](https://developer.mozilla.org/docs/Web/JavaScript/Closures).
> Closures em JavaScript são um tópico vasto e complexo. Esta lição aborda a ideia mais básica: no código deste terrário, você encontrará um closure — uma função interna e uma função externa construídas de forma que a função interna tenha acesso ao escopo da função externa. Para muito mais informações sobre como isso funciona, visite a [documentação detalhada](https://developer.mozilla.org/docs/Web/JavaScript/Closures).
Usaremos um closure para manipular o DOM.
Pense no DOM como uma árvore, representando todas as maneiras pelas quais um documento de página web pode ser manipulado. Diversas APIs (Interfaces de Programação de Aplicações) foram criadas para que programadores, usando sua linguagem de programação preferida, possam acessar o DOM e editá-lo, alterá-lo, reorganizá-lo e gerenciá-lo de outras formas.
Pense no DOM como uma árvore, representando todas as formas pelas quais um documento de página web pode ser manipulado. Diversas APIs (Interfaces de Programação de Aplicações) foram criadas para que programadores, usando a linguagem de programação de sua escolha, possam acessar o DOM e editá-lo, alterá-lo, reorganizá-lo e gerenciá-lo de outras formas.
![Representação da árvore DOM](../../../../translated_images/dom-tree.7daf0e763cbbba9273f9a66fe04c98276d7d23932309b195cb273a9cf1819b42.br.png)
![Representação da árvore do DOM](../../../../translated_images/dom-tree.7daf0e763cbbba9273f9a66fe04c98276d7d23932309b195cb273a9cf1819b42.br.png)
> Uma representação do DOM e da marcação HTML que o referencia. De [Olfa Nasraoui](https://www.researchgate.net/publication/221417012_Profile-Based_Focused_Crawler_for_Social_Media-Sharing_Websites)
@ -40,18 +40,18 @@ Você deve ter o HTML e o CSS do seu terrário prontos. Ao final desta lição,
### Tarefa
Na pasta do seu terrário, crie um novo arquivo chamado `script.js`. Importe esse arquivo na seção `<head>`:
No seu diretório do terrário, crie um novo arquivo chamado `script.js`. Importe esse arquivo na seção `<head>`:
```html
<script src="./script.js" defer></script>
```
> Nota: use `defer` ao importar um arquivo JavaScript externo no arquivo HTML para permitir que o JavaScript seja executado apenas após o arquivo HTML ter sido totalmente carregado. Você também poderia usar o atributo `async`, que permite que o script seja executado enquanto o arquivo HTML está sendo analisado, mas no nosso caso, é importante que os elementos HTML estejam totalmente disponíveis para arrastar antes de permitir que o script de arrastar seja executado.
> Nota: use `defer` ao importar um arquivo JavaScript externo no arquivo HTML para que o JavaScript seja executado apenas após o arquivo HTML ter sido completamente carregado. Você também poderia usar o atributo `async`, que permite que o script seja executado enquanto o arquivo HTML está sendo analisado, mas no nosso caso, é importante que os elementos HTML estejam totalmente disponíveis para arrastar antes de permitirmos que o script de arrastar seja executado.
---
## Os elementos do DOM
A primeira coisa que você precisa fazer é criar referências aos elementos que deseja manipular no DOM. No nosso caso, são as 14 plantas atualmente esperando nas barras laterais.
A primeira coisa que você precisa fazer é criar referências aos elementos que deseja manipular no DOM. No nosso caso, são as 14 plantas atualmente localizadas nas barras laterais.
### Tarefa
@ -72,7 +72,7 @@ dragElement(document.getElementById('plant13'));
dragElement(document.getElementById('plant14'));
```
O que está acontecendo aqui? Você está referenciando o documento e procurando em seu DOM um elemento com um Id específico. Lembre-se de que na primeira lição sobre HTML você deu Ids individuais a cada imagem de planta (`id="plant1"`)? Agora você fará uso desse esforço. Após identificar cada elemento, você passa esse item para uma função chamada `dragElement` que você construirá em breve. Assim, o elemento no HTML agora está habilitado para arrastar, ou estará em breve.
O que está acontecendo aqui? Você está referenciando o documento e procurando em seu DOM um elemento com um Id específico. Lembra que na primeira lição sobre HTML você deu Ids individuais para cada imagem de planta (`id="plant1"`)? Agora você fará uso desse esforço. Após identificar cada elemento, você passa esse item para uma função chamada `dragElement` que você criará em breve. Assim, o elemento no HTML agora está habilitado para ser arrastado, ou estará em breve.
✅ Por que referenciamos elementos pelo Id? Por que não pela classe CSS? Você pode consultar a lição anterior sobre CSS para responder a essa pergunta.
@ -80,7 +80,7 @@ O que está acontecendo aqui? Você está referenciando o documento e procurando
## O Closure
Agora você está pronto para criar o closure `dragElement`, que é uma função externa que encapsula uma função interna ou funções (no nosso caso, teremos três).
Agora você está pronto para criar o closure `dragElement`, que é uma função externa que encapsula uma ou mais funções internas (no nosso caso, teremos três).
Closures são úteis quando uma ou mais funções precisam acessar o escopo de uma função externa. Aqui está um exemplo:
@ -98,7 +98,7 @@ console.log(candy)
Neste exemplo, a função `displayCandy` envolve uma função que adiciona um novo tipo de doce a um array que já existe na função. Se você executar este código, o array `candy` será indefinido, pois é uma variável local (local ao closure).
✅ Como você pode tornar o array `candy` acessível? Tente movê-lo para fora do closure. Dessa forma, o array se torna global, em vez de permanecer disponível apenas no escopo local do closure.
✅ Como você pode tornar o array `candy` acessível? Experimente movê-lo para fora do closure. Assim, o array se torna global, em vez de permanecer disponível apenas no escopo local do closure.
### Tarefa
@ -115,17 +115,17 @@ function dragElement(terrariumElement) {
}
```
`dragElement` obtém seu objeto `terrariumElement` das declarações no topo do script. Em seguida, você define algumas posições locais como `0` para o objeto passado para a função. Estas são as variáveis locais que serão manipuladas para cada elemento enquanto você adiciona funcionalidade de arrastar e soltar dentro do closure para cada elemento. O terrário será preenchido por esses elementos arrastados, então o aplicativo precisa acompanhar onde eles são colocados.
`dragElement` obtém seu objeto `terrariumElement` das declarações no topo do script. Em seguida, você define algumas posições locais como `0` para o objeto passado para a função. Estas são as variáveis locais que serão manipuladas para cada elemento à medida que você adiciona a funcionalidade de arrastar e soltar dentro do closure para cada elemento. O terrário será preenchido por esses elementos arrastados, então o aplicativo precisa acompanhar onde eles são colocados.
Além disso, o `terrariumElement` que é passado para esta função é atribuído a um evento `pointerdown`, que faz parte das [APIs da web](https://developer.mozilla.org/docs/Web/API) projetadas para ajudar na gestão do DOM. `onpointerdown` é disparado quando um botão é pressionado ou, no nosso caso, um elemento arrastável é tocado. Este manipulador de eventos funciona tanto em [navegadores web quanto móveis](https://caniuse.com/?search=onpointerdown), com algumas exceções.
Além disso, o `terrariumElement` que é passado para esta função é atribuído a um evento `pointerdown`, que faz parte das [APIs da web](https://developer.mozilla.org/docs/Web/API) projetadas para ajudar no gerenciamento do DOM. O `onpointerdown` é acionado quando um botão é pressionado ou, no nosso caso, quando um elemento arrastável é tocado. Este manipulador de eventos funciona tanto em [navegadores web quanto móveis](https://caniuse.com/?search=onpointerdown), com algumas exceções.
✅ O [manipulador de eventos `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) tem muito mais suporte entre navegadores; por que você não o usaria aqui? Pense no tipo exato de interação de tela que você está tentando criar.
✅ O [manipulador de eventos `onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) tem muito mais suporte entre navegadores; por que você não o usaria aqui? Pense no tipo exato de interação de tela que você está tentando criar aqui.
---
## A função Pointerdrag
O `terrariumElement` está pronto para ser arrastado; quando o evento `onpointerdown` é disparado, a função `pointerDrag` é invocada. Adicione essa função logo abaixo desta linha: `terrariumElement.onpointerdown = pointerDrag;`:
O `terrariumElement` está pronto para ser arrastado; quando o evento `onpointerdown` é acionado, a função `pointerDrag` é invocada. Adicione essa função logo abaixo desta linha: `terrariumElement.onpointerdown = pointerDrag;`:
### Tarefa
@ -138,13 +138,13 @@ function pointerDrag(e) {
}
```
Várias coisas acontecem. Primeiro, você impede que os eventos padrão que normalmente ocorrem no pointerdown aconteçam usando `e.preventDefault();`. Dessa forma, você tem mais controle sobre o comportamento da interface.
Várias coisas acontecem. Primeiro, você impede que os eventos padrão que normalmente ocorrem no `pointerdown` aconteçam, usando `e.preventDefault();`. Assim, você tem mais controle sobre o comportamento da interface.
> Volte a esta linha quando tiver construído completamente o arquivo de script e tente sem `e.preventDefault()` - o que acontece?
> Volte a esta linha quando tiver construído completamente o arquivo de script e experimente sem o `e.preventDefault()` - o que acontece?
Em segundo lugar, abra `index.html` em uma janela do navegador e inspecione a interface. Quando você clica em uma planta, pode ver como o evento 'e' é capturado. Explore o evento para ver quanta informação é coletada por um único evento de pointerdown!
Em segundo lugar, abra o `index.html` em uma janela do navegador e inspecione a interface. Quando você clica em uma planta, pode ver como o evento 'e' é capturado. Explore o evento para ver quanta informação é coletada por um único evento de `pointerdown`!
Em seguida, observe como as variáveis locais `pos3` e `pos4` são definidas como e.clientX. Você pode encontrar os valores de `e` no painel de inspeção. Esses valores capturam as coordenadas x e y da planta no momento em que você clica ou toca nela. Você precisará de controle detalhado sobre o comportamento das plantas enquanto as clica e arrasta, então você acompanha suas coordenadas.
Depois, observe como as variáveis locais `pos3` e `pos4` são definidas como `e.clientX`. Você pode encontrar os valores de `e` no painel de inspeção. Esses valores capturam as coordenadas x e y da planta no momento em que você clica ou toca nela. Você precisará de controle detalhado sobre o comportamento das plantas enquanto as arrasta, então você acompanha suas coordenadas.
✅ Está ficando mais claro por que todo este aplicativo é construído com um grande closure? Se não fosse, como você manteria o escopo para cada uma das 14 plantas arrastáveis?
@ -154,7 +154,7 @@ Complete a função inicial adicionando mais duas manipulações de eventos de p
document.onpointermove = elementDrag;
document.onpointerup = stopElementDrag;
```
Agora você está indicando que deseja que a planta seja arrastada junto com o ponteiro enquanto você a move, e que o gesto de arrastar pare quando você deselecionar a planta. `onpointermove` e `onpointerup` fazem parte da mesma API que `onpointerdown`. A interface lançará erros agora, pois você ainda não definiu as funções `elementDrag` e `stopElementDrag`, então construa essas funções a seguir.
Agora você está indicando que deseja que a planta seja arrastada junto com o ponteiro enquanto você o move, e que o gesto de arrastar pare quando você deselecionar a planta. `onpointermove` e `onpointerup` fazem parte da mesma API que `onpointerdown`. A interface lançará erros agora, pois você ainda não definiu as funções `elementDrag` e `stopElementDrag`, então construa-as a seguir.
## As funções elementDrag e stopElementDrag
@ -177,9 +177,9 @@ function elementDrag(e) {
```
Nesta função, você faz muitas edições das posições iniciais 1-4 que definiu como variáveis locais na função externa. O que está acontecendo aqui?
Enquanto você arrasta, você redefine `pos1` tornando-o igual a `pos3` (que você definiu anteriormente como `e.clientX`) menos o valor atual de `e.clientX`. Você faz uma operação semelhante em `pos2`. Em seguida, você redefine `pos3` e `pos4` para as novas coordenadas X e Y do elemento. Você pode observar essas mudanças no console enquanto arrasta. Então, você manipula o estilo CSS da planta para definir sua nova posição com base nas novas posições de `pos1` e `pos2`, calculando as coordenadas X e Y da planta com base na comparação de seu deslocamento com essas novas posições.
Enquanto você arrasta, você redefine `pos1` tornando-o igual a `pos3` (que você definiu anteriormente como `e.clientX`) menos o valor atual de `e.clientX`. Você faz uma operação semelhante em `pos2`. Em seguida, redefine `pos3` e `pos4` para as novas coordenadas X e Y do elemento. Você pode observar essas mudanças no console enquanto arrasta. Depois, você manipula o estilo CSS da planta para definir sua nova posição com base nas novas posições de `pos1` e `pos2`, calculando as coordenadas X e Y da planta com base na comparação de seu deslocamento com essas novas posições.
> `offsetTop` e `offsetLeft` são propriedades CSS que definem a posição de um elemento com base na posição de seu pai; seu pai pode ser qualquer elemento que não esteja posicionado como `static`.
> `offsetTop` e `offsetLeft` são propriedades CSS que definem a posição de um elemento com base na de seu elemento pai; seu pai pode ser qualquer elemento que não esteja posicionado como `static`.
Toda essa recalculação de posicionamento permite que você ajuste o comportamento do terrário e suas plantas.
@ -196,7 +196,7 @@ function stopElementDrag() {
Esta pequena função redefine os eventos `onpointerup` e `onpointermove` para que você possa reiniciar o progresso da planta começando a arrastá-la novamente ou começar a arrastar uma nova planta.
✅ O que acontece se você não definir esses eventos como null?
✅ O que acontece se você não definir esses eventos como nulos?
Agora você completou seu projeto!
@ -206,15 +206,15 @@ Agora você completou seu projeto!
## 🚀Desafio
Adicione um novo manipulador de eventos ao seu closure para fazer algo mais com as plantas; por exemplo, clique duas vezes em uma planta para trazê-la para frente. Seja criativo!
Adicione um novo manipulador de eventos ao seu closure para fazer algo mais com as plantas; por exemplo, dar um duplo clique em uma planta para trazê-la para frente. Seja criativo!
## Quiz Pós-Aula
## Questionário Pós-Aula
[Quiz pós-aula](https://ff-quizzes.netlify.app/web/quiz/20)
[Questionário pós-aula](https://ff-quizzes.netlify.app/web/quiz/20)
## Revisão e Autoestudo
Embora arrastar elementos pela tela pareça trivial, existem muitas maneiras de fazer isso e muitos desafios, dependendo do efeito que você busca. Na verdade, existe uma [API de arrastar e soltar](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) que você pode experimentar. Não a usamos neste módulo porque o efeito que queríamos era um pouco diferente, mas experimente esta API em seu próprio projeto e veja o que você pode alcançar.
Embora arrastar elementos pela tela pareça trivial, existem muitas maneiras de fazer isso e muitos desafios, dependendo do efeito que você busca. Na verdade, existe uma [API de arrastar e soltar](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) inteira que você pode experimentar. Não a usamos neste módulo porque o efeito que queríamos era um pouco diferente, mas experimente esta API em seu próprio projeto e veja o que você pode alcançar.
Encontre mais informações sobre eventos de ponteiro na [documentação W3C](https://www.w3.org/TR/pointerevents1/) e na [documentação MDN](https://developer.mozilla.org/docs/Web/API/Pointer_events).
@ -224,5 +224,7 @@ Sempre verifique as capacidades dos navegadores usando [CanIUse.com](https://can
[Trabalhe um pouco mais com o DOM](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e982871b8388c59c22a41b73b5fca70f",
"translation_date": "2025-08-26T01:07:41+00:00",
"original_hash": "1b0aeccb600f83c603cd70cb42df594d",
"translation_date": "2025-08-28T23:57:50+00:00",
"source_file": "4-typing-game/typing-game/README.md",
"language_code": "br"
}
@ -15,31 +15,31 @@ CO_OP_TRANSLATOR_METADATA:
## Programação orientada a eventos
Ao criar uma aplicação baseada em navegador, fornecemos uma interface gráfica do usuário (GUI) para que o usuário interaja com o que construímos. A forma mais comum de interação com o navegador é clicando e digitando em vários elementos. O desafio que enfrentamos como desenvolvedores é que não sabemos quando essas operações serão realizadas!
Ao criar uma aplicação baseada em navegador, fornecemos uma interface gráfica de usuário (GUI) para que o usuário interaja com o que construímos. A maneira mais comum de interagir com o navegador é clicando e digitando em vários elementos. O desafio que enfrentamos como desenvolvedores é que não sabemos quando essas operações serão realizadas!
A [programação orientada a eventos](https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_orientada_a_eventos) é o nome do tipo de programação que precisamos fazer para criar nossa GUI. Se analisarmos essa frase, veremos que a palavra central aqui é **evento**. [Evento](https://www.merriam-webster.com/dictionary/event), de acordo com o Merriam-Webster, é definido como "algo que acontece". Isso descreve perfeitamente nossa situação. Sabemos que algo vai acontecer e queremos executar algum código em resposta, mas não sabemos quando isso ocorrerá.
A [programação orientada a eventos](https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_orientada_a_eventos) é o tipo de programação que precisamos usar para criar nossa GUI. Se analisarmos essa frase, vemos que a palavra principal aqui é **evento**. [Evento](https://www.merriam-webster.com/dictionary/event), segundo o Merriam-Webster, é definido como "algo que acontece". Isso descreve perfeitamente nossa situação. Sabemos que algo vai acontecer e queremos executar algum código em resposta, mas não sabemos quando isso ocorrerá.
A maneira como marcamos uma seção de código que queremos executar é criando uma função. Quando pensamos em [programação procedural](https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_procedural), as funções são chamadas em uma ordem específica. O mesmo será verdade para a programação orientada a eventos. A diferença está em **como** as funções serão chamadas.
A maneira como marcamos uma seção de código para ser executada é criando uma função. Quando pensamos em [programação procedural](https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_procedural), as funções são chamadas em uma ordem específica. O mesmo acontece na programação orientada a eventos. A diferença está em **como** as funções serão chamadas.
Para lidar com eventos (cliques de botão, digitação, etc.), registramos **ouvintes de eventos**. Um ouvinte de evento é uma função que "escuta" a ocorrência de um evento e é executada em resposta. Ouvintes de eventos podem atualizar a interface do usuário, fazer chamadas ao servidor ou realizar qualquer outra ação necessária em resposta à ação do usuário. Adicionamos um ouvinte de evento usando [addEventListener](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener) e fornecendo uma função para executar.
Para lidar com eventos (cliques em botões, digitação, etc.), registramos **ouvintes de eventos**. Um ouvinte de evento é uma função que "ouve" um evento ocorrer e é executada em resposta. Ouvintes de eventos podem atualizar a interface, fazer chamadas ao servidor ou realizar qualquer outra ação necessária em resposta à interação do usuário. Adicionamos um ouvinte de evento usando [addEventListener](https://developer.mozilla.org/pt-BR/docs/Web/API/EventTarget/addEventListener) e fornecendo uma função para ser executada.
> **NOTE:** Vale destacar que existem várias maneiras de criar ouvintes de eventos. Você pode usar funções anônimas ou criar funções nomeadas. Pode usar atalhos, como definir a propriedade `click`, ou usar `addEventListener`. No nosso exercício, vamos focar em `addEventListener` e funções anônimas, pois é provavelmente a técnica mais comum usada por desenvolvedores web. Também é a mais flexível, já que `addEventListener` funciona para todos os eventos, e o nome do evento pode ser fornecido como um parâmetro.
> **NOTE:** Vale destacar que existem várias maneiras de criar ouvintes de eventos. Você pode usar funções anônimas ou criar funções nomeadas. Também é possível usar atalhos, como definir a propriedade `click` ou usar `addEventListener`. No nosso exercício, vamos focar em `addEventListener` e funções anônimas, pois essa é provavelmente a técnica mais comum usada por desenvolvedores web. Além disso, é a mais flexível, já que `addEventListener` funciona para todos os eventos, e o nome do evento pode ser fornecido como um parâmetro.
### Eventos comuns
Existem [dezenas de eventos](https://developer.mozilla.org/docs/Web/Events) disponíveis para você ouvir ao criar uma aplicação. Basicamente, qualquer coisa que um usuário faz em uma página gera um evento, o que lhe dá muito poder para garantir que eles tenham a experiência desejada. Felizmente, normalmente você precisará de apenas alguns eventos. Aqui estão alguns comuns (incluindo os dois que usaremos ao criar nosso jogo):
Existem [dezenas de eventos](https://developer.mozilla.org/pt-BR/docs/Web/Events) disponíveis para você ouvir ao criar uma aplicação. Basicamente, qualquer coisa que o usuário faça em uma página gera um evento, o que lhe dá muito poder para garantir que ele tenha a experiência desejada. Felizmente, normalmente você precisará de apenas alguns eventos. Aqui estão alguns comuns (incluindo os dois que usaremos ao criar nosso jogo):
- [click](https://developer.mozilla.org/docs/Web/API/Element/click_event): O usuário clicou em algo, geralmente um botão ou link
- [contextmenu](https://developer.mozilla.org/docs/Web/API/Element/contextmenu_event): O usuário clicou com o botão direito do mouse
- [select](https://developer.mozilla.org/docs/Web/API/Element/select_event): O usuário destacou algum texto
- [input](https://developer.mozilla.org/docs/Web/API/Element/input_event): O usuário digitou algum texto
- [click](https://developer.mozilla.org/pt-BR/docs/Web/API/Element/click_event): O usuário clicou em algo, geralmente um botão ou link
- [contextmenu](https://developer.mozilla.org/pt-BR/docs/Web/API/Element/contextmenu_event): O usuário clicou com o botão direito do mouse
- [select](https://developer.mozilla.org/pt-BR/docs/Web/API/Element/select_event): O usuário destacou algum texto
- [input](https://developer.mozilla.org/pt-BR/docs/Web/API/Element/input_event): O usuário digitou algum texto
## Criando o jogo
Vamos criar um jogo para explorar como os eventos funcionam no JavaScript. Nosso jogo vai testar a habilidade de digitação de um jogador, que é uma das habilidades mais subestimadas que todos os desenvolvedores deveriam ter. Todos nós deveríamos praticar nossa digitação! O fluxo geral do jogo será assim:
Vamos criar um jogo para explorar como os eventos funcionam no JavaScript. Nosso jogo vai testar a habilidade de digitação do jogador, que é uma das habilidades mais subestimadas que todos os desenvolvedores deveriam ter. Todos nós deveríamos praticar nossa digitação! O fluxo geral do jogo será assim:
- O jogador clica no botão de início e é apresentado a uma frase para digitar
- O jogador digita a frase o mais rápido que puder em uma caixa de texto
- O jogador digita a frase o mais rápido possível em uma caixa de texto
- À medida que cada palavra é concluída, a próxima é destacada
- Se o jogador cometer um erro de digitação, a caixa de texto ficará vermelha
- Quando o jogador concluir a frase, uma mensagem de sucesso será exibida com o tempo decorrido
@ -48,9 +48,9 @@ Vamos construir nosso jogo e aprender sobre eventos!
### Estrutura de arquivos
Vamos precisar de três arquivos no total: **index.html**, **script.js** e **style.css**. Vamos começar configurando-os para facilitar nosso trabalho.
Vamos precisar de três arquivos no total: **index.html**, **script.js** e **style.css**. Vamos começar configurando esses arquivos para facilitar nosso trabalho.
- Crie uma nova pasta para seu trabalho abrindo um console ou terminal e emitindo o seguinte comando:
- Crie uma nova pasta para seu trabalho abrindo um console ou terminal e executando o seguinte comando:
```bash
# Linux or macOS
@ -107,22 +107,22 @@ Crie um novo arquivo chamado **index.html**. Adicione o seguinte HTML:
### Lançar a aplicação
É sempre melhor desenvolver de forma iterativa para ver como as coisas estão ficando. Vamos lançar nossa aplicação. Há uma extensão maravilhosa para o Visual Studio Code chamada [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) que hospedará sua aplicação localmente e atualizará o navegador cada vez que você salvar.
É sempre melhor desenvolver de forma iterativa para ver como as coisas estão ficando. Vamos lançar nossa aplicação. Há uma extensão maravilhosa para o Visual Studio Code chamada [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) que hospedará sua aplicação localmente e atualizará o navegador sempre que você salvar.
- Instale o [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) seguindo o link e clicando em **Install**
- O navegador solicitará que você abra o Visual Studio Code, e então o Visual Studio Code solicitará que você realize a instalação
- Instale o [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&WT.mc_id=academic-77807-sagibbon) seguindo o link e clicando em **Instalar**
- O navegador solicitará que você abra o Visual Studio Code, e o Visual Studio Code solicitará que você conclua a instalação
- Reinicie o Visual Studio Code se solicitado
- Uma vez instalado, no Visual Studio Code, clique em Ctrl-Shift-P (ou Cmd-Shift-P) para abrir o painel de comandos
- Digite **Live Server: Open with Live Server**
- O Live Server começará a hospedar sua aplicação
- Abra um navegador e navegue para **https://localhost:5500**
- Abra um navegador e navegue até **https://localhost:5500**
- Agora você deve ver a página que criou!
Vamos adicionar alguma funcionalidade.
## Adicionar o CSS
Com nosso HTML criado, vamos adicionar o CSS para o estilo principal. Precisamos destacar a palavra que o jogador deve digitar e colorir a caixa de texto se o que ele digitou estiver incorreto. Faremos isso com duas classes.
Com nosso HTML criado, vamos adicionar o CSS para o estilo básico. Precisamos destacar a palavra que o jogador deve digitar e colorir a caixa de texto se o que ele digitou estiver incorreto. Faremos isso com duas classes.
Crie um novo arquivo chamado **style.css** e adicione a seguinte sintaxe.
@ -163,10 +163,10 @@ Vamos precisar de alguns itens para facilitar nossa programação. Novamente, se
- Um espaço para armazenar o índice da palavra que o jogador está digitando no momento
- O horário em que o jogador clicou em iniciar
Também vamos querer referências aos elementos da interface do usuário:
Também vamos querer referências aos elementos da interface:
- A caixa de texto (**typed-value**)
- A exibição da frase (**quote**)
- O display da frase (**quote**)
- A mensagem (**message**)
```javascript
@ -196,7 +196,7 @@ const typedValueElement = document.getElementById('typed-value');
> **NOTE:** Podemos recuperar os elementos sempre que quisermos no código usando `document.getElementById`. Como vamos nos referir a esses elementos regularmente, evitaremos erros de digitação com literais de string usando constantes. Frameworks como [Vue.js](https://vuejs.org/) ou [React](https://reactjs.org/) podem ajudar a gerenciar melhor a centralização do seu código.
Tire um minuto para assistir a um vídeo sobre o uso de `const`, `let` e `var`.
Reserve um momento para assistir a um vídeo sobre o uso de `const`, `let` e `var`.
[![Tipos de variáveis](https://img.youtube.com/vi/JNIXfGiDWM8/0.jpg)](https://youtube.com/watch?v=JNIXfGiDWM8 "Tipos de variáveis")
@ -204,9 +204,9 @@ Tire um minuto para assistir a um vídeo sobre o uso de `const`, `let` e `var`.
### Adicionar lógica de início
Para começar o jogo, o jogador clicará em iniciar. Claro, não sabemos quando ele vai clicar em iniciar. É aqui que entra um [ouvinte de evento](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener). Um ouvinte de evento nos permitirá ouvir algo que ocorre (um evento) e executar código em resposta. No nosso caso, queremos executar código quando o usuário clicar em iniciar.
Para começar o jogo, o jogador clicará em iniciar. Claro, não sabemos quando ele fará isso. É aqui que entra um [ouvinte de evento](https://developer.mozilla.org/pt-BR/docs/Web/API/EventTarget/addEventListener). Um ouvinte de evento nos permitirá "ouvir" algo acontecer (um evento) e executar código em resposta. No nosso caso, queremos executar código quando o usuário clicar em iniciar.
Quando o usuário clicar em **iniciar**, precisamos selecionar uma frase, configurar a interface do usuário e configurar o rastreamento da palavra atual e do tempo. Abaixo está o JavaScript que você precisará adicionar; discutimos isso logo após o bloco de script.
Quando o usuário clicar em **iniciar**, precisamos selecionar uma frase, configurar a interface do usuário e configurar o rastreamento da palavra atual e do tempo. Abaixo está o JavaScript que você precisará adicionar; discutimos isso logo após o bloco de código.
```javascript
// at the end of script.js
@ -244,10 +244,10 @@ document.getElementById('start').addEventListener('click', () => {
Vamos detalhar o código!
- Configurar o rastreamento de palavras
- Usar [Math.floor](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) e [Math.random](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Math/random) nos permite selecionar aleatoriamente uma frase do array `quotes`
- Convertemos a `quote` em um array de `words` para que possamos rastrear a palavra que o jogador está digitando no momento
- Usar [Math.floor](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) e [Math.random](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Math/random) nos permite selecionar aleatoriamente uma frase do array `quotes`
- Convertemos a `quote` em um array de `words` para rastrear a palavra que o jogador está digitando
- `wordIndex` é definido como 0, já que o jogador começará na primeira palavra
- Configurar a interface do usuário
- Configurar a interface
- Criar um array de `spanWords`, que contém cada palavra dentro de um elemento `span`
- Isso nos permitirá destacar a palavra na exibição
- `join` o array para criar uma string que podemos usar para atualizar o `innerHTML` no `quoteElement`
@ -261,7 +261,7 @@ Vamos detalhar o código!
### Adicionar lógica de digitação
À medida que o jogador digita, um evento `input` será acionado. Esse ouvinte de evento verificará se o jogador está digitando a palavra corretamente e lidará com o status atual do jogo. Voltando ao **script.js**, adicione o seguinte código ao final. Vamos detalhá-lo em seguida.
À medida que o jogador digita, um evento `input` será acionado. Esse ouvinte de evento verificará se o jogador está digitando a palavra corretamente e lidará com o status atual do jogo. Retornando ao **script.js**, adicione o seguinte código ao final. Vamos detalhá-lo depois.
```javascript
// at the end of script.js
@ -306,17 +306,17 @@ Vamos detalhar o código! Começamos pegando a palavra atual e o valor que o jog
- Calcular `elapsedTime` subtraindo `startTime` do horário atual
- Dividir `elapsedTime` por 1.000 para converter de milissegundos para segundos
- Exibir uma mensagem de sucesso
- A palavra está completa, indicada por `typedValue` terminar com um espaço (o final de uma palavra) e `typedValue` ser igual a `currentWord`
- A palavra está completa, indicada por `typedValue` terminar com um espaço (o fim de uma palavra) e `typedValue` ser igual a `currentWord`
- Definir `value` em `typedElement` como `''` para permitir que a próxima palavra seja digitada
- Incrementar `wordIndex` para passar para a próxima palavra
- Incrementar `wordIndex` para avançar para a próxima palavra
- Percorrer todos os `childNodes` de `quoteElement` para definir `className` como `''` para reverter à exibição padrão
- Definir `className` da palavra atual como `highlight` para marcá-la como a próxima palavra a ser digitada
- A palavra está sendo digitada corretamente (mas não está completa), indicada por `currentWord` começar com `typedValue`
- Garantir que `typedValueElement` seja exibido como padrão limpando `className`
- Se chegarmos até aqui, um erro
- Se chegarmos até aqui, temos um erro
- Definir `className` em `typedValueElement` como `error`
## Teste sua aplicação
## Testar sua aplicação
Você chegou ao final! O último passo é garantir que nossa aplicação funcione. Experimente! Não se preocupe se houver erros; **todos os desenvolvedores** cometem erros. Examine as mensagens e depure conforme necessário.
@ -330,22 +330,23 @@ Clique em **iniciar** e comece a digitar! Deve parecer um pouco com a animação
Adicione mais funcionalidades:
- Desative o ouvinte de evento `input` ao concluir o jogo e reative-o quando o botão for clicado
- Desative o ouvinte de evento `input` ao concluir e reative-o quando o botão for clicado
- Desative a caixa de texto quando o jogador concluir a frase
- Exiba uma caixa de diálogo modal com a mensagem de sucesso
- Armazene pontuações altas usando [localStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage)
- Armazene pontuações altas usando o [localStorage](https://developer.mozilla.org/pt-BR/docs/Web/API/Window/localStorage)
## Quiz Pós-Aula
[Quiz pós-aula](https://ff-quizzes.netlify.app/web/quiz/22)
## Revisão e Autoestudo
Leia sobre [todos os eventos disponíveis](https://developer.mozilla.org/docs/Web/Events) para o desenvolvedor via navegador web e considere os cenários em que você utilizaria cada um deles.
Leia sobre [todos os eventos disponíveis](https://developer.mozilla.org/docs/Web/Events) para o desenvolvedor via o navegador web e considere os cenários em que você utilizaria cada um deles.
## Tarefa
[Crie um novo jogo de teclado](assignment.md)
[Criar um novo jogo de teclado](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução.
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "0bb55e0b98600afab801eea115228873",
"translation_date": "2025-08-25T23:40:52+00:00",
"original_hash": "2326d04e194a10aa760b51f5e5a1f61d",
"translation_date": "2025-08-28T23:50:00+00:00",
"source_file": "5-browser-extension/1-about-browsers/README.md",
"language_code": "br"
}
@ -18,24 +18,24 @@ CO_OP_TRANSLATOR_METADATA:
### Introdução
Extensões de navegador adicionam funcionalidades extras a um navegador. Mas antes de criar uma, é importante aprender um pouco sobre como os navegadores funcionam.
Extensões de navegador adicionam funcionalidades extras a um navegador. Mas antes de criar uma, é importante entender um pouco sobre como os navegadores funcionam.
### Sobre o navegador
Nesta série de lições, você aprenderá a criar uma extensão de navegador que funcionará nos navegadores Chrome, Firefox e Edge. Nesta parte, você descobrirá como os navegadores funcionam e estruturará os elementos da extensão de navegador.
Mas o que é exatamente um navegador? É um aplicativo de software que permite ao usuário final acessar conteúdo de um servidor e exibi-lo em páginas da web.
Mas o que é exatamente um navegador? É um aplicativo de software que permite ao usuário acessar conteúdo de um servidor e exibi-lo em páginas da web.
✅ Um pouco de história: o primeiro navegador foi chamado 'WorldWideWeb' e foi criado por Sir Timothy Berners-Lee em 1990.
![navegadores antigos](../../../../translated_images/earlybrowsers.d984b711cdf3a42ddac919d46c4b5ca7232f68ccfbd81395e04e5a64c0015277.br.jpg)
> Alguns navegadores antigos, via [Karen McGrane](https://www.slideshare.net/KMcGrane/week-4-ixd-history-personal-computing)
Quando um usuário se conecta à internet usando um endereço URL (Uniform Resource Locator), geralmente utilizando o protocolo Hypertext Transfer Protocol via um endereço `http` ou `https`, o navegador se comunica com um servidor web e busca uma página da web.
Quando um usuário se conecta à internet usando um endereço URL (Uniform Resource Locator), geralmente utilizando o protocolo de transferência de hipertexto via um endereço `http` ou `https`, o navegador se comunica com um servidor web e busca uma página da web.
Nesse momento, o mecanismo de renderização do navegador exibe a página no dispositivo do usuário, que pode ser um celular, desktop ou laptop.
Os navegadores também têm a capacidade de armazenar conteúdo em cache para que não seja necessário buscá-lo do servidor toda vez. Eles podem registrar o histórico de navegação do usuário, armazenar 'cookies', que são pequenos pedaços de dados que contêm informações usadas para registrar a atividade do usuário, e muito mais.
Os navegadores também têm a capacidade de armazenar em cache o conteúdo para que ele não precise ser recuperado do servidor toda vez. Eles podem registrar o histórico de navegação do usuário, armazenar 'cookies', que são pequenos pedaços de dados que contêm informações usadas para registrar a atividade do usuário, e muito mais.
Uma coisa muito importante a lembrar sobre navegadores é que eles não são todos iguais! Cada navegador tem seus pontos fortes e fracos, e um desenvolvedor web profissional precisa entender como fazer as páginas da web funcionarem bem em diferentes navegadores. Isso inclui lidar com telas pequenas, como as de celulares, bem como usuários que estão offline.
@ -45,39 +45,39 @@ Um site muito útil que você provavelmente deveria salvar nos favoritos do nave
## Extensões de navegador
Por que você gostaria de criar uma extensão de navegador? É algo prático para anexar ao seu navegador quando você precisa de acesso rápido a tarefas que tende a repetir. Por exemplo, se você frequentemente precisa verificar cores nas várias páginas da web com as quais interage, pode instalar uma extensão de navegador para seleção de cores. Se você tem dificuldade em lembrar senhas, pode usar uma extensão de navegador para gerenciamento de senhas.
Por que você gostaria de criar uma extensão de navegador? É algo prático para anexar ao navegador quando você precisa de acesso rápido a tarefas que tende a repetir. Por exemplo, se você frequentemente precisa verificar cores nas várias páginas da web que interage, pode instalar uma extensão de navegador para seleção de cores. Se você tem dificuldade em lembrar senhas, pode usar uma extensão de navegador para gerenciamento de senhas.
Extensões de navegador também são divertidas de desenvolver. Elas tendem a gerenciar um número limitado de tarefas que executam bem.
Criar extensões de navegador também é divertido. Elas geralmente gerenciam um número limitado de tarefas que executam bem.
✅ Quais são suas extensões de navegador favoritas? Quais tarefas elas realizam?
### Instalando extensões
Antes de começar a criar, dê uma olhada no processo de criação e implantação de uma extensão de navegador. Embora cada navegador varie um pouco na forma como gerencia essa tarefa, o processo é semelhante no Chrome e Firefox ao exemplo no Edge:
Antes de começar a criar, dê uma olhada no processo de construção e implantação de uma extensão de navegador. Embora cada navegador varie um pouco na forma como gerencia essa tarefa, o processo é semelhante no Chrome e Firefox ao exemplo no Edge:
![captura de tela do navegador Edge mostrando a página edge://extensions aberta e o menu de configurações aberto](../../../../translated_images/install-on-edge.d68781acaf0b3d3dada8b7507cde7a64bf74b7040d9818baaa9070668e819f90.br.png)
> Nota: Certifique-se de ativar o modo de desenvolvedor e permitir extensões de outras lojas.
> Nota: Certifique-se de ativar o modo desenvolvedor e permitir extensões de outras lojas.
Essencialmente, o processo será:
- criar sua extensão usando `npm run build`
- construir sua extensão usando `npm run build`
- navegar no navegador até o painel de extensões usando o botão "Configurações e mais" (o ícone `...`) no canto superior direito
- se for uma nova instalação, escolher `load unpacked` para carregar uma extensão nova a partir da pasta de build (no nosso caso é `/dist`)
- ou, clicar em `reload` se estiver recarregando a extensão já instalada
- ou, clicar em `reload` se estiver recarregando uma extensão já instalada
✅ Essas instruções se referem às extensões que você mesmo cria; para instalar extensões que foram lançadas na loja de extensões do navegador associado a cada navegador, você deve navegar até essas [lojas](https://microsoftedge.microsoft.com/addons/Microsoft-Edge-Extensions-Home) e instalar a extensão de sua escolha.
### Comece
Você vai criar uma extensão de navegador que exibe a pegada de carbono da sua região, mostrando o uso de energia da sua região e a fonte dessa energia. A extensão terá um formulário que coleta uma chave de API para que você possa acessar a API do CO2 Signal.
Você vai criar uma extensão de navegador que exibe a pegada de carbono da sua região, mostrando o uso de energia e a fonte dessa energia. A extensão terá um formulário que coleta uma chave de API para acessar a API do CO2 Signal.
**Você precisa:**
- [uma chave de API](https://www.co2signal.com/); insira seu e-mail na caixa nesta página e uma será enviada para você
- [uma chave de API](https://www.co2signal.com/); insira seu e-mail na caixa desta página e uma será enviada para você
- o [código da sua região](http://api.electricitymap.org/v3/zones) correspondente ao [Electricity Map](https://www.electricitymap.org/map) (em Boston, por exemplo, eu uso 'US-NEISO').
- o [código inicial](../../../../5-browser-extension/start). Baixe a pasta `start`; você completará o código nesta pasta.
- [NPM](https://www.npmjs.com) - NPM é uma ferramenta de gerenciamento de pacotes; instale-a localmente e os pacotes listados no seu arquivo `package.json` serão instalados para uso no seu ativo web
- [NPM](https://www.npmjs.com) - NPM é uma ferramenta de gerenciamento de pacotes; instale-a localmente e os pacotes listados no arquivo `package.json` serão instalados para uso em seus ativos web
✅ Saiba mais sobre gerenciamento de pacotes neste [excelente módulo de aprendizado](https://docs.microsoft.com/learn/modules/create-nodejs-project-dependencies/?WT.mc_id=academic-77807-sagibbon)
@ -125,7 +125,7 @@ Na pasta `/dist`, você criará um formulário e uma área de resultados. No arq
```
Este é o formulário onde suas informações salvas serão inseridas e armazenadas no armazenamento local.
Em seguida, crie a área de resultados; sob a tag final do formulário, adicione algumas divs:
Em seguida, crie a área de resultados; sob a tag final do formulário, adicione alguns divs:
```HTML
<div class="result">
@ -140,15 +140,15 @@ Em seguida, crie a área de resultados; sob a tag final do formulário, adicione
<button class="clear-btn">Change region</button>
</div>
```
Neste ponto, você pode tentar uma compilação. Certifique-se de instalar as dependências de pacotes desta extensão:
Neste ponto, você pode tentar uma construção. Certifique-se de instalar as dependências do pacote desta extensão:
```
npm install
```
Este comando usará o npm, o Gerenciador de Pacotes do Node, para instalar o webpack para o processo de compilação da sua extensão. O webpack é um empacotador que lida com a compilação de código. Você pode ver o resultado desse processo olhando em `/dist/main.js` - verá que o código foi empacotado.
Este comando usará o npm, o Gerenciador de Pacotes do Node, para instalar o webpack para o processo de construção da sua extensão. O webpack é um empacotador que lida com a compilação de código. Você pode ver o resultado desse processo olhando em `/dist/main.js` - verá que o código foi empacotado.
Por enquanto, a extensão deve ser compilada e, se você implantá-la no Edge como uma extensão, verá um formulário exibido de forma organizada.
Por enquanto, a extensão deve ser construída e, se você implantá-la no Edge como uma extensão, verá um formulário exibido de forma organizada.
Parabéns, você deu os primeiros passos para criar uma extensão de navegador. Nas próximas lições, você a tornará mais funcional e útil.
@ -162,7 +162,7 @@ Dê uma olhada em uma loja de extensões de navegador e instale uma no seu naveg
[Quiz pós-aula](https://ff-quizzes.netlify.app/web/quiz/24)
## Revisão e Autoestudo
## Revisão & Autoestudo
Nesta lição, você aprendeu um pouco sobre a história do navegador web; aproveite esta oportunidade para aprender sobre como os inventores da World Wide Web imaginaram seu uso lendo mais sobre sua história. Alguns sites úteis incluem:
@ -176,5 +176,7 @@ Nesta lição, você aprendeu um pouco sobre a história do navegador web; aprov
[Redefina o estilo da sua extensão](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "e10f168beac4e7b05e30e0eb5c92bf11",
"translation_date": "2025-08-25T23:31:51+00:00",
"original_hash": "a7587943d38d095de8613e1b508609f5",
"translation_date": "2025-08-28T23:51:35+00:00",
"source_file": "5-browser-extension/2-forms-browsers-local-storage/README.md",
"language_code": "br"
}
@ -15,13 +15,13 @@ CO_OP_TRANSLATOR_METADATA:
### Introdução
Nesta lição, você chamará uma API enviando o formulário da extensão do navegador e exibirá os resultados na extensão. Além disso, você aprenderá como armazenar dados no armazenamento local do navegador para referência e uso futuros.
Nesta lição, você chamará uma API enviando o formulário da sua extensão para navegador e exibirá os resultados na extensão. Além disso, você aprenderá como armazenar dados no armazenamento local do navegador para referência e uso futuros.
✅ Siga os segmentos numerados nos arquivos apropriados para saber onde colocar seu código.
### Configure os elementos para manipular na extensão:
Até agora, você já criou o HTML para o formulário e o `<div>` de resultados da sua extensão. A partir de agora, você precisará trabalhar no arquivo `/src/index.js` e construir sua extensão passo a passo. Consulte a [lição anterior](../1-about-browsers/README.md) para configurar seu projeto e entender o processo de build.
Até agora, você já criou o HTML para o formulário e o `<div>` de resultados da sua extensão para navegador. A partir de agora, você precisará trabalhar no arquivo `/src/index.js` e construir sua extensão passo a passo. Consulte a [lição anterior](../1-about-browsers/README.md) para configurar seu projeto e entender o processo de build.
Trabalhando no arquivo `index.js`, comece criando algumas variáveis `const` para armazenar os valores associados a vários campos:
@ -53,11 +53,11 @@ clearBtn.addEventListener('click', (e) => reset(e));
init();
```
✅ Observe a forma abreviada usada para escutar eventos de envio ou clique e como o evento é passado para as funções handleSubmit ou reset. Você consegue escrever o equivalente dessa forma abreviada em um formato mais longo? Qual você prefere?
✅ Observe a forma abreviada usada para ouvir eventos de envio ou clique e como o evento é passado para as funções `handleSubmit` ou `reset`. Você consegue escrever o equivalente dessa forma abreviada em um formato mais longo? Qual você prefere?
### Construa as funções init() e reset():
Agora você vai construir a função que inicializa a extensão, chamada init():
Agora você vai construir a função que inicializa a extensão, chamada `init()`:
```JavaScript
function init() {
@ -95,32 +95,32 @@ function reset(e) {
Nesta função, há uma lógica interessante. Lendo-a, você consegue entender o que acontece?
- Dois `const` são configurados para verificar se o usuário armazenou uma APIKey e um código de região no armazenamento local.
- Se qualquer um deles for nulo, exiba o formulário alterando seu estilo para 'block'.
- Oculte os resultados, o carregamento e o clearBtn, e defina qualquer texto de erro como uma string vazia.
- Duas variáveis `const` são configuradas para verificar se o usuário armazenou uma APIKey e um código de região no armazenamento local.
- Se qualquer uma delas for nula, exiba o formulário alterando seu estilo para 'block'.
- Oculte os resultados, o carregamento e o botão de limpar, e defina qualquer texto de erro como uma string vazia.
- Se houver uma chave e uma região, inicie uma rotina para:
- Chamar a API para obter dados de uso de carbono.
- Ocultar a área de resultados.
- Ocultar o formulário.
- Exibir o botão de redefinição.
Antes de prosseguir, é útil aprender sobre um conceito muito importante disponível nos navegadores: [LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage). O LocalStorage é uma maneira útil de armazenar strings no navegador como um par `chave-valor`. Esse tipo de armazenamento pode ser manipulado por JavaScript para gerenciar dados no navegador. O LocalStorage não expira, enquanto o SessionStorage, outro tipo de armazenamento, é limpo quando o navegador é fechado. Os diferentes tipos de armazenamento têm prós e contras em seu uso.
Antes de prosseguir, é útil aprender sobre um conceito muito importante disponível nos navegadores: [LocalStorage](https://developer.mozilla.org/docs/Web/API/Window/localStorage). O LocalStorage é uma maneira útil de armazenar strings no navegador como um par `chave-valor`. Esse tipo de armazenamento pode ser manipulado por JavaScript para gerenciar dados no navegador. O LocalStorage não expira, enquanto o SessionStorage, outro tipo de armazenamento, é limpo quando o navegador é fechado. Cada tipo de armazenamento tem prós e contras em seu uso.
> Nota - sua extensão de navegador tem seu próprio armazenamento local; a janela principal do navegador é uma instância diferente e se comporta separadamente.
> Nota - sua extensão para navegador tem seu próprio armazenamento local; a janela principal do navegador é uma instância diferente e se comporta separadamente.
Você define sua APIKey para ter um valor de string, por exemplo, e pode ver que ela é configurada no Edge ao "inspecionar" uma página da web (você pode clicar com o botão direito no navegador para inspecionar) e ir para a guia Applications para ver o armazenamento.
Você define sua APIKey para ter um valor de string, por exemplo, e pode ver que ela está configurada no Edge ao "inspecionar" uma página da web (você pode clicar com o botão direito do mouse no navegador para inspecionar) e ir para a aba Applications para ver o armazenamento.
![Painel de armazenamento local](../../../../translated_images/localstorage.472f8147b6a3f8d141d9551c95a2da610ac9a3c6a73d4a1c224081c98bae09d9.br.png)
✅ Pense em situações em que você NÃO gostaria de armazenar alguns dados no LocalStorage. Em geral, colocar API Keys no LocalStorage é uma má ideia! Consegue entender por quê? No nosso caso, como nosso aplicativo é puramente para aprendizado e não será publicado em uma loja de aplicativos, usaremos esse método.
✅ Pense em situações em que você NÃO gostaria de armazenar alguns dados no LocalStorage. Em geral, colocar chaves de API no LocalStorage é uma má ideia! Consegue entender por quê? No nosso caso, como nosso aplicativo é puramente para aprendizado e não será publicado em uma loja de aplicativos, usaremos esse método.
Observe que você usa a Web API para manipular o LocalStorage, seja usando `getItem()`, `setItem()` ou `removeItem()`. É amplamente suportado em navegadores.
Antes de construir a função `displayCarbonUsage()` que é chamada em `init()`, vamos construir a funcionalidade para lidar com o envio inicial do formulário.
Antes de construir a função `displayCarbonUsage()` que é chamada em `init()`, vamos criar a funcionalidade para lidar com o envio inicial do formulário.
### Lidar com o envio do formulário
### Lide com o envio do formulário
Crie uma função chamada `handleSubmit` que aceita um argumento de evento `(e)`. Pare a propagação do evento (neste caso, queremos impedir que o navegador atualize) e chame uma nova função, `setUpUser`, passando os argumentos `apiKey.value` e `region.value`. Dessa forma, você usa os dois valores que são trazidos pelo formulário inicial quando os campos apropriados são preenchidos.
Crie uma função chamada `handleSubmit` que aceita um argumento de evento `(e)`. Interrompa a propagação do evento (neste caso, queremos impedir que o navegador atualize) e chame uma nova função, `setUpUser`, passando os argumentos `apiKey.value` e `region.value`. Dessa forma, você usa os dois valores que são trazidos pelo formulário inicial quando os campos apropriados são preenchidos.
```JavaScript
function handleSubmit(e) {
@ -129,7 +129,7 @@ function handleSubmit(e) {
}
```
✅ Refresque sua memória - o HTML que você configurou na última lição tem dois campos de entrada cujos `values` são capturados via os `const` que você configurou no início do arquivo, e ambos são `required`, então o navegador impede que os usuários insiram valores nulos.
✅ Refresque sua memória - o HTML que você configurou na última lição tem dois campos de entrada cujos `values` são capturados pelas `const` que você configurou no início do arquivo, e ambos são `required`, então o navegador impede que os usuários insiram valores nulos.
### Configure o usuário
@ -147,17 +147,17 @@ function setUpUser(apiKey, regionName) {
}
```
Essa função exibe uma mensagem de carregamento enquanto a API é chamada. Neste ponto, você chegou à criação da função mais importante desta extensão de navegador!
Essa função define uma mensagem de carregamento para exibir enquanto a API é chamada. Neste ponto, você chegou à criação da função mais importante desta extensão para navegador!
### Exibir Uso de Carbono
### Exiba o Uso de Carbono
Finalmente, é hora de consultar a API!
Antes de prosseguir, devemos discutir APIs. APIs, ou [Interfaces de Programação de Aplicações](https://www.webopedia.com/TERM/A/API.html), são um elemento crítico na caixa de ferramentas de um desenvolvedor web. Elas fornecem maneiras padrão para programas interagirem e se conectarem. Por exemplo, se você está construindo um site que precisa consultar um banco de dados, alguém pode ter criado uma API para você usar. Embora existam muitos tipos de APIs, uma das mais populares é uma [API REST](https://www.smashingmagazine.com/2018/01/understanding-using-rest-api/).
Antes de prosseguir, devemos discutir APIs. APIs, ou [Interfaces de Programação de Aplicações](https://www.webopedia.com/TERM/A/API.html), são um elemento crítico na caixa de ferramentas de um desenvolvedor web. Elas fornecem maneiras padrão para programas interagirem e se conectarem. Por exemplo, se você está criando um site que precisa consultar um banco de dados, alguém pode ter criado uma API para você usar. Embora existam muitos tipos de APIs, uma das mais populares é uma [API REST](https://www.smashingmagazine.com/2018/01/understanding-using-rest-api/).
✅ O termo 'REST' significa 'Transferência de Estado Representacional' e utiliza URLs configurados de várias maneiras para buscar dados. Faça uma pequena pesquisa sobre os vários tipos de APIs disponíveis para desenvolvedores. Qual formato mais te atrai?
✅ O termo 'REST' significa 'Transferência de Estado Representacional' e utiliza URLs configurados de várias maneiras para buscar dados. Faça uma pequena pesquisa sobre os vários tipos de APIs disponíveis para desenvolvedores. Qual formato mais lhe agrada?
Há coisas importantes a serem observadas sobre esta função. Primeiro, observe a palavra-chave [`async`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Escrever suas funções para que elas sejam executadas de forma assíncrona significa que elas esperam por uma ação, como o retorno de dados, ser concluída antes de continuar.
Há coisas importantes a serem observadas sobre esta função. Primeiro, observe a palavra-chave [`async`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Escrever suas funções para que elas sejam executadas de forma assíncrona significa que elas esperam uma ação, como o retorno de dados, ser concluída antes de continuar.
Aqui está um vídeo rápido sobre `async`:
@ -207,7 +207,7 @@ async function displayCarbonUsage(apiKey, region) {
Esta é uma função grande. O que está acontecendo aqui?
- Seguindo as melhores práticas, você usa a palavra-chave `async` para fazer essa função se comportar de forma assíncrona. A função contém um bloco `try/catch`, pois retornará uma promessa quando a API retornar dados. Como você não tem controle sobre a velocidade com que a API responderá (ela pode nem responder!), você precisa lidar com essa incerteza chamando-a de forma assíncrona.
- Seguindo as melhores práticas, você usa a palavra-chave `async` para fazer com que esta função se comporte de forma assíncrona. A função contém um bloco `try/catch`, pois retornará uma promessa quando a API retornar dados. Como você não tem controle sobre a velocidade com que a API responderá (ela pode nem responder!), você precisa lidar com essa incerteza chamando-a de forma assíncrona.
- Você está consultando a API co2signal para obter os dados da sua região, usando sua API Key. Para usar essa chave, você precisa usar um tipo de autenticação nos parâmetros do cabeçalho.
- Assim que a API responder, você atribui vários elementos dos dados de resposta às partes da tela que você configurou para exibir esses dados.
- Se houver um erro ou se não houver resultado, você exibe uma mensagem de erro.
@ -220,7 +220,7 @@ Parabéns! Se você construir sua extensão (`npm run build`) e atualizá-la no
## 🚀 Desafio
Discutimos vários tipos de API até agora nestas lições. Escolha uma API da web e pesquise em profundidade o que ela oferece. Por exemplo, dê uma olhada nas APIs disponíveis nos navegadores, como a [API de Arrastar e Soltar do HTML](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API). O que faz uma API ser excelente, na sua opinião?
Discutimos vários tipos de API até agora nestas lições. Escolha uma API da web e pesquise em profundidade o que ela oferece. Por exemplo, dê uma olhada nas APIs disponíveis nos navegadores, como a [API de Arrastar e Soltar em HTML](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API). O que, na sua opinião, faz uma API ser excelente?
## Questionário Pós-Aula
@ -234,5 +234,7 @@ Você aprendeu sobre LocalStorage e APIs nesta lição, ambos muito úteis para
[Adote uma API](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "f198c6b817b4b2a99749f4662e7cae98",
"translation_date": "2025-08-25T23:47:28+00:00",
"original_hash": "49b58721a71cfda824e2f3e1f46908c6",
"translation_date": "2025-08-28T23:50:45+00:00",
"source_file": "5-browser-extension/3-background-tasks-and-performance/README.md",
"language_code": "br"
}
@ -15,15 +15,15 @@ CO_OP_TRANSLATOR_METADATA:
### Introdução
Nas duas últimas lições deste módulo, você aprendeu como criar um formulário e uma área de exibição para dados obtidos de uma API. Essa é uma maneira muito comum de criar uma presença na web. Você até aprendeu como lidar com a obtenção de dados de forma assíncrona. Sua extensão para navegador está quase completa.
Nas duas últimas lições deste módulo, você aprendeu a criar um formulário e uma área de exibição para dados obtidos de uma API. Essa é uma maneira bastante comum de criar uma presença na web. Você até aprendeu a lidar com a obtenção de dados de forma assíncrona. Sua extensão para navegador está quase completa.
Resta gerenciar algumas tarefas em segundo plano, incluindo atualizar a cor do ícone da extensão. Este é um ótimo momento para falar sobre como o navegador gerencia esse tipo de tarefa. Vamos pensar nessas tarefas do navegador no contexto do desempenho dos seus recursos web enquanto você os desenvolve.
Resta gerenciar algumas tarefas em segundo plano, incluindo a atualização da cor do ícone da extensão. Este é um ótimo momento para falar sobre como o navegador gerencia esse tipo de tarefa. Vamos pensar nessas tarefas do navegador no contexto do desempenho dos seus recursos web enquanto você os desenvolve.
## Noções Básicas de Desempenho na Web
> "O desempenho de um site se resume a duas coisas: quão rápido a página carrega e quão rápido o código nela é executado." -- [Zack Grossbart](https://www.smashingmagazine.com/2012/06/javascript-profiling-chrome-developer-tools/)
> "O desempenho de um site envolve duas coisas: quão rápido a página carrega e quão rápido o código nela é executado." -- [Zack Grossbart](https://www.smashingmagazine.com/2012/06/javascript-profiling-chrome-developer-tools/)
O tema de como tornar seus sites incrivelmente rápidos em todos os tipos de dispositivos, para todos os tipos de usuários, em todas as situações, é, sem surpresa, vasto. Aqui estão alguns pontos a serem considerados ao criar um projeto web padrão ou uma extensão para navegador.
O tema de como tornar seus sites extremamente rápidos em todos os tipos de dispositivos, para todos os tipos de usuários, em todas as situações, é, sem surpresa, vasto. Aqui estão alguns pontos a serem considerados ao criar um projeto web padrão ou uma extensão para navegador.
A primeira coisa que você precisa fazer para garantir que seu site esteja funcionando de forma eficiente é coletar dados sobre seu desempenho. O primeiro lugar para fazer isso é nas ferramentas de desenvolvedor do seu navegador. No Edge, você pode selecionar o botão "Configurações e mais" (o ícone de três pontos no canto superior direito do navegador), depois navegar até Mais Ferramentas > Ferramentas do Desenvolvedor e abrir a aba de Desempenho. Você também pode usar os atalhos de teclado `Ctrl` + `Shift` + `I` no Windows ou `Option` + `Command` + `I` no Mac para abrir as ferramentas de desenvolvedor.
@ -41,17 +41,17 @@ Obtenha um instantâneo do desempenho da sua página selecionando uma parte da l
![Instantâneo do perfilador do Edge](../../../../translated_images/snapshot.97750180ebcad73794a3594b36925eb5c8dbaac9e03fec7f9b974188c9ac63c7.br.png)
Verifique o painel de Registro de Eventos para ver se algum evento demorou mais de 15 ms:
Verifique o painel de Log de Eventos para ver se algum evento demorou mais de 15 ms:
![Registro de eventos do Edge](../../../../translated_images/log.804026979f3707e00eebcfa028b2b5a88cec6292f858767bb6703afba65a7d9c.br.png)
![Log de eventos do Edge](../../../../translated_images/log.804026979f3707e00eebcfa028b2b5a88cec6292f858767bb6703afba65a7d9c.br.png)
✅ Familiarize-se com seu perfilador! Abra as ferramentas de desenvolvedor neste site e veja se há gargalos. Qual é o recurso que carrega mais lentamente? E o mais rápido?
## Verificações de Perfilação
De forma geral, existem algumas "áreas problemáticas" que todo desenvolvedor web deve observar ao criar um site para evitar surpresas desagradáveis na hora de implantar em produção.
De modo geral, existem algumas "áreas problemáticas" que todo desenvolvedor web deve observar ao criar um site para evitar surpresas desagradáveis na hora de implantar em produção.
**Tamanhos de recursos**: A web ficou mais "pesada" e, portanto, mais lenta, nos últimos anos. Parte desse peso está relacionada ao uso de imagens.
**Tamanhos de recursos**: A web ficou mais "pesada" e, portanto, mais lenta nos últimos anos. Parte desse peso está relacionada ao uso de imagens.
✅ Consulte o [Internet Archive](https://httparchive.org/reports/page-weight) para uma visão histórica do peso das páginas e mais.
@ -94,13 +94,13 @@ O chrome.runtime possui [uma API](https://developer.chrome.com/extensions/runtim
> "Use a API chrome.runtime para recuperar a página de segundo plano, retornar detalhes sobre o manifesto e ouvir e responder a eventos no ciclo de vida do aplicativo ou extensão. Você também pode usar essa API para converter o caminho relativo de URLs em URLs totalmente qualificados."
✅ Se você está desenvolvendo esta extensão para o Edge, pode ser surpreendente que esteja usando uma API do Chrome. As versões mais recentes do navegador Edge são baseadas no mecanismo do navegador Chromium, então você pode aproveitar essas ferramentas.
✅ Se você está desenvolvendo esta extensão para o Edge, pode se surpreender ao descobrir que está usando uma API do Chrome. As versões mais recentes do navegador Edge são baseadas no mecanismo do navegador Chromium, então você pode aproveitar essas ferramentas.
> Nota: se você quiser perfilar uma extensão para navegador, abra as ferramentas de desenvolvedor dentro da própria extensão, pois ela é uma instância separada do navegador.
### Definir uma cor padrão para o ícone
Agora, na função `init()`, defina o ícone para ser um verde genérico inicialmente, chamando novamente a ação `updateIcon` do Chrome:
Agora, na função `init()`, defina o ícone como um verde genérico para começar, chamando novamente a ação `updateIcon` do Chrome:
```JavaScript
chrome.runtime.sendMessage({
@ -142,7 +142,7 @@ function drawIcon(value) {
}
```
Neste código, você está adicionando um listener para quaisquer mensagens que chegam ao gerenciador de tarefas em segundo plano. Se for chamada 'updateIcon', o próximo código será executado para desenhar um ícone da cor apropriada usando a API Canvas.
Neste código, você está adicionando um listener para quaisquer mensagens que chegam ao gerenciador de tarefas em segundo plano. Se for chamado 'updateIcon', o próximo código será executado para desenhar um ícone da cor apropriada usando a API Canvas.
✅ Você aprenderá mais sobre a API Canvas nas [lições do Jogo Espacial](../../6-space-game/2-drawing-to-canvas/README.md).
@ -170,5 +170,7 @@ Investigue algumas das maneiras como os navegadores avaliam o desempenho da web,
[Analise um site para desempenho](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,13 +1,13 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "d9da6dc61fb712b29f65e108c79b8a5d",
"translation_date": "2025-08-25T22:31:45+00:00",
"original_hash": "979cfcce2413a87d9e4c67eb79234bc3",
"translation_date": "2025-08-28T23:53:41+00:00",
"source_file": "6-space-game/1-introduction/README.md",
"language_code": "br"
}
-->
# Construindo um Jogo Espacial Parte 1: Introdução
# Crie um Jogo Espacial Parte 1: Introdução
![video](../../../../6-space-game/images/pewpew.gif)
@ -17,16 +17,16 @@ CO_OP_TRANSLATOR_METADATA:
### Herança e Composição no desenvolvimento de jogos
Nas lições anteriores, não havia muita necessidade de se preocupar com a arquitetura de design dos aplicativos que você criou, já que os projetos eram muito pequenos em escopo. No entanto, à medida que suas aplicações crescem em tamanho e complexidade, as decisões arquiteturais se tornam uma preocupação maior. Existem duas abordagens principais para criar aplicações maiores em JavaScript: *composição* ou *herança*. Ambas têm prós e contras, mas vamos explicá-las no contexto de um jogo.
Em aulas anteriores, não havia muita necessidade de se preocupar com a arquitetura dos aplicativos que você criou, já que os projetos eram muito pequenos em escopo. No entanto, à medida que suas aplicações crescem em tamanho e complexidade, as decisões arquiteturais se tornam uma preocupação maior. Existem duas abordagens principais para criar aplicações maiores em JavaScript: *composição* ou *herança*. Ambas têm prós e contras, mas vamos explicá-las no contexto de um jogo.
✅ Um dos livros de programação mais famosos já escritos trata de [padrões de design](https://en.wikipedia.org/wiki/Design_Patterns).
✅ Um dos livros de programação mais famosos já escritos trata de [design patterns](https://en.wikipedia.org/wiki/Design_Patterns).
Em um jogo, você tem `objetos do jogo`, que são objetos que existem em uma tela. Isso significa que eles têm uma localização em um sistema de coordenadas cartesianas, caracterizado por ter uma coordenada `x` e `y`. À medida que você desenvolve um jogo, perceberá que todos os seus objetos do jogo possuem uma propriedade padrão, comum a todos os jogos que você cria, ou seja, elementos que são:
Em um jogo, você tem `objetos do jogo`, que são objetos que existem na tela. Isso significa que eles têm uma localização em um sistema de coordenadas cartesianas, caracterizada por ter uma coordenada `x` e `y`. À medida que você desenvolve um jogo, perceberá que todos os seus objetos do jogo têm propriedades padrão, comuns a qualquer jogo que você criar, ou seja, elementos que são:
- **baseados em localização** A maioria, se não todos, os elementos do jogo são baseados em localização. Isso significa que eles têm uma localização, um `x` e um `y`.
- **móveis** Esses são objetos que podem se mover para uma nova localização. Normalmente, é um herói, um monstro ou um NPC (personagem não jogável), mas não, por exemplo, um objeto estático como uma árvore.
- **autodestrutivos** Esses objetos existem apenas por um período de tempo definido antes de se prepararem para exclusão. Geralmente, isso é representado por um booleano `morto` ou `destruído` que sinaliza ao motor do jogo que esse objeto não deve mais ser renderizado.
- **tempo de recarga** 'Tempo de recarga' é uma propriedade típica entre objetos de curta duração. Um exemplo típico é um pedaço de texto ou efeito gráfico, como uma explosão, que deve ser visto apenas por alguns milissegundos.
- **baseados em localização**: A maioria, se não todos, os elementos do jogo são baseados em localização. Isso significa que eles têm uma localização, um `x` e um `y`.
- **móveis**: São objetos que podem se mover para uma nova localização. Normalmente, isso inclui um herói, um monstro ou um NPC (personagem não jogável), mas não, por exemplo, um objeto estático como uma árvore.
- **autodestrutíveis**: Esses objetos existem apenas por um período de tempo definido antes de serem marcados para exclusão. Geralmente, isso é representado por um booleano `dead` ou `destroyed` que sinaliza ao motor do jogo que esse objeto não deve mais ser renderizado.
- **com tempo de espera**: 'Tempo de espera' é uma propriedade típica entre objetos de curta duração. Um exemplo típico é um pedaço de texto ou efeito gráfico, como uma explosão, que deve ser visto apenas por alguns milissegundos.
✅ Pense em um jogo como Pac-Man. Você consegue identificar os quatro tipos de objetos listados acima nesse jogo?
@ -40,7 +40,7 @@ A ideia é usar `classes` em conjunto com `herança` para adicionar um determina
✅ Herança é um conceito importante para entender. Saiba mais no [artigo da MDN sobre herança](https://developer.mozilla.org/docs/Web/JavaScript/Inheritance_and_the_prototype_chain).
Expressado em código, um objeto do jogo pode tipicamente se parecer com isso:
Expressado em código, um objeto do jogo pode ser algo assim:
```javascript
@ -88,7 +88,7 @@ hero.moveTo(5,5);
const tree = new Tree();
```
Tire alguns minutos para imaginar um herói do Pac-Man (Inky, Pinky ou Blinky, por exemplo) e como ele seria escrito em JavaScript.
Reserve alguns minutos para imaginar como seria um herói do Pac-Man (Inky, Pinky ou Blinky, por exemplo) escrito em JavaScript.
**Composição**
@ -149,13 +149,13 @@ Outro padrão comum no desenvolvimento de jogos aborda o problema de gerenciar a
✅ Pub/Sub significa 'publicar-assinar'
Esse padrão aborda a ideia de que as partes distintas da sua aplicação não devem saber umas das outras. Por quê? Isso torna muito mais fácil entender o que está acontecendo em geral se as várias partes estiverem separadas. Também facilita mudar o comportamento repentinamente, se necessário. Como fazemos isso? Estabelecendo alguns conceitos:
Esse padrão aborda a ideia de que as partes distintas da sua aplicação não devem saber umas das outras. Por quê? Isso facilita muito a visualização geral do que está acontecendo se as várias partes estiverem separadas. Também facilita mudar o comportamento repentinamente, se necessário. Como fazemos isso? Estabelecendo alguns conceitos:
- **mensagem**: Uma mensagem geralmente é uma string de texto acompanhada de uma carga útil opcional (um dado que esclarece sobre o que é a mensagem). Uma mensagem típica em um jogo pode ser `KEY_PRESSED_ENTER`.
- **mensagem**: Uma mensagem geralmente é uma string de texto acompanhada de uma carga opcional (um dado que esclarece sobre o que é a mensagem). Uma mensagem típica em um jogo pode ser `KEY_PRESSED_ENTER`.
- **publicador**: Este elemento *publica* uma mensagem e a envia para todos os assinantes.
- **assinante**: Este elemento *ouve* mensagens específicas e executa alguma tarefa como resultado de receber essa mensagem, como disparar um laser.
A implementação é bem pequena em tamanho, mas é um padrão muito poderoso. Veja como pode ser implementado:
A implementação é bem pequena, mas é um padrão muito poderoso. Veja como pode ser implementado:
```javascript
//set up an EventEmitter class that contains listeners
@ -204,7 +204,7 @@ window.addEventListener('keyup', (evt) => {
});
```
Acima, conectamos um evento de teclado, `ArrowLeft`, e enviamos a mensagem `HERO_MOVE_LEFT`. Ouvimos essa mensagem e movemos o `herói` como resultado. A força desse padrão é que o ouvinte de eventos e o herói não sabem um do outro. Você pode remapear o `ArrowLeft` para a tecla `A`. Além disso, seria possível fazer algo completamente diferente no `ArrowLeft` fazendo algumas edições na função `on` do eventEmitter:
No exemplo acima, conectamos um evento de teclado, `ArrowLeft`, e enviamos a mensagem `HERO_MOVE_LEFT`. Escutamos essa mensagem e movemos o `herói` como resultado. A força desse padrão é que o listener de eventos e o herói não sabem um do outro. Você pode remapear o `ArrowLeft` para a tecla `A`. Além disso, seria possível fazer algo completamente diferente no `ArrowLeft` fazendo algumas edições na função `on` do eventEmitter:
```javascript
eventEmitter.on(Messages.HERO_MOVE_LEFT, () => {
@ -218,7 +218,7 @@ eventEmitter.on(Messages.HERO_MOVE_LEFT, () => {
## 🚀 Desafio
Pense em como o padrão pub-sub pode melhorar um jogo. Quais partes devem emitir eventos e como o jogo deve reagir a eles? Agora é sua chance de ser criativo, pensando em um novo jogo e como suas partes podem se comportar.
Pense em como o padrão pub-sub pode melhorar um jogo. Quais partes deveriam emitir eventos e como o jogo deveria reagir a eles? Agora é sua chance de ser criativo, pensando em um novo jogo e como suas partes poderiam se comportar.
## Quiz Pós-Aula
@ -232,5 +232,7 @@ Saiba mais sobre Pub/Sub [lendo sobre o assunto](https://docs.microsoft.com/azur
[Crie um protótipo de jogo](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "41be8d35e7f30aa9dad10773c35e89c4",
"translation_date": "2025-08-25T22:18:45+00:00",
"original_hash": "056641280211e52fd0adb81b6058ec55",
"translation_date": "2025-08-28T23:53:03+00:00",
"source_file": "6-space-game/2-drawing-to-canvas/README.md",
"language_code": "br"
}
@ -27,15 +27,15 @@ Aqui está como ele é normalmente declarado, como parte do corpo da página:
Acima, estamos definindo o `id`, `width` e `height`.
- `id`: defina isso para que você possa obter uma referência quando precisar interagir com ele.
- `id`: defina isso para obter uma referência quando precisar interagir com o elemento.
- `width`: esta é a largura do elemento.
- `height`: esta é a altura do elemento.
## Desenhando formas geométricas simples
O Canvas utiliza um sistema de coordenadas cartesianas para desenhar. Assim, ele usa um eixo x e um eixo y para expressar onde algo está localizado. A localização `0,0` é a posição no canto superior esquerdo, e o canto inferior direito é o que você definiu como a LARGURA e ALTURA do canvas.
O Canvas utiliza um sistema de coordenadas cartesianas para desenhar. Assim, ele usa um eixo x e um eixo y para expressar onde algo está localizado. A localização `0,0` é a posição superior esquerda, e a inferior direita é o que você definiu como a LARGURA e ALTURA do canvas.
![a grade do canvas](../../../../translated_images/canvas_grid.5f209da785ded492a01ece440e3032afe51efa500cc2308e5ea4252487ceaf0b.br.png)
![a grade do canvas](../../../../translated_images/canvas_grid.5f209da785ded492a01ece440e3032afe51efa500cc2308e5ea4252487ceaf0b.br.png)
> Imagem de [MDN](https://developer.mozilla.org/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes)
Para desenhar no elemento canvas, você precisará seguir os seguintes passos:
@ -65,11 +65,11 @@ ctx.fillRect(0,0, 200, 200) // x,y,width, height
Você pode desenhar vários tipos de coisas com a API Canvas, como:
- **Formas geométricas**: já mostramos como desenhar um retângulo, mas há muito mais que você pode desenhar.
- **Texto**: você pode desenhar texto com qualquer fonte e cor que desejar.
- **Imagens**: você pode desenhar uma imagem baseada em um arquivo de imagem, como um .jpg ou .png, por exemplo.
- **Formas geométricas**, já mostramos como desenhar um retângulo, mas há muito mais que você pode desenhar.
- **Texto**, você pode desenhar texto com qualquer fonte e cor que desejar.
- **Imagens**, você pode desenhar uma imagem baseada em um arquivo de imagem, como um .jpg ou .png, por exemplo.
✅ Experimente! Você já sabe como desenhar um retângulo, consegue desenhar um círculo na página? Dê uma olhada em alguns desenhos interessantes no Canvas no CodePen. Aqui está um [exemplo particularmente impressionante](https://codepen.io/dissimulate/pen/KrAwx).
✅ Experimente! Você já sabe como desenhar um retângulo, consegue desenhar um círculo na página? Dê uma olhada em alguns desenhos interessantes feitos com Canvas no CodePen. Aqui está um [exemplo particularmente impressionante](https://codepen.io/dissimulate/pen/KrAwx).
## Carregar e desenhar um recurso de imagem
@ -87,7 +87,7 @@ img.onload = () => {
### Padrão de carregamento de recurso
É recomendado encapsular o código acima em uma estrutura como esta, para que seja mais fácil de usar e você só tente manipulá-lo quando estiver totalmente carregado:
É recomendado encapsular o código acima em uma estrutura como esta, para facilitar o uso e garantir que você só tente manipulá-lo quando estiver completamente carregado:
```javascript
function loadAsset(path) {
@ -134,9 +134,9 @@ Você criará uma página web com um elemento Canvas. Ela deve renderizar uma te
![Nave do herói](../../../../translated_images/player.dd24c1afa8c71e9b82b2958946d4bad13308681392d4b5ddcc61a0e818ef8088.br.png)
- Nave dos monstros 5*5
- Nave inimiga 5*5
![Nave dos monstros](../../../../translated_images/enemyShip.5df2a822c16650c2fb3c06652e8ec8120cdb9122a6de46b9a1a56d54db22657f.br.png)
![Nave inimiga](../../../../translated_images/enemyShip.5df2a822c16650c2fb3c06652e8ec8120cdb9122a6de46b9a1a56d54db22657f.br.png)
### Passos recomendados para começar o desenvolvimento
@ -160,7 +160,7 @@ cd your-work
npm start
```
O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`. Abra um navegador e insira esse endereço. É uma página em branco agora, mas isso vai mudar.
O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`. Abra um navegador e insira esse endereço. É uma página em branco por enquanto, mas isso vai mudar.
> Nota: para ver as alterações na tela, atualize seu navegador.
@ -169,13 +169,13 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
Adicione o código necessário em `your-work/app.js` para resolver o seguinte:
1. **Desenhar** um canvas com fundo preto
> dica: adicione duas linhas sob o TODO apropriado em `/app.js`, configurando o elemento `ctx` para ser preto e as coordenadas superior/esquerda para 0,0, e a altura e largura para igualar às do canvas.
> dica: adicione duas linhas sob o TODO apropriado em `/app.js`, configurando o elemento `ctx` para ser preto e as coordenadas superior/esquerda para 0,0, com altura e largura iguais às do canvas.
2. **Carregar** texturas
> dica: adicione as imagens do jogador e dos inimigos usando `await loadTexture` e passando o caminho da imagem. Você ainda não verá elas na tela!
3. **Desenhar** o herói no centro da tela na metade inferior
> dica: use a API `drawImage` para desenhar heroImg na tela, configurando `canvas.width / 2 - 45` e `canvas.height - canvas.height / 4)`.
4. **Desenhar** monstros 5*5
> dica: agora você pode descomentar o código para desenhar os inimigos na tela. Em seguida, vá para a função `createEnemies` e desenvolva-a.
4. **Desenhar** 5*5 monstros
> dica: agora você pode descomentar o código para desenhar inimigos na tela. Em seguida, vá para a função `createEnemies` e desenvolva-a.
Primeiro, configure algumas constantes:
@ -200,11 +200,11 @@ Adicione o código necessário em `your-work/app.js` para resolver o seguinte:
O resultado final deve se parecer com isto:
![Tela preta com um herói e monstros 5*5](../../../../translated_images/partI-solution.36c53b48c9ffae2a5e15496b23b604ba5393433e4bf91608a7a0a020eb7a2691.br.png)
![Tela preta com um herói e 5*5 monstros](../../../../translated_images/partI-solution.36c53b48c9ffae2a5e15496b23b604ba5393433e4bf91608a7a0a020eb7a2691.br.png)
## Solução
Tente resolver sozinho primeiro, mas se ficar preso, dê uma olhada em uma [solução](../../../../6-space-game/2-drawing-to-canvas/solution/app.js).
Tente resolver sozinho primeiro, mas se ficar preso, veja uma [solução](../../../../6-space-game/2-drawing-to-canvas/solution/app.js).
---
@ -224,5 +224,7 @@ Saiba mais sobre a API Canvas [lendo sobre ela](https://developer.mozilla.org/do
[Brinque com a API Canvas](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional feita por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "23f088add24f0f1fa51014a9e27ea280",
"translation_date": "2025-08-25T22:12:57+00:00",
"original_hash": "a9a161871de7706cb0e23b1bd0c74559",
"translation_date": "2025-08-28T23:51:59+00:00",
"source_file": "6-space-game/3-moving-elements-around/README.md",
"language_code": "br"
}
@ -13,20 +13,20 @@ CO_OP_TRANSLATOR_METADATA:
[Quiz pré-aula](https://ff-quizzes.netlify.app/web/quiz/33)
Jogos não são muito divertidos até que você tenha alienígenas se movendo na tela! Neste jogo, utilizaremos dois tipos de movimentos:
Jogos não são muito divertidos até que você tenha alienígenas se movendo pela tela! Neste jogo, utilizaremos dois tipos de movimentos:
- **Movimento por teclado/mouse**: quando o usuário interage com o teclado ou mouse para mover um objeto na tela.
- **Movimento induzido pelo jogo**: quando o jogo move um objeto em um determinado intervalo de tempo.
Então, como movemos coisas na tela? Tudo se resume a coordenadas cartesianas: mudamos a localização (x, y) do objeto e, em seguida, redesenhamos a tela.
Normalmente, você precisa das seguintes etapas para realizar o *movimento* na tela:
Normalmente, você precisa dos seguintes passos para realizar o *movimento* na tela:
1. **Definir uma nova localização** para um objeto; isso é necessário para que o objeto pareça ter se movido.
2. **Limpar a tela**, a tela precisa ser limpa entre os desenhos. Podemos limpá-la desenhando um retângulo preenchido com uma cor de fundo.
3. **Redesenhar o objeto** na nova localização. Fazendo isso, finalmente conseguimos mover o objeto de um local para outro.
Veja como isso pode parecer em código:
Veja como isso pode parecer no código:
```javascript
//set the hero's location
@ -41,11 +41,11 @@ ctx.drawImage(heroImg, hero.x, hero.y);
✅ Você consegue pensar em um motivo pelo qual redesenhar seu herói várias vezes por segundo pode gerar custos de desempenho? Leia sobre [alternativas para este padrão](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas).
## Manipular eventos de teclado
## Manipulando eventos de teclado
Você manipula eventos conectando eventos específicos ao código. Eventos de teclado são acionados em toda a janela, enquanto eventos de mouse, como um `click`, podem ser conectados ao clique em um elemento específico. Usaremos eventos de teclado ao longo deste projeto.
Você manipula eventos anexando eventos específicos ao código. Eventos de teclado são acionados em toda a janela, enquanto eventos de mouse, como um `click`, podem ser conectados a um elemento específico. Usaremos eventos de teclado ao longo deste projeto.
Para manipular um evento, você precisa usar o método `addEventListener()` da janela e fornecer dois parâmetros de entrada. O primeiro parâmetro é o nome do evento, por exemplo, `keyup`. O segundo parâmetro é a função que deve ser invocada como resultado do evento ocorrer.
Para manipular um evento, você precisa usar o método `addEventListener()` da janela e fornecer dois parâmetros de entrada. O primeiro parâmetro é o nome do evento, por exemplo, `keyup`. O segundo parâmetro é a função que deve ser invocada como resultado do evento.
Aqui está um exemplo:
@ -60,14 +60,14 @@ window.addEventListener('keyup', (evt) => {
Para eventos de teclado, há duas propriedades no evento que você pode usar para ver qual tecla foi pressionada:
- `key`, esta é uma representação em string da tecla pressionada, por exemplo, `ArrowUp`.
- `keyCode`, esta é uma representação numérica, por exemplo, `37`, que corresponde a `ArrowLeft`.
- `key`, que é uma representação em string da tecla pressionada, por exemplo, `ArrowUp`.
- `keyCode`, que é uma representação numérica, por exemplo, `37`, que corresponde a `ArrowLeft`.
Manipulação de eventos de teclado é útil fora do desenvolvimento de jogos. Quais outros usos você consegue pensar para esta técnica?
A manipulação de eventos de teclado é útil fora do desenvolvimento de jogos. Em que outros usos você consegue pensar para essa técnica?
### Teclas especiais: um alerta
Existem algumas teclas *especiais* que afetam a janela. Isso significa que, se você estiver ouvindo um evento `keyup` e usar essas teclas especiais para mover seu herói, também ocorrerá rolagem horizontal. Por esse motivo, você pode querer *desativar* esse comportamento padrão do navegador enquanto desenvolve seu jogo. Você precisa de um código como este:
Existem algumas teclas *especiais* que afetam a janela. Isso significa que, se você estiver ouvindo um evento `keyup` e usar essas teclas especiais para mover seu herói, isso também realizará o deslocamento horizontal. Por esse motivo, você pode querer *desativar* esse comportamento padrão do navegador ao construir seu jogo. Você precisará de um código como este:
```javascript
let onKeyDown = function (e) {
@ -88,7 +88,7 @@ let onKeyDown = function (e) {
window.addEventListener('keydown', onKeyDown);
```
O código acima garantirá que as teclas de seta e a tecla de espaço tenham seu comportamento *padrão* desativado. O mecanismo de *desativação* ocorre quando chamamos `e.preventDefault()`.
O código acima garantirá que as teclas de seta e a barra de espaço tenham seu comportamento *padrão* desativado. O mecanismo de *desativação* ocorre quando chamamos `e.preventDefault()`.
## Movimento induzido pelo jogo
@ -103,7 +103,7 @@ let id = setInterval(() => {
## O loop do jogo
O loop do jogo é um conceito que, essencialmente, é uma função invocada em intervalos regulares. É chamado de loop do jogo porque tudo o que deve ser visível para o usuário é desenhado dentro do loop. O loop do jogo utiliza todos os objetos do jogo que fazem parte dele, desenhando todos eles, a menos que, por algum motivo, não devam mais fazer parte do jogo. Por exemplo, se um objeto é um inimigo que foi atingido por um laser e explodiu, ele não faz mais parte do loop atual do jogo (você aprenderá mais sobre isso em lições subsequentes).
O loop do jogo é um conceito que é essencialmente uma função invocada em intervalos regulares. É chamado de loop do jogo porque tudo o que deve ser visível para o usuário é desenhado dentro do loop. O loop do jogo utiliza todos os objetos do jogo que fazem parte dele, desenhando todos eles, a menos que, por algum motivo, não devam mais fazer parte do jogo. Por exemplo, se um objeto for um inimigo atingido por um laser e explodir, ele não faz mais parte do loop atual do jogo (você aprenderá mais sobre isso em lições subsequentes).
Veja como um loop de jogo pode ser tipicamente expresso em código:
@ -119,7 +119,7 @@ let gameLoopId = setInterval(() =>
}, 200);
```
O loop acima é invocado a cada `200` milissegundos para redesenhar o canvas. Você tem a capacidade de escolher o melhor intervalo que faz sentido para o seu jogo.
O loop acima é invocado a cada `200` milissegundos para redesenhar o canvas. Você pode escolher o melhor intervalo que faça sentido para o seu jogo.
## Continuando o Jogo Espacial
@ -128,7 +128,7 @@ Você pegará o código existente e o expandirá. Comece com o código que você
- **Movendo o herói**: você adicionará código para garantir que pode mover o herói usando as teclas de seta.
- **Mover inimigos**: você também precisará adicionar código para garantir que os inimigos se movam de cima para baixo em uma determinada taxa.
## Etapas recomendadas
## Passos recomendados
Localize os arquivos que foram criados para você na subpasta `your-work`. Ela deve conter o seguinte:
@ -148,15 +148,15 @@ cd your-work
npm start
```
O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`. Abra um navegador e insira esse endereço; neste momento, ele deve renderizar o herói e todos os inimigos; nada está se movendo - ainda!
O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`. Abra um navegador e insira esse endereço. No momento, ele deve renderizar o herói e todos os inimigos; nada está se movendo - ainda!
### Adicionar código
### Adicione código
1. **Adicione objetos dedicados** para `hero`, `enemy` e `game object`, eles devem ter propriedades `x` e `y`. (Lembre-se da parte sobre [Herança ou composição](../README.md)).
1. **Adicione objetos dedicados** para `hero`, `enemy` e `game object`, eles devem ter propriedades `x` e `y`. (Lembre-se da seção sobre [Herança ou composição](../README.md)).
*DICA*: `game object` deve ser aquele com `x` e `y` e a capacidade de se desenhar em um canvas.
*DICA*: `game object` deve ser o que possui `x` e `y` e a capacidade de se desenhar em um canvas.
> dica: comece adicionando uma nova classe GameObject com seu construtor delineado como abaixo e, em seguida, desenhe-a no canvas:
> dica: comece adicionando uma nova classe GameObject com seu construtor delineado como abaixo, e depois desenhe-a no canvas:
```javascript
@ -209,7 +209,7 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
*LEMBRE-SE*: é um sistema cartesiano, o canto superior esquerdo é `0,0`. Também lembre-se de adicionar código para interromper o *comportamento padrão*.
> dica: crie sua função onKeyDown e conecte-a à janela:
> dica: crie sua função onKeyDown e anexe-a à janela:
```javascript
let onKeyDown = function (e) {
@ -223,11 +223,11 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
Verifique o console do navegador neste ponto e observe as teclas sendo registradas.
3. **Implemente** o [Padrão Pub/Sub](../README.md), isso manterá seu código limpo enquanto você segue as partes restantes.
3. **Implemente** o [Padrão Pub/Sub](../README.md), isso manterá seu código limpo enquanto você segue as próximas partes.
Para fazer esta última parte, você pode:
1. **Adicionar um listener de eventos** na janela:
1. **Adicionar um ouvinte de eventos** na janela:
```javascript
window.addEventListener("keyup", (evt) => {
@ -334,7 +334,7 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
};
```
5. **Adicione código** para mover inimigos em um determinado intervalo
5. **Adicione código** para mover inimigos em um determinado intervalo.
Refatore a função `createEnemies()` para criar os inimigos e empurrá-los para a nova classe gameObjects:
@ -368,7 +368,7 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
}
```
e, finalmente, adicione uma função `drawGameObjects()` para iniciar o desenho:
e, finalmente, adicione uma função `drawGameObjects()` para começar a desenhar:
```javascript
function drawGameObjects(ctx) {
@ -376,25 +376,27 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
}
```
Seus inimigos devem começar a avançar em direção à sua nave espacial!
Seus inimigos devem começar a avançar em direção à sua nave espacial herói!
---
## 🚀 Desafio
Como você pode ver, seu código pode se transformar em 'código espaguete' quando você começa a adicionar funções, variáveis e classes. Como você pode organizar melhor seu código para que ele seja mais legível? Esboce um sistema para organizar seu código, mesmo que ele ainda esteja em um único arquivo.
Como você pode ver, seu código pode se transformar em um 'código espaguete' quando você começa a adicionar funções, variáveis e classes. Como você pode organizar melhor seu código para que ele seja mais legível? Esboce um sistema para organizar seu código, mesmo que ele ainda resida em um único arquivo.
## Quiz Pós-Aula
[Quiz pós-aula](https://ff-quizzes.netlify.app/web/quiz/34)
## Revisão & Autoestudo
## Revisão e Autoestudo
Embora estejamos escrevendo nosso jogo sem usar frameworks, existem muitos frameworks baseados em JavaScript para desenvolvimento de jogos com canvas. Reserve um tempo para fazer [leitura sobre eles](https://github.com/collections/javascript-game-engines).
Embora estejamos escrevendo nosso jogo sem usar frameworks, existem muitos frameworks baseados em JavaScript para desenvolvimento de jogos com canvas. Reserve um tempo para fazer algumas [leituras sobre eles](https://github.com/collections/javascript-game-engines).
## Tarefa
[Comente seu código](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "2e83e38c35dc003f046d7cc0bbfd4920",
"translation_date": "2025-08-25T22:24:41+00:00",
"original_hash": "a6ce295ff03bb49df7a3e17e6e7100a0",
"translation_date": "2025-08-28T23:52:39+00:00",
"source_file": "6-space-game/4-collision-detection/README.md",
"language_code": "br"
}
@ -16,11 +16,11 @@ CO_OP_TRANSLATOR_METADATA:
Nesta lição, você aprenderá a disparar lasers com JavaScript! Vamos adicionar dois elementos ao nosso jogo:
- **Um laser**: este laser será disparado da nave do herói e seguirá verticalmente para cima.
- **Detecção de colisões**, como parte da implementação da habilidade de *atirar*, também adicionaremos algumas regras interessantes ao jogo:
- **Laser atinge inimigo**: O inimigo é destruído se for atingido por um laser.
- **Laser atinge o topo da tela**: O laser é destruído se atingir a parte superior da tela.
- **Colisão entre inimigo e herói**: Tanto o inimigo quanto o herói são destruídos se colidirem.
- **Inimigo atinge a parte inferior da tela**: Tanto o inimigo quanto o herói são destruídos se o inimigo atingir a parte inferior da tela.
- **Detecção de colisões**: como parte da implementação da habilidade de *atirar*, também adicionaremos algumas regras interessantes ao jogo:
- **Laser atinge inimigo**: o inimigo é destruído se for atingido por um laser.
- **Laser atinge o topo da tela**: o laser é destruído se atingir a parte superior da tela.
- **Colisão entre inimigo e herói**: o inimigo e o herói são destruídos se colidirem.
- **Inimigo atinge a parte inferior da tela**: o inimigo e o herói são destruídos se o inimigo atingir a parte inferior da tela.
Resumindo, você -- *o herói* -- precisa atingir todos os inimigos com um laser antes que eles consigam chegar à parte inferior da tela.
@ -58,9 +58,9 @@ Se dois retângulos, ou seja, um herói e um inimigo, *se cruzarem*, temos uma c
}
```
## Como destruir objetos
## Como destruir coisas
Para destruir objetos em um jogo, você precisa informar ao jogo que ele não deve mais desenhar esse item no loop do jogo que é acionado em um determinado intervalo. Uma maneira de fazer isso é marcar um objeto do jogo como *morto* quando algo acontece, assim:
Para destruir coisas em um jogo, você precisa informar ao jogo que ele não deve mais desenhar esse item no loop do jogo que é acionado em um determinado intervalo. Uma maneira de fazer isso é marcar um objeto do jogo como *morto* quando algo acontece, assim:
```javascript
// collision happened
@ -75,15 +75,15 @@ gameObjects = gameObject.filter(go => !go.dead);
## Como disparar um laser
Disparar um laser significa responder a um evento de tecla e criar um objeto que se move em uma determinada direção. Precisamos realizar os seguintes passos:
Disparar um laser significa responder a um evento de tecla e criar um objeto que se move em uma determinada direção. Precisamos, portanto, realizar os seguintes passos:
1. **Criar um objeto laser**: que parte do topo da nave do herói e, ao ser criado, começa a se mover para cima em direção ao topo da tela.
1. **Criar um objeto laser**: a partir do topo da nave do herói, que ao ser criado começa a se mover para cima em direção ao topo da tela.
2. **Vincular código a um evento de tecla**: precisamos escolher uma tecla no teclado que represente o jogador disparando o laser.
3. **Criar um objeto do jogo que pareça um laser** quando a tecla for pressionada.
3. **Criar um objeto do jogo que se pareça com um laser** quando a tecla for pressionada.
## Tempo de recarga do laser
O laser precisa ser disparado toda vez que você pressionar uma tecla, como a barra de espaço, por exemplo. Para evitar que o jogo produza lasers em excesso em um curto período, precisamos corrigir isso. A solução é implementar um chamado *tempo de recarga*, um temporizador que garante que o laser só possa ser disparado em intervalos específicos. Você pode implementar isso da seguinte forma:
O laser precisa ser disparado toda vez que você pressionar uma tecla, como *espaço*, por exemplo. Para evitar que o jogo produza lasers em excesso em um curto período de tempo, precisamos corrigir isso. A solução é implementar um chamado *tempo de recarga*, um temporizador, que garante que um laser só possa ser disparado em intervalos específicos. Você pode implementar isso da seguinte forma:
```javascript
class Cooldown {
@ -113,7 +113,7 @@ class Weapon {
## O que construir
Você usará o código existente (que deve ter sido limpo e refatorado) da lição anterior e o estenderá. Comece com o código da parte II ou use o código em [Parte III - inicial](../../../../../../../../../your-work).
Você usará o código existente (que você deve ter organizado e refatorado) da lição anterior e o estenderá. Comece com o código da parte II ou use o código em [Parte III - inicial](../../../../../../../../../your-work).
> dica: o laser com o qual você trabalhará já está na sua pasta de ativos e referenciado pelo seu código.
@ -183,7 +183,7 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",
```
1. **Manipule a tecla espaço**. Edite a função `window.addEventListener` para lidar com a tecla espaço:
1. **Manipule a tecla espaço**. Edite a função `window.addEventListener` keyup para lidar com espaços:
```javascript
} else if(evt.keyCode === 32) {
@ -191,7 +191,7 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
}
```
1. **Adicione ouvintes de eventos**. Edite a função `initGame()` para garantir que o herói possa disparar quando a barra de espaço for pressionada:
1. **Adicione ouvintes**. Edite a função `initGame()` para garantir que o herói possa disparar quando a barra de espaço for pressionada:
```javascript
eventEmitter.on(Messages.KEY_EVENT_SPACE, () => {
@ -230,7 +230,7 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
}
```
1. **Manipule colisões**, Implemente as regras de colisão para o laser. Adicione uma função `updateGameObjects()` que testa objetos colidindo:
1. **Manipule colisões**, Implemente as regras de colisão para o laser. Adicione uma função `updateGameObjects()` que testa objetos colidindo para detectar impactos:
```javascript
function updateGameObjects() {
@ -305,5 +305,7 @@ Experimente os intervalos no seu jogo até agora. O que acontece quando você os
[Explore colisões](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "4e8250db84b027c9ff816b4e4c093457",
"translation_date": "2025-08-25T22:05:17+00:00",
"original_hash": "adda95e02afa3fbee67b6e385b1109e1",
"translation_date": "2025-08-28T23:52:25+00:00",
"source_file": "6-space-game/5-keeping-score/README.md",
"language_code": "br"
}
@ -17,7 +17,7 @@ Nesta lição, você aprenderá como adicionar pontuação a um jogo e calcular
## Exibir texto na tela
Para exibir a pontuação do jogo na tela, você precisará saber como posicionar texto. A resposta é usar o método `fillText()` no objeto canvas. Você também pode controlar outros aspectos, como qual fonte usar, a cor do texto e até mesmo seu alinhamento (esquerda, direita, centro). Abaixo está um código que desenha texto na tela.
Para exibir a pontuação do jogo na tela, você precisará saber como colocar texto na tela. A resposta é usar o método `fillText()` no objeto canvas. Você também pode controlar outros aspectos, como qual fonte usar, a cor do texto e até mesmo seu alinhamento (esquerda, direita, centro). Abaixo está um código que desenha texto na tela.
```javascript
ctx.font = "30px Arial";
@ -30,14 +30,14 @@ ctx.fillText("show this on the screen", 0, 0);
## Vida, como um conceito de jogo
O conceito de ter vidas em um jogo é apenas um número. No contexto de um jogo espacial, é comum atribuir um conjunto de vidas que são reduzidas uma a uma quando sua nave sofre dano. É interessante mostrar uma representação gráfica disso, como mini-naves ou corações, em vez de apenas um número.
O conceito de ter vidas em um jogo é apenas um número. No contexto de um jogo espacial, é comum atribuir um conjunto de vidas que são deduzidas uma a uma quando sua nave sofre dano. É interessante mostrar uma representação gráfica disso, como mini-naves ou corações, em vez de apenas um número.
## O que construir
Vamos adicionar o seguinte ao seu jogo:
- **Pontuação do jogo**: Para cada nave inimiga destruída, o herói deve ganhar alguns pontos. Sugerimos 100 pontos por nave. A pontuação do jogo deve ser exibida no canto inferior esquerdo.
- **Vida**: Sua nave tem três vidas. Você perde uma vida toda vez que uma nave inimiga colide com você. A pontuação de vidas deve ser exibida no canto inferior direito e ser composta pelo seguinte gráfico ![imagem de vida](../../../../translated_images/life.6fb9f50d53ee0413cd91aa411f7c296e10a1a6de5c4a4197c718b49bf7d63ebf.br.png).
- **Vidas**: Sua nave tem três vidas. Você perde uma vida toda vez que uma nave inimiga colide com você. A contagem de vidas deve ser exibida no canto inferior direito e ser composta pelo seguinte gráfico ![imagem de vida](../../../../translated_images/life.6fb9f50d53ee0413cd91aa411f7c296e10a1a6de5c4a4197c718b49bf7d63ebf.br.png).
## Passos recomendados
@ -64,7 +64,7 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
### Adicionar código
1. **Copie os recursos necessários** da pasta `solution/assets/` para a pasta `your-work`; você adicionará o recurso `life.png`. Adicione o `lifeImg` à função `window.onload`:
1. **Copie os recursos necessários** da pasta `solution/assets/` para a pasta `your-work`; você adicionará o recurso `life.png`. Adicione o `lifeImg` à função window.onload:
```javascript
lifeImg = await loadTexture("assets/life.png");
@ -82,7 +82,7 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
2. **Adicione variáveis**. Adicione código que represente sua pontuação total (0) e vidas restantes (3), exibindo essas pontuações na tela.
3. **Estenda a função `updateGameObjects()`**. Estenda a função `updateGameObjects()` para lidar com colisões com inimigos:
3. **Estenda a função `updateGameObjects()`**. Estenda a função `updateGameObjects()` para lidar com colisões de inimigos:
```javascript
enemies.forEach(enemy => {
@ -93,8 +93,8 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
})
```
4. **Adicione `vida` e `pontos`**.
1. **Inicialize variáveis**. Sob `this.cooldown = 0` na classe `Hero`, defina vida e pontos:
4. **Adicione `vidas` e `pontos`**.
1. **Inicialize variáveis**. Sob `this.cooldown = 0` na classe `Hero`, defina vidas e pontos:
```javascript
this.life = 3;
@ -128,14 +128,14 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
```
1. **Adicione métodos ao loop do jogo**. Certifique-se de adicionar essas funções à sua função `window.onload` sob `updateGameObjects()`:
1. **Adicione métodos ao loop do jogo**. Certifique-se de adicionar essas funções à sua função window.onload sob `updateGameObjects()`:
```javascript
drawPoints();
drawLife();
```
1. **Implemente as regras do jogo**. Implemente as seguintes regras:
1. **Implemente as regras do jogo**. Implemente as seguintes regras do jogo:
1. **Para cada colisão entre herói e inimigo**, deduza uma vida.
@ -152,7 +152,7 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
2. **Para cada laser que atinge um inimigo**, aumente a pontuação do jogo em 100 pontos.
Estenda a classe `Hero` para realizar esse incremento:
Estenda a classe Hero para realizar esse incremento:
```javascript
incrementPoints() {
@ -177,7 +177,7 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
✅ Faça uma pequena pesquisa para descobrir outros jogos criados usando JavaScript/Canvas. Quais são suas características comuns?
Ao final deste trabalho, você deverá ver as pequenas naves de "vida" no canto inferior direito, os pontos no canto inferior esquerdo, e deverá ver sua contagem de vidas diminuir ao colidir com inimigos e seus pontos aumentarem ao atirar nos inimigos. Muito bem! Seu jogo está quase completo.
Ao final deste trabalho, você deverá ver as pequenas naves de 'vida' no canto inferior direito, os pontos no canto inferior esquerdo, e deverá ver sua contagem de vidas diminuir conforme colide com inimigos e sua pontuação aumentar ao atirar nos inimigos. Muito bem! Seu jogo está quase completo.
---
@ -197,5 +197,7 @@ Pesquise algumas maneiras de incrementar e decrementar pontuações e vidas em j
[Construa um Jogo de Pontuação](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,26 +1,26 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "01336cddd638242e99b133614111ea40",
"translation_date": "2025-08-25T22:36:53+00:00",
"original_hash": "05be6c37791668e3719c4fba94566367",
"translation_date": "2025-08-28T23:53:22+00:00",
"source_file": "6-space-game/6-end-condition/README.md",
"language_code": "br"
}
-->
# Construindo um Jogo Espacial Parte 6: Final e Reinício
# Construir um Jogo Espacial Parte 6: Finalizar e Reiniciar
## Quiz Pré-Aula
## Questionário Pré-Aula
[Quiz pré-aula](https://ff-quizzes.netlify.app/web/quiz/39)
[Questionário pré-aula](https://ff-quizzes.netlify.app/web/quiz/39)
Existem diferentes maneiras de expressar uma *condição de término* em um jogo. Cabe a você, como criador do jogo, decidir por que o jogo terminou. Aqui estão algumas razões, assumindo que estamos falando sobre o jogo espacial que você tem construído até agora:
- **`N` Naves inimigas foram destruídas**: É bastante comum, se você dividir um jogo em diferentes níveis, que seja necessário destruir `N` naves inimigas para completar um nível.
- **Sua nave foi destruída**: Existem jogos em que você perde se sua nave for destruída. Outra abordagem comum é o conceito de vidas. Cada vez que sua nave é destruída, uma vida é deduzida. Quando todas as vidas forem perdidas, você perde o jogo.
- **Você coletou `N` pontos**: Outra condição comum de término é coletar pontos. Como você ganha pontos depende de você, mas é bastante comum atribuir pontos a várias atividades, como destruir uma nave inimiga ou coletar itens que caem quando são destruídos.
- **Sua nave foi destruída**: Existem jogos em que você perde se sua nave for destruída. Outra abordagem comum é o conceito de vidas. Cada vez que sua nave é destruída, uma vida é deduzida. Quando todas as vidas são perdidas, o jogo termina.
- **Você coletou `N` pontos**: Outra condição comum de término é coletar pontos. Como você ganha pontos depende de você, mas é comum atribuir pontos a várias atividades, como destruir uma nave inimiga ou coletar itens que são *soltos* quando destruídos.
- **Completar um nível**: Isso pode envolver várias condições, como destruir `X` naves inimigas, coletar `Y` pontos ou talvez coletar um item específico.
## Reinício
## Reiniciar
Se as pessoas gostarem do seu jogo, é provável que queiram jogá-lo novamente. Quando o jogo termina, por qualquer motivo, você deve oferecer uma alternativa para reiniciá-lo.
@ -33,7 +33,7 @@ Você adicionará estas regras ao seu jogo:
1. **Vencer o jogo**. Quando todas as naves inimigas forem destruídas, você vence o jogo. Além disso, exiba algum tipo de mensagem de vitória.
1. **Reiniciar**. Quando todas as suas vidas forem perdidas ou o jogo for vencido, você deve oferecer uma maneira de reiniciar o jogo. Lembre-se! Você precisará reinicializar o jogo e limpar o estado anterior.
## Passos recomendados
## Etapas recomendadas
Localize os arquivos que foram criados para você na subpasta `your-work`. Ela deve conter o seguinte:
@ -48,7 +48,7 @@ Localize os arquivos que foram criados para você na subpasta `your-work`. Ela d
-| package.json
```
Você inicia seu projeto na pasta `your_work` digitando:
Inicie seu projeto na pasta `your_work` digitando:
```bash
cd your-work
@ -61,7 +61,7 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
### Adicionar código
1. **Rastrear condição de término**. Adicione código que rastreie o número de inimigos ou se a nave do herói foi destruída, adicionando estas duas funções:
1. **Acompanhar a condição de término**. Adicione código que acompanhe o número de inimigos ou se a nave do herói foi destruída, adicionando estas duas funções:
```javascript
function isHeroDead() {
@ -115,9 +115,9 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
GAME_END_WIN: "GAME_END_WIN",
```
2. **Adicionar código de reinício** que reinicia o jogo ao pressionar um botão selecionado.
2. **Adicionar código de reinício** que reinicie o jogo ao pressionar um botão selecionado.
1. **Ouvir a tecla `Enter`**. Edite o eventListener da janela para ouvir essa tecla:
1. **Ouvir a tecla `Enter`**. Edite o eventListener da sua janela para ouvir essa tecla:
```javascript
else if(evt.key === "Enter") {
@ -171,7 +171,7 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
}
```
1. **Lógica de reinício**. Quando todas as vidas forem perdidas ou o jogador vencer o jogo, exiba que o jogo pode ser reiniciado. Além disso, reinicie o jogo quando a tecla de *reinício* for pressionada (você pode decidir qual tecla será mapeada para reinício).
1. **Lógica de reinício**. Quando todas as vidas forem perdidas ou o jogador vencer o jogo, exiba que o jogo pode ser reiniciado. Além disso, reinicie o jogo quando a tecla de *reinício* for pressionada (você pode decidir qual tecla será mapeada para reiniciar).
1. Crie a função `resetGame()`:
@ -216,11 +216,11 @@ O comando acima iniciará um servidor HTTP no endereço `http://localhost:5000`.
## 🚀 Desafio
Adicione um som! Você consegue adicionar um som para melhorar a experiência do jogo, talvez quando houver um disparo de laser, ou quando o herói morrer ou vencer? Confira este [sandbox](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_play) para aprender como tocar som usando JavaScript.
Adicione um som! Você consegue adicionar um som para melhorar a experiência do jogo? Talvez quando houver um disparo de laser, ou quando o herói morrer ou vencer? Dê uma olhada neste [sandbox](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_play) para aprender como tocar som usando JavaScript.
## Quiz Pós-Aula
## Questionário Pós-Aula
[Quiz pós-aula](https://ff-quizzes.netlify.app/web/quiz/40)
[Questionário pós-aula](https://ff-quizzes.netlify.app/web/quiz/40)
## Revisão e Autoestudo
@ -230,5 +230,7 @@ Sua tarefa é criar um novo jogo de exemplo, então explore alguns jogos interes
[Crie um Jogo de Exemplo](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,27 +1,27 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "8da1b5e2c63f749808858c53f37b8ce7",
"translation_date": "2025-08-26T00:35:38+00:00",
"original_hash": "8a07db14e75ac62f013b7de5df05981d",
"translation_date": "2025-08-28T23:49:31+00:00",
"source_file": "7-bank-project/1-template-route/README.md",
"language_code": "br"
}
-->
# Construindo um App Bancário Parte 1: Templates HTML e Rotas em um Aplicativo Web
## Questionário Pré-Aula
## Quiz Pré-Aula
[Questionário pré-aula](https://ff-quizzes.netlify.app/web/quiz/41)
[Quiz pré-aula](https://ff-quizzes.netlify.app/web/quiz/41)
### Introdução
Desde o surgimento do JavaScript nos navegadores, os sites estão se tornando mais interativos e complexos do que nunca. As tecnologias web agora são comumente usadas para criar aplicativos totalmente funcionais que rodam diretamente no navegador, conhecidos como [aplicativos web](https://en.wikipedia.org/wiki/Web_application). Como os aplicativos web são altamente interativos, os usuários não querem esperar por um recarregamento completo da página toda vez que uma ação é realizada. Por isso, o JavaScript é usado para atualizar o HTML diretamente através do DOM, proporcionando uma experiência de usuário mais fluida.
Desde o surgimento do JavaScript nos navegadores, os sites estão se tornando mais interativos e complexos do que nunca. As tecnologias web agora são comumente usadas para criar aplicativos totalmente funcionais que rodam diretamente no navegador, chamados de [aplicativos web](https://en.wikipedia.org/wiki/Web_application). Como os aplicativos web são altamente interativos, os usuários não querem esperar por um recarregamento completo da página toda vez que uma ação é realizada. É por isso que o JavaScript é usado para atualizar o HTML diretamente usando o DOM, proporcionando uma experiência mais fluida para o usuário.
Nesta lição, vamos estabelecer as bases para criar um aplicativo bancário web, utilizando templates HTML para criar múltiplas telas que podem ser exibidas e atualizadas sem a necessidade de recarregar toda a página HTML.
Nesta lição, vamos estabelecer as bases para criar um aplicativo bancário web, utilizando templates HTML para criar múltiplas telas que podem ser exibidas e atualizadas sem precisar recarregar toda a página HTML.
### Pré-requisitos
Você precisa de um servidor web local para testar o aplicativo web que construiremos nesta lição. Caso não tenha um, você pode instalar o [Node.js](https://nodejs.org) e usar o comando `npx lite-server` a partir da pasta do seu projeto. Isso criará um servidor web local e abrirá seu aplicativo em um navegador.
Você precisa de um servidor web local para testar o aplicativo web que construiremos nesta lição. Se você não tiver um, pode instalar o [Node.js](https://nodejs.org) e usar o comando `npx lite-server` na pasta do seu projeto. Isso criará um servidor web local e abrirá seu aplicativo em um navegador.
### Preparação
@ -45,22 +45,22 @@ No seu computador, crie uma pasta chamada `bank` com um arquivo chamado `index.h
## Templates HTML
Se você quiser criar múltiplas telas para uma página web, uma solução seria criar um arquivo HTML para cada tela que deseja exibir. No entanto, essa solução apresenta alguns inconvenientes:
Se você quiser criar múltiplas telas para uma página web, uma solução seria criar um arquivo HTML para cada tela que deseja exibir. No entanto, essa solução traz algumas inconveniências:
- É necessário recarregar todo o HTML ao alternar entre telas, o que pode ser lento.
- Você precisa recarregar todo o HTML ao trocar de tela, o que pode ser lento.
- É difícil compartilhar dados entre as diferentes telas.
Outra abordagem é ter apenas um arquivo HTML e definir múltiplos [templates HTML](https://developer.mozilla.org/docs/Web/HTML/Element/template) usando o elemento `<template>`. Um template é um bloco HTML reutilizável que não é exibido pelo navegador e precisa ser instanciado em tempo de execução usando JavaScript.
### Tarefa
Vamos criar um aplicativo bancário com duas telas: a página de login e o painel (dashboard). Primeiro, vamos adicionar no corpo do HTML um elemento placeholder que usaremos para instanciar as diferentes telas do nosso aplicativo:
Vamos criar um aplicativo bancário com duas telas: a página de login e o painel de controle. Primeiro, vamos adicionar no corpo do HTML um elemento placeholder que usaremos para instanciar as diferentes telas do nosso aplicativo:
```html
<div id="app">Loading...</div>
```
Estamos atribuindo um `id` a ele para facilitar sua localização com JavaScript mais tarde.
Estamos dando a ele um `id` para facilitar sua localização com JavaScript mais tarde.
> Dica: como o conteúdo deste elemento será substituído, podemos colocar uma mensagem ou indicador de carregamento que será exibido enquanto o aplicativo está carregando.
@ -75,9 +75,9 @@ Em seguida, vamos adicionar abaixo o template HTML para a página de login. Por
</template>
```
Depois, adicionaremos outro template HTML para a página do painel. Esta página conterá diferentes seções:
Depois, adicionaremos outro template HTML para a página do painel de controle. Esta página conterá diferentes seções:
- Um cabeçalho com um título e um link para logout
- Um cabeçalho com um título e um link de logout
- O saldo atual da conta bancária
- Uma lista de transações, exibida em uma tabela
@ -106,13 +106,13 @@ Depois, adicionaremos outro template HTML para a página do painel. Esta página
</template>
```
> Dica: ao criar templates HTML, se você quiser ver como eles ficarão, pode comentar as linhas `<template>` e `</template>` envolvendo-as com `<!-- -->`.
> Dica: ao criar templates HTML, se você quiser ver como eles ficarão, pode comentar as linhas `<template>` e `</template>` usando `<!-- -->`.
✅ Por que você acha que usamos atributos `id` nos templates? Poderíamos usar algo como classes?
## Exibindo templates com JavaScript
Se você tentar abrir seu arquivo HTML atual em um navegador, verá que ele fica travado exibindo `Loading...`. Isso acontece porque precisamos adicionar algum código JavaScript para instanciar e exibir os templates HTML.
Se você testar seu arquivo HTML atual em um navegador, verá que ele fica preso exibindo `Loading...`. Isso acontece porque precisamos adicionar algum código JavaScript para instanciar e exibir os templates HTML.
Instanciar um template geralmente é feito em 3 etapas:
@ -142,7 +142,7 @@ function updateRoute(templateId) {
}
```
O que fazemos aqui são exatamente os 3 passos descritos acima. Instanciamos o template com o `id` `templateId` e colocamos seu conteúdo clonado dentro do nosso placeholder do aplicativo. Note que precisamos usar `cloneNode(true)` para copiar toda a subárvore do template.
O que fazemos aqui são exatamente as 3 etapas descritas acima. Instanciamos o template com o id `templateId` e colocamos seu conteúdo clonado dentro do nosso placeholder do aplicativo. Note que precisamos usar `cloneNode(true)` para copiar toda a subárvore do template.
Agora chame essa função com um dos templates e veja o resultado.
@ -154,7 +154,7 @@ updateRoute('login');
## Criando rotas
Quando falamos de um aplicativo web, chamamos de *Roteamento* a intenção de mapear **URLs** para telas específicas que devem ser exibidas. Em um site com múltiplos arquivos HTML, isso é feito automaticamente, pois os caminhos dos arquivos são refletidos na URL. Por exemplo, com esses arquivos na pasta do seu projeto:
Ao falar sobre um aplicativo web, chamamos de *Roteamento* a intenção de mapear **URLs** para telas específicas que devem ser exibidas. Em um site com múltiplos arquivos HTML, isso é feito automaticamente, pois os caminhos dos arquivos são refletidos na URL. Por exemplo, com esses arquivos na pasta do seu projeto:
```
mywebsite/index.html
@ -162,7 +162,7 @@ mywebsite/login.html
mywebsite/admin/index.html
```
Se você criar um servidor web com `mywebsite` como raiz, o mapeamento de URLs será:
Se você criar um servidor web com `mywebsite` como raiz, o mapeamento de URL será:
```
https://site.com --> mywebsite/index.html
@ -170,7 +170,7 @@ https://site.com/login.html --> mywebsite/login.html
https://site.com/admin/ --> mywebsite/admin/index.html
```
No entanto, para nosso aplicativo web, estamos usando um único arquivo HTML contendo todas as telas, então esse comportamento padrão não nos ajudará. Precisamos criar esse mapeamento manualmente e atualizar o template exibido usando JavaScript.
No entanto, para nosso aplicativo web, estamos usando um único arquivo HTML contendo todas as telas, então esse comportamento padrão não nos ajudará. Precisamos criar esse mapa manualmente e atualizar a tela exibida usando JavaScript.
### Tarefa
@ -213,7 +213,7 @@ Já cuidamos da segunda parte com a função `updateRoute`, então precisamos de
Teremos que usar JavaScript e, mais especificamente, o [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), que permite atualizar a URL e criar uma nova entrada no histórico de navegação, sem recarregar o HTML.
> Nota: Embora o elemento âncora HTML [`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a) possa ser usado sozinho para criar hiperlinks para diferentes URLs, ele fará o navegador recarregar o HTML por padrão. É necessário evitar esse comportamento ao lidar com roteamento usando JavaScript personalizado, utilizando a função `preventDefault()` no evento de clique.
> Nota: Embora o elemento âncora HTML [`<a href>`](https://developer.mozilla.org/docs/Web/HTML/Element/a) possa ser usado sozinho para criar hiperlinks para diferentes URLs, ele fará o navegador recarregar o HTML por padrão. É necessário evitar esse comportamento ao lidar com roteamento usando JavaScript personalizado, utilizando a função preventDefault() no evento de clique.
### Tarefa
@ -228,7 +228,7 @@ function navigate(path) {
Este método primeiro atualiza a URL atual com base no caminho fornecido e, em seguida, atualiza o template. A propriedade `window.location.origin` retorna a raiz da URL, permitindo-nos reconstruir uma URL completa a partir de um caminho fornecido.
Agora que temos essa função, podemos resolver o problema que temos se um caminho não corresponder a nenhuma rota definida. Vamos modificar a função `updateRoute` adicionando um fallback para uma das rotas existentes caso não consigamos encontrar uma correspondência.
Agora que temos essa função, podemos resolver o problema que temos se um caminho não corresponder a nenhuma rota definida. Vamos modificar a função `updateRoute` adicionando um fallback para uma das rotas existentes caso não possamos encontrar uma correspondência.
```js
function updateRoute() {
@ -244,7 +244,7 @@ function updateRoute() {
Se uma rota não puder ser encontrada, agora redirecionaremos para a página de `login`.
Agora vamos criar uma função para obter a URL quando um link for clicado e evitar o comportamento padrão do navegador para links:
Agora vamos criar uma função para obter a URL quando um link for clicado e evitar o comportamento padrão de links do navegador:
```js
function onLinkClick(event) {
@ -263,21 +263,21 @@ Vamos completar o sistema de navegação adicionando vinculações aos links de
O objeto `event` acima captura o evento de `click` e o passa para nossa função `onLinkClick`.
Usando o atributo [`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick), vinculamos o evento de `click` ao código JavaScript, aqui a chamada para a função `navigate()`.
Usando o atributo [`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick), vincule o evento de `click` ao código JavaScript, aqui a chamada para a função `navigate()`.
Tente clicar nesses links, agora você deve ser capaz de navegar entre as diferentes telas do seu aplicativo.
✅ O método `history.pushState` faz parte do padrão HTML5 e é implementado em [todos os navegadores modernos](https://caniuse.com/?search=pushState). Se você estiver criando um aplicativo web para navegadores mais antigos, há um truque que pode usar no lugar dessa API: utilizando um [hash (`#`)](https://en.wikipedia.org/wiki/URI_fragment) antes do caminho, você pode implementar um roteamento que funciona com navegação de âncoras regulares e não recarrega a página, já que seu propósito era criar links internos dentro de uma página.
✅ O método `history.pushState` faz parte do padrão HTML5 e é implementado em [todos os navegadores modernos](https://caniuse.com/?search=pushState). Se você estiver criando um aplicativo web para navegadores mais antigos, há um truque que pode usar no lugar dessa API: utilizando um [hash (`#`)](https://en.wikipedia.org/wiki/URI_fragment) antes do caminho, você pode implementar roteamento que funciona com navegação regular de âncoras e não recarrega a página, já que seu propósito era criar links internos dentro de uma página.
## Lidando com os botões de voltar e avançar do navegador
Usar o `history.pushState` cria novas entradas no histórico de navegação do navegador. Você pode verificar isso segurando o *botão de voltar* do navegador, ele deve exibir algo como isto:
Usar o `history.pushState` cria novas entradas no histórico de navegação do navegador. Você pode verificar isso segurando o botão *voltar* do navegador, ele deve exibir algo como isto:
![Captura de tela do histórico de navegação](../../../../translated_images/history.7fdabbafa521e06455b738d3dafa3ff41d3071deae60ead8c7e0844b9ed987d8.br.png)
Se você tentar clicar no botão de voltar algumas vezes, verá que a URL atual muda e o histórico é atualizado, mas o mesmo template continua sendo exibido.
Se você tentar clicar no botão voltar algumas vezes, verá que a URL atual muda e o histórico é atualizado, mas o mesmo template continua sendo exibido.
Isso acontece porque o aplicativo não sabe que precisamos chamar `updateRoute()` toda vez que o histórico muda. Se você der uma olhada na [documentação do `history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), verá que, se o estado mudar - ou seja, se nos movermos para uma URL diferente - o evento [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event) é acionado. Vamos usar isso para corrigir o problema.
Isso acontece porque o aplicativo não sabe que precisamos chamar `updateRoute()` toda vez que o histórico muda. Se você olhar a documentação do [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState), verá que, se o estado mudar - ou seja, se nos movemos para uma URL diferente - o evento [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event) é acionado. Vamos usar isso para corrigir o problema.
### Tarefa
@ -294,7 +294,7 @@ Aqui está um vídeo de revisão sobre funções arrow:
[![Funções Arrow](https://img.youtube.com/vi/OP6eEbOj2sc/0.jpg)](https://youtube.com/watch?v=OP6eEbOj2sc "Funções Arrow")
> 🎥 Clique na imagem acima para assistir a um vídeo sobre funções arrow.
> 🎥 Clique na imagem acima para um vídeo sobre funções arrow.
Agora tente usar os botões de voltar e avançar do navegador e verifique se a rota exibida é atualizada corretamente desta vez.
@ -304,17 +304,19 @@ Agora tente usar os botões de voltar e avançar do navegador e verifique se a r
Adicione um novo template e rota para uma terceira página que mostre os créditos deste aplicativo.
## Questionário Pós-Aula
## Quiz Pós-Aula
[Questionário pós-aula](https://ff-quizzes.netlify.app/web/quiz/42)
[Quiz pós-aula](https://ff-quizzes.netlify.app/web/quiz/42)
## Revisão e Autoestudo
O roteamento é uma das partes surpreendentemente complicadas do desenvolvimento web, especialmente à medida que a web se move de comportamentos de atualização de página para atualizações de página em Aplicativos de Página Única (SPA). Leia um pouco sobre [como o serviço Azure Static Web App](https://docs.microsoft.com/azure/static-web-apps/routes/?WT.mc_id=academic-77807-sagibbon) lida com roteamento. Você consegue explicar por que algumas das decisões descritas nesse documento são necessárias?
O roteamento é uma das partes surpreendentemente complicadas do desenvolvimento web, especialmente à medida que a web se move de comportamentos de atualização de página para atualizações de página em Aplicativos de Página Única. Leia um pouco sobre [como o serviço Azure Static Web App](https://docs.microsoft.com/azure/static-web-apps/routes/?WT.mc_id=academic-77807-sagibbon) lida com roteamento. Você consegue explicar por que algumas das decisões descritas nesse documento são necessárias?
## Tarefa
[Melhore o roteamento](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,13 +1,13 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "b667b7d601e2ee19acb5aa9d102dc9f3",
"translation_date": "2025-08-26T00:14:20+00:00",
"original_hash": "8baca047d77a5f43fa4099c0578afa42",
"translation_date": "2025-08-28T23:48:11+00:00",
"source_file": "7-bank-project/2-forms/README.md",
"language_code": "br"
}
-->
# Construindo um App Bancário Parte 2: Criando um Formulário de Login e Registro
# Construir um App Bancário Parte 2: Criar um Formulário de Login e Registro
## Quiz Pré-Aula
@ -26,7 +26,7 @@ Você precisa ter concluído a etapa de [templates HTML e roteamento](../1-templ
**Atenção**
Você terá dois terminais rodando ao mesmo tempo, conforme listado abaixo:
1. Para o aplicativo bancário principal que construímos na lição de [templates HTML e roteamento](../1-template-route/README.md)
2. Para a [API do servidor do App Bancário](../api/README.md) que acabamos de configurar acima.
2. Para a [API do servidor do aplicativo bancário](../api/README.md) que acabamos de configurar acima.
Você precisa que os dois servidores estejam funcionando para seguir o restante da lição. Eles escutam em portas diferentes (porta `3000` e porta `5000`), então tudo deve funcionar perfeitamente.
@ -41,7 +41,7 @@ curl http://localhost:5000/api
## Formulário e controles
O elemento `<form>` encapsula uma seção de um documento HTML onde o usuário pode inserir e enviar dados com controles interativos. Existem vários tipos de controles de interface de usuário (UI) que podem ser usados dentro de um formulário, sendo os mais comuns os elementos `<input>` e `<button>`.
O elemento `<form>` encapsula uma seção de um documento HTML onde o usuário pode inserir e enviar dados usando controles interativos. Existem vários tipos de controles de interface de usuário (UI) que podem ser usados dentro de um formulário, sendo os mais comuns os elementos `<input>` e `<button>`.
Há muitos [tipos](https://developer.mozilla.org/docs/Web/HTML/Element/input) diferentes de `<input>`. Por exemplo, para criar um campo onde o usuário pode inserir seu nome de usuário, você pode usar:
@ -53,13 +53,13 @@ O atributo `name` será usado como o nome da propriedade quando os dados do form
> Confira a lista completa de [tipos de `<input>`](https://developer.mozilla.org/docs/Web/HTML/Element/input) e [outros controles de formulário](https://developer.mozilla.org/docs/Learn/Forms/Other_form_controls) para ter uma ideia de todos os elementos nativos de UI que você pode usar ao construir sua interface.
✅ Note que `<input>` é um [elemento vazio](https://developer.mozilla.org/docs/Glossary/Empty_element) no qual você *não* deve adicionar uma tag de fechamento correspondente. No entanto, você pode usar a notação de auto-fechamento `<input/>`, mas isso não é obrigatório.
✅ Note que `<input>` é um [elemento vazio](https://developer.mozilla.org/docs/Glossary/Empty_element) no qual você *não* deve adicionar uma tag de fechamento correspondente. Você pode, no entanto, usar a notação de auto-fechamento `<input/>`, mas isso não é obrigatório.
O elemento `<button>` dentro de um formulário é um pouco especial. Se você não especificar seu atributo `type`, ele automaticamente enviará os dados do formulário ao servidor quando pressionado. Aqui estão os valores possíveis para o atributo `type`:
- `submit`: O padrão dentro de um `<form>`, o botão aciona a ação de envio do formulário.
- `reset`: O botão redefine todos os controles do formulário para seus valores iniciais.
- `button`: Não atribui um comportamento padrão ao botão quando pressionado. Você pode então atribuir ações personalizadas a ele usando JavaScript.
- `button`: Não atribui um comportamento padrão ao botão quando pressionado. Você pode então atribuir ações personalizadas usando JavaScript.
### Tarefa
@ -84,7 +84,7 @@ Se você observar mais de perto, perceberá que também adicionamos um elemento
- Ao associar um label a um controle de formulário, ele ajuda usuários que utilizam tecnologias assistivas (como leitores de tela) a entender quais dados são esperados.
- Você pode clicar no label para colocar o foco diretamente no controle associado, facilitando o acesso em dispositivos com tela sensível ao toque.
> [Acessibilidade](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility) na web é um tópico muito importante que muitas vezes é negligenciado. Graças aos [elementos semânticos HTML](https://developer.mozilla.org/docs/Learn/Accessibility/HTML), não é difícil criar conteúdo acessível se você os usar corretamente. Você pode [ler mais sobre acessibilidade](https://developer.mozilla.org/docs/Web/Accessibility) para evitar erros comuns e se tornar um desenvolvedor responsável.
> [Acessibilidade](https://developer.mozilla.org/docs/Learn/Accessibility/What_is_accessibility) na web é um tópico muito importante que frequentemente é negligenciado. Graças aos [elementos semânticos HTML](https://developer.mozilla.org/docs/Learn/Accessibility/HTML), não é difícil criar conteúdo acessível se você os usar corretamente. Você pode [ler mais sobre acessibilidade](https://developer.mozilla.org/docs/Web/Accessibility) para evitar erros comuns e se tornar um desenvolvedor responsável.
Agora vamos adicionar um segundo formulário para o registro, logo abaixo do anterior:
@ -104,9 +104,9 @@ Agora vamos adicionar um segundo formulário para o registro, logo abaixo do ant
</form>
```
Usando o atributo `value`, podemos definir um valor padrão para um determinado campo de entrada. Note também que o campo de entrada para `balance` tem o tipo `number`. Ele parece diferente dos outros campos? Experimente interagir com ele.
Usando o atributo `value`, podemos definir um valor padrão para um determinado input. Note também que o input para `balance` tem o tipo `number`. Ele parece diferente dos outros inputs? Experimente interagir com ele.
✅ Você consegue navegar e interagir com os formulários usando apenas o teclado? Como você faria isso?
✅ Você consegue navegar e interagir com os formulários usando apenas o teclado? Como faria isso?
## Enviando dados para o servidor
@ -119,8 +119,8 @@ Você notou a mudança na seção de URL do navegador?
A ação padrão de um `<form>` é enviar os dados do formulário para o URL atual do servidor usando o [método GET](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3), anexando os dados do formulário diretamente ao URL. No entanto, esse método tem algumas limitações:
- Os dados enviados são muito limitados em tamanho (cerca de 2000 caracteres)
- Os dados são visíveis diretamente no URL (não é ideal para senhas)
- Não funciona com upload de arquivos
- Os dados são diretamente visíveis no URL (não é ideal para senhas)
- Não funciona com uploads de arquivos
Por isso, você pode alterá-lo para usar o [método POST](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5), que envia os dados do formulário para o servidor no corpo da requisição HTTP, sem as limitações anteriores.
@ -134,9 +134,9 @@ Adicione as propriedades `action` e `method` ao formulário de registro:
<form id="registerForm" action="//localhost:5000/api/accounts" method="POST">
```
Agora tente registrar uma nova conta com seu nome. Após clicar no botão *Register*, você deve ver algo assim:
Agora tente registrar uma nova conta com seu nome. Após clicar no botão *Register*, você deve ver algo como isto:
![Uma janela do navegador no endereço localhost:5000/api/accounts, mostrando uma string JSON com os dados do usuário](../../../../translated_images/form-post.61de4ca1b964d91a9e338416e19f218504dd0af5f762fbebabfe7ae80edf885f.br.png)
![Janela do navegador no endereço localhost:5000/api/accounts, mostrando uma string JSON com os dados do usuário](../../../../translated_images/form-post.61de4ca1b964d91a9e338416e19f218504dd0af5f762fbebabfe7ae80edf885f.br.png)
Se tudo correr bem, o servidor deve responder à sua requisição com uma resposta [JSON](https://www.json.org/json-en.html) contendo os dados da conta que foi criada.
@ -190,13 +190,13 @@ async function createAccount(account) {
}
```
O que essa função está fazendo? Primeiro, observe a palavra-chave `async` aqui. Isso significa que a função contém código que será executado [**assincronamente**](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Quando usada junto com a palavra-chave `await`, ela permite esperar que o código assíncrono seja executado - como esperar pela resposta do servidor aqui - antes de continuar.
O que essa função faz? Primeiro, note a palavra-chave `async` aqui. Isso significa que a função contém código que será executado [**assincronamente**](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function). Quando usada junto com a palavra-chave `await`, permite esperar que o código assíncrono seja executado - como esperar pela resposta do servidor aqui - antes de continuar.
Aqui está um vídeo rápido sobre o uso de `async/await`:
[![Async e Await para gerenciar promessas](https://img.youtube.com/vi/YwmlRkrxvkk/0.jpg)](https://youtube.com/watch?v=YwmlRkrxvkk "Async e Await para gerenciar promessas")
> 🎥 Clique na imagem acima para assistir a um vídeo sobre async/await.
> 🎥 Clique na imagem acima para assistir ao vídeo sobre async/await.
Usamos a API `fetch()` para enviar dados JSON ao servidor. Este método recebe 2 parâmetros:
@ -217,7 +217,7 @@ Como usamos a palavra-chave `await` aqui, precisamos adicionar a palavra-chave `
async function register() {
```
Por fim, vamos adicionar alguns logs para verificar o resultado. A função final deve se parecer com esta:
Por fim, vamos adicionar alguns logs para verificar o resultado. A função final deve se parecer com isto:
```js
async function register() {
@ -244,14 +244,14 @@ Foi um pouco longo, mas chegamos lá! Se você abrir as [ferramentas de desenvol
Se você tentar registrar uma nova conta sem definir um nome de usuário primeiro, verá que o servidor retorna um erro com o código de status [400 (Bad Request)](https://developer.mozilla.org/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).).
Antes de enviar dados a um servidor, é uma boa prática [validar os dados do formulário](https://developer.mozilla.org/docs/Learn/Forms/Form_validation) previamente, sempre que possível, para garantir que você está enviando uma requisição válida. Os controles de formulário HTML5 fornecem validação integrada usando vários atributos:
Antes de enviar dados para um servidor, é uma boa prática [validar os dados do formulário](https://developer.mozilla.org/docs/Learn/Forms/Form_validation) previamente, sempre que possível, para garantir que você envie uma requisição válida. Os controles de formulário HTML5 fornecem validação embutida usando vários atributos:
- `required`: o campo precisa ser preenchido, caso contrário o formulário não pode ser enviado.
- `minlength` e `maxlength`: definem o número mínimo e máximo de caracteres em campos de texto.
- `min` e `max`: definem o valor mínimo e máximo de um campo numérico.
- `type`: define o tipo de dado esperado, como `number`, `email`, `file` ou [outros tipos integrados](https://developer.mozilla.org/docs/Web/HTML/Element/input). Este atributo também pode alterar a renderização visual do controle de formulário.
- `minlength` e `maxlength`: define o número mínimo e máximo de caracteres em campos de texto.
- `min` e `max`: define o valor mínimo e máximo de um campo numérico.
- `type`: define o tipo de dado esperado, como `number`, `email`, `file` ou [outros tipos embutidos](https://developer.mozilla.org/docs/Web/HTML/Element/input). Este atributo também pode alterar a renderização visual do controle de formulário.
- `pattern`: permite definir um padrão de [expressão regular](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions) para testar se os dados inseridos são válidos ou não.
Dica: você pode personalizar a aparência dos seus controles de formulário dependendo se eles são válidos ou não, utilizando as pseudo-classes CSS `:valid` e `:invalid`.
Dica: você pode personalizar a aparência dos controles do seu formulário dependendo se eles são válidos ou não, utilizando as pseudo-classes CSS `:valid` e `:invalid`.
### Tarefa
Existem 2 campos obrigatórios para criar uma nova conta válida: o nome de usuário e a moeda. Os outros campos são opcionais. Atualize o HTML do formulário, utilizando tanto o atributo `required` quanto o texto no rótulo do campo para que:
@ -264,7 +264,7 @@ Existem 2 campos obrigatórios para criar uma nova conta válida: o nome de usu
<input id="currency" name="currency" type="text" value="$" required>
```
Embora esta implementação específica do servidor não imponha limites específicos no comprimento máximo dos campos, é sempre uma boa prática definir limites razoáveis para qualquer entrada de texto do usuário.
Embora esta implementação específica do servidor não imponha limites específicos para o comprimento máximo dos campos, é sempre uma boa prática definir limites razoáveis para qualquer entrada de texto do usuário.
Adicione um atributo `maxlength` aos campos de texto:
@ -280,9 +280,9 @@ Agora, se você pressionar o botão *Registrar* e algum campo não atender a uma
![Captura de tela mostrando o erro de validação ao tentar enviar o formulário](../../../../translated_images/validation-error.8bd23e98d416c22f80076d04829a4bb718e0e550fd622862ef59008ccf0d5dce.br.png)
A validação como esta, realizada *antes* de enviar qualquer dado para o servidor, é chamada de validação **do lado do cliente**. Mas observe que nem sempre é possível realizar todas as verificações sem enviar os dados. Por exemplo, não podemos verificar aqui se já existe uma conta com o mesmo nome de usuário sem enviar uma solicitação ao servidor. Validações adicionais realizadas no servidor são chamadas de validação **do lado do servidor**.
A validação como esta, realizada *antes* de enviar qualquer dado para o servidor, é chamada de validação **do lado do cliente**. Mas observe que nem sempre é possível realizar todas as verificações sem enviar os dados. Por exemplo, não podemos verificar aqui se já existe uma conta com o mesmo nome de usuário sem enviar uma solicitação ao servidor. A validação adicional realizada no servidor é chamada de validação **do lado do servidor**.
Normalmente, ambas precisam ser implementadas, e enquanto a validação do lado do cliente melhora a experiência do usuário ao fornecer feedback instantâneo, a validação do lado do servidor é crucial para garantir que os dados do usuário que você manipula sejam consistentes e seguros.
Geralmente, ambas precisam ser implementadas, e enquanto a validação do lado do cliente melhora a experiência do usuário ao fornecer feedback instantâneo, a validação do lado do servidor é crucial para garantir que os dados do usuário que você manipula sejam confiáveis e seguros.
---
@ -306,5 +306,7 @@ Os desenvolvedores têm sido muito criativos em seus esforços para criar formul
[Estilize seu aplicativo bancário](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "f587e913e3f7c0b1c549a05dd74ee8e5",
"translation_date": "2025-08-26T00:25:32+00:00",
"original_hash": "89d0df9854ed020f155e94882ae88d4c",
"translation_date": "2025-08-28T23:47:32+00:00",
"source_file": "7-bank-project/3-data/README.md",
"language_code": "br"
}
@ -93,7 +93,7 @@ async function login() {
}
```
Primeiro, como `getAccount` é uma função assíncrona, precisamos combiná-la com a palavra-chave `await` para esperar pelo resultado do servidor. Como em qualquer solicitação ao servidor, também temos que lidar com casos de erro. Por enquanto, adicionaremos apenas uma mensagem de log para exibir o erro e voltaremos a isso mais tarde.
Primeiro, como `getAccount` é uma função assíncrona, precisamos combiná-la com a palavra-chave `await` para aguardar o resultado do servidor. Como em qualquer solicitação ao servidor, também precisamos lidar com casos de erro. Por enquanto, adicionaremos apenas uma mensagem de log para exibir o erro e voltaremos a isso mais tarde.
Depois, precisamos armazenar os dados em algum lugar para que possamos usá-los posteriormente para exibir as informações do painel. Como a variável `account` ainda não existe, criaremos uma variável global para ela no topo do nosso arquivo:
@ -134,7 +134,7 @@ Agora que temos os dados do usuário, precisamos atualizar o HTML existente para
### Tarefa
Antes de avançar para a tela do *dashboard*, há mais uma coisa que devemos fazer na página de *login*. Atualmente, se você tentar fazer login com um nome de usuário que não existe, uma mensagem é exibida no console, mas para um usuário comum nada muda e você não sabe o que está acontecendo.
Antes de avançar para a tela do painel, há mais uma coisa que devemos fazer na página de *login*. Atualmente, se você tentar fazer login com um nome de usuário que não existe, uma mensagem é exibida no console, mas para um usuário comum nada muda e você não sabe o que está acontecendo.
Vamos adicionar um elemento de espaço reservado no formulário de login onde podemos exibir uma mensagem de erro, se necessário. Um bom lugar seria logo antes do botão de login `<button>`:
@ -147,7 +147,7 @@ Vamos adicionar um elemento de espaço reservado no formulário de login onde po
Este elemento `<div>` está vazio, o que significa que nada será exibido na tela até adicionarmos algum conteúdo a ele. Também damos a ele um `id` para que possamos recuperá-lo facilmente com JavaScript.
Volte ao arquivo `app.js` e crie uma nova função auxiliar `updateElement`:
Volte para o arquivo `app.js` e crie uma nova função auxiliar `updateElement`:
```js
function updateElement(id, text) {
@ -156,7 +156,7 @@ function updateElement(id, text) {
}
```
Esta função é bastante simples: dado um *id* de elemento e um *texto*, ela atualizará o conteúdo de texto do elemento DOM com o `id` correspondente. Vamos usar este método no lugar da mensagem de erro anterior na função `login`:
Esta função é bastante simples: dado um *id* de elemento e um *texto*, ela atualizará o conteúdo de texto do elemento DOM correspondente ao `id`. Vamos usar este método no lugar da mensagem de erro anterior na função `login`:
```js
if (data.error) {
@ -164,7 +164,7 @@ if (data.error) {
}
```
Agora, se você tentar fazer login com uma conta inválida, verá algo assim:
Agora, se você tentar fazer login com uma conta inválida, deverá ver algo assim:
![Captura de tela mostrando a mensagem de erro exibida durante o login](../../../../translated_images/login-error.416fe019b36a63276764c2349df5d99e04ebda54fefe60c715ee87a28d5d4ad0.br.png)
@ -176,11 +176,11 @@ Agora temos um texto de erro que aparece visualmente, mas se você tentar com um
Implemente o mesmo comportamento para os erros da função `register` (não se esqueça de atualizar o HTML).
## Exibir informações no dashboard
## Exibir informações no painel
Usando as mesmas técnicas que acabamos de ver, também cuidaremos de exibir as informações da conta na página do dashboard.
Usando as mesmas técnicas que acabamos de ver, também cuidaremos de exibir as informações da conta na página do painel.
Este é o que um objeto de conta recebido do servidor parece:
Este é o formato de um objeto de conta recebido do servidor:
```json
{
@ -200,7 +200,7 @@ Este é o que um objeto de conta recebido do servidor parece:
### Tarefa
Vamos começar substituindo a seção "Balance" no HTML para adicionar elementos de espaço reservado:
Vamos começar substituindo a seção "Saldo" no HTML para adicionar elementos de espaço reservado:
```html
<section>
@ -214,9 +214,9 @@ Também adicionaremos uma nova seção logo abaixo para exibir a descrição da
<h2 id="description"></h2>
```
✅ Como a descrição da conta funciona como um título para o conteúdo abaixo dela, ela é marcada semanticamente como um cabeçalho. Saiba mais sobre como [estrutura de cabeçalhos](https://www.nomensa.com/blog/2017/how-structure-headings-web-accessibility) é importante para acessibilidade e analise criticamente a página para determinar o que mais poderia ser um cabeçalho.
✅ Como a descrição da conta funciona como um título para o conteúdo abaixo dela, ela é marcada semanticamente como um cabeçalho. Saiba mais sobre como a [estrutura de cabeçalhos](https://www.nomensa.com/blog/2017/how-structure-headings-web-accessibility) é importante para acessibilidade e analise criticamente a página para determinar o que mais poderia ser um cabeçalho.
Em seguida, criaremos uma nova função em `app.js` para preencher o espaço reservado:
Em seguida, criaremos uma nova função no `app.js` para preencher o espaço reservado:
```js
function updateDashboard() {
@ -232,9 +232,9 @@ function updateDashboard() {
Primeiro, verificamos se temos os dados da conta necessários antes de prosseguir. Em seguida, usamos a função `updateElement()` que criamos anteriormente para atualizar o HTML.
> Para tornar a exibição do saldo mais bonita, usamos o método [`toFixed(2)`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) para forçar a exibição do valor com 2 dígitos após o ponto decimal.
> Para deixar a exibição do saldo mais bonita, usamos o método [`toFixed(2)`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) para forçar a exibição do valor com 2 dígitos após o ponto decimal.
Agora precisamos chamar nossa função `updateDashboard()` toda vez que a página do dashboard for carregada. Se você já terminou a [lição 1](../1-template-route/assignment.md), isso deve ser simples, caso contrário, você pode usar a seguinte implementação.
Agora precisamos chamar nossa função `updateDashboard()` toda vez que a página do painel for carregada. Se você já terminou a [tarefa da lição 1](../1-template-route/assignment.md), isso deve ser simples, caso contrário, você pode usar a seguinte implementação.
Adicione este código ao final da função `updateRoute()`:
@ -253,7 +253,7 @@ const routes = {
};
```
Com esta alteração, toda vez que a página do dashboard for exibida, a função `updateDashboard()` será chamada. Após um login, você deve então conseguir ver o saldo da conta, a moeda e a descrição.
Com esta alteração, toda vez que a página do painel for exibida, a função `updateDashboard()` será chamada. Após um login, você deve então ver o saldo da conta, a moeda e a descrição.
## Criar linhas de tabela dinamicamente com templates HTML
@ -277,7 +277,7 @@ Adicione um novo template no `<body>` do HTML:
Este template representa uma única linha de tabela, com as 3 colunas que queremos preencher: *data*, *objeto* e *quantia* de uma transação.
Em seguida, adicione esta propriedade `id` ao elemento `<tbody>` da tabela dentro do template do dashboard para facilitar a localização usando JavaScript:
Em seguida, adicione esta propriedade `id` ao elemento `<tbody>` da tabela dentro do template do painel para facilitar a localização usando JavaScript:
```html
<tbody id="transactions"></tbody>
@ -341,5 +341,7 @@ Aqui está um exemplo de uma página de painel estilizada:
[Refatore e comente seu código](assignment.md)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,23 +1,23 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "4fa20c513e367e9cdd401bf49ae16e33",
"translation_date": "2025-08-26T00:46:32+00:00",
"original_hash": "5d2efabbc8f94d89f4317ee8646c3ce9",
"translation_date": "2025-08-28T23:48:53+00:00",
"source_file": "7-bank-project/4-state-management/README.md",
"language_code": "br"
}
-->
# Construir um App Bancário Parte 4: Conceitos de Gerenciamento de Estado
# Construindo um App Bancário Parte 4: Conceitos de Gerenciamento de Estado
## Questionário Pré-Aula
## Quiz Pré-Aula
[Questionário pré-aula](https://ff-quizzes.netlify.app/web/quiz/47)
[Quiz pré-aula](https://ff-quizzes.netlify.app/web/quiz/47)
### Introdução
À medida que uma aplicação web cresce, torna-se um desafio acompanhar todos os fluxos de dados. Qual código obtém os dados, qual página os consome, onde e quando eles precisam ser atualizados... é fácil acabar com um código confuso e difícil de manter. Isso é especialmente verdadeiro quando você precisa compartilhar dados entre diferentes páginas do seu app, como os dados do usuário. O conceito de *gerenciamento de estado* sempre existiu em todos os tipos de programas, mas à medida que os aplicativos web continuam a crescer em complexidade, tornou-se um ponto-chave a ser considerado durante o desenvolvimento.
À medida que uma aplicação web cresce, torna-se um desafio acompanhar todos os fluxos de dados. Qual código obtém os dados, qual página os consome, onde e quando eles precisam ser atualizados... é fácil acabar com um código bagunçado e difícil de manter. Isso é especialmente verdadeiro quando você precisa compartilhar dados entre diferentes páginas do seu app, como os dados do usuário. O conceito de *gerenciamento de estado* sempre existiu em todos os tipos de programas, mas à medida que os apps web continuam crescendo em complexidade, tornou-se um ponto-chave a ser considerado durante o desenvolvimento.
Nesta última parte, revisaremos o app que construímos para repensar como o estado é gerenciado, permitindo suporte para atualização do navegador em qualquer ponto e persistindo os dados entre sessões do usuário.
Nesta última parte, vamos revisar o app que construímos para repensar como o estado é gerenciado, permitindo suporte para atualização do navegador a qualquer momento e persistindo dados entre sessões do usuário.
### Pré-requisitos
@ -32,32 +32,32 @@ curl http://localhost:5000/api
---
## Repensar o gerenciamento de estado
## Repensando o gerenciamento de estado
Na [lição anterior](../3-data/README.md), introduzimos um conceito básico de estado no nosso app com a variável global `account`, que contém os dados bancários do usuário atualmente logado. No entanto, nossa implementação atual tem algumas falhas. Tente atualizar a página quando estiver no painel. O que acontece?
Na [lição anterior](../3-data/README.md), introduzimos um conceito básico de estado em nosso app com a variável global `account`, que contém os dados bancários do usuário atualmente logado. No entanto, nossa implementação atual tem algumas falhas. Tente atualizar a página enquanto estiver no painel. O que acontece?
Há 3 problemas com o código atual:
- O estado não é persistido, pois uma atualização do navegador leva você de volta à página de login.
- Existem várias funções que modificam o estado. À medida que o app cresce, isso pode dificultar o rastreamento das alterações e é fácil esquecer de atualizar algo.
- Existem várias funções que modificam o estado. À medida que o app cresce, isso pode dificultar o rastreamento das mudanças e é fácil esquecer de atualizar algo.
- O estado não é limpo, então quando você clica em *Logout*, os dados da conta ainda estão lá, mesmo que você esteja na página de login.
Poderíamos atualizar nosso código para resolver esses problemas um por um, mas isso criaria mais duplicação de código e tornaria o app mais complexo e difícil de manter. Ou poderíamos pausar por alguns minutos e repensar nossa estratégia.
Poderíamos atualizar nosso código para resolver esses problemas um por um, mas isso criaria mais duplicação de código e tornaria o app mais complexo e difícil de manter. Ou poderíamos parar por alguns minutos e repensar nossa estratégia.
> Quais problemas estamos realmente tentando resolver aqui?
O [gerenciamento de estado](https://en.wikipedia.org/wiki/State_management) trata de encontrar uma boa abordagem para resolver esses dois problemas específicos:
[Gerenciamento de estado](https://en.wikipedia.org/wiki/State_management) trata de encontrar uma boa abordagem para resolver esses dois problemas específicos:
- Como manter os fluxos de dados em um app compreensíveis?
- Como manter os dados do estado sempre sincronizados com a interface do usuário (e vice-versa)?
- Como manter os dados de estado sempre sincronizados com a interface do usuário (e vice-versa)?
Depois de resolver esses problemas, quaisquer outras questões que você possa ter podem já estar resolvidas ou se tornar mais fáceis de corrigir. Existem muitas abordagens possíveis para resolver esses problemas, mas seguiremos uma solução comum que consiste em **centralizar os dados e as formas de alterá-los**. Os fluxos de dados seriam assim:
Depois de resolver esses problemas, quaisquer outros problemas que você possa ter podem já estar resolvidos ou se tornar mais fáceis de corrigir. Existem muitas abordagens possíveis para resolver esses problemas, mas seguiremos uma solução comum que consiste em **centralizar os dados e as formas de alterá-los**. Os fluxos de dados seriam assim:
![Esquema mostrando os fluxos de dados entre o HTML, ações do usuário e estado](../../../../translated_images/data-flow.fa2354e0908fecc89b488010dedf4871418a992edffa17e73441d257add18da4.br.png)
> Não abordaremos aqui a parte em que os dados atualizam automaticamente a visualização, pois isso está ligado a conceitos mais avançados de [Programação Reativa](https://en.wikipedia.org/wiki/Reactive_programming). É um bom assunto para um mergulho mais profundo.
> Não abordaremos aqui a parte em que os dados automaticamente acionam a atualização da visualização, pois está ligada a conceitos mais avançados de [Programação Reativa](https://en.wikipedia.org/wiki/Reactive_programming). É um bom assunto para um mergulho mais profundo.
✅ Existem muitas bibliotecas por aí com diferentes abordagens para gerenciamento de estado, sendo o [Redux](https://redux.js.org) uma opção popular. Dê uma olhada nos conceitos e padrões usados, pois muitas vezes é uma boa maneira de aprender quais problemas potenciais você pode enfrentar em grandes apps web e como resolvê-los.
✅ Existem muitas bibliotecas por aí com diferentes abordagens para gerenciamento de estado, sendo o [Redux](https://redux.js.org) uma opção popular. Dê uma olhada nos conceitos e padrões usados, pois muitas vezes é uma boa maneira de aprender quais problemas potenciais você pode enfrentar em apps web grandes e como eles podem ser resolvidos.
### Tarefa
@ -75,7 +75,7 @@ let state = {
};
```
A ideia é *centralizar* todos os dados do nosso app em um único objeto de estado. Por enquanto, temos apenas `account` no estado, então isso não muda muito, mas cria um caminho para evoluções.
A ideia é *centralizar* todos os dados do nosso app em um único objeto de estado. Por enquanto, temos `account` no estado, então isso não muda muito, mas cria um caminho para evoluções.
Também precisamos atualizar as funções que o utilizam. Nas funções `register()` e `login()`, substitua `account = ...` por `state.account = ...`;
@ -85,17 +85,17 @@ No início da função `updateDashboard()`, adicione esta linha:
const account = state.account;
```
Essa refatoração por si só não trouxe muitas melhorias, mas a ideia foi preparar o terreno para as próximas mudanças.
Essa refatoração por si só não trouxe muitas melhorias, mas a ideia era preparar o terreno para as próximas mudanças.
## Rastrear alterações nos dados
## Rastrear mudanças nos dados
Agora que configuramos o objeto `state` para armazenar nossos dados, o próximo passo é centralizar as atualizações. O objetivo é facilitar o rastreamento de quaisquer alterações e quando elas ocorrem.
Agora que colocamos em prática o objeto `state` para armazenar nossos dados, o próximo passo é centralizar as atualizações. O objetivo é facilitar o rastreamento de quaisquer mudanças e quando elas acontecem.
Para evitar alterações feitas diretamente no objeto `state`, também é uma boa prática considerá-lo [*imutável*](https://en.wikipedia.org/wiki/Immutable_object), o que significa que ele não pode ser modificado de forma alguma. Isso também significa que você precisa criar um novo objeto de estado se quiser alterar algo nele. Fazendo isso, você constrói uma proteção contra possíveis [efeitos colaterais](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) indesejados e abre possibilidades para novos recursos no seu app, como implementar desfazer/refazer, além de facilitar a depuração. Por exemplo, você poderia registrar todas as alterações feitas no estado e manter um histórico para entender a origem de um bug.
Para evitar que mudanças sejam feitas diretamente no objeto `state`, também é uma boa prática considerá-lo [*imutável*](https://en.wikipedia.org/wiki/Immutable_object), o que significa que ele não pode ser modificado de forma alguma. Isso também significa que você precisa criar um novo objeto de estado se quiser alterar algo nele. Ao fazer isso, você constrói uma proteção contra possíveis [efeitos colaterais](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) indesejados e abre possibilidades para novos recursos no seu app, como implementar desfazer/refazer, além de facilitar a depuração. Por exemplo, você poderia registrar todas as mudanças feitas no estado e manter um histórico das alterações para entender a origem de um bug.
Em JavaScript, você pode usar [`Object.freeze()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) para criar uma versão imutável de um objeto. Se você tentar fazer alterações em um objeto imutável, uma exceção será lançada.
✅ Você sabe a diferença entre um objeto imutável *raso* e *profundo*? Você pode ler sobre isso [aqui](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze).
✅ Você sabe a diferença entre um objeto imutável *superficial* e *profundo*? Você pode ler sobre isso [aqui](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze).
### Tarefa
@ -110,9 +110,9 @@ function updateState(property, newData) {
}
```
Nesta função, estamos criando um novo objeto de estado e copiando os dados do estado anterior usando o [*operador spread (`...`)*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals). Em seguida, sobrescrevemos uma propriedade específica do objeto de estado com os novos dados usando a [notação de colchetes](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` para atribuição. Por fim, bloqueamos o objeto para evitar modificações usando `Object.freeze()`. Por enquanto, temos apenas a propriedade `account` armazenada no estado, mas com essa abordagem você pode adicionar quantas propriedades precisar.
Nesta função, estamos criando um novo objeto de estado e copiando os dados do estado anterior usando o [*operador spread (`...`)*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals). Em seguida, substituímos uma propriedade específica do objeto de estado com os novos dados usando a [notação de colchetes](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` para atribuição. Por fim, bloqueamos o objeto para evitar modificações usando `Object.freeze()`. Por enquanto, temos a propriedade `account` armazenada no estado, mas com essa abordagem você pode adicionar quantas propriedades precisar no estado.
Também atualizaremos a inicialização do `state` para garantir que o estado inicial também esteja congelado:
Também atualizaremos a inicialização do `state` para garantir que o estado inicial seja congelado:
```js
let state = Object.freeze({
@ -143,17 +143,17 @@ function logout() {
}
```
Na função `updateDashboard()`, substitua a redireção `return navigate('/login');` por `return logout()`;
Na função `updateDashboard()`, substitua o redirecionamento `return navigate('/login');` por `return logout();`;
Tente registrar uma nova conta, fazer logout e login novamente para verificar se tudo ainda funciona corretamente.
> Dica: você pode verificar todas as alterações de estado adicionando `console.log(state)` no final de `updateState()` e abrindo o console nas ferramentas de desenvolvimento do navegador.
> Dica: você pode observar todas as mudanças de estado adicionando `console.log(state)` no final de `updateState()` e abrindo o console nas ferramentas de desenvolvimento do navegador.
## Persistir o estado
A maioria dos apps web precisa persistir dados para funcionar corretamente. Todos os dados críticos geralmente são armazenados em um banco de dados e acessados por meio de uma API de servidor, como os dados da conta do usuário no nosso caso. Mas, às vezes, também é interessante persistir alguns dados no app cliente que está sendo executado no navegador, para uma melhor experiência do usuário ou para melhorar o desempenho de carregamento.
A maioria dos apps web precisa persistir dados para funcionar corretamente. Todos os dados críticos geralmente são armazenados em um banco de dados e acessados por meio de uma API de servidor, como os dados da conta do usuário no nosso caso. Mas às vezes, também é interessante persistir alguns dados no app cliente que está sendo executado no navegador, para uma melhor experiência do usuário ou para melhorar o desempenho de carregamento.
Quando você deseja persistir dados no navegador, há algumas perguntas importantes que deve se fazer:
Quando você deseja persistir dados no navegador, há algumas perguntas importantes que você deve se fazer:
- *Os dados são sensíveis?* Você deve evitar armazenar qualquer dado sensível no cliente, como senhas de usuários.
- *Por quanto tempo você precisa manter esses dados?* Você planeja acessar esses dados apenas para a sessão atual ou deseja que eles sejam armazenados para sempre?
@ -162,12 +162,12 @@ Existem várias maneiras de armazenar informações dentro de um app web, depend
Outra opção é usar uma das muitas APIs do navegador para armazenar dados. Duas delas são particularmente interessantes:
- [`localStorage`](https://developer.mozilla.org/docs/Web/API/Window/localStorage): um [armazenamento chave/valor](https://en.wikipedia.org/wiki/Key%E2%80%93value_database) que permite persistir dados específicos do site atual entre diferentes sessões. Os dados salvos nele nunca expiram.
- [`localStorage`](https://developer.mozilla.org/docs/Web/API/Window/localStorage): um [Key/Value store](https://en.wikipedia.org/wiki/Key%E2%80%93value_database) que permite persistir dados específicos do site atual entre diferentes sessões. Os dados salvos nele nunca expiram.
- [`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage): funciona da mesma forma que o `localStorage`, exceto que os dados armazenados nele são apagados quando a sessão termina (quando o navegador é fechado).
Observe que ambas as APIs permitem armazenar apenas [strings](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String). Se você quiser armazenar objetos complexos, precisará serializá-los no formato [JSON](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON) usando [`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify).
Observe que ambas as APIs permitem apenas armazenar [strings](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String). Se você quiser armazenar objetos complexos, precisará serializá-los no formato [JSON](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON) usando [`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify).
✅ Se você quiser criar um app web que não funcione com um servidor, também é possível criar um banco de dados no cliente usando a API [`IndexedDB`](https://developer.mozilla.org/docs/Web/API/IndexedDB_API). Essa opção é reservada para casos de uso avançados ou se você precisar armazenar uma quantidade significativa de dados, pois é mais complexa de usar.
✅ Se você quiser criar um app web que não funcione com um servidor, também é possível criar um banco de dados no cliente usando a API [`IndexedDB`](https://developer.mozilla.org/docs/Web/API/IndexedDB_API). Esta é reservada para casos de uso avançados ou se você precisar armazenar uma quantidade significativa de dados, pois é mais complexa de usar.
### Tarefa
@ -204,7 +204,7 @@ init();
Aqui, recuperamos os dados salvos e, se houver algum, atualizamos o estado de acordo. É importante fazer isso *antes* de atualizar a rota, pois pode haver código que depende do estado durante a atualização da página.
Também podemos tornar a página *Dashboard* a página padrão do nosso app, já que agora estamos persistindo os dados da conta. Se nenhum dado for encontrado, o painel cuida de redirecionar para a página de *Login* de qualquer forma. Na função `updateRoute()`, substitua o fallback `return navigate('/login');` por `return navigate('/dashboard');`.
Também podemos tornar a página *Dashboard* a página padrão do nosso app, já que agora estamos persistindo os dados da conta. Se nenhum dado for encontrado, o painel cuida de redirecionar para a página de *Login* de qualquer forma. Em `updateRoute()`, substitua o fallback `return navigate('/login');` por `return navigate('/dashboard');`.
Agora faça login no app e tente atualizar a página. Você deve permanecer no painel. Com essa atualização, resolvemos todos os nossos problemas iniciais...
@ -221,9 +221,9 @@ curl --request POST \
http://localhost:5000/api/accounts/test/transactions
```
Tente atualizar a página do painel no navegador agora. O que acontece? Você vê a nova transação?
Agora tente atualizar a página do painel no navegador. O que acontece? Você vê a nova transação?
O estado é persistido indefinidamente graças ao `localStorage`, mas isso também significa que ele nunca é atualizado até que você saia do app e faça login novamente!
O estado é persistido indefinidamente graças ao `localStorage`, mas isso também significa que ele nunca é atualizado até que você saia do app e entre novamente!
Uma possível estratégia para corrigir isso é recarregar os dados da conta toda vez que o painel for carregado, para evitar dados desatualizados.
@ -247,7 +247,7 @@ async function updateAccountData() {
}
```
Este método verifica se estamos atualmente logados e, em seguida, recarrega os dados da conta do servidor.
Este método verifica se estamos atualmente logados e então recarrega os dados da conta do servidor.
Crie outra função chamada `refresh`:
@ -267,7 +267,7 @@ const routes = {
};
```
Tente recarregar o painel agora, ele deve exibir os dados da conta atualizados.
Agora tente atualizar o painel. Ele deve exibir os dados da conta atualizados.
---
@ -275,18 +275,20 @@ Tente recarregar o painel agora, ele deve exibir os dados da conta atualizados.
Agora que recarregamos os dados da conta toda vez que o painel é carregado, você acha que ainda precisamos persistir *todos os dados da conta*?
Trabalhem juntos para alterar o que é salvo e carregado do `localStorage` para incluir apenas o que é absolutamente necessário para o app funcionar.
Tente trabalhar em equipe para alterar o que é salvo e carregado do `localStorage` para incluir apenas o que é absolutamente necessário para o app funcionar.
## Quiz Pós-Aula
## Questionário Pós-Aula
[Quiz pós-aula](https://ff-quizzes.netlify.app/web/quiz/48)
## Tarefa
[Implementar o diálogo "Adicionar transação"](assignment.md)
Aqui está um exemplo de resultado após concluir a tarefa:
Aqui está um exemplo do resultado após concluir a tarefa:
![Captura de tela mostrando um exemplo de diálogo "Adicionar transação"](../../../../translated_images/dialog.93bba104afeb79f12f65ebf8f521c5d64e179c40b791c49c242cf15f7e7fab15.br.png)
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,8 +1,8 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "7aa6e4f270d38d9cb17f2b5bd86b863d",
"translation_date": "2025-08-25T23:19:18+00:00",
"original_hash": "1ba61d96a11309a2a6ea507496dcf7e5",
"translation_date": "2025-08-28T23:57:03+00:00",
"source_file": "8-code-editor/1-using-a-code-editor/README.md",
"language_code": "br"
}
@ -25,7 +25,7 @@ Antes de começar, você precisará criar uma conta no [GitHub](https://github.c
### Introdução
Um editor de código é uma ferramenta essencial para escrever programas e colaborar em projetos de programação existentes. Depois de entender os conceitos básicos de um editor e como aproveitar seus recursos, você poderá aplicá-los ao escrever código.
Um editor de código é uma ferramenta essencial para escrever programas e colaborar em projetos de programação existentes. Assim que você entender os conceitos básicos de um editor e como aproveitar seus recursos, poderá aplicá-los ao escrever código.
## Começando com o VSCode.dev
@ -35,7 +35,7 @@ Depois de carregar, ele deve se parecer com esta imagem:
![VSCode.dev padrão](../../../../translated_images/default-vscode-dev.5d06881d65c1b3234ce50cd9ed3b0028e6031ad5f5b441bcbed96bfa6311f6d0.br.png)
três seções principais, da esquerda para a direita:
Existem três seções principais, da esquerda para a direita:
1. A _barra de atividades_, que inclui alguns ícones, como a lupa 🔎, a engrenagem ⚙️ e outros.
2. A barra de atividades expandida, que por padrão exibe o _Explorador_, chamada de _barra lateral_.
@ -43,19 +43,19 @@ Há três seções principais, da esquerda para a direita:
Clique em cada um dos ícones para exibir um menu diferente. Quando terminar, clique no _Explorador_ para voltar ao ponto de partida.
Quando você começar a criar ou modificar código, isso acontecerá na maior área à direita. Você também usará essa área para visualizar o código existente, o que fará a seguir.
Quando você começar a criar ou modificar código existente, isso acontecerá na maior área à direita. Você também usará essa área para visualizar o código existente, o que será feito a seguir.
## Abrir um repositório do GitHub
A primeira coisa que você precisará fazer é abrir um repositório do GitHub. Existem várias maneiras de abrir um repositório. Nesta seção, você verá duas formas diferentes de abrir um repositório para começar a trabalhar nas alterações.
### 1. Pelo editor
### 1. Com o editor
Use o próprio editor para abrir um repositório remoto. Se você acessar [VSCode.dev](https://vscode.dev), verá um botão _"Open Remote Repository"_:
![Abrir repositório remoto](../../../../translated_images/open-remote-repository.bd9c2598b8949e7fc283cdfc8f4050c6205a7c7c6d3f78c4b135115d037d6fa2.br.png)
Você também pode usar a paleta de comandos. A paleta de comandos é uma caixa de entrada onde você pode digitar qualquer palavra que faça parte de um comando ou ação para encontrar o comando certo a ser executado. Use o menu no canto superior esquerdo, selecione _View_ e, em seguida, escolha _Command Palette_, ou use o atalho de teclado: Ctrl-Shift-P (no MacOS seria Command-Shift-P).
Você também pode usar a paleta de comandos. A paleta de comandos é uma caixa de entrada onde você pode digitar qualquer palavra que faça parte de um comando ou ação para encontrar o comando correto a ser executado. Use o menu no canto superior esquerdo, selecione _View_ e, em seguida, escolha _Command Palette_, ou use o atalho de teclado: Ctrl-Shift-P (no MacOS seria Command-Shift-P).
![Menu da Paleta](../../../../translated_images/palette-menu.4946174e07f426226afcdad707d19b8d5150e41591c751c45b5dee213affef91.br.png)
@ -89,7 +89,7 @@ Selecione um arquivo para abri-lo na área de código, faça suas alterações e
![Editar um arquivo](../../../../translated_images/edit-a-file.52c0ee665ef19f08119d62d63f395dfefddc0a4deb9268d73bfe791f52c5807a.br.png)
Depois de concluir as atualizações no seu projeto, selecione o ícone _`source control`_, que contém todas as novas alterações feitas no repositório.
Depois de terminar de atualizar seu projeto, selecione o ícone _`source control`_, que contém todas as novas alterações feitas no repositório.
Para visualizar as alterações feitas no projeto, selecione o(s) arquivo(s) na pasta `Changes` na barra de atividades expandida. Isso abrirá um 'Working Tree' para você visualizar as alterações feitas no arquivo. Vermelho indica uma exclusão no projeto, enquanto verde indica uma adição.
@ -97,11 +97,11 @@ Para visualizar as alterações feitas no projeto, selecione o(s) arquivo(s) na
Se estiver satisfeito com as alterações feitas, passe o mouse sobre a pasta `Changes` e clique no botão `+` para preparar as alterações. Preparar significa simplesmente preparar suas alterações para enviá-las ao GitHub.
Se, no entanto, você não estiver confortável com algumas alterações e quiser descartá-las, passe o mouse sobre a pasta `Changes` e selecione o ícone `undo`.
Se, no entanto, você não estiver confortável com algumas alterações e quiser descartá-las, passe o mouse sobre a pasta `Changes` e selecione o ícone de `desfazer`.
Depois, digite uma `mensagem de commit` _(uma descrição das alterações feitas no projeto)_, clique no ícone de `check` para confirmar e enviar suas alterações.
Quando terminar de trabalhar no projeto, selecione o `ícone do menu hambúrguer` no canto superior esquerdo para retornar ao repositório no github.com.
Quando terminar de trabalhar no projeto, selecione o `ícone de menu hambúrguer` no canto superior esquerdo para retornar ao repositório no github.com.
![Preparar e confirmar alterações](../../../../8-code-editor/images/edit-vscode.dev.gif)
@ -109,7 +109,7 @@ Quando terminar de trabalhar no projeto, selecione o `ícone do menu hambúrguer
Instalar extensões no VSCode permite adicionar novos recursos e opções de personalização ao ambiente de desenvolvimento no editor, melhorando seu fluxo de trabalho. Essas extensões também ajudam a adicionar suporte para várias linguagens de programação e geralmente são genéricas ou específicas para uma linguagem.
Para navegar pela lista de todas as extensões disponíveis, clique no _`ícone de Extensões`_ na barra de atividades e comece a digitar o nome da extensão no campo de texto rotulado como _'Search Extensions in Marketplace'_.
Para navegar pela lista de todas as extensões disponíveis, clique no ícone _`Extensions`_ na barra de atividades e comece a digitar o nome da extensão no campo de texto rotulado como _'Search Extensions in Marketplace'_.
Você verá uma lista de extensões, cada uma contendo **o nome da extensão, o nome do publicador, uma descrição de uma frase, o número de downloads** e **uma classificação por estrelas**.
![Detalhes da extensão](../../../../translated_images/extension-details.9f8f1fd4e9eb2de5069ae413119eb8ee43172776383ebe2f7cf640e11df2e106.br.png)
@ -118,7 +118,7 @@ Você também pode visualizar todas as extensões previamente instaladas expandi
![Visualizar extensões](../../../../translated_images/extensions.eca0e0c7f59a10b5c88be7fe24b3e32cca6b6058b35a49026c3a9d80b1813b7c.br.png)
### 1. Instalar Extensões
### 1. Instalar extensões
Para instalar uma extensão, digite o nome da extensão no campo de busca e clique nela para visualizar informações adicionais na área de código assim que ela aparecer na barra de atividades expandida.
@ -126,15 +126,15 @@ Você pode clicar no _botão azul de instalar_ na barra de atividades expandida
![Instalar extensões](../../../../8-code-editor/images/install-extension.gif)
### 2. Personalizar Extensões
### 2. Personalizar extensões
Depois de instalar a extensão, talvez seja necessário modificar seu comportamento e personalizá-la de acordo com suas preferências. Para fazer isso, selecione o ícone de Extensões e, desta vez, sua extensão aparecerá na pasta _Installed_. Clique no _**ícone de engrenagem**_ e navegue até _Extensions Setting_.
Depois de instalar a extensão, talvez seja necessário modificar seu comportamento e personalizá-la de acordo com suas preferências. Para fazer isso, selecione o ícone Extensions e, desta vez, sua extensão aparecerá na pasta _Installed_. Clique no _**ícone de engrenagem**_ e navegue até _Extensions Setting_.
![Modificar configurações da extensão](../../../../translated_images/extension-settings.21c752ae4f4cdb78a867f140ccd0680e04619d0c44bb4afb26373e54b829d934.br.png)
### 3. Gerenciar Extensões
### 3. Gerenciar extensões
Depois de instalar e usar sua extensão, o vscode.dev oferece opções para gerenciar a extensão com base em diferentes necessidades. Por exemplo, você pode:
Depois de instalar e usar sua extensão, o vscode.dev oferece opções para gerenciá-la com base em diferentes necessidades. Por exemplo, você pode:
- **Desativar:** _(Você pode desativar temporariamente uma extensão quando não precisar mais dela, mas não quiser desinstalá-la completamente)_
@ -152,5 +152,7 @@ Depois de instalar e usar sua extensão, o vscode.dev oferece opções para gere
Leia mais sobre o [VSCode.dev](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza) e alguns de seus outros recursos.
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

@ -1,15 +1,15 @@
<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "2fcb983b8dbadadb1bc2e97f8c12dac5",
"translation_date": "2025-08-25T23:24:20+00:00",
"original_hash": "bd3aa6d2b879c30ea496c43aec1c49ed",
"translation_date": "2025-08-28T23:57:29+00:00",
"source_file": "8-code-editor/1-using-a-code-editor/assignment.md",
"language_code": "br"
}
-->
# Crie um site de currículo usando vscode.dev
_Que incrível seria se um recrutador pedisse seu currículo e você enviasse um URL?_ 😎
_Que incrível seria se um recrutador pedisse seu currículo e você enviasse um link?_ 😎
## Objetivos
@ -19,13 +19,13 @@ Após esta tarefa, você aprenderá a:
### Pré-requisitos
1. Uma conta no GitHub. Acesse [GitHub](https://github.com/) e crie uma conta, caso ainda não tenha.
1. Uma conta no GitHub. Acesse [GitHub](https://github.com/) e crie uma conta, caso ainda não tenha uma.
## Passos
**Passo 1:** Crie um novo repositório no GitHub e dê a ele o nome `my-resume`
**Passo 1:** Crie um novo repositório no GitHub e dê a ele o nome `my-resume`.
**Passo 2:** Crie um arquivo `index.html` no seu repositório. Vamos adicionar pelo menos um arquivo diretamente no github.com, pois você não pode abrir um repositório vazio no vscode.dev.
**Passo 2:** Crie um arquivo `index.html` no seu repositório. Vamos adicionar pelo menos um arquivo diretamente no github.com, pois não é possível abrir um repositório vazio no vscode.dev.
Clique no link `creating a new file`, digite o nome `index.html` e selecione o botão `Commit new file`.
@ -33,15 +33,15 @@ Clique no link `creating a new file`, digite o nome `index.html` e selecione o b
**Passo 3:** Abra [VSCode.dev](https://vscode.dev) e selecione o botão `Open Remote Repository`.
Copie a URL do repositório que você acabou de criar para o site do seu currículo e cole na caixa de entrada:
Copie a URL do repositório que você acabou de criar para o site do currículo e cole na caixa de entrada:
_Substitua `your-username` pelo seu nome de usuário do GitHub_
_Substitua `your-username` pelo seu nome de usuário do GitHub._
```
https://github.com/your-username/my-resume
```
✅ Se for bem-sucedido, você verá seu projeto e o arquivo index.html abertos no editor de texto no navegador.
✅ Se tudo der certo, você verá seu projeto e o arquivo index.html abertos no editor de texto no navegador.
![Criar um novo arquivo](../../../../translated_images/project-on-vscode.dev.e79815a9a95ee7feac72ebe5c941c91279716be37c575dbdbf2f43bea2c7d8b6.br.png)
@ -95,7 +95,7 @@ https://github.com/your-username/my-resume
</section>
<section>
<h2>EDUCAÇÃO</h2>
<!-- sua formação -->
<!-- sua formação acadêmica -->
<h3>Escreva seu curso aqui!</h3>
<p>
Escreva sua instituição aqui!
@ -114,7 +114,7 @@ https://github.com/your-username/my-resume
<section>
<h2>EXPERIÊNCIA PROFISSIONAL</h2>
<!-- sua experiência profissional -->
<h3>Cargo</h3>
<h3>Título do Cargo</h3>
<p>
Nome da Organização Aqui | Mês de Início Mês de Término
</p>
@ -124,7 +124,7 @@ https://github.com/your-username/my-resume
<li>Escreva os resultados/impacto da sua contribuição</li>
</ul>
<h3>Cargo 2</h3>
<h3>Título do Cargo 2</h3>
<p>
Nome da Organização Aqui | Mês de Início Mês de Término
</p>
@ -141,7 +141,7 @@ https://github.com/your-username/my-resume
</html>
</details>
Adicione os detalhes do seu currículo para substituir o _texto de exemplo_ no código HTML.
Adicione os detalhes do seu currículo substituindo o _texto de exemplo_ no código HTML.
**Passo 5:** Passe o mouse sobre a pasta My-Resume, clique no ícone `New File ...` e crie 2 novos arquivos no seu projeto: `style.css` e `codeswing.json`.
@ -227,9 +227,9 @@ Isso é o que você verá na sua tela após instalar a extensão.
![Extensão Codeswing em ação](../../../../translated_images/after-codeswing-extension-pb.0ebddddcf73b550994947a9084e35e2836c713ae13839d49628e3c764c1cfe83.br.png)
Se estiver satisfeito com as mudanças feitas, passe o mouse sobre a pasta `Changes` e clique no botão `+` para preparar as alterações.
Se estiver satisfeito com as alterações feitas, passe o mouse sobre a pasta `Changes` e clique no botão `+` para preparar as alterações.
Digite uma mensagem de commit _(Uma descrição da mudança que você fez no projeto)_ e confirme suas alterações clicando no `check`. Quando terminar de trabalhar no projeto, selecione o ícone do menu hambúrguer no canto superior esquerdo para retornar ao repositório no GitHub.
Digite uma mensagem de commit _(Uma descrição das alterações feitas no projeto)_ e confirme suas alterações clicando no `check`. Quando terminar de trabalhar no projeto, selecione o ícone de menu hambúrguer no canto superior esquerdo para retornar ao repositório no GitHub.
Parabéns 🎉 Você acabou de criar seu site de currículo usando vscode.dev em poucos passos.
@ -239,7 +239,9 @@ Abra um repositório remoto no qual você tenha permissões para fazer alteraç
## Revisão e Autoestudo
Leia mais sobre [VSCode.dev](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza) e alguns de seus outros recursos.
Leia mais sobre [VSCode.dev](https://code.visualstudio.com/docs/editor/vscode-web?WT.mc_id=academic-0000-alfredodeza) e algumas de suas outras funcionalidades.
---
**Aviso Legal**:
Este documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automatizadas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte autoritativa. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save