Twitter Bootstrap - แท็บ - URL ไม่เปลี่ยนแปลง


109

ฉันใช้ Twitter Bootstrap และ "แท็บ"

ฉันมีรหัสต่อไปนี้:

<ul class="nav nav-tabs">
    <li class="active"><a data-toggle="tab" href="#add">add</a></li>
    <li><a data-toggle="tab" href="#edit" >edit</a></li>
    <li><a data-toggle="tab" href="#delete" >delete</a></li>
</ul>

แท็บทำงานได้อย่างถูกต้อง แต่ใน URL ไม่ได้เพิ่ม #add, #edit, #delete

เมื่อฉันลบdata-toggleการเปลี่ยนแปลง URL แต่แท็บไม่ทำงาน

วิธีแก้ปัญหานี้หรือไม่?


1
ปลั๊กอินที่แก้ไขปัญหานี้: github.com/timabell/jquery.stickytabs
Tim Abell

นี่เป็นคำถามที่คล้ายกันกับstackoverflow.com/q/18999501/873282
koppor

คำตอบ:


269

ลองใช้รหัสนี้ เพิ่มแท็บ href ไปยัง url + เปิดแท็บตามแฮชในการโหลดหน้า:

$(function(){
  var hash = window.location.hash;
  hash && $('ul.nav a[href="' + hash + '"]').tab('show');

  $('.nav-tabs a').click(function (e) {
    $(this).tab('show');
    var scrollmem = $('body').scrollTop() || $('html').scrollTop();
    window.location.hash = this.hash;
    $('html,body').scrollTop(scrollmem);
  });
});

1
มันใช้งานได้ดีมาก +1. แต่อะไรคือสาเหตุของ "แฮช && $ .. " จากตัวเลือกคือแสดงแท็บ แต่ "แฮช &&" หมายถึงอะไร ขอบคุณ
richardhell

4
&&หมายความว่าANDถ้าทางซ้ายของสิ่งนั้นเท่ากับจริง ( hashไม่ใช่ 0 เป็นโมฆะหรือว่างเปล่า) และทางขวาเท่ากับ true ให้ทำอะไรสักอย่างอย่างไรก็ตามบรรทัดจะลงท้ายด้วย a ;ดังนั้นจึงไม่มีอะไรต้องทำก่อนหน้านี้;และไม่สำคัญว่า a แท็บแสดงหรือไม่และไม่สำคัญว่า.tab('show')จะส่งคืนอย่างไรก็ยังคงพยายาม เมื่อประเมินตรรกะด้วยวิธีนี้หากส่วนแรกของสมการ (ก่อนหน้า&&นี้) เป็นเท็จก็ไม่จำเป็นต้องทำการประเมินต่อไปดังนั้นแท็บจะไม่แสดง คุณสามารถบรรลุผลเช่นนี้:if(hash){ $('ul.nav a[href="' + hash + '"]').tab('show'); }
vahanpwns

1
TL; DR: a && b;วิธีการลองแล้วเท่านั้นถ้าจริงลองa bสตริงเป็นจริงหากไม่ว่างเปล่า
vahanpwns

8
ฉันจะทำให้มันโหลดซ้ำหน้าเว็บที่ด้านบนเมื่อฉันใช้ URL "#" ได้อย่างไร ตอนนี้มันเลื่อนลงไปที่จุดเริ่มต้นของแท็บ ฉันแค่อยากจะเลื่อนขึ้นไปบนหน้าเว็บจริง
kibaekr

1
ใช้งานได้ดี แต่ต้องแทนที่ "$ ('. nav-tabs a') คลิก (" โดย "$ ('# navtabs a'). on ('shown.bs.tabs," ใน Bootstrap 3
Zzirconium

49

