Skip to main content Skip to docs navigation

اجعل الـ Bootstrap ينبض بالحياة باستخدام الـ JavaScript plugins الاختيارية الخاصة بنا. تعرف على كل إضافة، وخيارات الـ API البرمجية والبيانات، والمزيد.

إضافات فردية أو مجمعة

يمكن تضمين الإضافات (plugins) بشكل فردي (باستخدام ملفات js/dist/*.js الفردية الخاصة بـ Bootstrap) أو جميعها مرة واحدة باستخدام bootstrap.js أو النسخة المصغرة bootstrap.min.js (لا تقم بتضمين كليهما).

إذا كنت تستخدم مجمع حزم (Webpack, Parcel, Vite…) يمكنك استخدام ملفات /js/dist/*.js الجاهزة بنظام UMD.

الاستخدام مع أطر عمل JavaScript

بينما يمكن استخدام الـ Bootstrap CSS مع أي إطار عمل، فإن الـ Bootstrap JavaScript غير متوافق تماماً مع أطر عمل JavaScript مثل React و Vue و Angular التي تفترض معرفة كاملة بالـ DOM. قد يحاول كل من Bootstrap وإطار العمل تعديل نفس عنصر DOM، مما يؤدي إلى حدوث أخطاء مثل القوائم المنسدلة التي تظل عالقة في وضع "الفتح".

البديل الأفضل لأولئك الذين يستخدمون هذا النوع من أطر العمل هو استخدام حزمة خاصة بإطار العمل بدلاً من الـ Bootstrap JavaScript. إليك بعض الخيارات الأكثر شيوعاً:

استخدام Bootstrap كـ module

جرب ذلك بنفسك! قم بتنزيل الكود المصدري والعرض التوضيحي الشغال لاستخدام Bootstrap كـ ES module من مستودع twbs/examples. يمكنك أيضاً فتح المثال في StackBlitz.

نحن نوفر نسخة من Bootstrap مبنية كـ ESM (bootstrap.esm.js و bootstrap.esm.min.js) والتي تتيح لك استخدام Bootstrap كـ module في المتصفح، إذا كانت المتصفحات المستهدفة تدعم ذلك.

<script type="module">
  import { Toast } from 'bootstrap.esm.min.js'

  Array.from(document.querySelectorAll('.toast'))
    .forEach(toastNode => new Toast(toastNode))
</script>

مقارنة بمجمعات الـ JS، فإن استخدام ESM في المتصفح يتطلب منك استخدام المسار الكامل واسم الملف بدلاً من اسم الـ module. اقرأ المزيد عن JS modules في المتصفح. لهذا السبب نستخدم 'bootstrap.esm.min.js' بدلاً من 'bootstrap' أعلاه. ومع ذلك، فإن هذا يزداد تعقيداً بسبب اعتمادنا على Popper، والتي تقوم باستيراد Popper إلى الـ JavaScript الخاصة بنا كما يلي:

import * as Popper from "@popperjs/core"

إذا حاولت القيام بذلك كما هو، فسترى خطأً في وحدة التحكم (console) على النحو التالي:

Uncaught TypeError: Failed to resolve module specifier "@popperjs/core". Relative references must start with either "/", "./", or "../".

لإصلاح ذلك، يمكنك استخدام importmap لتحويل أسماء الـ modules العشوائية إلى مسارات كاملة. إذا كانت المتصفحات المستهدفة لا تدعم importmap ، فستحتاج إلى استخدام مشروع es-module-shims. إليك كيف يعمل ذلك بالنسبة لـ Bootstrap و Popper:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
    <title>Hello, modularity!</title>
  </head>
  <body>
    <h1>Hello, modularity!</h1>
    <button id="popoverButton" type="button" class="btn btn-primary btn-lg" data-bs-toggle="popover" title="ESM in Browser" data-bs-content="Bang!">Custom popover</button>

    <script async src="https://cdn.jsdelivr.net/npm/es-module-shims@1/dist/es-module-shims.min.js" crossorigin="anonymous"></script>
    <script type="importmap">
    {
      "imports": {
        "@popperjs/core": "https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/esm/popper.min.js",
        "bootstrap": "https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.esm.min.js"
      }
    }
    </script>
    <script type="module">
      import * as bootstrap from 'bootstrap'

      new bootstrap.Popover(document.getElementById('popoverButton'))
    </script>
  </body>
</html>

التبعيات (Dependencies)

تعتمد بعض الإضافات (plugins) ومكونات CSS على إضافات أخرى. إذا قمت بتضمين الإضافات بشكل فردي، فتأكد من مراجعة هذه التبعيات في المستندات.

تعتمد القوائم المنسدلة، والـ popovers، والـ tooltips الخاصة بنا أيضاً على Popper.

سمات البيانات (Data attributes)

يمكن تفعيل وتكوين جميع إضافات Bootstrap تقريباً من خلال HTML فقط باستخدام سمات البيانات (وهي طريقتنا المفضلة لاستخدام وظائف الـ JavaScript). تأكد من استخدام مجموعة واحدة فقط من سمات البيانات على عنصر واحد (على سبيل المثال، لا يمكنك تشغيل tooltip و modal من نفس الزر).

بما أنه يمكن تمرير الخيارات عبر سمات البيانات (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 حيث يقوم آخر مفتاح-قيمة مُعطى بتجاوز القيم الأخرى.

المحددات (Selectors)

نحن نستخدم دوال querySelector و querySelectorAll الأصلية للاستعلام عن عناصر DOM لأسباب تتعلق بالأداء، لذا يجب عليك استخدام محددات صالحة. إذا كنت تستخدم محددات خاصة مثل collapse:Example ، فتأكد من عمل escape لها.

الأحداث (Events)

يوفر Bootstrap أحداثاً مخصصة لمعظم إجراءات الإضافات الفريدة. بشكل عام، تأتي هذه الأحداث في صيغة المصدر واسم المفعول - حيث يتم تشغيل صيغة المصدر (مثلاً show) عند بدء الحدث، ويتم تشغيل صيغة اسم المفعول (مثلاً shown) عند اكتمال الإجراء.

توفر جميع أحداث المصدر وظيفة preventDefault(). وهذا يوفر القدرة على إيقاف تنفيذ الإجراء قبل أن يبدأ. كما أن إرجاع false من معالج الحدث سيؤدي تلقائياً إلى استدعاء preventDefault().

const myModal = document.querySelector('#myModal')

myModal.addEventListener('show.bs.modal', event => {
  return event.preventDefault() // stops modal from being shown
})

الـ API البرمجية (Programmatic API)

تقبل جميع الدوال المنشئة (constructors) كائناً اختيارياً للخيارات أو لا شيء (مما يؤدي إلى بدء تشغيل إضافة (plugin) بسلوكها الافتراضي):

const myModalEl = document.querySelector('#myModal')
const modal = new bootstrap.Modal(myModalEl) // initialized with defaults

const configObject = { keyboard: false }
const modal1 = new bootstrap.Modal(myModalEl, configObject) // initialized with no keyboard

إذا كنت ترغب في الحصول على نسخة (instance) معينة من إضافة (plugin)، فإن كل إضافة توفر دالة getInstance. على سبيل المثال، لاسترداد نسخة مباشرة من عنصر:

bootstrap.Popover.getInstance(myPopoverEl)

ستعيد هذه الدالة null إذا لم يتم إنشاء نسخة فوق العنصر المطلوب.

بدلاً من ذلك، يمكن استخدام getOrCreateInstance للحصول على النسخة المرتبطة بعنصر DOM، أو إنشاء نسخة جديدة في حال لم يتم تهيئتها.

bootstrap.Popover.getOrCreateInstance(myPopoverEl, configObject)

في حال لم يتم تهيئة نسخة (instance)، فقد تقبل وتستخدم كائناً اختيارياً للتكوين كمعامل ثانٍ.

محددات CSS في الدوال المنشئة (constructors)

بالإضافة إلى دالتي getInstance و getOrCreateInstance، يمكن لجميع الدوال المنشئة (constructors) للإضافات (plugins) قبول عنصر DOM أو محدد CSS صالح كمعامل أول. يتم العثور على عناصر الإضافات باستخدام دالة querySelector لأن إضافاتنا تدعم عنصراً واحداً فقط.

const modal = new bootstrap.Modal('#myModal')
const dropdown = new bootstrap.Dropdown('[data-bs-toggle="dropdown"]')
const offcanvas = bootstrap.Offcanvas.getInstance('#myOffcanvas')
const alert = bootstrap.Alert.getOrCreateInstance('#myAlert')

الـ (functions) غير المتزامنة والانتقالات

جميع طرق الـ API البرمجية هي غير متزامنة (asynchronous) وتعود إلى المستدعي بمجرد بدء الانتقال، ولكن قبل انتهائه. ومن أجل تنفيذ إجراء بمجرد اكتمال الانتقال، يمكنك الاستماع إلى الحدث المقابل.

const myCollapseEl = document.querySelector('#myCollapse')

myCollapseEl.addEventListener('shown.bs.collapse', event => {
  // Action to execute once the collapsible area is expanded
})

بالإضافة إلى ذلك، فإن استدعاء أي method على مكون في حالة انتقال (transitioning component) سيتم تجاهله.

const myCarouselEl = document.querySelector('#myCarousel')
const carousel = bootstrap.Carousel.getInstance(myCarouselEl) // Retrieve a Carousel instance

myCarouselEl.addEventListener('slid.bs.carousel', event => {
  carousel.to('2') // Will slide to the slide 2 as soon as the transition to slide 1 is finished
})

carousel.to('1') // Will start sliding to the slide 1 and returns to the caller
carousel.to('2') // !! Will be ignored, as the transition to the slide 1 is not finished !!

الطريقة dispose (method)

بينما قد يبدو من الصحيح استخدام الطريقة dispose مباشرة بعد hide()، إلا أن ذلك سيؤدي إلى نتائج غير صحيحة. إليك مثال على الاستخدام الخاطئ:

const myModal = document.querySelector('#myModal')
myModal.hide() // it is asynchronous

myModal.addEventListener('shown.bs.hidden', event => {
  myModal.dispose()
})

الإعدادات الافتراضية

يمكنك تغيير الإعدادات الافتراضية لإضافة (plugin) عن طريق تعديل كائن Constructor.Default الخاص بالإضافة:

// changes default for the modal plugin’s `keyboard` option to false
bootstrap.Modal.Default.keyboard = false

الطرق والخصائص (Methods and properties)

توفر كل إضافة (plugin) في Bootstrap الطرق والخصائص الاستاتيكية (static properties) التالية.

الطريقة (Method)الوصف
disposeتقوم بتدمير الـ modal الخاص بالعنصر. (تزيل البيانات المخزنة في عنصر DOM)
getInstanceطريقة استاتيكية (Static) تتيح لك الحصول على نسخة (instance) الـ modal المرتبطة بعنصر DOM.
getOrCreateInstanceطريقة استاتيكية (Static) تتيح لك الحصول على نسخة (instance) الـ modal المرتبطة بعنصر DOM، أو إنشاء نسخة جديدة في حال لم يتم تهيئتها.
الخاصية الاستاتيكية (Static property)الوصف
NAMEتعيد اسم الإضافة (plugin). (مثال: bootstrap.Tooltip.NAME)
VERSIONيمكن الوصول إلى إصدار كل إضافة من إضافات Bootstrap عبر خاصية VERSION الخاصة بالدالة المنشئة (constructor) للإضافة (مثال: bootstrap.Tooltip.VERSION)

التنظيف/التطهير/التعقيم (Sanitizer)

تستطيع مكونات الـ tooltip والـ popover لدينا عرض HTML عشوائي في الصفحة إذا تم تكوينها للقيام بذلك. لمنع هجمات حقن النصوص البرمجية عبر المواقع (XSS)، تستخدم هذه المكونات الـ content sanitizer المدمج لدينا لتطهير أي خيارات تقبل HTML قبل عرضها على الصفحة. يتم تفعيل تطهير المحتوى (Content sanitization) بشكل افتراضي.

العلامات (tags) والسمات (attributes) المسموح بها افتراضياً هي كما يلي. أي علامات أو سمات غير مسموح بها صراحةً سيتم إزالتها أثناء التطهير:

const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i

export const DefaultAllowlist = {
  // Global attributes allowed on any supplied element below.
  '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
  a: ['target', 'href', 'title', 'rel'],
  area: [],
  b: [],
  br: [],
  col: [],
  code: [],
  dd: [],
  div: [],
  dl: [],
  dt: [],
  em: [],
  hr: [],
  h1: [],
  h2: [],
  h3: [],
  h4: [],
  h5: [],
  h6: [],
  i: [],
  img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
  li: [],
  ol: [],
  p: [],
  pre: [],
  s: [],
  small: [],
  span: [],
  sub: [],
  sup: [],
  strong: [],
  u: [],
  ul: []
}

توخَّ الحذر عند استخدام هذه الخيارات المتقدمة. راجع قائمة غش منع حقن النصوص البرمجية عبر المواقع من OWASP لمزيد من المعلومات. الثغرات الناتجة فقط عن تعطيل أو تعديل تطهير المحتوى لا تعتبر ضمن نطاق نموذج الأمان الخاص بـ Bootstrap.

يمكنك إضافة قيم جديدة إلى الـ allowList الافتراضية هذه:

const myDefaultAllowList = bootstrap.Tooltip.Default.allowList

// To allow table elements
myDefaultAllowList.table = []

// To allow td elements and data-bs-option attributes on td elements
myDefaultAllowList.td = ['data-bs-option']

// You can push your custom regex to validate your attributes.
// Be careful about your regular expressions being too lax
const myCustomRegex = /^data-my-app-[\w-]+/
myDefaultAllowList['*'].push(myCustomRegex)

يمكنك أيضاً استبدال الـ sanitizer الخاص بنا بمكتبة مخصصة، على سبيل المثال DOMPurify:

const yourTooltipEl = document.querySelector('#yourTooltip')
const tooltip = new bootstrap.Tooltip(yourTooltipEl, {
  sanitizeFn(content) {
    return DOMPurify.sanitize(content)
  }
})

استخدام الـ (jQuery) اختيارياً

أنت لست بحاجة إلى jQuery في Bootstrap 5، ولكن لا يزال من الممكن استخدام المكونات الخاصة بنا مع jQuery. إذا اكتشف Bootstrap وجود jQuery في كائن window ، فسيقوم بإضافة جميع المكونات الخاصة بنا إلى نظام الإضافات (plugins) الخاص بـ jQuery. وهذا يتيح لك القيام بما يلي:

// to enable tooltips with the default configuration
$('[data-bs-toggle="tooltip"]').tooltip()

// to initialize tooltips with given configuration
$('[data-bs-toggle="tooltip"]').tooltip({
  boundary: 'clippingParents',
  customClass: 'myClass'
})

// to trigger the `show` method
$('#myTooltip').tooltip('show')

ينطبق الأمر نفسه على المكونات الأخرى لدينا.

عدم التعارض (No conflict)

في بعض الأحيان يكون من الضروري استخدام إضافات (plugins) Bootstrap مع أطر عمل واجهة مستخدم (UI frameworks) أخرى. في هذه الظروف، قد تحدث تصادمات في نطاق الأسماء (namespace collisions) أحياناً. إذا حدث هذا، يمكنك استدعاء .noConflict على الإضافة التي ترغب في استعادة قيمتها.

const bootstrapButton = $.fn.button.noConflict() // return $.fn.button to previously assigned value
$.fn.bootstrapBtn = bootstrapButton // give $().bootstrapBtn the Bootstrap functionality

لا يدعم Bootstrap رسمياً مكتبات JavaScript الخارجية مثل Prototype أو jQuery UI. وعلى الرغم من وجود .noConflict والأحداث ذات النطاقات المحددة (namespaced events)، فقد تكون هناك مشاكل في التوافق يتعين عليك إصلاحها بنفسك.

أحداث الـ (jQuery)

سيكتشف Bootstrap وجود jQuery إذا كان jQuery موجوداً في كائن window ولم يتم تعيين سمة data-bs-no-jquery على عنصر <body>. إذا تم العثور على jQuery، سيقوم Bootstrap بإصدار الأحداث بفضل نظام أحداث jQuery. لذا، إذا كنت تريد الاستماع إلى أحداث Bootstrap، فسيتعين عليك استخدام طرق (methods) jQuery (.on و .one) بدلاً من addEventListener.

$('#myTab a').on('shown.bs.tab', () => {
  // do something...
})

تعطيل الـ (JavaScript)

ليس لإضافات (plugins) Bootstrap أي بديل خاص (fallback) عندما يتم تعطيل JavaScript. إذا كنت تهتم بتجربة المستخدم في هذه الحالة، استخدم <noscript> لشرح الموقف (وكيفية إعادة تفعيل JavaScript) لمستخدميك، و/أو أضف البدائل المخصصة الخاصة بك.