التتبع (Scrollspy)
تحديث مكونات التنقل أو مجموعات القوائم في الـ Bootstrap تلقائياً بناءً على موضع التمرير للإشارة إلى الرابط النشط حالياً في منطقة العرض.
كيف يعمل ؟
يقوم Scrollspy بتبديل الفئة .active على عناصر الروابط (<a>) عندما يتم تمرير العنصر الذي يحمل الـ id المشار إليه بواسطة href الخاص بالرابط إلى منطقة العرض. يفضل استخدام Scrollspy بالتزامن مع مكون التنقل (nav) في الـ Bootstrap أو مجموعة القوائم (list group), ولكنه سيعمل أيضاً مع أي عناصر روابط في الصفحة الحالية. إليك كيف يعمل.
-
للبدء، يتطلب Scrollspy شيئين: تنقل، أو مجموعة قوائم، أو مجموعة بسيطة من الروابط، بالإضافة إلى حاوية قابلة للتمرير. يمكن أن تكون الحاوية القابلة للتمرير هي الـ
<body>أو عنصراً مخصصاً بارتفاعheightمحدد وoverflow-y: scroll. -
في الحاوية القابلة للتمرير، أضف
data-bs-spy="scroll"وdata-bs-target="#navId"حيثnavIdهو الـidالفريد للتنقل المرتبط. إذا لم يكن هناك عنصر قابل للتركيز داخل العنصر، فتأكد من تضمينtabindex="0"لضمان الوصول عبر لوحة المفاتيح. -
أثناء تمرير الحاوية "المُراقبة"، يتم إضافة وإزالة الفئة
.activeمن روابط التنقل داخل التنقل المرتبط. يجب أن يكون للروابط أهدافidقابلة للتحليل، وإلا فسيتم تجاهلها. على سبيل المثال، يجب أن يتوافق<a href="#home">home</a>مع شيء ما في الـ DOM مثل<div id="home"></div> -
سيتم تجاهل العناصر المستهدفة غير المرئية. راجع قسم العناصر غير المرئية أدناه.
أمثلة
"شريط التنقل (Navbar)"
قم بتمرير المنطقة الموجودة أسفل شريط التنقل (navbar) وراقب تغيير الفئة (class) النشطة. افتح القائمة المنسدلة وراقب تمييز عناصر القائمة المنسدلة أيضاً.
First heading
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
Second heading
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
Third heading
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
Fourth heading
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
Fifth heading
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
<nav id="navbar-example2" class="navbar bg-body-tertiary px-3 mb-3">
<a class="navbar-brand" href="#">Navbar</a>
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link" href="#scrollspyHeading1">First</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#scrollspyHeading2">Second</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">Dropdown</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#scrollspyHeading3">Third</a></li>
<li><a class="dropdown-item" href="#scrollspyHeading4">Fourth</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#scrollspyHeading5">Fifth</a></li>
</ul>
</li>
</ul>
</nav>
<div data-bs-spy="scroll" data-bs-target="#navbar-example2" data-bs-root-margin="0px 0px -40%" data-bs-smooth-scroll="true" class="scrollspy-example bg-body-tertiary p-3 rounded-2" tabindex="0">
<h4 id="scrollspyHeading1">First heading</h4>
<p>...</p>
<h4 id="scrollspyHeading2">Second heading</h4>
<p>...</p>
<h4 id="scrollspyHeading3">Third heading</h4>
<p>...</p>
<h4 id="scrollspyHeading4">Fourth heading</h4>
<p>...</p>
<h4 id="scrollspyHeading5">Fifth heading</h4>
<p>...</p>
</div>
تنقل متداخل (Nested nav)
Scrollspy يعمل أيضاً مع الـ .nav المتداخلة. إذا كانت الـ .nav المتداخلة نشطة .active، فإن العناصر الأبوية لها ستكون نشطة .active أيضاً. قم بتمرير المنطقة المجاورة لشريط التنقل وراقب تغيير الفئة النشطة.
Item 1
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
Keep in mind that the JavaScript plugin tries to pick the right element among all that may be visible. Multiple visible scrollspy targets at the same time may cause some issues.
Item 1-1
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
Keep in mind that the JavaScript plugin tries to pick the right element among all that may be visible. Multiple visible scrollspy targets at the same time may cause some issues.
Item 1-2
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
Keep in mind that the JavaScript plugin tries to pick the right element among all that may be visible. Multiple visible scrollspy targets at the same time may cause some issues.
Item 2
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
Keep in mind that the JavaScript plugin tries to pick the right element among all that may be visible. Multiple visible scrollspy targets at the same time may cause some issues.
Item 3
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
Keep in mind that the JavaScript plugin tries to pick the right element among all that may be visible. Multiple visible scrollspy targets at the same time may cause some issues.
Item 3-1
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
Keep in mind that the JavaScript plugin tries to pick the right element among all that may be visible. Multiple visible scrollspy targets at the same time may cause some issues.
Item 3-2
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
Keep in mind that the JavaScript plugin tries to pick the right element among all that may be visible. Multiple visible scrollspy targets at the same time may cause some issues.
<div class="row">
<div class="col-4">
<nav id="navbar-example3" class="h-100 flex-column align-items-stretch pe-4 border-end">
<nav class="nav nav-pills flex-column">
<a class="nav-link" href="#item-1">Item 1</a>
<nav class="nav nav-pills flex-column">
<a class="nav-link ms-3 my-1" href="#item-1-1">Item 1-1</a>
<a class="nav-link ms-3 my-1" href="#item-1-2">Item 1-2</a>
</nav>
<a class="nav-link" href="#item-2">Item 2</a>
<a class="nav-link" href="#item-3">Item 3</a>
<nav class="nav nav-pills flex-column">
<a class="nav-link ms-3 my-1" href="#item-3-1">Item 3-1</a>
<a class="nav-link ms-3 my-1" href="#item-3-2">Item 3-2</a>
</nav>
</nav>
</nav>
</div>
<div class="col-8">
<div data-bs-spy="scroll" data-bs-target="#navbar-example3" data-bs-smooth-scroll="true" class="scrollspy-example-2" tabindex="0">
<div id="item-1">
<h4>Item 1</h4>
<p>...</p>
</div>
<div id="item-1-1">
<h5>Item 1-1</h5>
<p>...</p>
</div>
<div id="item-1-2">
<h5>Item 1-2</h5>
<p>...</p>
</div>
<div id="item-2">
<h4>Item 2</h4>
<p>...</p>
</div>
<div id="item-3">
<h4>Item 3</h4>
<p>...</p>
</div>
<div id="item-3-1">
<h5>Item 3-1</h5>
<p>...</p>
</div>
<div id="item-3-2">
<h5>Item 3-2</h5>
<p>...</p>
</div>
</div>
</div>
</div>
مجموعة القوائم (List group)
يعمل الـ Scrollspy أيضاً مع الـ .list-group . قم بتمرير المنطقة المجاورة لمجموعة القوائم وراقب تغيير الفئة (class) النشطة.
Item 1
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
Item 2
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
Item 3
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
Item 4
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
<div class="row">
<div class="col-4">
<div id="list-example" class="list-group">
<a class="list-group-item list-group-item-action" href="#list-item-1">Item 1</a>
<a class="list-group-item list-group-item-action" href="#list-item-2">Item 2</a>
<a class="list-group-item list-group-item-action" href="#list-item-3">Item 3</a>
<a class="list-group-item list-group-item-action" href="#list-item-4">Item 4</a>
</div>
</div>
<div class="col-8">
<div data-bs-spy="scroll" data-bs-target="#list-example" data-bs-smooth-scroll="true" class="scrollspy-example" tabindex="0">
<h4 id="list-item-1">Item 1</h4>
<p>...</p>
<h4 id="list-item-2">Item 2</h4>
<p>...</p>
<h4 id="list-item-3">Item 3</h4>
<p>...</p>
<h4 id="list-item-4">Item 4</h4>
<p>...</p>
</div>
</div>
</div>
روابط بسيطة
لا يقتصر الـ Scrollspy على مكونات التنقل ومجموعات القوائم، لذا فهو سيعمل على أي عناصر روابط <a> في المستند الحالي. قم بتمرير المنطقة وراقب تغيير الفئة (class) .active.
Item 1
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
Item 2
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
Item 3
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
Item 4
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
Item 5
This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It’s repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.
<div class="row">
<div class="col-4">
<div id="simple-list-example" class="d-flex flex-column gap-2 simple-list-example-scrollspy text-center">
<a class="p-1 rounded" href="#simple-list-item-1">Item 1</a>
<a class="p-1 rounded" href="#simple-list-item-2">Item 2</a>
<a class="p-1 rounded" href="#simple-list-item-3">Item 3</a>
<a class="p-1 rounded" href="#simple-list-item-4">Item 4</a>
<a class="p-1 rounded" href="#simple-list-item-5">Item 5</a>
</div>
</div>
<div class="col-8">
<div data-bs-spy="scroll" data-bs-target="#simple-list-example" data-bs-offset="0" data-bs-smooth-scroll="true" class="scrollspy-example" tabindex="0">
<h4 id="simple-list-item-1">Item 1</h4>
<p>...</p>
<h4 id="simple-list-item-2">Item 2</h4>
<p>...</p>
<h4 id="simple-list-item-3">Item 3</h4>
<p>...</p>
<h4 id="simple-list-item-4">Item 4</h4>
<p>...</p>
<h4 id="simple-list-item-5">Item 5</h4>
<p>...</p>
</div>
</div>
</div>
العناصر غير المرئية
سيتم تجاهل العناصر المستهدفة غير المرئية ولن تتلقى عناصر التنقل المقابلة لها الفئة .active. ستتجاهل مثيلات الـ Scrollspy التي تم تهيئتها في غلاف غير مرئي جميع العناصر المستهدفة. استخدم الدالة (method) refresh للتحقق من العناصر القابلة للملاحظة بمجرد أن يصبح الغلاف مرئياً.
document.querySelectorAll('#nav-tab>[data-bs-toggle="tab"]').forEach(el => {
el.addEventListener('shown.bs.tab', () => {
const target = el.getAttribute('data-bs-target')
const scrollElem = document.querySelector(`${target} [data-bs-spy="scroll"]`)
bootstrap.ScrollSpy.getOrCreateInstance(scrollElem).refresh()
})
})
الإستخدام
عبر سمات البيانات (Via data attributes)
لإضافة سلوك التتبع (scrollspy) بسهولة إلى شريط التنقل العلوي، أضف data-bs-spy="scroll" إلى العنصر الذي تريد تتبعه (عادةً ما يكون هذا هو <body>). ثم أضف سمة data-bs-target مع الـ id أو اسم الفئة (class) للعنصر الأب لأي مكون .nav في الـ Bootstrap.
<body data-bs-spy="scroll" data-bs-target="#navbar-example">
...
<div id="navbar-example">
<ul class="nav nav-tabs" role="tablist">
...
</ul>
</div>
...
</body>
عبر الـ (JavaScript)
const scrollSpy = new bootstrap.ScrollSpy(document.body, {
target: '#navbar-example'
})
خيارات
بما أنه يمكن تمرير الخيارات عبر سمات البيانات (data attributes) أو الـ JavaScript، يمكنك إضافة اسم الخيار إلى -data-bs ، كما في "data-bs-animation="{value}. تأكد من تغيير نوع حالة اسم الخيار من “camelCase” إلى “kebab-case” عند تمرير الخيارات عبر سمات البيانات. على سبيل المثال، استخدم "data-bs-custom-class="beautifier بدلاً من "data-bs-customClass="beautifier.
بدءاً من Bootstrap 5.2.0، تدعم جميع المكونات سمة بيانات محجوزة تجريبية وهي data-bs-config والتي يمكن أن تحتوي على تكوين بسيط للمكون كسلسلة JSON. عندما يحتوي العنصر على سمات 'data-bs-config='{"delay":0, "title":123} و "data-bs-title="456، ستكون قيمة title النهائية هي 456 وستقوم سمات البيانات المنفصلة بتجاوز القيم المعطاة في data-bs-config. بالإضافة إلى ذلك، يمكن لسمات البيانات الموجودة أن تحتوي على قيم JSON مثل 'data-bs-delay='{"show":0,"hide":150}.
كائن التكوين النهائي هو النتيجة المدمجة لـ data-bs-config و -data-bs و js object حيث يقوم آخر مفتاح-قيمة مُعطى بتجاوز القيم الأخرى.
| الاسم | النوع | الإفتراضي | الوصف |
|---|---|---|---|
rootMargin | string | 0px 0px -25% | وحدات rootMargin صالحة لـ Intersection Observer rootMargin، عند حساب موضع التمرير. |
smoothScroll | boolean | false | تفعيل التمرير السلس عندما ينقر المستخدم على رابط يشير إلى عناصر ScrollSpy القابلة للملاحظة. |
target | string, DOM element | null | يحدد العنصر الذي سيتم تطبيق إضافة Scrollspy عليه. |
threshold | array | [0.1, 0.5, 1] | مدخلات threshold صالحة لـ IntersectionObserver threshold، عند حساب موضع التمرير. |
خيارات مستبعدة
حتى الإصدار v5.1.3 كنا نستخدم خياري offset و method ، واللذين أصبحا الآن مستبعدين وتم استبدالهما بـ rootMargin.
للحفاظ على التوافق مع الإصدارات السابقة، سنستمر في تحليل offset المعطى إلى rootMargin ، ولكن هذه الميزة سيتم إزالتها في الإصدار v6.
الطرق، الأساليب (Methods)
| الأسلوب | الوصف |
|---|---|
dispose | يقوم بإزالة الـ scrollspy الخاص بالعنصر. (يزيل البيانات المخزنة في عنصر الـ DOM) |
getInstance | طريقة (Static) للحصول على مثيل (instance) الـ scrollspy المرتبط بعنصر DOM. |
getOrCreateInstance | طريقة (Static) للحصول على مثيل (instance) الـ scrollspy المرتبط بعنصر DOM، أو إنشاء مثيل جديد في حال لم يتم تهيئته. |
refresh | عند إضافة أو إزالة عناصر في الـ DOM، ستحتاج إلى استدعاء طريقة الـ refresh. |
إليك مثال باستخدام أسلوب الـ refresh:
const dataSpyList = document.querySelectorAll('[data-bs-spy="scroll"]')
dataSpyList.forEach(dataSpyEl => {
bootstrap.ScrollSpy.getInstance(dataSpyEl).refresh()
})
الأحداث (Events)
| الحدث | الوصف |
|---|---|
activate.bs.scrollspy | يتم إطلاق هذا الحدث على عنصر التمرير كلما تم تفعيل رابط بواسطة الـ scrollspy. |
const firstScrollSpyEl = document.querySelector('[data-bs-spy="scroll"]')
firstScrollSpyEl.addEventListener('activate.bs.scrollspy', () => {
// do something...
})