Bootstrap'te ScrollSpy için ofseti nasıl ayarlarım?


98

Gezinme çubuğu üstte sabitlenmiş ve ana içerik alanında altında 3 div bulunan bir sitem var.

Bootstrap çerçevesinden scrollspy kullanmaya çalışıyorum.

Div'leri kaydırdığınızda menüdeki farklı başlıkları başarılı bir şekilde vurguladım.

Ayrıca bende, menüye tıkladığınızda sayfanın doğru kısmına kayacak. Ancak, uzaklık yanlıştır (Gezinti çubuğunu hesaba katmıyor, bu nedenle yaklaşık 40 piksel kaydırmam gerekiyor)

Bootstrap sayfasında bir ofset seçeneğinden bahsettiğini görüyorum, ancak nasıl kullanılacağından emin değilim.

Ayrıca $('#navbar').scrollspy(), scrollspy'i kullanabileceğinizi söylediği zaman ne anlama geldiğini bilmiyorum , onu nereye dahil edeceğimi bilmiyorum, bu yüzden eklemedim ve her şey çalışıyor gibi görünüyor (ofset hariç).

Ofsetin data-offset='10'vücut etiketinde olabileceğini düşündüm , ama benim için hiçbir şey yapmıyor.

Bunun gerçekten bariz bir şey olduğuna dair bir his var ve sadece onu özlüyorum. Herhangi bir yardım?

Benim kodum

...
<!-- note: the data-offset doesn't do anything for me -->
<body data-spy="scroll" data-offset="20">
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
    <div class="container">
    <a class="brand" href="#">VIPS</a>
    <ul class="nav">
        <li class="active">
             <a href="#trafficContainer">Traffic</a>
        </li>
        <li class="">
        <a href="#responseContainer">Response Times</a>
        </li>
        <li class="">
        <a href="#cpuContainer">CPU</a>
        </li>
      </ul>
    </div>
</div>
</div>
<div class="container">
<div class="row">
    <div class="span12">
    <div id="trafficContainer" class="graph" style="position: relative;">
    <!-- graph goes here -->
    </div>
    </div>
</div>
<div class="row">
    <div class="span12">
    <div id="responseContainer" class="graph" style="position: relative;">
    <!-- graph goes here -->
    </div>
    </div>
</div>
<div class="row">
    <div class="span12">
    <div id="cpuContainer" class="graph" style="position: relative;">
    <!-- graph goes here -->
    </div>
    </div>
</div>
</div>

...
<script src="assets/js/jquery-1.7.1.min.js"></script>
<script src="assets/js/bootstrap-scrollspy.js"></script>
</body>
</html>

Neden bir pozisyon veriyorsunuz: div'lerinize göre mi? Belki de buna sebep olan budur. Eylemde görebilmemiz için kodunuzla bir jsfiddle oluşturabilir misiniz?
periklis

Yanıtlar:


113

Bootstrap kaydırmayı değil, yalnızca casusluğu çözmek için ofset kullanır. Bu, doğru yere kaydırmanın size bağlı olduğu anlamına gelir.

Bunu deneyin, benim için çalışıyor: gezinme tıklamaları için bir olay işleyicisi ekleyin.

var offset = 80;

$('.navbar li a').click(function(event) {
    event.preventDefault();
    $($(this).attr('href'))[0].scrollIntoView();
    scrollBy(0, -offset);
});

Burada buldum: https://github.com/twitter/bootstrap/issues/3316


3
Cevap için teşekkürler. Ofsetin kaydırmayı etkilemediğini anlamam epey zaman aldı. Bu, sabit bir tavan kullanan herkesin bu şekilde manuel olarak ayarlaması gerektiği anlamına gelir.
Brian Smith

8
URL'nin karma bölümünü uygun şekilde güncellemek window.location.hash = $(this).attr('href')için bu işleve ekleyin .
Stephen M. Harris

2
Teşekkürler! FWIW, veri ofsetini vücuda koymak da önemlidir, çünkü soruyu soran kişi hiçbir şey yapmadığını, ancak uygun casusluk için gerekli olduğunu söyledi. Kapsamlı bir cevaba sahip olmak yardımcı olabilir.
mrooney

4
Dinamik kazanma: var navOffset = $('#navbar').height();vescrollBy(0, -navOffset);
ahnbizcad

79

