The initial transition in offcanvas on bootstrap 5 is not appearing when a placement is dynamically added

I am currently working on triggering an Offcanvas with JS and making the placement configurable. The issue arises when attempting to dynamically set the offcanvas-end class to the offcanvas element, as it does not transition smoothly the first time it is triggered. However, on subsequent triggers, the transition works fine. Is there a workaround to make this work seamlessly?

var myOffcanvas = document.getElementById('myOffcanvas')

var btnClicked = function (event) {
    myOffcanvas.className += ' offcanvas-end'
    var bsOffcanvas = new bootstrap.Offcanvas(myOffcanvas)
    bsOffcanvas.show()
}

document.getElementById('myBtn').addEventListener('click', btnClicked)
    
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="caa8a5a5beb9beb8abba8affe4f9e4f8">[email protected]</a>/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="187a77776c6b6c6a7968582d362b">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet"/>

<div class="offcanvas" tabindex="-1" id="myOffcanvas">My offcanvas</div>

<button type="button" id="myBtn">Open</button>

UPDATE:


Perhaps the following snippet provides a clearer understanding of my objective and why I need to assign the position class in JS rather than HTML - I aim to dynamically open the offcanvas at different positions based on the trigger element.

var myOffcanvas = document.getElementById('myOffcanvas')
var bsOffcanvas = null

var openLeftBtnClicked = function(event) {
  myOffcanvas.className = 'offcanvas offcanvas-start'
  if (bsOffcanvas) {
    bsOffcanvas.dispose()
  }
  bsOffcanvas = new bootstrap.Offcanvas(myOffcanvas)
  bsOffcanvas.show()
}

var openRightBtnClicked = function(event) {
  myOffcanvas.className = 'offcanvas offcanvas-end'
  if (bsOffcanvas) {
    bsOffcanvas.dispose()
  }
  bsOffcanvas = new bootstrap.Offcanvas(myOffcanvas)
  bsOffcanvas.show()
}

document.getElementById('openLeftBtn').addEventListener('click', openLeftBtnClicked)
document.getElementById('openRightBtn').addEventListener('click', openRightBtnClicked)
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ef8d80809b9c9b9d8e9fafdac1dfc1dd">[email protected]</a>/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="97f5f8f8e3e4e3e5f6e7d7a2b9a7b9a5">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet" />

<div tabindex="-1" id="myOffcanvas"></div>

<button type="button" id="openLeftBtn">Open left</button>
<button type="button" id="openRightBtn">Open right</button>

Answer №1

Make sure to apply the offcanvas-end class directly to the element itself for the animation to work, rather than using JavaScript. Remember that it is the .show class that actually makes the element visible, not the offcanvas-end class.

Instead of manually adding and removing classes in your code, consider utilizing the .toggle method to toggle the offcanvas on click:

Give this a try:

const myOffcanvas = new bootstrap.Offcanvas('#myOffcanvas');

var btnClicked = function (event) {

    myOffcanvas.toggle();
}

document.getElementById('myBtn').addEventListener('click', btnClicked);
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="35575a5a41464147544575001b061b07">[email protected]</a>/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e2808d8d969196908392a2d7ccd1ccd0">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet"/>

<div class="offcanvas offcanvas-end" tabindex="-1" id="myOffcanvas">My offcanvas</div>

<button type="button" id="myBtn">Open</button>

EDIT

If you're experiencing issues with dynamically adding classes due to potential race conditions, consider creating the element dynamically as a workaround:

var myOffcanvasContainer = document.getElementById('myOffcanvas')
var myOffcanvas = document.createElement('div');

myOffcanvas.textContent = 'My offcanvas';

var bsOffcanvas = null

var openLeftBtnClicked = function(event) {
  myOffcanvas.className = 'offcanvas offcanvas-start'
  if (bsOffcanvas) {
    bsOffcanvas.dispose()
  }

  myOffcanvasContainer.appendChild(myOffcanvas);

  bsOffcanvas = new bootstrap.Offcanvas(myOffcanvas)
  bsOffcanvas.show()
}

