จะใช้ปลั๊กอิน Affix ใหม่ใน bootstrap 2.1.0 ของ Twitter ได้อย่างไร


110

เอกสาร bootstrap ในหัวข้อนั้นทำให้ฉันสับสนเล็กน้อย ฉันต้องการให้เกิดลักษณะการทำงานที่คล้ายกันเช่นในเอกสารที่มีแถบนำทางที่ติดอยู่: แถบนำทางอยู่ด้านล่างส่วนหัวของย่อหน้า / หน้าและเมื่อเลื่อนลงมาควรเลื่อนไปก่อนจนกว่าจะถึงด้านบนสุดของหน้าจากนั้นติดที่นั่นเพื่อแก้ไขเพื่อเลื่อนลงต่อไป .

เนื่องจาก jsFiddle ไม่ทำงานกับแนวคิด navbar ฉันจึงได้ตั้งค่าหน้าแยกสำหรับการใช้งานเป็นตัวอย่างขั้นต่ำ: http://i08fs1.ira.uka.de/~s_drr/navbar.html

ฉันใช้สิ่งนี้เป็นแถบนำทางของฉัน:

<div class="navbar affix-top" data-spy="affix" data-offset-top="50">
    <div class="navbar-inner">
        <div class="container">
            <div class="span12">
                <a class="brand" href="#">My Brand</a> 
                This is my navbar.
             </div>
        </div> <!-- container -->
    </div> <!-- navbar-inner -->
</div> <!-- navbar -->

ฉันคิดว่าฉันต้องการdata-offset-topให้มีค่าเป็น 0 (เนื่องจากแถบควร "ติด" ที่ด้านบนสุด "แต่ด้วย 50 จะมีเอฟเฟกต์บางอย่างที่สามารถรับชมได้เป็นอย่างน้อย

หากใส่รหัสจาวาสคริปต์ด้วย:

     <script>
        $(document).ready (function (){
            $(".navbar").affix ();
        });
     </script>

ความช่วยเหลือใด ๆ ที่ชื่นชม


คุณกำลังพยายามใช้ affix () บนแถบนำทางหลักของเพจของคุณหรือไม่
Nithin Emmanuel

@NithinEmmanuel ใช่ดู javascript ในโพสต์หรือที่ตัวอย่าง: i08fs1.ira.uka.de/~s_drr/navbar.html
Dynalon

ทำไมคุณไม่ใช้ use .navbar-fixed-topแทนการใช้ affix () ล่ะ?
Nithin Emmanuel

6
@NithinEmmanuel เพราะนั่นไม่ใช่สิ่งที่ฉันต้องการ .navbar-fixed-topจะวาง navbar ไปด้านบนตลอดเวลา ฉันต้องการให้ส่วนหัวของหน้าอยู่เหนือแถบนำทางและเมื่อเลื่อนลง (ดังนั้นแถบนำทางจะเลื่อนออกไป) มันควรจะอยู่ด้านบนสุด - จากนั้นก็เท่านั้น เอกสาร Bootstrap ใช้กลไกเดียวกันกับ subnav ในเอกสารก่อนหน้านี้ แต่น่าเสียดายที่พวกเขาได้ลบออกสำหรับเอกสาร 2.1.0
Dynalon

1
สำหรับหนึ่งการซ้อน Javascript ของคุณไม่ถูกต้อง )};ควรจะเป็น});
Owen

คำตอบ:


160

ฉันประสบปัญหาที่คล้ายกันและฉันเชื่อว่าฉันพบวิธีแก้ไขที่ดีขึ้นแล้ว

อย่ากังวลกับการระบุdata-offset-topใน HTML ของคุณ ให้ระบุเมื่อคุณโทร.affix():

$('#nav').affix({
    offset: { top: $('#nav').offset().top }
});​