Tim'in bahsettiği gibi, püf noktası, dolgudan yararlanmaktır. Yani sorun şu ki, tarayıcınız her zaman çapanızı pencerenin tam üstüne kaydırmak istiyor. Bağlantınızı metninizin gerçekte başladığı yere ayarlarsanız, menü çubuğunuz tarafından tıkanacaktır. Bunun yerine, yaptığınız şey, nav / navbar'ın otomatik olarak kullanacağı kapsayıcıya <section>veya <div>etiketin kimliğine çapanızı ayarlamaktır. Ardından padding-top, konteyner için istediğiniz ofset miktarına ve margin-topkonteyner için de bunun tersine ayarlamanız gerekir padding-top. Artık, kapsayıcınızın bloğu ve bağlantı sayfanın tam üstünden başlıyor, ancak içindeki içerik menü çubuğunun altına kadar başlamıyor.

Normal çapa kullanıyorsanız, aynı şeyi, konteynırınızda yukarıdaki gibi negatif margin-top kullanarak, ancak dolgu yapmadan gerçekleştirebilirsiniz. Ardından <a target="...">kabın ilk çocuğu olarak normal bir çapa koyarsınız . Sonra ikinci alt öğeyi zıt ama eşit bir şekilde margin-top, ancak seçiciyi kullanarak biçimlendirirsiniz .container:first-child +.

Tüm bunlar, <body>etiketinizin marjının zaten norm olan başlığınızın altında başlayacak şekilde ayarlandığını varsayar (aksi takdirde, sayfa hemen kapatılmış metinle oluşturulur).

İşte bunun uygulamalı bir örneği. Sayfanızda kimliği olan her şeye URL'nizin sonuna # the-elements-id işaretlenerek bağlanılabilir. Eğer tüm h etiketlerinizi, kimliklerine bağlanabilir ( github'ın yaptığı gibi ) dt etiketlerini , sollarına küçük bir bağlantı enjekte eden bir tür komut dosyasıyla yaparsanız ; Aşağıdakileri CSS'nize eklemek, gezinme çubuğu ofsetini sizin için halleder:

body {
    margin-top: 40px;/* make room for the nav bar */
}

/* make room for the nav bar */
h1[id],
h2[id],
h3[id],
h4[id],
h5[id],
h6[id],
dt[id]{
    padding-top: 60px;
    margin-top: -40px;
}

9
Üst dolgu, negatif kenar boşluğu (aynı öğede) kombinasyonunu sevin. JS ile uğraşmaktan daha kolay.
Eystein

En iyi cevap gibi görünüyor, ama biraz kayboldum. Herhangi bir örnek şansı.
eddyparkinson

@eddyparkinson, sanırım şu anda anladınız: Örneğin, önyükleme satırlarında kimliğiniz olduğunda: .row [id] {padding-top: 60px; margin-top: -40px; } Bunu daha az dosyanıza koyun: .row [id] {padding-top: 60px; margin-top: -40px; }
Klaaz

Bootstrap'in varsayılan ofset parametresinin bunun için olması gerekmiyor mu? Dahil edilmesi çok bariz bir şey gibi görünüyor ve bunun gibi geçici çözümlere başvurmak zorunda değil.
ahnbizcad

Bu, hedeflediğiniz div'e etkili bir şekilde fazladan alan ekler mi? Ya bunu istemiyorsan? Görünmez bir ekstra boşluk ideal olacaktır.
ahnbizcad

10

Parşömen casusunun ofsetini, bununla anında değiştirebilirsiniz (vücutta casusluk yaptığınızı varsayarak):

offsetValue = 40;
$('body').data().scrollspy.options.offset = offsetValue;
// force scrollspy to recalculate the offsets to your targets
$('body').data().scrollspy.process();

