Twitter Bootstrap - 选项卡 - URL 不变
Posted
技术标签:
【中文标题】Twitter Bootstrap - 选项卡 - URL 不变【英文标题】:Twitter Bootstrap - Tabs - URL doesn't change 【发布时间】:2012-08-21 07:25:00 【问题描述】:我正在使用 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 会发生变化,但选项卡不起作用。
有什么解决办法吗?
【问题讨论】:
修复此问题的插件:github.com/timabell/jquery.stickytabs 这是一个与***.com/q/18999501/873282类似的问题 【参考方案1】:我知道 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】:完整的解决方案需要三个组件:
-
如果 URL 中有哈希,则在加载页面时显示正确的选项卡。
更改选项卡时更改 URL 中的哈希值。
当 URL 中的哈希更改时更改选项卡(后退/前进按钮),并确保第一个选项卡循环正确。
我认为这里的任何 cmets 以及公认的答案都不能处理所有这些情况。
由于涉及的内容很多,我认为它作为一个小型 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 - 非常感谢插件,很好用。 这个解决方案的+1,因为它也适用于@tomaszback'解决方案不支持的后退/下一个浏览。谢谢! 这很棒而且效果很好,但是当我在 URL 中加载带有哈希的页面时就不行了。将继续挖掘以确保这是我做错的事情(很可能)。但是,我会给它一个 +1【参考方案3】:以上都不适合我,所以这是我的工作方式:
-
将
class="tab-link"
添加到所有需要此功能的链接
将以下代码添加到您的 javascript:
【讨论】:
【参考方案4】:由于您的锚元素已经更改了 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");
最后,在定义监听器之后触发事件也将有助于在页面加载时显示正确的选项卡。
【讨论】:
【参考方案5】:我使用的是 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'));
);
);
希望对你有所帮助。
【讨论】:
【参考方案6】:这是一个使用 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');
);
);
【讨论】:
【参考方案7】:试试这个代码。它将标签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。但是选择器中“hash && $..”的原因是显示选项卡,但“hash &&”是什么意思。谢谢&&
表示AND
所以如果左边等于真(hash
不是 0,null 或空)并且右边等于真,那么做一些事情,但是行结束使用;
,因此在;
之前无事可做,无论是否显示选项卡和.tab('show')
返回的内容都无关紧要,它仍然会尝试。以这种方式评估逻辑时,如果等式的第一部分(&&
之前)为假,则无需继续评估,因此不会显示选项卡。你可以达到同样的效果:if(hash) $('ul.nav a[href="' + hash + '"]').tab('show');
TL;DR: a && b;
表示尝试a
,然后只有当它为真时,才尝试b
。如果字符串不为空,则字符串为真。
当我使用 "#" url 时,我将如何让它重新加载顶部的页面?现在它向下滚动到选项卡开始的位置。我只想滚动到实际页面
工作正常,但必须将 "$('.nav-tabs a').click(" 替换为 "$('#navtabs a').on('shown.bs.tabs,"在 Bootstrap 3 上【参考方案8】:
感谢 @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
);
);
【讨论】:
Rejected 对我不起作用(可能只是 Firefox 版本)。无论如何,我对 var scrollmem = $('body').scrollTop() || 进行了更改$('html').scrollTop();谢谢! 是的。当你说我意识到这是一个浏览器的事情时,告诉我这件事,并迅速进入 chrome 以确保。我当然希望有一种方法可以对编辑评论发表评论。【参考方案9】:使用 Bootstrap 3 选项卡的 Cakephp 也存在同样的问题,而且当我使用外部 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
【讨论】:
【参考方案10】:对于那些使用 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 中使用。
【讨论】:
【参考方案11】:最简单的,假设您使用here 描述的记录在案的data-toggle="tab"
语法:
$(document).on('shown.bs.tab', function(event)
window.location.hash = $(event.target).attr('href');
);
【讨论】:
这会更改 URL,但在单击链接以打开特定选项卡时无法转到那里【参考方案12】:还有一种对哈希更改做出反应的简单方法(例如后退按钮)。只需将 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);
);
【讨论】:
【参考方案13】:我对您问题的解决方案:
首先为每个a
链接添加新的data-value
属性,如下所示:
<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>
其次,更改选项卡的 id,例如从 add
到 tab-add
,同时更新 href 以包含 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 - 但由于 jsFiddle 使用 iframe,它不起作用,但您可以阅读我的解决方案的源代码。
【讨论】:
【参考方案14】:这也修复了使用 jquery 和 bootstrap 时一个非常模糊的选项卡 a href 没有触发
<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>
【讨论】:
-1 我看不出这个答案如何为 3 个月前给出的已经给出的答案增加任何价值,并且答案中的代码完全相同。因此,在我看来,这不是一个有用的答案。【参考方案15】:使用data-toggle="tab"
询问插件来处理选项卡,同时在事件中调用preventDefault
(code on github)。
您可以使用自己的选项卡激活,并让事件通过:
$('.nav-tabs a').click(function (e)
// No e.preventDefault() here
$(this).tab('show');
);
而且你必须删除属性data-toggle="tab"
如有疑问,请查看the doc。
【讨论】:
以上是关于Twitter Bootstrap - 选项卡 - URL 不变的主要内容,如果未能解决你的问题,请参考以下文章
将 Twitter Bootstrap 导航选项卡与 Jade 一起使用
Twitter Bootstrap 选项卡活动类切换不起作用
Twitter Bootstrap - 选项卡 - URL 不变
页面重新加载后,如何使用 twitter bootstrap 保持当前选项卡处于活动状态?