ข้อดีคือคุณสามารถเปลี่ยนการจัดวางไซต์ของคุณได้โดยไม่จำเป็นต้องอัปเดตdata-offset-topแอตทริบิวต์ เนื่องจากสิ่งนี้ใช้ตำแหน่งที่คำนวณจริงขององค์ประกอบจึงป้องกันความไม่สอดคล้องกับเบราว์เซอร์ที่แสดงองค์ประกอบในตำแหน่งที่แตกต่างกันเล็กน้อย


คุณยังคงต้องยึดองค์ประกอบไว้ด้านบนด้วย CSS นอกจากนี้ฉันต้องตั้งค่าwidth: 100%ในองค์ประกอบ nav เนื่องจาก.navองค์ประกอบที่มีการposition: fixedทำงานผิดปกติด้วยเหตุผลบางประการ:

#nav.affix {
    position: fixed;
    top: 0px;
    width: 100%;
}

สิ่งสุดท้าย: เมื่อองค์ประกอบที่ติดอยู่ได้รับการแก้ไของค์ประกอบของมันจะไม่ใช้พื้นที่บนหน้าอีกต่อไปส่งผลให้องค์ประกอบด้านล่าง "กระโดด" เพื่อป้องกันความอัปลักษณ์นี้ฉันห่อ navbar ด้วยdivความสูงที่ฉันตั้งไว้ให้เท่ากับ navbar ที่รันไทม์:

<div id="nav-wrapper">
    <div id="nav" class="navbar">
        <!-- ... -->
    </div>
</div>

.

$('#nav-wrapper').height($("#nav").height());

นี่คือบังคับ jsFiddle ที่จะเห็นมันในการดำเนินการ


6
เคล็ดลับที่ดีในการลบ "การกระโดด" - มองข้ามความจริงที่ว่ารายการนี้ถูกลบออกไปโดยสิ้นเชิงและคิดว่าปัญหาของฉันอยู่ในส่วน affix / js ของรหัสของฉัน
โธมัส

1
คำตอบนี้ดีที่สุด! ทุกอย่างทำงานได้ตามที่ควร ส่วน 'กระโดด' เป็นส่วนที่ขาดหายไปในบทช่วยสอนส่วนใหญ่ที่ฉันพบ ขอบคุณ!
Ricardo Otero