มีองค์ประกอบสามอย่างที่จำเป็นสำหรับโซลูชันที่สมบูรณ์:

  1. แสดงแท็บที่ถูกต้องเมื่อโหลดเพจหากมีแฮชใน URL
  2. การเปลี่ยนแฮชใน URL เมื่อแท็บมีการเปลี่ยนแปลง
  3. เปลี่ยนแท็บเมื่อแฮชเปลี่ยน URL (ปุ่มย้อนกลับ / เดินหน้า) และตรวจสอบให้แน่ใจว่าแท็บแรกวนอย่างถูกต้อง

ฉันไม่คิดว่าความคิดเห็นใด ๆ ที่นี่หรือคำตอบที่ยอมรับจะจัดการกับสถานการณ์เหล่านี้ทั้งหมด

เนื่องจากมีส่วนเกี่ยวข้องค่อนข้างน้อยฉันคิดว่ามันเป็นปลั๊กอิน jQuery ขนาดเล็ก: https://github.com/aidanlister/jquery-stickytabs

คุณสามารถเรียกปลั๊กอินได้ดังนี้:

$('.nav-tabs').stickyTabs();

ฉันได้สร้างบล็อกโพสต์สำหรับเรื่องนี้http://aidanlister.com/2014/03/persisting-the-tab-state-in-bootstrap/


ฉันให้มันเป็น git repo ของตัวเอง: github.com/timabell/jquery.stickytabs - ขอบคุณมากสำหรับปลั๊กอินใช้งานได้ดี
Tim Abell

+1 สำหรับโซลูชันนี้เนื่องจากใช้งานได้ในการเรียกดูย้อนกลับ / ถัดไปซึ่งโซลูชันของ @tomaszback ไม่ได้ ขอบคุณ!
bitfidget

สิ่งนี้ยอดเยี่ยมและใช้งานได้ดี แต่ไม่ใช่เมื่อฉันโหลดหน้าเว็บที่มีแฮชใน URL จะขุดไปเรื่อย ๆ เพื่อให้แน่ใจว่าเป็นสิ่งที่ฉันทำผิด (เป็นไปได้สูง) อย่างไรก็ตามฉันจะให้ +1
MattBoothDev

27

การใช้data-toggle="tab" ขอให้ปลั๊กอินจัดการแท็บซึ่งในขณะที่เรียกpreventDefaultใช้เหตุการณ์นั้น ( รหัสบน github )

คุณสามารถใช้การเปิดใช้งานแท็บของคุณเองและปล่อยให้เหตุการณ์ผ่านไป:

$('.nav-tabs a').click(function (e) {
    // No e.preventDefault() here
    $(this).tab('show');
});

และคุณต้องลบแอตทริบิวต์ data-toggle="tab"

ตรวจสอบเอกสารหากคุณมีข้อสงสัย


11

เนื่องจากองค์ประกอบจุดยึดของคุณเปลี่ยนแฮช URL อยู่แล้วการฟังเหตุการณ์onhashchangeจึงเป็นอีกทางเลือกหนึ่งที่ดี ดังที่ @flori ได้กล่าวไปแล้ววิธีนี้ใช้ได้ดีกับปุ่มย้อนกลับของเบราว์เซอร์

var tabs$ = $(".nav-tabs a");

$( window ).on("hashchange", function() {
    var hash = window.location.hash, // get current hash
        menu_item$ = tabs$.filter('[href="' + hash + '"]'); // get the menu element

    menu_item$.tab("show"); // call bootstrap to show the tab
}).trigger("hashchange");

สุดท้ายการทริกเกอร์เหตุการณ์หลังจากที่คุณกำหนด Listener จะช่วยแสดงแท็บที่ถูกต้องในการโหลดหน้าเว็บ


3

วิธีแก้ปัญหาของฉัน:

ขั้นแรกให้เพิ่มdata-valueแอตทริบิวต์ใหม่ในแต่ละaลิงก์ดังนี้:

