76- آموزش جاوااسکریپت | ساخت Profile Scroller با Iterator
در این آموزش یک پروژه کوچک با JavaScript Iterator میسازیم که پروفایل کاربران را بهصورت مرحلهای نمایش میدهد. همچنین یاد میگیریم چطور Iterator را با DOM ترکیب کنیم و با Bootstrap یک رابط ساده و مرتب بسازیم.
در این آموزش یک پروژه کوچک و کاربردی پیادهسازی میکنیم تا استفاده واقعی از Iterator در جاوااسکریپت را بهتر درک کنیم.
بسیاری از توسعهدهندگان با مفاهیمی مثل Iterator و Generator آشنا میشوند، اما درک کاربرد عملی آنها در پروژههای واقعی همیشه ساده نیست. به همین دلیل در این بخش یک Profile Scroller میسازیم؛ یعنی بخشی که با هر بار کلیک روی دکمه Next، اطلاعات پروفایل بعدی نمایش داده میشود.
در این پروژه:
- از Bootstrap برای ظاهر مناسب رابط کاربری استفاده میکنیم.
- دادهها را بهصورت موقت به شکل Hard Code تعریف میکنیم.
- با یک Iterator سفارشی، پروفایلها را یکییکی پیمایش میکنیم.
- اطلاعات هر پروفایل را در DOM نمایش میدهیم.
ساختار پروژه
برای شروع، یک پوشه پروژه با فایلهای زیر در نظر میگیریم:
index.htmlapp.js
در فایل HTML، قالب اولیه Bootstrap را قرار میدهیم و فایل جاوااسکریپت را هم به آن متصل میکنیم.
کد HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Profile Scroller</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css"
/>
</head>
<body>
<div class="container mt-5 text-center">
<div class="row">
<div class="col-md-6 mx-auto">
<h1 class="mb-3">Profile Scroller</h1>
<div id="imageDisplay"></div>
<br />
<div id="profileDisplay"></div>
<br />
<button id="next" class="btn btn-dark btn-block">
Next
</button>
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
تعریف دادهها
در یک پروژه واقعی، این اطلاعات معمولاً از API یا دیتابیس دریافت میشوند. اما در این آموزش، دادهها را بهصورت ثابت در فایل جاوااسکریپت قرار میدهیم.
کد دادهها
const data = [
{
name: 'John Doe',
age: 32,
gender: 'male',
lookingfor: 'female',
location: 'Boston, MA',
image: 'https://randomuser.me/api/portraits/men/82.jpg'
},
{
name: 'Jen Smith',
age: 26,
gender: 'female',
lookingfor: 'male',
location: 'Miami, FL',
image: 'https://randomuser.me/api/portraits/women/82.jpg'
},
{
name: 'William Johnson',
age: 38,
gender: 'male',
lookingfor: 'female',
location: 'Lynn, MA',
image: 'https://randomuser.me/api/portraits/men/83.jpg'
}
];
ساخت Iterator سفارشی
حالا یک Iterator میسازیم که پروفایلها را بهترتیب برگرداند. این Iterator در هر بار اجرای متد next()، یک پروفایل جدید تحویل میدهد.
کد Iterator
function profileIterator(profiles) {
let nextIndex = 0;
return {
next: function () {
return nextIndex < profiles.length
? { value: profiles[nextIndex++], done: false }
: { done: true };
}
};
}
توضیح عملکرد
در این تابع:
- متغیر
nextIndexنقش شمارنده را دارد. - تا زمانی که مقدار آن از طول آرایه کمتر باشد، پروفایل بعدی برگردانده میشود.
- وقتی همه پروفایلها تمام شوند، خروجی
done: trueخواهد بود.
مقداردهی اولیه Iterator
حالا Iterator را با دادههای خود مقداردهی میکنیم:
const profiles = profileIterator(data);
مدیریت رویداد کلیک
در مرحله بعد، روی دکمه Next یک رویداد کلیک تعریف میکنیم تا با هر بار کلیک، پروفایل بعدی نمایش داده شود.
document.getElementById('next').addEventListener('click', nextProfile);
نمایش پروفایل در DOM
اکنون تابعی مینویسیم که اطلاعات پروفایل فعلی را از Iterator بگیرد و در صفحه نمایش دهد.
کد نمایش پروفایل
function nextProfile() {
const currentProfile = profiles.next().value;
if (currentProfile !== undefined) {
document.getElementById('profileDisplay').innerHTML = `
<ul class="list-group">
<li class="list-group-item">Name: ${currentProfile.name}</li>
<li class="list-group-item">Age: ${currentProfile.age}</li>
<li class="list-group-item">Location: ${currentProfile.location}</li>
<li class="list-group-item">Gender: ${currentProfile.gender}</li>
<li class="list-group-item">Looking For: ${currentProfile.lookingfor}</li>
</ul>
`;
document.getElementById('imageDisplay').innerHTML = `
<img src="${currentProfile.image}" class="img-fluid" alt="${currentProfile.name}">
`;
} else {
window.location.reload();
}
}
نکته مهم
اگر دیگر پروفایلی وجود نداشته باشد، مقدار currentProfile برابر undefined میشود.
اگر این وضعیت را مدیریت نکنیم، برنامه هنگام دسترسی به ویژگیهایی مثل name خطا میدهد. به همین دلیل از شرط if استفاده میکنیم.
در این مثال، وقتی همه پروفایلها تمام شوند، صفحه دوباره بارگذاری میشود تا پیمایش از ابتدا شروع شود.
نمایش اولین پروفایل هنگام بارگذاری صفحه
در حال حاضر، نمایش پروفایل فقط با کلیک روی دکمه انجام میشود. اگر بخواهیم اولین پروفایل از همان ابتدا نمایش داده شود، کافی است تابع nextProfile() را یک بار بهصورت دستی اجرا کنیم.
nextProfile();
کد کامل فایل app.js
const data = [
{
name: 'John Doe',
age: 32,
gender: 'male',
lookingfor: 'female',
location: 'Boston, MA',
image: 'https://randomuser.me/api/portraits/men/82.jpg'
},
{
name: 'Jen Smith',
age: 26,
gender: 'female',
lookingfor: 'male',
location: 'Miami, FL',
image: 'https://randomuser.me/api/portraits/women/82.jpg'
},
{
name: 'William Johnson',
age: 38,
gender: 'male',
lookingfor: 'female',
location: 'Lynn, MA',
image: 'https://randomuser.me/api/portraits/men/83.jpg'
}
];
function profileIterator(profiles) {
let nextIndex = 0;
return {
next: function () {
return nextIndex < profiles.length
? { value: profiles[nextIndex++], done: false }
: { done: true };
}
};
}
const profiles = profileIterator(data);
document.getElementById('next').addEventListener('click', nextProfile);
function nextProfile() {
const currentProfile = profiles.next().value;
if (currentProfile !== undefined) {
document.getElementById('profileDisplay').innerHTML = `
<ul class="list-group">
<li class="list-group-item">Name: ${currentProfile.name}</li>
<li class="list-group-item">Age: ${currentProfile.age}</li>
<li class="list-group-item">Location: ${currentProfile.location}</li>
<li class="list-group-item">Gender: ${currentProfile.gender}</li>
<li class="list-group-item">Looking For: ${currentProfile.lookingfor}</li>
</ul>
`;
document.getElementById('imageDisplay').innerHTML = `
<img src="${currentProfile.image}" class="img-fluid" alt="${currentProfile.name}">
`;
} else {
window.location.reload();
}
}
nextProfile();
جمعبندی
در این آموزش دیدیم که چگونه میتوان از Iterator در یک سناریوی واقعی و قابل لمس استفاده کرد.
با کمک این الگو توانستیم:
- دادهها را بهصورت مرحلهای پیمایش کنیم
- نمایش پروفایلها را کنترل کنیم
- Iterator را با DOM ترکیب کنیم
- یک رابط ساده و کاربردی با Bootstrap بسازیم
این پروژه کوچک است، اما ایدهای بسیار خوب برای درک بهتر کاربرد Iteratorها در برنامههای فرانتاند محسوب میشود.