1
การแก้ไขที่สำคัญอย่างหนึ่ง: ใช้ offset () แทน position () ในโค้ด jquery ของคุณในข้อมูลโค้ดแรกของคุณ คำอธิบาย: ฟังก์ชัน position () ให้ค่าชดเชยภายในองค์ประกอบหลัก แต่ offset () คือตำแหน่งภายในเอกสารซึ่งเป็นสิ่งที่คุณต้องการจริง ๆ (ใช่ชื่อนั้นใช้งานง่าย) ดังนั้นรหัสของคุณจะไม่ทำงานหากองค์ประกอบที่ติดของคุณอยู่ในองค์ประกอบอื่น คุณควรส่งเฉพาะค่า "top" เช่นนี้: $ ("# nav"). affix ({offset: {top: $ ('# nav'). offset (). top และควรอยู่ในช่องพร้อม () เพื่อให้ทราบว่าเค้าโครงหน้าเสร็จสมบูรณ์
ออร์

ขอบคุณ @orrd - กำลังอัปเดตคำตอบและซอ!
namuol

ดี! ทำงานได้อย่างสมบูรณ์และราบรื่นมาก ยังไงก็ตามฉันกำลังมองหาตัวอย่างเดียวกันกับส่วนท้ายที่ติดหนึบ ถ้าคุณรู้วิธีการนั้นคุณสามารถอัปเดต jsFiddle ได้หรือไม่? ขอบคุณ!
Jocelyn

76

เพิ่งติดตั้งเป็นครั้งแรกและนี่คือสิ่งที่ฉันพบ

data-offset-topค่าเป็นจำนวนพิกเซลที่คุณต้องเลื่อนเพื่อให้มีผลบังคับใช้พิมพ์ตัวหนังสือลงบนจะใช้สถานที่ ในกรณีของคุณเมื่อ50pxมีการเลื่อนระดับในรายการของคุณจะเปลี่ยนจากการ.affix-top .affixคุณอาจต้องการตั้งค่าdata-offset-topเป็น about 130pxในกรณีการใช้งานของคุณ

เมื่อการเปลี่ยนแปลงระดับนี้เกิดขึ้นคุณต้องวางตำแหน่งองค์ประกอบของคุณในการจัดแต่งทรงผม CSS .affixโดยการวางตำแหน่งสำหรับการเรียน เงินทุน 2.1 แล้วกำหนด.affixเป็นposition: fixed;ดังนั้นสิ่งที่คุณต้องทำคือการเพิ่มค่าของตำแหน่งของคุณเอง

ตัวอย่าง:

.affix {
    position: fixed; 
    top: 20px; 
    left: 0px;
}

1
ขอบคุณที่ค่อนข้างได้ผล ฉันได้อัปเดตหน้าตัวอย่างของฉันไปแล้ว ปัญหาคือทันทีที่ navbar ได้รับ "affix" เป็นคลาส css คลาส navbar css จะถูกละทิ้ง แต่ฉันคิดว่านั่นเป็นเพียงข้อบกพร่อง / คำสั่งสั้น ๆ จาก bootstrap จะไม่ง่ายที่จะเปลี่ยนโดยไม่ต้องทำใน LESS และสร้าง bootstrap ใหม่
Dynalon

ดูเหมือนว่า.navbarชั้นจะถูกเก็บรักษาไว้ - คุณแน่ใจหรือ
Dave Kiss

ขอบคุณสำหรับคำตอบนี้ฉันใช้เวลานานหลายปีในการพยายามคิดออก
รูเบน

ดูคำตอบของฉันสำหรับวิธีแก้ปัญหาทั่วไปที่ปรับปรุงเล็กน้อย
namuol

5

เพื่อแก้ไขปัญหานี้ฉันได้แก้ไขปลั๊กอิน affix เพื่อปล่อยเหตุการณ์ jQuery เมื่อวัตถุติดหรือไม่ติดกัน

นี่คือคำขอดึง: https://github.com/twitter/bootstrap/pull/4712

และรหัส: https://github.com/corbinu/bootstrap/blob/master/js/bootstrap-affix.js

จากนั้นทำสิ่งนี้เพื่อแนบ navbar:

<script type="text/javascript">
$(function(){
    $('#navbar').on('affixed', function () {
        $('#navbar').addClass('navbar-fixed-top')
    });

    $('#navbar').on('unaffixed', function () {
        $('#navbar').removeClass('navbar-fixed-top')
    });
});
</script>

3

คุณต้องลบออก.affix()จากสคริปต์ของคุณ

Bootstrap ให้ตัวเลือกในการทำสิ่งต่างๆให้สำเร็จผ่านdata-attributesJavaScript หรือแบบตรงเกือบตลอดเวลา


2

ฉันได้รับสิ่งนี้จากซอร์สโค้ดของ twitterbootstrap และมันใช้งานได้ดี:

HTML:

<div class="row">
    <div class="span3 bs-docs-sidebar">
        <ul id="navbar" class="nav nav-list bs-docs-sidenav">
            ...
        </ul>
    </div>
</div>

CSS:

.bs-docs-sidenav {
    max-height: 340px;
    overflow-y: scroll;
}

.affix {
    position: fixed;
    top: 50px;
    width: 240px;
}

JS:

$(document).ready(function(){
    var $window = $(window);
    setTimeout(function () {
        $('.bs-docs-sidenav').affix({
            offset: {
                top: function (){
                    return $window.width() <= 980 ? 290 : 210
                }
            }
        })
    }, 100);
});

1

คุณเพียงแค่ต้องลบสคริปต์ นี่คือตัวอย่างของฉัน:

<!DOCTYPE html>
<html>

<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
<script type="text/javascript" src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.0/js/bootstrap.min.js"></script>

  <style>
  #content {
    width: 800px;
    height: 2000px;
    background: #f5f5f5;
    margin: 0 auto;
  }
  .menu {
    background: #ccc;
    width: 200px;
    height: 400px;
    float: left;
  }
  .affix {
    position: fixed;
    top: 20px;
    left: auto;
    right: auto;
  }
  </style>

</head>
<body>
    <div id="content">
        <div style="height: 200px"></div>

        <div class="affix-top" data-spy="affix" data-offset-top="180">
            <div class="menu">AFFIX BAR</div>
        </div>
    </div>
</body>
</html>

1

ขอบคุณ namuol และ Dave Kiss สำหรับวิธีแก้ปัญหา ในกรณีของฉันฉันมีปัญหาเล็กน้อยเกี่ยวกับความสูงและความกว้างของ navbar เมื่อฉันใช้ปลั๊กอิน afflix และยุบร่วมกัน ปัญหาเกี่ยวกับความกว้างสามารถแก้ไขได้อย่างง่ายดายโดยสืบทอดมาจากองค์ประกอบหลัก (คอนเทนเนอร์ในกรณีของฉัน) นอกจากนี้ฉันสามารถจัดการเพื่อให้มันยุบลงอย่างราบรื่นด้วยจาวาสคริปต์ (กาแฟจริง) เคล็ดลับคือการตั้งค่าความสูงของกระดาษห่อautoก่อนที่จะเกิดการสลับการยุบและแก้ไขกลับในภายหลัง

มาร์กอัป (haml):

#wrapper
  #navbar.navbar
    .navbar-inner
      %a.btn.btn-navbar.btn-collapse
        %span.icon-bar
        %span.icon-bar
        %span.icon-bar

      #menu.nav-collapse
        -# Menu goes here

CSS:

#wrapper {
  width: inherit;
}

#navbar {
  &.affix {
    top: 0;
    width: inherit;
  }
}