<ul class="nav nav-tabs">
    <li class="active">
        <a data-toggle="tab" href="#tab-add" data-value="#add">add</a>
    </li>
    <li>
        <a data-toggle="tab" href="#tab-edit" data-value="#edit">edit</a>
    </li>
    <li>
        <a data-toggle="tab" href="#tab-delete" data-value="#delete">delete</a>
    </li>
</ul>

ประการที่สองเปลี่ยนรหัสของแท็บเช่นจากเป็นaddถึงtab-addอัปเดต hrefs เพื่อรวมtab-คำนำหน้า:

<div class="tab-content">
    <div class="tab-pane" id="tab-add">Add panel</div>
    <div class="tab-pane" id="tab-edit">Edit panel</div>
    <div class="tab-pane" id="tab-delete">Panel panel</div>
</div>

และสุดท้ายรหัส js:

<script type="text/javascript">
    $(function () {
        var navTabs = $('.nav-tabs a');
        var hash = window.location.hash;
        hash && navTabs.filter('[data-value="' + hash + '"]').tab('show');

        navTabs.on('shown', function (e) {
            var newhash = $(e.target).attr('data-value');
            window.location.hash = newhash;
        });
    })
</script>

นี่คือjsFiddle - แต่ใช้งานไม่ได้เนื่องจากใช้ iframe โดย jsFiddle แต่คุณสามารถอ่านแหล่งที่มาของโซลูชันของฉันได้


3

ปัญหาเดียวกันกับ CakePHP กับ Bootstrap 3 Tabs บวกกับเมื่อฉันส่งด้วย URL ภายนอกและจุดยึดมันจะข้ามไปที่ส่วนที่สูญเสียเมนูของฉันหลังจากตรวจสอบวิธีแก้ปัญหามากมายทำให้สิ่งนี้ ...

ขอบคุณ: http://ck.kennt-wayne.de/2012/dec/twitter-bootstrap-how-to-fix-tabs

$(document).ready(function()
 {  
//Redirecciona al tab, usando un prefijo al cargar por primera vez, al usar redirect en cake #_Pagos    
//Redirecciona al tab, usando #Pagos
/* Automagically jump on good tab based on anchor; for page reloads or links */
 if(location.hash) 
  {
     $('a[href=' + location.hash + ']').tab('show');         
  }


//Para evitar el bajar al nivel del tab, (al mostrarse el tab subimos)
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) 
{
    location.hash = $(e.target).attr('href').substr(1);
    scrollTo(0,0);      
});



//Actualiza el URL con el anchor o ancla del tab al darle clic
 /* Update hash based on tab, basically restores browser default behavior to
 fix bootstrap tabs */
$(document.body).on("click", "a[data-toggle]", function(event) 
  {
    location.hash = this.getAttribute("href");
  });


//Redirecciona al tab, al usar los botones de regresar y avanzar del navegador.
/* on history back activate the tab of the location hash if exists or the default tab if no hash exists */   
$(window).on('popstate', function() 
{
  //Si se accesa al menu, se regresa al tab del perfil (activo default), fixed conflict with menu
  //var anchor = location.hash || $("a[data-toggle=tab]").first().attr("href");
  var anchor = location.hash;
  $('a[href=' + anchor + ']').tab('show');

});   

});//Fin OnReady

2

นอกจากนี้ยังมีวิธีง่ายๆในการตอบสนองต่อการเปลี่ยนแปลงแฮช (เช่นปุ่มย้อนกลับ) เพียงแค่เพิ่มตัวฟังเหตุการณ์ hashchange ในโซลูชัน tomaszbak:

$(function(){
  // Change tab on load
  var hash = window.location.hash;
  hash && $('ul.nav a[href="' + hash + '"]').tab('show');

  $('.nav-tabs a').click(function (e) {
    $(this).tab('show');
    var scrollmem = $('body').scrollTop();
    window.location.hash = this.hash;
    $('html,body').scrollTop(scrollmem);
  });

  // Change tab on hashchange
  window.addEventListener('hashchange', function() {
    var changedHash = window.location.hash;
    changedHash && $('ul.nav a[href="' + changedHash + '"]').tab('show');
  }, false);
});

