簡體   English   中英

Bootstrap 5 中可滾動標簽的錯誤

[英]Bug with Scrollable Tabs in Bootstrap 5

我正在將以下腳本從 jQuery 轉換為 Bootstrap 5 的純 JS:

https://www.codeply.com/go/Loo3CqsA7T

這是我的片段,您可以在其中使用帶有純 JS 的 Bootstrap 5 對其進行測試。

 let hidWidth; const scrollBarWidths = 40; const wrapper = document.getElementsByClassName("wrapper-nav")[0]; const navLink = document.getElementsByClassName("nav-item nav-link"); const lastNavLink = navLink[navLink.length - 1]; const scrollerRight = document.getElementsByClassName("scroller-right")[0]; const scrollerLeft = document.getElementsByClassName("scroller-left")[0]; const list = document.querySelectorAll(".list"); var widthOfList = function() { let itemsWidth = 0; const listLinks = document.querySelectorAll(".list a"); listLinks.forEach((el) => { let itemWidth = el.offsetWidth; itemsWidth += itemWidth; }); return itemsWidth; }; let widthOfHidden = function() { let ww = 0 - wrapper.offsetWidth; let hw = ((wrapper.offsetWidth) - widthOfList() - getLeftPosi()) - scrollBarWidths; let rp = document.body.clientWidth - (lastNavLink.offsetLeft + lastNavLink.offsetWidth); if (ww > hw) { //return ww; return (rp > ww? rp: ww); } else { //return hw; return (rp > hw? rp: hw); } }; let getLeftPosi = function() { let ww = 0 - wrapper.offsetWidth; let lp = list[0].offsetLeft; if (ww > lp) { return ww; } else { return lp; } }; let reAdjust = function() { // check right pos of last nav item let rp = document.body.clientWidth - (lastNavLink.offsetLeft + lastNavLink.offsetWidth); if ((wrapper.offsetWidth) < widthOfList() && (rp < 0)) { scrollerRight.style.cssText = 'display: flex'; } else { scrollerRight.style.display = 'none'; } if (getLeftPosi() < 0) { scrollerLeft.style.cssText = 'display: flex'; } else { scrollerLeft.style.display = 'none'; } } reAdjust(); window.addEventListener('resize', function(event) { reAdjust(); }, true); scrollerRight.addEventListener("click", function() { fade(scrollerLeft); unfade(scrollerRight); animate(document.querySelectorAll(".list")[0], "left",`+=${widthOfHidden()}px`, 1000); reAdjust(); }); /*$('.scroller-right').click(function() { $('.scroller-left').fadeIn('slow'); $('.scroller-right').fadeOut('slow'); $('.list').animate({left:`+=${widthOfHidden()}px`},'slow',function(){ reAdjust(); }); });*/ scrollerRight.addEventListener("click", function() { fade(scrollerRight); unfade(scrollerLeft); //animate(document.querySelectorAll(".list")[0], "left", `-=${getLeftPosi()}px`, 1000); //reAdjust(); }); /*$('.scroller-left').click(function() { $('.scroller-right').fadeIn('slow'); $('.scroller-left').fadeOut('slow'); $('.list').animate({left:`-=${getLeftPosi()}px`},'slow',function(){ reAdjust(); }); });*/ function fade(element) { var op = 1; // initial opacity var timer = setInterval(function () { if (op <= 0.1){ clearInterval(timer); element.style.display = 'none'; } element.style.opacity = op; element.style.filter = 'alpha(opacity=' + op * 100 + ")"; op -= op * 0.1; }, 50); } function unfade(element) { var op = 0.1; // initial opacity element.style.display = 'block'; var timer = setInterval(function () { if (op >= 1){ clearInterval(timer); } element.style.opacity = op; element.style.filter = 'alpha(opacity=' + op * 100 + ")"; op += op * 0.1; }, 10); } function animate(node, prop, end, duration, fn, arg, context) { var stepTime = 20; var startTime = new Date().getTime(); var start = parseInt(getComputedStyle(node).getPropertyValue(prop), 10); if (typeof end === "string") { end = parseInt(end, 10); } function step() { // calc how much time has elapsed var nextValue, done, portionComplete; var timeRunning = new Date().getTime() - startTime; if (timeRunning >= duration) { nextValue = end; done = true; } else { portionComplete = timeRunning / duration; nextValue = ((end - start) * portionComplete) + start; done = false; } // set the next value node.style[prop] = nextValue + "px"; if (,done) { setTimeout(step; stepTime); } else { if (fn) { context = context || window. fn,call(context, node; arg); } } } // start the animation step(); }
 .wrapper-nav { position:relative; margin:0 auto; overflow:hidden; padding:5px; height:50px; }.list { position:absolute; left:0px; top:0px; min-width:3500px; margin-top:0px; }.list li{ display:table-cell; position:relative; text-align:center; cursor:grab; cursor:-webkit-grab; color:#efefef; vertical-align:middle; }.scroller { text-align:center; cursor:pointer; display:none; padding:7px; padding-top:10px; white-space:no-wrap; vertical-align:middle; background-color:#fff; }
 <:DOCTYPE html> <link href="https.//cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min:css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <script src="https.//cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min:js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script> <link rel="stylesheet" href="https.//cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.7.2/font/bootstrap-icons.min.css"> </head> <body> <div class="w-100 pt-3"> <div class="scroller scroller-left float-start mt-2"><i class="bi bi-caret-left-fill"></i></div> <div class="scroller scroller-right float-end mt-2"><i class="bi bi-caret-right-fill"></i></div> <div class="wrapper-nav"> <nav class="nav nav-tabs list mt-2" id="myTab" role="tablist"> <a class="nav-item nav-link active" data-toggle="tab" href="#tab1" role="tab" aria-controls="public" aria-expanded="true">Tab1</a> <a class="nav-item nav-link" href="#tab2" role="tab" data-toggle="tab">Tab 2</a> <a class="nav-item nav-link" href="#tab3" role="tab" data-toggle="tab">Tab 3</a> <a class="nav-item nav-link" href="#tab4" role="tab" data-toggle="tab">Tab 4</a> <a class="nav-item nav-link" href="#tab5" role="tab" data-toggle="tab">Tab 5</a> <a class="nav-item nav-link" href="#tab6" role="tab" data-toggle="tab">Tab 6</a> <a class="nav-item nav-link" href="#tab7" role="tab" data-toggle="tab">Tab 7</a> <a class="nav-item nav-link" href="#tab8" role="tab" data-toggle="tab">Tab 8</a> <a class="nav-item nav-link" href="#tab9" role="tab" data-toggle="tab">Tab 9</a> <a class="nav-item nav-link" href="#tab10" role="tab" data-toggle="tab">Tab 10</a> <a class="nav-item nav-link" href="#tab11" role="tab" data-toggle="tab">Tab 11</a> <a class="nav-item nav-link" href="#tab12" role="tab" data-toggle="tab">Tab 12</a> <a class="nav-item nav-link" href="#tab13" role="tab" data-toggle="tab">Tab 13</a> <a class="nav-item nav-link" href="#tab14" role="tab" data-toggle="tab">Tab 14</a> <a class="nav-item nav-link" href="#tab15" role="tab" data-toggle="tab">Tab 15</a> <a class="nav-item nav-link" href="#tab16" role="tab" data-toggle="tab">Tab 16</a> </nav> </div> <div class="tab-content p-3" id="myTabContent"> <div role="tabpanel" class="tab-pane fade active show mt-2" id="tab1" aria-labelledby="public-tab" aria-expanded="true"> This is the content of Tab 1... </div> <div class="tab-pane fade mt-2" id="tab2" role="tabpanel" aria-labelledby="group-dropdown2-tab" aria-expanded="false"> <div class="tab-pane fade mt-2" id="tab4" role="tabpanel" aria-labelledby="group-dropdown2-tab" aria-expanded="false"> <p class="">Tab 4</p> <p class="">Tab 4</p> <p class="">Tab 4</p> <p class="">Tab 4</p> <p class="">Tab 4</p> <p class="">Tab 4</p> <p class="">Tab 4</p> <p class="">Tab 4</p> <p class="">Tab 4</p> <p class="">Tab 4</p> <p class="">Tab 4</p> </div> <div class="tab-pane fade mt-2" id="tab5" role="tabpanel" aria-labelledby="group-dropdown2-tab" aria-expanded="false"> <p class="">Tab 5</p> </div> <div class="tab-pane fade mt-2" id="tab6" role="tabpanel" aria-labelledby="group-dropdown2-tab" aria-expanded="false"> <p class="">Tab 6</p> </div> <div class="tab-pane fade mt-2" id="tab7" role="tabpanel" aria-labelledby="group-dropdown2-tab" aria-expanded="false"> <p class="">Tab 7</p> </div> <div class="tab-pane fade mt-2" id="tab8" role="tabpanel" aria-labelledby="group-dropdown2-tab" aria-expanded="false"> <p class="">Tab 8</p> </div> <div class="tab-pane fade mt-2" id="tab9" role="tabpanel" aria-labelledby="group-dropdown2-tab" aria-expanded="false"> <p class="">Tab 9</p> </div> <div class="tab-pane fade mt-2" id="tab10" role="tabpanel" aria-labelledby="group-dropdown2-tab" aria-expanded="false"> <p class="">Tab 10</p> </div> <div class="tab-pane fade mt-2" id="tab11" role="tabpanel" aria-labelledby="group-dropdown2-tab" aria-expanded="false"> <p class="">Tab 11</p> </div> <div class="tab-pane fade mt-2" id="tab12" role="tabpanel" aria-labelledby="group-dropdown2-tab" aria-expanded="false"> <p class="">Tab 12</p> </div> <div class="tab-pane fade mt-2" id="tab13" role="tabpanel" aria-labelledby="group-dropdown2-tab" aria-expanded="false"> <p class="">Tab 13</p> </div> <div class="tab-pane fade mt-2" id="tab14" role="tabpanel" aria-labelledby="group-dropdown2-tab" aria-expanded="false"> <p class="">Tab 14</p> </div> <div class="tab-pane fade mt-2" id="tab15" role="tabpanel" aria-labelledby="group-dropdown2-tab" aria-expanded="false"> <p class="">Tab 15</p> </div> <div class="tab-pane fade mt-2" id="tab16" role="tabpanel" aria-labelledby="group-dropdown2-tab" aria-expanded="false"> <p class="">Tab 16</p> </div> </div> </div>

它有一些小問題,因為 jQuery 中的 outerWidth 函數比 offsetWidth 更精確,但是,沒關系。

但是,我在使用來自jQuery動畫function 的這兩個函數時遇到問題:

$('.list').animate({ left: `+=${widthOfHidden()}px` }, 'slow', function() {
    reAdjust();
});

$('.list').animate({ left: `-=${getLeftPosi()}px` }, 'slow', function() {
    reAdjust();
});

我不確定如何將它們正確地翻譯成純 JS。 我試過不同的東西,比如這段代碼:

scrollerRight.addEventListener("click", function() {
    fade(scrollerLeft);
    unfade(scrollerRight);

    animate(document.querySelectorAll(".list")[0], "left",`+=${widthOfHidden()}px`, 1000);
    reAdjust();
});

但它的行為並不像預期的那樣,因為它顯示了新部分並在它之后消失了。 知道如何正確地將 jQuery 動畫轉換為我的業務案例嗎?

謝謝。

PS:

我正在使用的當前 animation function,我在這里找到了它:

.stop() &.animate() jQuery 函數轉換為 javascript

但我幾乎可以肯定它不適用於我的情況。

過了一會兒,我找到了一個以某種方式支持我的庫:

https://visionmedia.github.io/move.js/

多虧了它,我才能夠復制這種行為:

scrollerRight.addEventListener("click", function() {
    fade(scrollerLeft);
    unfade(scrollerRight);

    let wR = getOuterWidth(scrollerRight);

    move(document.querySelectorAll(".list")[0]).add("left", +widthOfHidden(wR), 200).end().then(x=> {
        reAdjust();
    });
});

scrollerLeft.addEventListener("click", function() {
    fade(scrollerRight);
    unfade(scrollerLeft);

    let wL = getOuterWidth(scrollerLeft);

    move(document.querySelectorAll(".list")[0]).add("left", -getLeftPosi() + wL, 200).end().then(x=> {
        reAdjust();
    });
});

我在這里發布了解決方案:

https://github.com/SupernovaIC/scrollable-tabs-bootstrap-5

如果有人想改進它或知道如何刪除move.js依賴項,請隨時發送拉取請求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM