Skip to main content Skip to docs navigation

JavaScript

Dale vida a Bootstrap con nuestros plugins de JavaScript opcionales. Obtén información sobre cada plugin, nuestras opciones de API de datos y programáticas, y más.

Individual o compilado

Los plugins se pueden incluir individualmente (usando los archivos individuales js/dist/*.js de Bootstrap), o todos a la vez usando bootstrap.js o el archivo minificado bootstrap.min.js (no incluyas ambos).

Si utilizas un empaquetador (Webpack, Parcel, Vite…), puedes utilizar los archivos /js/dist/*.js que están listos para UMD.

Uso con frameworks de JavaScript

Si bien el CSS de Bootstrap se puede usar con cualquier framework, el JavaScript de Bootstrap no es totalmente compatible con frameworks de JavaScript como React, Vue y Angular, que asumen un conocimiento total del DOM. Tanto Bootstrap como el framework pueden intentar mutar el mismo elemento DOM, lo que resulta en errores como menús desplegables que se quedan atascados en la posición "abierto".

Una mejor alternativa para quienes usan este tipo de frameworks es usar un paquete específico del framework en lugar de el JavaScript de Bootstrap. Estas son algunas de las opciones más populares:

Uso de Bootstrap como un módulo

¡Pruébalo tú mismo! Descarga el código fuente y la demostración de trabajo para usar Bootstrap como un módulo ES desde el repositorio twbs/examples. También puedes abrir el ejemplo en StackBlitz.

Proporcionamos una versión de Bootstrap compilada como ESM (bootstrap.esm.js y bootstrap.esm.min.js) que te permite usar Bootstrap como un módulo en el navegador, si tus navegadores de destino lo admiten.

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

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

En comparación con los empaquetadores de JS, el uso de ESM en el navegador requiere que utilices la ruta completa y el nombre del archivo en lugar del nombre del módulo. Obtén más información sobre los módulos JS en el navegador. Por eso usamos 'bootstrap.esm.min.js' en lugar de 'bootstrap' anteriormente. Sin embargo, esto se complica aún más por nuestra dependencia de Popper, que importa Popper a nuestro JavaScript de esta manera:

import * as Popper from "@popperjs/core"

Si intentas esto tal cual, verás un error en la consola como el siguiente:

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

Para solucionar esto, puedes usar un importmap para resolver los nombres de módulos arbitrarios a rutas completas. Si tus navegadores de destino no admiten importmap, deberás utilizar el proyecto es-module-shims. Así es como funciona para Bootstrap y Popper:

<!doctype html>
<html lang="es">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
    <title>¡Hola, modularidad!</title>
  </head>
  <body>
    <h1>¡Hola, modularidad!</h1>
    <button id="popoverButton" type="button" class="btn btn-primary btn-lg" data-bs-toggle="popover" title="ESM en el navegador" data-bs-content="¡Bang!">Popover personalizado</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/[email protected]/dist/esm/popper.min.js",
        "bootstrap": "https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.esm.min.js"
      }
    }
    </script>
    <script type="module">
      import * as bootstrap from 'bootstrap'

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

Dependencias

Algunos plugins y componentes CSS dependen de otros plugins. Si incluyes plugins individualmente, asegúrate de comprobar estas dependencias en la documentación.

Nuestros menús desplegables, popovers y tooltips también dependen de Popper.

Atributos de datos

Casi todos los plugins de Bootstrap se pueden habilitar y configurar únicamente a través de HTML con atributos de datos (nuestra forma preferida de usar la funcionalidad de JavaScript). Asegúrate de usar solo un conjunto de atributos de datos en un solo elemento (por ejemplo, no puedes activar un tooltip y un modal desde el mismo botón).

Como las opciones se pueden pasar a través de atributos de datos o JavaScript, puedes añadir un nombre de opción a data-bs-, como en data-bs-animation="{value}". Asegúrate de cambiar el tipo de mayúsculas y minúsculas del nombre de la opción de “camelCase” a “kebab-case” al pasar las opciones a través de atributos de datos. Por ejemplo, usa data-bs-custom-class="beautifier" en lugar de data-bs-customClass="beautifier".

A partir de Bootstrap 5.2.0, todos los componentes admiten un atributo de datos reservado experimental data-bs-config que puede albergar una configuración simple del componente como una cadena JSON. Cuando un elemento tiene los atributos data-bs-config='{"delay":0, "title":123}' y data-bs-title="456", el valor final de title será 456 y los atributos de datos separados anularán los valores proporcionados en data-bs-config. Además, los atributos de datos existentes pueden albergar valores JSON como data-bs-delay='{"show":0,"hide":150}'.

El objeto de configuración final es el resultado fusionado de data-bs-config, data-bs- y el js object (objeto js) donde el último par clave-valor proporcionado anula a los demás.

Selectores

Utilizamos los métodos nativos querySelector y querySelectorAll para consultar elementos DOM por razones de rendimiento, por lo que debes utilizar selectores válidos. Si utilizas selectores especiales como collapse:Example, asegúrate de escaparlos.

Eventos

Bootstrap proporciona eventos personalizados para la mayoría de las acciones únicas de los plugins. Generalmente, estos vienen en forma de infinitivo y participio pasivo, donde el infinitivo (por ejemplo, show) se activa al inicio de un evento, y su forma de participio pasivo (por ejemplo, shown) se activa al finalizar una acción.

Todos los eventos infinitivos proporcionan la funcionalidad preventDefault(). Esto proporciona la capacidad de detener la ejecución de una acción antes de que comience. Devolver false desde un controlador de eventos también llamará automáticamente a preventDefault().

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

myModal.addEventListener('show.bs.modal', event => {
  return event.preventDefault() // evita que se muestre el modal
})

API programática

Todos los constructores aceptan un objeto de opciones opcional o nada (lo que inicia un plugin con su comportamiento predeterminado):

const myModalEl = document.querySelector('#myModal')
const modal = new bootstrap.Modal(myModalEl) // inicializado con los valores predeterminados

const configObject = { keyboard: false }
const modal1 = new bootstrap.Modal(myModalEl, configObject) // inicializado sin teclado

Si deseas obtener una instancia de un plugin en particular, cada plugin expone un método getInstance. Por ejemplo, para recuperar una instancia directamente desde un elemento:

bootstrap.Popover.getInstance(myPopoverEl)

Este método devolverá null si no se inicia una instancia sobre el elemento solicitado.

Alternativamente, se puede usar getOrCreateInstance para obtener la instancia asociada con un elemento DOM, o crear una nueva en caso de que no se haya inicializado.

bootstrap.Popover.getOrCreateInstance(myPopoverEl, configObject)

En caso de que no se haya inicializado una instancia, puede aceptar y usar un objeto de configuración opcional como segundo argumento.

Selectores CSS en constructores

Además de los métodos getInstance y getOrCreateInstance, todos los constructores de plugins pueden aceptar un elemento DOM o un selector CSS válido como primer argumento. Los elementos del plugin se encuentran con el método querySelector ya que nuestros plugins solo admiten un único elemento.

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')

Funciones asíncronas y transiciones

Todos los métodos de la API programática son asíncronos y regresan al llamador una vez que se inicia la transición, pero antes de que termine. Para ejecutar una acción una vez completada la transición, puedes escuchar el evento correspondiente.

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

myCollapseEl.addEventListener('shown.bs.collapse', event => {
  // Acción a ejecutar una vez que se expande el área colapsable
})

Además, se ignorará una llamada de método en un componente en transición.

const myCarouselEl = document.querySelector('#myCarousel')
const carousel = bootstrap.Carousel.getInstance(myCarouselEl) // Recuperar una instancia de Carousel

myCarouselEl.addEventListener('slid.bs.carousel', event => {
  carousel.to('2') // Deslizará a la diapositiva 2 tan pronto como finalice la transición a la diapositiva 1
})

carousel.to('1') // Comenzará a deslizarse a la diapositiva 1 y regresa al llamador
carousel.to('2') // !! ¡¡Se ignorará, ya que la transición a la diapositiva 1 no ha terminado!!

Método dispose

Si bien puede parecer correcto usar el método dispose inmediatamente después de hide(), esto conducirá a resultados incorrectos. Aquí tienes un ejemplo del uso problemático:

const myModal = document.querySelector('#myModal')
myModal.hide() // es asíncrono

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

Configuración predeterminada

Puedes cambiar la configuración predeterminada de un plugin modificando el objeto Constructor.Default del plugin:

// cambia el valor predeterminado para la opción `keyboard` del plugin modal a false
bootstrap.Modal.Default.keyboard = false

Métodos y propiedades

Cada plugin de Bootstrap expone los siguientes métodos y propiedades estáticas.

MétodoDescripción
disposeDestruye el modal de un elemento. (Elimina los datos almacenados en el elemento DOM)
getInstanceMétodo estático que te permite obtener la instancia del modal asociada con un elemento DOM.
getOrCreateInstanceMétodo estático que te permite obtener la instancia del modal asociada con un elemento DOM, o crear una nueva en caso de que no se haya inicializado.
Propiedad estáticaDescripción
NAMEDevuelve el nombre del plugin. (Ejemplo: bootstrap.Tooltip.NAME)
VERSIONSe puede acceder a la versión de cada uno de los plugins de Bootstrap a través de la propiedad VERSION del constructor del plugin (Ejemplo: bootstrap.Tooltip.VERSION)

Sanitizer

Nuestros componentes de tooltip y popover pueden renderizar HTML arbitrario en la página si están configurados para hacerlo. Para evitar ataques de vulnerabilidad de ejecución de comandos en sitios cruzados (XSS), estos componentes utilizan nuestro desinfectante (sanitizer) de contenido integrado para desinfectar cualquier opción que acepte HTML antes de que se rendericen en la página. La desinfección de contenido está habilitada de forma predeterminada.

Las etiquetas y atributos permitidos de forma predeterminada son los siguientes. Cualquier etiqueta o atributo que no esté permitido explíquitamente se eliminará durante la desinfección:

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: []
}

Ten precaución al utilizar estas opciones avanzadas. Consulta la Guía de prevención de Cross Site Scripting de OWASP para obtener más información. Las vulnerabilidades causadas únicamente por deshabilitar o modificar la desinfección de contenido no se consideran dentro del alcance del modelo de seguridad de Bootstrap.

Puedes agregar nuevos valores a esta allowList predeterminada:

const myDefaultAllowList = bootstrap.Tooltip.Default.allowList

// Para permitir elementos table
myDefaultAllowList.table = []

// Para permitir elementos td y atributos data-bs-option en elementos td
myDefaultAllowList.td = ['data-bs-option']

// Puedes añadir tu expresión regular personalizada para validar tus atributos.
// Ten cuidado de que tus expresiones regulares no sean demasiado laxas
const myCustomRegex = /^data-my-app-[\w-]+/
myDefaultAllowList['*'].push(myCustomRegex)

También puedes reemplazar nuestro desinfectante con una biblioteca dedicada, por ejemplo DOMPurify:

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

Uso opcional de jQuery

No necesitas jQuery en Bootstrap 5, pero aún es posible usar nuestros componentes con jQuery. Si Bootstrap detecta jQuery en el objeto window, agregará todos nuestros componentes al sistema de plugins de jQuery. Esto te permite hacer lo siguiente:

// para habilitar tooltips con la configuración predeterminada
$('[data-bs-toggle="tooltip"]').tooltip()

// para inicializar tooltips con una configuración determinada
$('[data-bs-toggle="tooltip"]').tooltip({
  boundary: 'clippingParents',
  customClass: 'myClass'
})

// para activar el método show
$('#myTooltip').tooltip('show')

Lo mismo ocurre con nuestros otros componentes.

Sin conflicto

A veces es necesario utilizar plugins de Bootstrap con otros frameworks de interfaz de usuario. En estas circunstancias, ocasionalmente pueden ocurrir colisiones de nombres. Si esto sucede, puedes llamar a .noConflict en el plugin cuyo valor deseas revertir.

const bootstrapButton = $.fn.button.noConflict() // devuelve $.fn.button al valor asignado previamente
$.fn.bootstrapBtn = bootstrapButton // otorga a $().bootstrapBtn la funcionalidad de Bootstrap

Bootstrap no admite oficialmente bibliotecas de JavaScript de terceros como Prototype o jQuery UI. A pesar de .noConflict y los eventos con espacio de nombres, puede haber problemas de compatibilidad que debas solucionar por tu cuenta.

Eventos de jQuery

Bootstrap detectará jQuery si jQuery está presente en el objeto window y no hay ningún atributo data-bs-no-jquery establecido en <body>. Si se encuentra jQuery, Bootstrap emitirá eventos gracias al sistema de eventos de jQuery. Por lo tanto, si deseas escuchar los eventos de Bootstrap, tendrás que usar los métodos de jQuery (.on, .one) en lugar de addEventListener.

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

JavaScript deshabilitado

Los plugins de Bootstrap no tienen un plan de respaldo (fallback) especial cuando JavaScript está deshabilitado. Si te preocupa la experiencia del usuario en este caso, utiliza <noscript> para explicar la situación (y cómo volver a habilitar JavaScript) a tus usuarios, y/o agrega tus propios planes de respaldo personalizados.