1

ฉันใช้ Bootstrap 3.3. * และไม่มีวิธีแก้ปัญหาใด ๆ ข้างต้นช่วยฉันเลยแม้จะทำเครื่องหมายว่าเป็นคำตอบ ฉันเพิ่งเพิ่มสคริปต์ด้านล่างและใช้งานได้

$(function(){
    var hash = document.location.hash;
    if (hash) {
       $('.navbar-nav a[href="' + hash + '"]').tab('show');
    }
    $('a[data-toggle="tab"]').on('click', function (e) {
       history.pushState(null, null, $(this).attr('href'));
    });
});

หวังว่านี่จะช่วยคุณได้


0

ง่ายที่สุดโดยสมมติว่าคุณใช้data-toggle="tab"ไวยากรณ์ที่อธิบายไว้ที่นี่ :

$(document).on('shown.bs.tab', function(event) {
  window.location.hash = $(event.target).attr('href');
});

สิ่งนี้เปลี่ยน URL แต่ไม่สามารถไปที่นั่นได้เมื่อคลิกลิงก์เพื่อเปิดแท็บเฉพาะ
Khrys

0

สำหรับผู้ที่ใช้ Ruby on Rails หรือสคริปต์ฝั่งเซิร์ฟเวอร์อื่น ๆ คุณจะต้องใช้anchorตัวเลือกบนพา ธ เนื่องจากเมื่อโหลดหน้าเว็บแล้วจะไม่มีแฮช URL คุณจะต้องใส่แท็บที่ถูกต้องผ่านลิงค์หรือการส่งแบบฟอร์มของคุณ

<%= form_for @foo, url: foo_path(@foo, anchor: dom_id(foo)) do |f| %>
# Or
<%= link_to 'Foo', foo_path(@foo, anchor: dom_id(foo)) %>

หากคุณใช้คำนำหน้าเพื่อป้องกันไม่ให้หน้าต่างข้ามไปที่ id:

<%= form_for @foo, url: foo_path(@foo, anchor: "bar_#{dom_id(foo)}") do |f| %>

แล้วคุณ CoffeeScript:

  hash = document.location.hash
  prefix = 'bar_'
  $('.nav-tabs a[href=' + hash.replace(prefix, '') + ']').tab 'show' if hash
  $('.nav-tabs a').on 'shown.bs.tab', (e) ->
    window.location.hash = e.target.hash.replace '#', '#' + prefix

หรือ JavaScript:

var hash, prefix;

hash = document.location.hash;
prefix = 'bar_';

if (hash) {
  $('.nav-tabs a[href=' + hash.replace(prefix, '') + ']').tab('show');
}

$('.nav-tabs a').on('shown.bs.tab', function(e) {
  window.location.hash = e.target.hash.replace('#', '#' + prefix);
});

สิ่งนี้ควรใช้ได้ใน Bootstrap 3


0

ขอบคุณ@tomaszbakสำหรับวิธีแก้ปัญหาดั้งเดิมอย่างไรก็ตามเนื่องจากการแก้ไขของฉันถูกปฏิเสธและฉันไม่สามารถแสดงความคิดเห็นในโพสต์ของเขาได้ฉันจะปล่อยให้เวอร์ชันปรับปรุงและอ่านได้ง่ายขึ้นเล็กน้อยที่นี่

โดยพื้นฐานแล้วจะเป็นสิ่งเดียวกัน แต่หากแก้ไขปัญหาความเข้ากันได้ข้ามเบราว์เซอร์ที่ฉันมีกับเขา