Bu, ofset değerini dinamik olarak değiştirmeniz gerektiğinde de işe yarar. (Scrollspy'nin sonraki bölüm pencerenin yaklaşık yarısına geldiğinde geçiş yapmasını seviyorum, bu nedenle pencere yeniden boyutlandırma sırasında ofseti değiştirmem gerekiyor.)


2
Bunun için teşekkürler - Bootstrap 3.0 $ ['body']. Data () ['bs.scrollspy']. Options.offset = newOffset; // Yeni göreli konumu ayarla $ ['body']. Data () ['bs.scrollspy']. Process (); // Kaydırma casusunu hedeflerinize olan uzaklıkları yeniden hesaplamak için zorlayın $ ('body']. Scrollspy ('yenileme'); // Kaydırma casusunu yenileyin.
Sam

Bu yöntemin iyi olduğunu buldum, ancak farklı menü yüksekliklerine sahip olduğu için ofseti baştan ayarlamak için kullanmak istersem $ ['body']. Data (). Scrollspy.options.offset (veya sürüm 3.0 için varyant) henüz ayarlanmadı. Kaydırma casusuyla ilgili kaçırdığım eşzamansız bir şey var mı?
ness-EE

Bootstrap 3.1.1 itibariyle bu olmalıdır $('body').data()['bs.scrollspy'].options.offset. Sayfa yüklemesinde kaydırma casusunu tetiklemek için kullanışlıdırwindow.scrollBy(X,Y)
Meredith

8

10'luk bir ofset istiyorsanız, bunu kafanıza koyarsınız:

<script>
  $('#navbar').scrollspy({
    offset: 10
  });
</script>

Vücut etiketiniz şöyle görünecektir:

<body data-spy="scroll">

6
Bu içeriği dengelemez, navigasyonu dengeler.
markus

Bu, tıklamanın yönlendirdiği konumu değil (orijinal poster sorusudur) doğru gezinme öğesini vurgulamak için çalışacaktır. Bununla birlikte, aradığım şey buydu! Teşekkürler!
valin077

6

Gönderen önyükleme sorunu # 3316 :

[Bu] yalnızca kaydırma hesaplamalarını değiştirmeye yöneliktir - gerçek çapa tıklamasını değiştirmeyiz

Bu nedenle, ofset ayarı yalnızca scrollspy'nin sayfanın kaydırıldığını düşündüğü yeri etkiler . Bu kaydırma etkilemez bir çapa etiketi tıkladığında.

Sabit bir gezinme çubuğu kullanmak, tarayıcının yanlış yere kaydırdığı anlamına gelir. Bunu JavaScript ile düzeltebilirsiniz:

var navOffset = $('.navbar').height();

$('.navbar li a').click(function(event) {
    var href = $(this).attr('href');

    // Don't let the browser scroll, but still update the current address
    // in the browser.
    event.preventDefault();
    window.location.hash = href;

    // Explicitly scroll to where the browser thinks the element
    // is, but apply the offset.
    $(href)[0].scrollIntoView();
    window.scrollBy(0, -navOffset);
});

Ancak, scrollspy'nin doğru geçerli öğeyi vurguladığından emin olmak için yine de ofseti ayarlamanız gerekir:

<body class="container" data-spy="scroll" data-target=".navbar" data-offset="70">

İşte JSFiddle ile ilgili eksiksiz bir demo .


Alternatif olarak, CSS hilelerinin önerdiği şekilde bağlantı etiketlerinize dolgu yapabilirsiniz .

a[id]:before { 
  display: block; 
  content: " ";
  // Use the browser inspector to find out the correct value here.
  margin-top: -285px; 
  height: 285px; 
  visibility: hidden; 
}

1

Ofsetin, bölümün alt konumu ile bir şeyler yapabileceğini düşünüyorum.

Sorunumu - sizinki gibi - ekleyerek düzelttim

  padding-top: 60px;

bootstrap.css'deki bölüm için bildirimde

Umarım yardımcı olur!


"bölüm beyanı" nedir bu kodu nereye koyuyorsunuz?
ahnbizcad

1

Öğelerimin .vspaceher birinin önüne çapayı tutan 40px yüksekliğinde öğe ekledim h1.

<div class="vspace" id="gherkin"></div>
<div class="page-header">
  <h1>Gherkin</h1>
</div>

CSS'de:

.vspace { height: 40px;}

Harika çalışıyor ve alan boğucu değil.


1

Bootstrap 4 (2019 güncellemesi)

Uygulama: Sabit Gezinme, Scrollspy ve Düzgün Kaydırma

Bu, @ wilfred-hughes'in yukarıdaki çözümüdür, her bölüm etiketinin önüne görüntülenmeyen bir bloğu eklemek için CSS ':: before' kullanarak Bootstrap Fixed Navbar ile örtüşme sorununu tam olarak düzeltir. Avantaj: Bölümleriniz arasında gereksiz dolgu ile karşılaşmazsınız. Örneğin, bölüm 3 dikey olarak 2. bölümün tam karşısına yerleştirilebilir ve yine bölüm 3'ün üstündeki tam doğru konuma kaydırılacaktır.

Yan not: komut dosyası etiketinde kaydırma casusu ofsetinin ayarlanması hiçbir şeyin olmamasına neden oldu ($ ('# navbar'). Scrollspy ({offset: 105});) ve animasyon bloğundaki ofseti ayarlama girişimleri hala yanlış hizalama sonrası sonuçlandı. animasyon.

index.html

<section id="section1" class="my-5">
...
<section id="section2" class="my-5">
...
<section id="section3" class="my-5">
...

index.html'de daha sonra ...

 <script>
      // Init Scrollspy
      $('body').scrollspy({ target: '#main-nav' });

      // Smooth Scrolling
      $('#main-nav a').on('click', function(event) {
        if (this.hash !== '') {
          event.preventDefault();

          const hash = this.hash;

          $('html, body').animate(
            {
              scrollTop: $(hash).offset().top
            },
            800,
            function() {
              window.location.hash = hash;
            }
          );
        }
      });
    </script>

style.css:

// Solution to Fixed NavBar overlapping content of the section.  Apply to each navigable section.
// adjust the px values to your navbar height
// Source: https://github.com/twbs/bootstrap/issues/1768
#section1::before,
#section2::before,
#section3::before {
  display: block;
  content: ' ';
  margin-top: -105px;
  height: 105px;
  visibility: hidden;
}

