ما هي أفضل الممارسات لتصميم التمرير اللانهائي Designing Infinite Scrolls ؟
نظريملاحظة: قد تستخدم بعض الأمثلة التفاعلية أكواد CSS و JavaScript لم تتعلمها بعد. لا تقلق بشأن محاولة فهم الكود بالكامل؛ فالهدف من هذه الأمثلة هو عرض نماذج لمفاهيم التصميم هذه، لتتمكن من فهم آلية عملها بشكل أفضل.
يُعد التمرير اللانهائي (Infinite scrolling) نمطاً تصميمياً يعمل على تحميل المزيد من المحتوى كلما قام المستخدم بالتمرير إلى أسفل الصفحة (scrolls down the page). وغالباً ما يُستخدم هذا النمط في مواقع التواصل الاجتماعي مثل "تويتر"؛ فعلى سبيل المثال، إذا كنت قد سجلت دخولك وترغب في الاطلاع على المزيد من التغريدات، يمكنك التمرير للأسفل ليتم تحميل تغريدات إضافية، وهذا مثال على التمرير اللانهائي (Infinite scrolling).
index.html
<link rel="stylesheet" href="styles.css">
<div class="infinite-scroll">
<div class="post">المنشور 1</div>
<div class="post">المنشور 2</div>
<div class="post">المنشور 3</div>
<div class="post">المنشور 4</div>
<div class="post">المنشور 5</div>
<div class="post">المنشور 6</div>
<div class="post">المنشور 7</div>
<div class="post">المنشور 8</div>
<div class="post">المنشور 9</div>
<div class="post">المنشور 10</div>
<!-- سيتم تحميل المزيد من المنشورات هنا كلما قام المستخدم بالتمرير للأسفل -->
</div>
<script src="index.js"></script>
styles.css
.infinite-scroll {
display: flex;
flex-direction: column;
gap: 12px;
}
.post {
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
}
index.js
// محاكاة تحميل المزيد من المحتوى أثناء تمرير المستخدم
window.addEventListener('scroll', () => {
if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
loadMorePosts();
}
});
function loadMorePosts() {
const container = document.querySelector('.infinite-scroll');
for (let i = 0; i < 3; i ++) {
const post = document.createElement('div');
post.className = 'post';
post.textContent = `المنشور ${container.children.length + 1}`;
container.appendChild(post);
}
}
معاينة:
يُستخدم التمرير اللانهائي (Infinite scrolling) أيضاً كبديل لنظام تقسيم المحتوى إلى صفحات (Pagination). ويُعد هذا التقسيم نمطاً تصميمياً يعمل على تجزئة المحتوى إلى صفحات متعددة، وغالباً ما يُستخدم عندما تكون هناك كمية كبيرة من المحتوى المراد عرضه؛ ومن الأمثلة عليه ما يحدث عند البحث عن شيء ما في "جوجل"، حيث تظهر نتائج البحث موزعة على صفحات متعددة. ففي نظام تقسيم الصفحات (pagination)، يتعين عليك النقر على زر للانتقال إلى الصفحة التالية، بينما يتيح لك التمرير اللانهائي مواصلة التمرير للأسفل (scrolling down) ليتم تحميل المزيد من المحتوى تلقائياً.
index.html
<link rel="stylesheet" href="styles.css">
<div class="pagination">
<div class="post">المنشور 1</div>
<div class="post">المنشور 2</div>
<div class="post">المنشور 3</div>
<!-- ستتوفر المزيد من المنشورات في الصفحات التالية. -->
</div>
<div class="pagination-controls">
<button class="prev" disabled>السابق</button>
<button class="next">التالي</button>
</div>
<script src="index.js"></script>
styles.css
.pagination {
display: flex;
flex-direction: column;
gap: 12px;
}
.post {
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
}
.pagination-controls {
margin-top: 12px;
}
.pagination-controls button {
padding: 8px 16px;
margin-right: 8px;
}
index.js
let currentPage = 1;
const postsPerPage = 3;
const totalPosts = 9;
const totalPages = Math.ceil(totalPosts / postsPerPage);
const container = document.querySelector('.pagination');
const prevButton = document.querySelector('.prev');
const nextButton = document.querySelector('.next');
function renderPosts() {
container.innerHTML = '';
const start = (currentPage - 1) * postsPerPage;
const end = start + postsPerPage;
for (let i = start; i < end && i < totalPosts; i++) {
const post = document.createElement('div');
post.className = 'post';
post.textContent = `المنشور ${i + 1}`;
container.appendChild(post);
}
prevButton.disabled = currentPage === 1;
nextButton.disabled = currentPage === totalPages;
}
prevButton.addEventListener('click', () => {
if (currentPage > 1) {
currentPage--;
renderPosts();
}
});
nextButton.addEventListener('click', () => {
if (currentPage < totalPages) {
currentPage++;
renderPosts();
}
});
renderPosts();
معاينة:
عند دمج ميزة التمرير اللانهائي (infinite scrolling) في تصميمك، هناك بعض الممارسات المثلى التي ينبغي وضعها في الاعتبار. وتتمثل الخطوة الأولى في توفير زر "تحميل المزيد" (Load More) يقوم بتحميل المجموعة التالية من النتائج عند النقر عليه؛ إذ تُعد هذه وسيلة فعالة لمنح المستخدم حرية التحكم في توقيت رغبته في عرض المزيد من المحتوى.
index.html
<link rel="stylesheet" href="styles.css">
<div class="infinite-scroll">
<div class="post">المنشور 1</div>
<div class="post">المنشور 2</div>
<div class="post">المنشور 3</div>
<!-- سيتم تحميل المزيد من المنشورات عندما ينقر المستخدم على "تحميل المزيد". -->
</div>
<button class="load-more">تحميل المزيد</button>
<script src="index.js"></script>
styles.css
.infinite-scroll {
display: flex;
flex-direction: column;
gap: 12px;
}
.post {
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
}
.load-more {
margin-top: 12px;
padding: 8px 16px;
}
index.js
const loadMoreButton = document.querySelector('.load-more');
const container = document.querySelector('.infinite-scroll');
loadMoreButton.addEventListener('click', () => {
loadMorePosts();
});
function loadMorePosts() {
for (let i = 0; i < 3; i++) {
const post = document.createElement('div');
post.className = 'post';
post.textContent = `المنشور ${container.children.length + 1}`;
container.appendChild(post);
}
}
معاينة:
من الأمور الأخرى التي يمكن أخذها بعين الاعتبار إضافة زر "رجوع" ؛ إذ يتيح ذلك للمستخدمين العودة إلى الصفحة السابقة دون الحاجة إلى التمرير صعوداً إلى أعلى الصفحة بالكامل، مما يعزز تجربة المستخدم ويمنحهم تحكماً أكبر في تجربة التصفح.
قد تلاحظ أحياناً تصاميم تتضمن زر "العودة إلى الأعلى" (Back to the top)، والذي يعيد المستخدمين إلى بداية صفحة النتائج. ومن الأمور الأخرى التي ينبغي مراعاتها توفير مؤشر للتحميل (loading indicator)؛ إذ يجب أن يدرك المستخدمون بوضوح أنه يجري تحميل المزيد من المحتوى، وإلا فقد يظنون أن الصفحة معطلة.
index.html
<link rel="stylesheet" href="styles.css">
<div class="infinite-scroll">
<div class="post">المنشور 1</div>
<div class="post">المنشور 2</div>
<div class="post">المنشور 3</div>
<div class="post">المنشور 4</div>
<div class="post">المنشور 5</div>
<div class="post">المنشور 6</div>
<div class="post">المنشور 7</div>
<div class="post">المنشور 8</div>
<div class="post">المنشور 9</div>
<div class="post">المنشور 10</div>
<!-- سيتم تحميل المزيد من المنشورات هنا كلما قام المستخدم بالتمرير للأسفل -->
</div>
<div class="loading-indicator" style="display: none">تحميل...</div>
<button id="back-to-top" class="back-to-top">↑ العودة إلى الأعلى</div>
<script src="index.js"></script>
styles.css
.infinite-scroll {
display: flex;
flex-direction: column;
gap: 12px;
}
.post {
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
}
.loading-indicator {
margin-top: 12px;
font-weight: bold;
}
.back-to-top {
position: fixed;
bottom: 30px;
right: 30px;
display: none;
padding: 10px 15px;
background-color: #007BFF;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
}
.back-to-top:hover {
background-color: #0056b3;
}
index.js
const container = document.querySelector('.infinite-scroll');
const loadingIndicator = document.querySelector('.loading-indicator');
const backToTopBtn = document.getElementById('back-to-top');
window.addEventListener('scroll', () => {
if (window.scrollY > 400) {
backToTopBtn.style.display = 'block';
} else {
backToTopBtn.style.display = 'none';
}
if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
loadMorePosts();
}
});
backToTopBtn.addEventListener('click', () => {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
function loadMorePosts() {
loadingIndicator.style.display = 'block';
setTimeout(() => {
for (let i = 0; i < 3; i++) {
const post = document.createElement('div');
post.className = 'post';
post.textContent = `المنشور ${container.children.length + 1}`;
container.appendChild(post);
}
loadingIndicator.style.display = 'none';
}, 1000);
}
معاينة:
من الاعتبارات الأخيرة الحرصُ على إبقاء تذييل الصفحة (footer) متاحاً للمستخدم؛ فإذا كان التذييل (footer) يحتوي على معلومات مهمة، فينبغي أن يكون في متناول المستخدم في جميع الأوقات.
ختاماً، يُعد التمرير اللانهائي (infinite scrolling) وسيلةً ممتازةً لعرض المحتوى على موقعك الإلكتروني؛ ومع ذلك، ينبغي عليك مراعاة أفضل الممارسات عند تصميم هذه الميزة لضمان توفير أفضل تجربة ممكنة للمستخدم.
أسئلة :
ما هو التمرير اللانهائي (infinite scrolling) ؟
1. نمط تصميم يغير شريط التمرير في الصفحة. ❌
2. نمط تصميم يغير حجم الصفحة. ❌
3. نمط تصميم لتغيير لون خلفية الصفحة. ❌
4. نمط تصميم يقوم بتحميل المزيد من المحتوى أثناء قيام المستخدم بالتمرير لأسفل الصفحة. ✅
ما هو دور زر "تحميل المزيد" في خاصية التمرير اللانهائي؟
1. يُعيد تحميل الصفحة. ❌
2. يمنح المستخدمين التحكم في توقيت رغبتهم في رؤية المزيد من المحتوى. ✅
3. يتيح للمستخدمين العودة إلى المحتوى الذي تم تحميله سابقاً. ❌
4. يُقيّد كمية البيانات التي يمكن تحميلها. ❌
لماذا من المهم الحفاظ على إمكانية الوصول إلى تذييل الصفحة (footer) عند استخدام خاصية التمرير اللانهائي؟
1. يساعد ذلك في إبراز الألوان بشكل أكبر على الصفحة. ❌
2. يساعد ذلك في تسريع تحميل الصفحة. ❌
3. ليس من الضروري جعل تذييل الصفحة متاحاً وسهل الوصول إليه. ❌
4. لكي يتمكن المستخدم من الوصول إلى الروابط والمعلومات المهمة الموجودة في تذييل الصفحة في جميع الأوقات. ✅