var openRightBtnClicked = function(event) {
  myOffcanvas.className = 'offcanvas offcanvas-end'
  if (bsOffcanvas) {
    bsOffcanvas.dispose()
  }

  myOffcanvasContainer.appendChild(myOffcanvas);

  bsOffcanvas = new bootstrap.Offcanvas(myOffcanvas)
  bsOffcanvas.show()
}

document.getElementById('openLeftBtn').addEventListener('click', openLeftBtnClicked)
document.getElementById('openRightBtn').addEventListener('click', openRightBtnClicked)
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8eece1e1fafdfafceffecebba0bea0bc">[email protected]</a>/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0f6d60607b7c7b7d6e7f4f3a213f213d">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet" />

<div tabindex="-1" id="myOffcanvas"></div>

<button type="button" id="openLeftBtn">Open left</button>
<button type="button" id="openRightBtn">Open right</button>

EDIT2

For updating element styles dynamically, replacing the element with itself can be a workaround:

myOffcanvas.replaceWith(myOffcanvas);

The browser may not redraw elements already in the DOM when their classes are changed by JavaScript and Bootstrap offcanvas interactions...

var myOffcanvas = document.getElementById('myOffcanvas')
var bsOffcanvas = null

var openLeftBtnClicked = function(event) {
  myOffcanvas.className = 'offcanvas offcanvas-start'

  myOffcanvas.replaceWith(myOffcanvas);

  if (bsOffcanvas) {
    bsOffcanvas.dispose()
  }
  bsOffcanvas = new bootstrap.Offcanvas(myOffcanvas)
  bsOffcanvas.show()
}

var openRightBtnClicked = function(event) {
  myOffcanvas.className = 'offcanvas offcanvas-end'

  myOffcanvas.replaceWith(myOffcanvas);

  if (bsOffcanvas) {
    bsOffcanvas.dispose()
  }
  bsOffcanvas = new bootstrap.Offcanvas(myOffcanvas)
  bsOffcanvas.show()
}

document.getElementById('openLeftBtn').addEventListener('click', openLeftBtnClicked)
document.getElementById('openRightBtn').addEventListener('click', openRightBtnClicked)
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3f5d50504b4c4b4d5e4f7f0a110f110d">[email protected]</a>/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="086a67667d7a7d7b686977363923372b">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet" />

<div tabindex="-1" id="myOffcanvas"></div>

<button type="button" id="openLeftBtn">Open left</button>
<button type="button" id="openRightBtn">Open right</button>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Troubleshooting a problem with CSS Matrix animations

Lately, I've been working on creating some matrix animations. However, I noticed an unusual issue. The code below seems to function differently across Firefox, Safari, and Chrome: @-moz-keyframes matrix { from { -moz-transform: matri ...

Assistance Required in Turning Down Trade Requests on Steam That Involve Losing items

Currently, I have a code snippet from a Steam bot that processes incoming trade offers by accepting or declining them based on their state. However, my goal is to modify it in a way so that it automatically accepts trade offers where I receive items, but ...

Formik's handleSubmit function seems to be being overlooked and not executed as

I've encountered an issue while trying to validate a form before submission using formik and yup validation. The form is divided into two parts, where the first part needs to be validated before moving on to the second part. I set a state handleShow(t ...

There seems to be a caching issue in ReactJS and Spring Data Rest that could be causing problems with

Encountering an unusual caching problem here. Just recently wiped out my database. While adding new users to the system, an old user mysteriously reappeared. This user has not been recreated and is not in the current database whatsoever. I'm at a lo ...

What is the best way to retrieve data from the state in react components?

