【问题标题】:Bootstrap horizontal scrollspy?引导水平滚动间谍?
【发布时间】:2013-04-01 22:28:04
【问题描述】:

我正在成功使用 Bootstrap 的 scrollspy,但我想在目标锚点水平级联的页面上使用它。我已经调整无济于事,无法使其正常工作。我也尝试了https://gist.github.com/marcoleong/1922743,但没有成功。

请查看我在http://jsfiddle.net/AzSWV/2/ 的小提琴,它适用于对$('body').scrollspy(); 的调用

您最初可以看到垂直滚动间谍有效。 取消注释 CSS 并更新 fiddle 以查看水平布局。

【问题讨论】:

    标签: javascript jquery twitter-bootstrap scroll scrollspy


    【解决方案1】:

    通过将所有出现的topTop 分别替换为leftLeft 并将heightHeight 分别替换为widthWidth 来解决此问题。我还更改了目标元素。

    http://jsfiddle.net/AzSWV/19/

    【讨论】:

      【解决方案2】:

      我需要类似的东西,但比我在网上找到的任何东西都要干净一些,所以我自己做了。

      为每个幻灯片项设置多列:https://jsfiddle.net/darcher/dLmyhgzq/249/

      除了将active 类分配给正确的nav-link 之外,一切都是CSS 驱动的,这需要额外的javascript。

      $(function() {
        
        var parent = document.querySelector('.scrollspy-h-container');
        var parentDimensions = parent.getBoundingClientRect();
        var parentX = parentDimensions.x;
      
        parent.querySelectorAll('.nav-link').forEach(function(item, index, array) {
          item.setAttribute('aria-controls', item.href);
          item.classList.remove('active');
          array[0].classList.add('active');
        });
        
        parent.addEventListener('scroll', function () {
      
          var items = document.querySelectorAll('.scrollspy-h-item');
          var arr = [];
          
          items.forEach(function (item, index, array) {
          
            var itemDimensions = item.getBoundingClientRect();
            var itemX = itemDimensions.x;
            arr[index] = itemX;
            
            var itemId = item.id;
            var itemBtn = document.querySelector('a[href="#' + itemId + '"]');
            itemBtn.setAttribute('data-index', index);
           
            itemBtn.classList.contains('active') && itemBtn.classList.remove('active');
                      
          });
          
          var closest = arr.reduce(function(prev, curr, index, array) {
            return  (Math.abs(curr - parentX) < Math.abs(prev - parentX) ? curr : prev)
          });
          
          arr.map(function(item, index, array){
            (item === closest) && document.querySelector('[data-index="' + index  + '"]').classList.add('active');
          });
          
        });
        
      });
      @import 'https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css';
      
      html {
        scroll-behavior: smooth;
      }
      
      body {
        height: 1000px;
      }
      
      .pull-right{float:right}
      
      .nav {
        position: relative;
        z-index: 2;
        transform:translate(-5px, 80px);
      }
      
      .scrollspy-h-container {
        overflow-x: scroll;
        scroll-behavior: smooth;
        width: 100%;
        border-radius: .25rem;
      }
      
      .scrollspy-h {
        position: relative;
        width: calc(100% * 4);
      }
      
      .scrollspy-h>.scrollspy-h-item {
        display: inline-block;
        padding:5rem 0;
        float: left;
        width: calc(100% / 4);
        text-align: center;
      }
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.min.js"></script>
      
      <div class="container-fluid">
      
        <div class="row">
          <div class="col p-4">
            <nav class="pull-right">
              <ul class="nav nav-pills pull-right" id="scrollspy-h">
                <li class="nav-item">
                  <a class="nav-link text-light active" href="#item-1">Link 1</a>
                </li>
                <li class="nav-item">
                  <a class="nav-link text-light" href="#item-2">Link 2</a>
                </li>
                <li class="nav-item">
                  <a class="nav-link text-light" href="#item-3">Link 3</a>
                </li>
                <li class="nav-item">
                  <a class="nav-link text-light" href="#item-4">Link 4</a>
                </li>
              </ul>
            </nav>
          </div>
        </div>
      
        <div class="row">
          <div class="col">
            <div class="scrollspy-h-container">
              <div data-spy="scroll" data-target="#scrollspy-h" data-offset="88" class="scrollspy-h">
                <div class="scrollspy-h-item bg-success" id="item-1">
                  <h2 class="display-4">Link 1</h2>
                  <p>This is the first pane that you'll see in the scroller</p>
                </div>
                <div class="scrollspy-h-item bg-warning" id="item-2">
                  <h2 class="display-4">Link 2</h2>
                  <p>This is the second pane that you'll see in the scroller</p>
                </div>
                <div class="scrollspy-h-item bg-info" id="item-3">
                  <h2 class="display-4">Link 3</h2>
                  <p>This is the third pane that you'll see in the scroller</p>
                </div>
                <div class="scrollspy-h-item bg-danger" id="item-4">
                  <h2 class="display-4">Link 4</h2>
                  <p>This is the fourth pane that you'll see in the scroller</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      
      </div>

      【讨论】:

        【解决方案3】:

        我通过参考这个简约的垂直滚动间谍:http://jsfiddle.net/mekwall/up4nu/

        没有看到您的 [实际] 代码,我无法真正专门为您更改我的价值观,但使用它应该不会太难:

        $(document).ready(function(){
            var lastId;
            //change this selector to the section containing your menu items
            var pickerMenu = $("#sliderInner");
            var menuItems = pickerMenu.find("a");
            //finds the anchors to be linked to
            var scrollItems = menuItems.map(function(){
                var item = $($(this).attr("href"));
                if(item.length){ return item; }
            });
        
            //if you are scrolling the body rather than an overflow div change #main to body
            $('#main').scroll(function(){
                var currentItem = scrollItems.map(function(){
                    //currently uses center of the screen as active location
                    //feel free to place the $(window) section with 0 to go from left
                    //or remove the the /2 to have from the right
                    if($(this).offset().left < ($(window).width()/2)){
                        return this;
                    }
                });
                currentItem = currentItem[currentItem.length - 1];
        
                var id = currentItem && currentItem.length ? currentItem[0].id : "";
                if (lastId !== id) {
                    lastId = id;
        
                //adds the class 'active' to the parent of the link
                menuItems
                    .parent().removeClass("active")
                    .end().filter("[href=#"+id+"]").parent().addClass("active");
                }
            });
            //set first item to active
            menuItems.first().parent().addClass("active");
        });
        

        编辑: 根据您的要求使用您的测试数据更新您的小提琴http://jsfiddle.net/AzSWV/12/

        编辑2: 您可能想要包含一些方便的向下滚动以向左滚动内容。在https://github.com/brandonaaron/jquery-mousewheel 上查看 Brandon Aaron 的 jQuery Mousewheel 插件并将其与以下内容结合使用:

        $("#main").mousewheel(function(e, delta) {
            this.scrollLeft -= (delta * 50);
            e.preventDefault();
        });
        

        【讨论】:

        • “没有看到我的代码”?我发布了一个小提琴,请随时更新或分叉!
        • @gordian 我的意思是..这显然是您小提琴上的填充内容..没有您的特定代码