body {
  padding-top: 105px;
}

Kredi: Yukarıdaki @ wilfred-hughes ve https://github.com/twbs/bootstrap/issues/1768 adresinde @mnot kullanıcısının orijinal kaynağı


1
teşekkür ederim! ugh Bir saattir bununla boğuşuyorum, LOL!
Nexus

0

Acjohnson55 ve Kurt UXD'nin çözümlerinde sorunlar yaşadım. Her ikisi de karma bağlantısına tıklamak için çalıştı, ancak kaydırma casusu uzaklığı hala doğru değildi.

Aşağıdaki çözümü buldum:

<div class="anchor-outer">
  <div id="anchor">
    <div class="anchor-inner">
      <!-- your content -->
    </div>
  </div>
</div>

Ve ilgili CSS:

body {
  padding-top:40px;
}

.anchor-outer {
  margin-top:-40px;
}

.anchor-inner {
  padding-top:40px;
}

@media (max-width: 979px) {
  body {
    padding-top:0px;
  }

  .anchor-outer {
    margin-top:0px;
  }

  .anchor-inner {
    padding-top:0px;
  }
}

@media (max-width: 767px) {
  body {
    padding-top:0px;
  }

  .anchor-outer {
    margin-top:0px;
  }

  .anchor-inner {
    padding-top:0px;
  }
}

40px dolgusunu / kenar boşluğunu navbarınızın yüksekliği ve çapanızın kimliği ile değiştirmeniz gerekecektir.

Bu kurulumda, veri ofseti özniteliği için bir değer ayarlamanın bir etkisini bile gözlemleyebiliyorum. 100-200 civarında veri ofseti için büyük değerler bulursanız, daha beklenen bir davranışa yol açar (başlık ekranın ortasındaysa kaydırma casusu- "anahtar" olacaktır).

Ayrıca scrollspy'nin kapatılmamış div etiketleri gibi hatalara karşı çok hassas olduğunu buldum (ki bu oldukça açıktır), bu yüzden http://validator.w3.org/check buradaki arkadaşımdı.

Kanımca kaydırma casusu en iyi bağlantı kimliğini taşıyan tüm bölümlerde işe yarar, çünkü normal bağlantı öğeleri geriye doğru kaydırıldığında beklenen etkilere yol açmaz (kaydırma casusu - "anahtar", bağlantı öğesine vurduğunuz anda gerçekleşir, örneğin başlığınız, ancak o zaman, kullanıcının ilgili başlığa ait olmasını beklediği içeriği zaten kaydırmışsınızdır).


0

Google aracılığıyla bu soruyu (benim yaptığım gibi) tökezlediyseniz ve yine de kaydırma casusunun ofsetini dinamik olarak değiştirmenin bir yolunu arıyorsanız. Şimdi benim için çalışan bir çözüme bağlantı ekliyorum.

Başka bir başlıkta yaptığım bu gönderiye bir göz atın . Bu, ofset değerini programlı olarak nasıl değiştirebileceğiniz ve değişikliklere dinamik olarak nasıl tepki verebileceğiniz (örneğin, navbar boyut olarak değişirse) hakkında bir pasaj içerir.

CSS düzeltmeleriyle uğraşmanıza gerek yok, bunun yerine belirli olaylara bağlı olarak şu anda ihtiyaç duyduğunuz ofseti ayarlamanız gerekiyor.


-1

Ayrıca açabilir bootstap-offset.jsve değiştirebilirsiniz

$.fn.scrollspy.defaults = {
  offset: 10
}

Orada.


1
Scrollspy ofseti içeriği dengelemez, navigasyonu dengeler.
markus

-1

Sadece ayarlayın:

data-offset="200"

data-offsetvarsayılan olarak "50" dir ve bu 10px'e eşdeğerdir, bu yüzden sadece artırın data-offsetve probleminiz çözülür.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.