After fetching data from my API using a getAll call, I stored all the values in this.state. However, I am struggling with extracting the arrays or objects from my state. Specifically, I am interested in retrieving the 'id' field from: 0: {id: 1, ...

What is the best way to use jQuery to toggle the visibility of a <panel>?

My objective is to display a panel with two labels on a button click, but I'm facing issues achieving this functionality. When I click on the button (id=Button1), the panel (id=anspanel) should appear, but it remains hidden even after clicking the but ...

Deactivate a few CSS guidelines

For my project, I am incorporating interfaces within other interfaces and have been facing conflicts between bootstrap rules and other CSS files. To address this, I encapsulated all Bootstrap rules within a .use_bootstrap class. Now, within my interfaces ...

Is the table not displaying properly in the print preview with a messy

I have a large table with multiple rows. Due to its length, I have provided a link to the jsfiddle where you can view it: jsfiddle. The table is structured in HTML and contains many rows with various attributes. <table> <thead>text here!</t ...

ESLint's feature experimentalObjectRestSpread not being applied with expected behavior

ESLint is showing an unexpected token error, specifically error Parsing error: Unexpected token .., and I'm struggling to identify the root cause. In my .eslintrc.js file, I have: module.exports = { extends: "devmountain/react-config" , rul ...

How can I achieve a similar functionality to array_unique() using jQuery?

When I select values from a dropdown, they are stored as an array like ["1","2","3"] Upon each change, the code below is executed to generate a new array based on the selected values: $('#event-courses-type').on('change', function(){ ...

Utilize express.router() to send a get request to a third-party API while including an API key

As I develop my react application, I am faced with the task of retrieving data from a third-party site that requires me to include an API key in the header as 'X-Auth-Token'. Currently, I am using the fetch() API from the client-side JavaScript ...

Distribute progress bar evenly around a circular path

I am working on a component in ReactJS that involves a circle in the center displaying the average (rendered as a div element), with 12 progress bars aligned around it at equal angles. To achieve this, I am utilizing React Bootstrap ProgressBar. <Progr ...

How can you align an icon to the right in a Bootstrap4 navbar while keeping it separate from the toggle menu?

Looking to utilize the Twitter Bootstrap framework for structuring my navbar with distinct "left", "middle", and "right" sections, where the middle portion collapses beneath the navbar-toggler (burger menu) when space is limited. For a self-contained exam ...

What methods can be used to test scss subclasses within an Angular environment?

Exploring different background colors in various environments is a task I want to undertake. The environments include bmw, audi, and vw, with each environment having its own unique background color. Need help writing an Angular test for this? How can I mod ...

Click the navigation bar to toggle it on and off

I have a script that creates a navbar. Currently, the dropdown menu only opens when hovered over. The issue arises when accessing this on a mobile browser, as the dropdown menu does not open. How can I modify this script to make the dropdown menu open wh ...

### Setting Default String Values for Columns in TypeORM MigrationsDo you want to know how to

I'm working on setting the default value of a column to 'Canada/Eastern' and making it not nullable. This is the current setup for the column: queryRunner.addColumn('users', new TableColumn({ name: 'timezone_name', ...

Troubles with NextJS and TailwindCSS Styling

I encountered a strange issue when I used the component separately. Here's how the code looked like: <> <Head> <title>Staycation | Home</title> <meta name="viewport" content="initial- ...

Passing data between the view and JavaScript in a Django application

Initially, I pass a JavaScript variable 'confirmed' to my Django view using a POST request. Then, a Python script processes this variable to perform certain actions. Finally, I aim to pass the processed data back to my HTML/JavaScript for display ...

Adjust the color of the text depending on the background it is displayed on

While practicing HTML and CSS as I normally do, I decided to work on a PSD template yesterday. Initially, it seemed straightforward, but soon I encountered the issue I'm currently facing. Specifically, I am trying to change a specific part of text ba ...

Changing over to the left hand coordinate systemUniquely converting to a

One of the challenges I am facing involves an application that loads a model. Upon receiving a server response, I am provided with information regarding the axis to use for the right and up orientation. The format in which this information is sent can be ...