Bootstrap 当动态添加放置时,引导5中的offcanvas缺少初始转换

cwdobuhd  于 2023-10-14  发布在  Bootstrap
关注(0)|答案(1)|浏览(118)

我尝试用JS触发一个Offcanvas,并使放置可配置。问题是,如果我尝试动态地将offcanvas-end类设置为offcanvas元素,那么在第一次触发它时,不会发生转换。第二次就没事了。有什么办法能让它工作吗?

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/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>

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

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

更新:

也许下面的代码片段更好地传达了我为什么需要在JS中设置position类,而不是在HTML中-我想根据trigger元素在不同的位置动态打开offcanvas。

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/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/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>
oxcyiej7

oxcyiej71#

offcanvas-end类添加到元素本身,而不是通过JavaScript,这将启用动画。它实际上是.show类来显示它,而不是offcanvas-end
所以,你不需要在你的代码中添加类,它可以通过使用.toggle方法来修改,而不是.show,你也不需要在每次点击时创建一个示例,而是在点击之前创建,然后在点击时切换:
试试这个:

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/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/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>

编辑

动态添加类似乎不起作用,可能是由于一些竞争条件。
解决方法可能是完全动态地创建元素:

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/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/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>

编辑2

用自身替换元素似乎也可以工作:

myOffcanvas.replaceWith(myOffcanvas);

所以我猜浏览器不会重绘元素,当它已经在DOM中,并且有JS和BS offcanvas更改的类时......

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/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/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>

相关问题