javascript - una - Pestañas de inicio de Twitter: Vaya a la pestaña específica en Recarga de página o Hipervínculo
html otra pestaña (22)
Acabo de tener este problema, pero necesitaba manejar múltiples niveles de pestañas. El código es bastante feo (ver comentarios), pero cumple su función: https://gist.github.com/JensRantil/4721860 Esperemos que alguien más lo encuentre útil (¡y siéntase libre de proponer mejores soluciones!).
Estoy desarrollando una página web en la que estoy usando el marco de Bootstrap de Twitter y sus Bootstrap Tabs JS . Funciona muy bien, excepto por algunos problemas menores, uno de los cuales es no sé cómo ir directamente a una pestaña específica desde un enlace externo. Por ejemplo:
<a href="facility.php#home">Home</a>
<a href="facility.php#notes">Notes</a>
debe ir a la pestaña Inicio y la pestaña Notas respectivamente cuando haga clic en los enlaces desde una página externa
Aquí está mi solución al problema, quizás un poco tarde. Pero tal vez podría ayudar a otros:
// Javascript to enable link to tab
var url = document.location.toString();
if (url.match(''#'')) {
$(''.nav-tabs a[href="#'' + url.split(''#'')[1] + ''"]'').tab(''show'');
}
// Change hash for page-reload
$(''.nav-tabs a'').on(''shown.bs.tab'', function (e) {
window.location.hash = e.target.hash;
})
Combinando elementos de otras respuestas, aquí hay una solución que puede abrir muchos niveles de pestañas anidadas:
// opens all tabs down to the specified tab
var hash = location.hash.split(''?'')[0];
if(hash) {
var $link = $(''[href='' + hash + '']'');
var parents = $link.parents(''.tab-pane'').get();
$(parents.reverse()).each(function() {
$(''[href=#'' + this.id + '']'').tab(''show'') ;
});
$link.tab(''show'');
}
Esta es mi solución para manejar pestañas anidadas. Acabo de agregar una función para verificar si la pestaña activa tiene una pestaña principal para activar. Esta es la función:
function activateParentTab(tab) {
$(''.tab-pane'').each(function() {
var cur_tab = $(this);
if ( $(this).find(''#'' + tab).length > 0 ) {
$(''.nav-tabs a[href=#''+ cur_tab.attr(''id'') +'']'').tab(''show'');
return false;
}
});
}
Y se puede llamar así (basado en la solución de @flynfish):
var hash = document.location.hash;
var prefix = "";
if (hash) {
$(''.nav-tabs a[href=''+hash.replace(prefix,"")+'']'').tab(''show'');
activateParentTab(hash);
}
// Change hash for page-reload
$(''.nav-tabs a'').on(''shown'', function (e) {
window.location.hash = e.target.hash.replace("#", "#" + prefix);
});
Esta solución funciona bastante bien para mí en este momento. Espero que esto pueda ser útil para otra persona;)
Esta es una implementación mejorada de la solución de dubbe que evita el desplazamiento.
// Javascript to enable link to tab
var url = document.location.toString();
if (url.match(''#'')) {
$(''.nav-tabs a[href="#''+url.split(''#'')[1]+''"]'').tab(''show'') ;
}
// With HTML5 history API, we can easily prevent scrolling!
$(''.nav-tabs a'').on(''shown.bs.tab'', function (e) {
if(history.pushState) {
history.pushState(null, null, e.target.hash);
} else {
window.location.hash = e.target.hash; //Polyfill for old browsers
}
})
Este código selecciona la pestaña derecha según el #hash y agrega el #hash correcto cuando se hace clic en una pestaña. (esto usa jquery)
En Coffeescript:
$(document).ready ->
if location.hash != ''''
$(''a[href="''+location.hash+''"]'').tab(''show'')
$(''a[data-toggle="tab"]'').on ''shown'', (e) ->
location.hash = $(e.target).attr(''href'').substr(1)
o en JS:
$(document).ready(function() {
if (location.hash !== '''') $(''a[href="'' + location.hash + ''"]'').tab(''show'');
return $(''a[data-toggle="tab"]'').on(''shown'', function(e) {
return location.hash = $(e.target).attr(''href'').substr(1);
});
});
Esto es lo que hice, realmente simple, y siempre que los enlaces de las pestañas tengan un ID asociado, puede obtener el atributo href y pasarlo a la función que muestra el contenido de la pestaña:
<script type="text/javascript">
jQuery(document).ready(function() {
var hash = document.location.hash;
var prefix = "tab_";
if (hash) {
var tab = jQuery(hash.replace(prefix,"")).attr(''href'');
jQuery(''.nav-tabs a[href=''+tab+'']'').tab(''show'');
}
});
</script>
Luego, en su url puede agregar el hash como algo así como: # tab_tab1, la parte ''tab_'' se elimina del hash mismo para que la ID del enlace de la pestaña real en las pestañas de navegación (tabid1) se coloque después de esto, así que url se vería algo así como: www.mydomain.com/index.php#tab_tabid1.
Esto funciona perfecto para mí y espero que ayude a alguien más :-)
Esto funciona en Bootstrap 3 y mejora las 2 respuestas principales de dubbe y flynfish al integrar también la respuesta de GarciaWebDev (que permite los parámetros de URL después del hash y es directamente de los autores de Bootstrap en el rastreador de problemas de Github):
// Javascript to enable link to tab
var hash = document.location.hash;
var prefix = "tab_";
if (hash) {
hash = hash.replace(prefix,'''');
var hashPieces = hash.split(''?'');
activeTab = $(''.nav-tabs a[href='' + hashPieces[0] + '']'');
activeTab && activeTab.tab(''show'');
}
// Change hash for page-reload
$(''.nav-tabs a'').on(''shown'', function (e) {
window.location.hash = e.target.hash.replace("#", "#" + prefix);
});
Gracias por compartir tus opiniones.
Leyendo todas las soluciones. Se me ocurrió una solución que utiliza el hash de URL o el almacenamiento local, dependiendo de la disponibilidad de este último con el siguiente código:
$(function(){
$(document).on(''shown.bs.tab'', ''a[data-toggle="tab"]'', function (e) {
localStorage.setItem(''activeTab'', $(e.target).attr(''href''));
})
var hash = window.location.hash;
var activeTab = localStorage.getItem(''activeTab'');
if(hash){
$(''#project-tabs a[href="'' + hash + ''"]'').tab(''show'');
}else if (activeTab){
$(''#project-tabs a[href="'' + activeTab + ''"]'').tab(''show'');
}
});
Hago algo así para los enlaces con ajax #!#
(Por ejemplo, / test.com #! # Test3) pero puedes modificarlo como quieras.
$(document).ready(function() {
let hash = document.location.hash;
let prefix = "!#";
//change hash url on page reload
if (hash) {
$(''.nav-tabs a[href=/"''+hash.replace(prefix,"")+''/"]'').tab(''show'');
}
// change hash url on switch tab
$(''.nav-tabs a'').on(''shown.bs.tab'', function (e) {
window.location.hash = e.target.hash.replace("#", "#" + prefix);
});
});
Ejemplo con página simple en Github aquí.
La solución @flynfish + @Ztyx que uso para las pestañas anidadas:
handleTabLinks();
function handleTabLinks() {
if(window.location.hash == '''') {
window.location.hash = window.location.hash + ''#_'';
}
var hash = window.location.hash.split(''#'')[1];
var prefix = ''_'';
var hpieces = hash.split(''/'');
for (var i=0;i<hpieces.length;i++) {
var domelid = hpieces[i].replace(prefix,'''');
var domitem = $(''a[href=#'' + domelid + ''][data-toggle=tab]'');
if (domitem.length > 0) {
domitem.tab(''show'');
}
}
$(''a[data-toggle=tab]'').on(''shown'', function (e) {
if ($(this).hasClass(''nested'')) {
var nested = window.location.hash.split(''/'');
window.location.hash = nested[0] + ''/'' + e.target.hash.split(''#'')[1];
} else {
window.location.hash = e.target.hash.replace(''#'', ''#'' + prefix);
}
});
}
los niños deben tener clase = "anidado"
Le sugiero que use el código provisto por los autores de Bootstrap en su github.com/twbs/bootstrap/issues/2415 :
var hash = location.hash
, hashPieces = hash.split(''?'')
, activeTab = $(''[href='' + hashPieces[0] + '']'');
activeTab && activeTab.tab(''show'');
Puede encontrar en el enlace al problema más información sobre por qué no eligieron apoyar eso.
No soy un gran fan de si ... más; Así que tomé un enfoque más simple.
$(document).ready(function(event) {
$(''ul.nav.nav-tabs a:first'').tab(''show''); // Select first tab
$(''ul.nav.nav-tabs a[href="''+ window.location.hash+ ''"]'').tab(''show''); // Select tab by name if provided in location hash
$(''ul.nav.nav-tabs a[data-toggle="tab"]'').on(''shown'', function (event) { // Update the location hash to current tab
window.location.hash= event.target.hash;
})
});
- Elija una pestaña predeterminada (generalmente la primera)
- Cambie a la pestaña (si tal elemento está realmente presente; deje que jQuery lo maneje); No pasa nada si se especifica un hash incorrecto
- [Opcional] Actualice el hash si se elige manualmente otra pestaña
No dirige el desplazamiento al hash solicitado; pero ¿ debería ?
Para Bootstrap 3:
$(''.nav-tabs a[href="#'' + tabID + ''"]'').tab(''show'');
Probé un par de maneras discutidas anteriormente y terminas con la siguiente solución de trabajo, simplemente copia y pega en tu editor para probar. Para probar, simplemente cambie el hash a la bandeja de entrada, a la bandeja de salida, componga en url y presione la tecla enter.
<html>
<head>
<link type=''text/css'' rel=''stylesheet'' href=''https://maxcdn.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css'' />
<script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container body-content">
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#inbox">Inbox</a></li>
<li><a data-toggle="tab" href="#outbox">Outbox</a></li>
<li><a data-toggle="tab" href="#compose">Compose</a></li>
</ul>
<div class="tab-content">
<div id="inbox" class="tab-pane fade in active">
Inbox Content
</div>
<div id="outbox" class="tab-pane fade">
Outbox Content
</div>
<div id="compose" class="tab-pane fade">
Compose Content
</div>
</div>
</div>
<script>
$(function () {
var hash = window.location.hash;
hash && $(''ul.nav a[href="'' + hash + ''"]'').tab(''show'');
});
</script>
</body>
</html>
Espero que esto te ahorre tiempo.
Si bien la solución de JavaScript proporcionada puede funcionar, tomé una forma ligeramente diferente que no requiere JavaScript adicional, pero requiere lógica en su opinión. Crea un enlace con un parámetro de URL estándar, como:
<a href = "http://link.to.yourpage?activeTab=home">My Link</a>
Luego simplemente detectas el valor de activeTab para escribir ''class = "active"'' en el <li>
apropiado
Pseudocódigo (implementar en consecuencia en su idioma). Nota: He establecido la pestaña ''Inicio'' como activa por defecto si no se proporciona ningún parámetro en este ejemplo.
$activetabhome = (params.activeTab is null or params.activeTab == ''home'') ? ''class="active"'' : '''';
$activetabprofile = (params.activeTab == ''profile'') ? ''class="active"'' : '''';
<li $activetabhome><a href="#home">Home</a></li>
<li $activetabprofile><a href="#profile">Profile</a></li>
Si le importa a alguien, el siguiente código es pequeño y funciona perfectamente, para obtener un valor de hash único de la URL y mostrar que:
<script>
window.onload = function () {
let url = document.location.toString();
let splitHash = url.split("#");
document.getElementById(splitHash[1]).click();
};
</script>
lo que hace es recuperar el id y disparar el evento de clic. Sencillo.
Sobre la base de la solución de Demircan Celebi; Quería que la pestaña se abriera al modificar la url y la pestaña abierta sin tener que volver a cargar la página desde el servidor.
<script type="text/javascript">
$(function() {
openTabHash(); // for the initial page load
window.addEventListener("hashchange", openTabHash, false); // for later changes to url
});
function openTabHash()
{
console.log(''openTabHash'');
// Javascript to enable link to tab
var url = document.location.toString();
if (url.match(''#'')) {
$(''.nav-tabs a[href=#''+url.split(''#'')[1]+'']'').tab(''show'') ;
}
// With HTML5 history API, we can easily prevent scrolling!
$(''.nav-tabs a'').on(''shown.bs.tab'', function (e) {
if(history.pushState) {
history.pushState(null, null, e.target.hash);
} else {
window.location.hash = e.target.hash; //Polyfill for old browsers
}
})
}
</script>
Tuve que modificar algunos bits para que esto funcione para mí. Estoy usando Bootstrap 3 y jQuery 2
// Javascript to enable link to tab
var hash = document.location.hash;
var prefix = "!";
if (hash) {
hash = hash.replace(prefix,'''');
var hashPieces = hash.split(''?'');
activeTab = $(''[role="tablist"] a[href='' + hashPieces[0] + '']'');
activeTab && activeTab.tab(''show'');
}
// Change hash for page-reload
$(''[role="tablist"] a'').on(''shown.bs.tab'', function (e) {
window.location.hash = e.target.hash.replace("#", "#" + prefix);
});
podría activar un evento de click
en el enlace de la pestaña correspondiente:
$(document).ready(function(){
if(window.location.hash != "") {
$(''a[href="'' + window.location.hash + ''"]'').click()
}
});
ACTUALIZAR
Para Bootstrap 3, cambie .on(''shown'', ...)
por .on(''shown.bs.tab'', ....)
Esto se basa en la respuesta de @dubbe y esta respuesta tan aceptada . Maneja el problema con window.scrollTo(0,0)
no funciona correctamente. El problema es que cuando reemplaza el hash de url en la pestaña que se muestra, el navegador se desplazará a ese hash ya que es un elemento en la página. Para solucionar esto, agregue un prefijo para que el hash no haga referencia a un elemento de página real
// Javascript to enable link to tab
var hash = document.location.hash;
var prefix = "tab_";
if (hash) {
$(''.nav-tabs a[href="''+hash.replace(prefix,"")+''"]'').tab(''show'');
}
// Change hash for page-reload
$(''.nav-tabs a'').on(''shown'', function (e) {
window.location.hash = e.target.hash.replace("#", "#" + prefix);
});
Ejemplo de uso
Si tienes un panel de pestañas con id = "mytab" necesitas poner tu enlace de esta manera:
<a href="yoursite.com/#tab_mytab">Go to Specific Tab </a>
$(function(){
var hash = window.location.hash;
hash && $(''ul.nav a[href="'' + hash + ''"]'').tab(''show'');
});
Este código de http://github.com/twitter/bootstrap/issues/2415#issuecomment-4450768 funcionó perfectamente para mí.