Coffeescript:

class Navigation
  @initialize: ->
    @navbar = $('#navbar')
    @menu = $('#menu')
    @wrapper = $('#wrapper')

    @navbar.affix({offset: @navbar.position()})
    @adjustWrapperHeight(@navbar.height())

    @navbar.find('a.btn-collapse').on 'click', () => @collapse()

    @menu.on 'shown', () => @adjustWrapperHeight(@navbar.height())
    @menu.on 'hidden', () => @adjustWrapperHeight(@navbar.height())

  @collapse: ->
    @adjustWrapperHeight("auto")
    @menu.collapse('toggle')

  @adjustWrapperHeight: (height) ->
    @wrapper.css("height", height)

$ ->
  Navigation.initialize()

0

วิธีแก้ปัญหาของฉันสำหรับการแนบ navbar:

function affixnolag(){

    $navbar = $('#navbar');
    if($navbar.length < 1)
        return false;

    h_obj = $navbar.height();

    $navbar
        .on('affixed', function(){      
            $navbar.after('<div id="nvfix_tmp" style="height:'+h_obj+'px">');
        })
        .on('unaffixed', function(){
            if($('#nvfix_tmp').length > 0)
                $('#nvfix_tmp').remove();
        });
 }

0

เช่นเดียวกับคำตอบที่ยอมรับคุณสามารถทำสิ่งต่อไปนี้เพื่อทำทุกอย่างได้ในครั้งเดียว:

$('#nav').affix({
  offset: { top: $('#nav').offset().top }
}).wrap(function() {
  return $('<div></div>', {
    height: $(this).outerHeight()
  });
});​

สิ่งนี้ไม่เพียง แต่เรียกใช้affixปลั๊กอิน แต่ยังรวมองค์ประกอบที่ติดอยู่ใน div ซึ่งจะช่วยปรับความสูงเดิมของแถบนำทาง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.