$(document).ready(function(){
   // go to hash on window load
   var hash = window.location.hash;
   if (hash) {
       $('ul.nav a[href="' + hash + '"]').tab('show');
   }
   // change hash on click
   $('.nav-tabs a').click(function (e) {
       $(this).tab('show');
       if($('html').scrollTop()){
           var scrollmem = $('html').scrollTop(); // get scrollbar position (firefox)
       }else{
           var scrollmem = $('body').scrollTop(); // get scrollbar position (chrome)
       }
       window.location.hash = this.hash;
       $('html,body').scrollTop(scrollmem); // set scrollbar position
   });
});

ถูกปฏิเสธไม่ได้ผลสำหรับฉัน (อาจเป็นเพียงเวอร์ชัน Firefox) อย่างไรก็ตามฉันได้ทำการเปลี่ยนแปลง var scrollmem = $ ('body') scrollTop () || $ ('html'). scrollTop (); ขอบคุณ!
tomaszbak

1
ใช่. บอกฉันเกี่ยวกับเรื่องนี้ทันทีที่คุณบอกว่าฉันรู้ว่ามันเป็นเบราว์เซอร์ที่เข้าสู่ Chrome อย่างรวดเร็วเพื่อให้แน่ใจ ฉันหวังว่าจะมีวิธีแสดงความคิดเห็นในการแก้ไขบทวิจารณ์
Fuxy

0

นี่คือตัวเลือกที่ใช้history.pushStateเพื่อให้คุณสามารถใช้ประวัติเบราว์เซอร์เพื่อย้อนกลับไปยังแท็บก่อนหน้า

  $(document).ready(function() {
  // add a hash to the URL when the user clicks on a tab
  $('a[data-toggle="tab"]').on('click', function(e) {
    history.pushState(null, null, $(this).attr('href'));
  });
  // navigate to a tab when the history changes
  window.addEventListener("popstate", function(e) {
    var activeTab = $('[href=' + location.hash + ']');
    if (activeTab.length) {
      activeTab.tab('show');
    } else {
      $('.nav-tabs a:first').tab('show');
    }
  });
});

0

ข้างต้นไม่ได้ผลสำหรับฉันดังนั้นนี่คือวิธีการทำงานของฉัน:

  1. เพิ่มclass="tab-link"ในลิงก์ทั้งหมดที่ต้องการฟังก์ชันนี้
  2. เพิ่มรหัสต่อไปนี้ในจาวาสคริปต์ของคุณ:
    window.addEventListener
    (
        'popstate',
        ฟังก์ชัน (เหตุการณ์)
        {
            tab_change ();
        }
    );

    ฟังก์ชัน tab_change ()
    {
        var แฮช = window.location.hash;
        แฮช && $ ('ul.nav a [href = "' + แฮช + '"]') .tab ('แสดง');

        $ ('.tab-link') คลิก
        (
            ฟังก์ชัน (e)
            {
                $ (this) .tab ('แสดง');

                var scrollmem = $ ('body') .scrollTop () || $ ('html') .scrollTop ();
                window.location.hash = this.hash;
                $ ('html, body') .scrollTop (scrollmem);

                $ ('ul.nav-tabs a [href = "' + window.location.hash + '"]') .tab ('แสดง');
            }
        );
    }


0

ฉันเข้าใจว่า OP พูดโดยใช้ JQuery แต่คุณสามารถใช้ vanilla JS เพื่อทำสิ่งนั้น:

document.querySelectorAll('ul.nav a.nav-link').forEach(link => {
    link.onclick = () => window.history.pushState(null, null, link.attributes.href.value);
});

-2

นอกจากนี้ยังแก้ไขแท็บที่คลุมเครืออย่างมากที่ href ไม่เริ่มทำงานเมื่อใช้ jquery และ bootstrap

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> 

<script type="text/javascript">
$('.nav-tabs a').click(function (e) {
    // No e.preventDefault() here.
    $(this).tab('show');
});
</script>

<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/js/bootstrap.min.js"></script>

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