提问人:pmishev 提问时间:10/11/2023 最后编辑:traynorpmishev 更新时间:10/13/2023 访问量:126
Bootstrap 5 中的 offcanvas 在动态添加放置时缺少初始过渡
offcanvas in bootstrap 5 missing initial transition when placement is added dynamically
问:
我正在尝试使用 JS 触发 Offcanvas 并使放置可配置。
问题是,如果我尝试将类动态设置为 offcanvas 元素,则第一次触发它时,不会发生转换。第二次没事。有什么方法可以欺骗它工作吗?offcanvas-end
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 中而不是在 HTML 中设置 position 类 - 我想根据触发元素在不同的位置动态打开 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>
答:
0赞
traynor
10/12/2023
#1
将类添加到元素本身,而不是通过 JavaScript,这将启用动画。
实际上是类显示它,而不是 .offcanvas-end
.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>
评论
0赞
pmishev
10/12/2023
我在页面上有一个 offcanvas div,我用它来打开带有 ajax 的动态内容。我只希望它的位置取决于触发它显示的元素。这就是为什么我需要在 JS 中而不是在 HTML 中设置位置类。我用另一个代码片段编辑了我的帖子,以更好地表达我的意思。
0赞
traynor
10/12/2023
嗯,那是完全不同的.嗯,看起来过渡动画不起作用。.很可能是某种比赛条件,但无法真正分辨.使用前强制重新粉刷没有区别。不过,如果您动态创建 offcanvas 元素,它似乎有效,所以我会采用这种方式作为解决方法。.show
0赞
traynor
10/12/2023
我添加了解决方法,它似乎正在使用完全动态的元素。我翻遍了源代码,这可能是一些竞争条件,但无法真正分辨..: github.com/twbs/bootstrap/blob/main/js/src/offcanvas.js
评论