2011-12-24 5 views
10

Estoy usando JQuery UI para crear pestañas en mi aplicación. Necesitaba las pestañas para ser enlazables (enlace directo que abre la página y selecciona la pestaña correcta). Esto se hace usando una etiqueta hash/fragmented identifier. Pero tengo un problema cuando el contenido sobre las pestañas y dentro de las pestañas es muy largo.Prevención de desplazamiento al usar el hash URI para identificar la pestaña

Al hacer clic en las pestañas, la página se desplaza hacia abajo hasta el comienzo de la pestaña. Esto no es lo que quiero.

Estoy usando Jquery 1.7.1 y Jquery UI 1.8.16.

El código javascript/Jquery es una pestañas estándar de Jquery UI con la adición al evento "tabsshow". Esto se sugiere en Changing location.hash with jquery ui tabs (pregunta Stackoverflow) y JQuery UI Tabs: Updating URL with hash while clicking the tab (blog - Tech diario por Robin)

$(document).ready(function() { 
    $("#tabs").tabs(); 

    /** 
    * Add hash to URL of the current page 
    * 
    * http://chwang.blogspot.com/2010/02/jquery-ui-tabs-updating-url-with-hash.html 
    * https://stackoverflow.com/questions/570276/changing-location-hash-with-jquery-ui-tabs 
    */ 
    $("#tabs").bind('tabsshow',function(event, ui) { 
     window.location.hash = ui.tab.hash; 
    }); 
}); 

El código HTML siguiente se puede utilizar para probar el comportamiento

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script> 
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script> 
<div style="height: 400px;">Some other content</div> 
<div id="tabs" class="ui-tabs ui-widget ui-widget-content ui-corner-all"> 
    <ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"> 
     <li class="ui-state-default ui-corner-top"><a href="#tab_1"><span>Tab 1</span></a></li> 
     <li class="ui-state-default ui-corner-top"><a href="#tab_100"><span>Tab 100</span></a></li> 
     <li class="ui-state-default ui-corner-top ui-tabs-selected ui-state-active"><a href="#tab_1000"><span>Tab 1000</span></a></li> 
    </ul> 

    <div id="tab_1" class="ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"> 
     <table style="height: 1000px"><tr><td>Hello. This is tab 1</td></tr></table> 
    </div> 


    <div id="tab_100" class="ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"> 
     <table style="height: 1000px"><tr><td>Hello. This is tab 100.</td></tr></table> 
    </div> 


    <div id="tab_1000" class="ui-tabs-panel ui-widget-content ui-corner-bottom"><h2>Heading</h2> 
     <table style="height: 1000px"><tr><td>Hello. This is tab 1000.</td></tr></table> 
    </div> 
</div> 

Al abrir la página con el siguiente URL, uno debe tener la pestaña 1 abierta y no desplazarse hacia abajo hasta donde se inicia la pestaña. Lo mismo ocurre con hacer clic en una de las pestañas.

file.html#tab_1 
+0

posible duplicado de [jQuery UI aquí Causando la pantalla de "saltar"] (http://stackoverflow.com/ preguntas/243794/jquery-ui-tabs-causing-screen-to-jump) –

+0

No exactamente lo mismo pero muy similar. – HNygard

Respuesta

5

esto puede no ser el mejor método, pero si cambia el nombre de todos los ID vez que se hayan creado las pestañas, a continuación, añadir un hash con el ID original no se desplazará a la página. Usé este método porque incluso con javascript desactivado, el hash llevará al usuario a la identificación correcta. Aquí es a demo del código de abajo:

$("#tabs").tabs({ 
    create: function(event, ui) { 
     // get tab plugin data 
     var tabs = $('#tabs').data('tabs'), 
      // tabs.anchors contains all of the tab anchors 
      links = tabs.anchors; 
     // tabs.panels contains each tab 
     tabs.panels.each(function(i){ 
      // just adding a "mod_" prefix to every ID/hash 
      this.id = 'mod_' + this.id; 
      links[i].hash = '#' + this.id; 
     }); 
    } 
}); 

/** 
* Add hash to URL of the current page 
* 
* http://chwang.blogspot.com/2010/02/jquery-ui-tabs-updating-url-with-hash.html 
* http://stackoverflow.com/questions/570276/changing-location-hash-with-jquery-ui-tabs 
*/ 
$("#tabs").bind('tabsshow', function(event, ui) { 
    // remove the prefix from the ID, so we're showing the original ID in the hash 
    window.location.hash = ui.tab.hash.replace('mod_', ''); 
}); 
1

Tienes que cambiar el hash ventana sin desplazar la página. Aquí hay una pregunta sobre SO - Modifying document.location.hash without page scrolling.

Los cambios necesarios son:

$("#tabs").bind('tabsshow',function(event, ui) { 
    setHashWithoutScroll(ui.tab.hash); 
}); 

La función setHashWithoutScroll se pueden tomar desde el enlace mencionado anteriormente.

function setHashWithoutScroll(hash) { 
    hash = hash.replace(/^#/, ''); 
    var fx, node = $('#' + hash); 
    if (node.length) { 
     node.attr('id', ''); 
     fx = $('<div></div>') 
       .css({ 
        position:'absolute', 
        visibility:'hidden', 
        top: $(document).scrollTop() + 'px' 
       }) 
       .attr('id', hash) 
       .appendTo(document.body); 
    } 
    document.location.hash = hash; 
    if (node.length) { 
     fx.remove(); 
     node.attr('id', hash); 
    } 
} 

La respuesta aceptada genera un error para mí - jQuery UI Tabs: Mismatching fragment identifier. Entonces tuve que usar este.

+0

Eso no soluciona los enlaces entrantes con "# tab-id" cargando la página desplazada parcialmente – Rich

0

acabo añade lo siguiente a mi javascript:

$('#tabs').tabs(); 
    // Direct links to the tabs, e.g. /my-page#tab-id can cause browsers 
    // to scroll down to half-way down the page, which is ugly. We override that here. 
    // (This can cause a brief FOUC effect where the page first displays then scrolls up) 
    window.scrollTop = '0'; 
    window.scrollTo(0,0); 

En MSIE, aparece un breve efecto FOUC como se carga la página desplazar parte de ida hacia abajo, a continuación, películas a la parte superior.

En Firefox, esto funciona bien sin ningún FOUC visible.

En Chrome, esto no funciona en absoluto - ver scrollTop does not work in Chrome, nor do suggested workarounds

-1

Probé @mottie solución, pero no está funcionando ahora (2 años después).
Activa un error: TypeError: tabs is undefined.

A continuación se presenta una solución aceptable para mí:

// preventing scroll 
// $("#tabs li a[href^='#tab']").bind('click',function(e){ // less general but better 
$("#tabs li a").bind('click',function(e){ 
    $("html, body").animate({ scrollTop: 0 }); 
}); 
2

Como otros han mencionado el código de @Mottie podría tener alguna vez trabajó en versiones anteriores de jQuery UI, pero esto definitivamente ha dejado de funcionar. La API de jQuery UI aquí ha cambiado un poco desde que fue escrito por lo que aquí es una versión actualizada que funcione con al menos jQuery 1.10.2

demo aquí: http://jsfiddle.net/xsx5u5g2/

var $tabs = $("#tabs"); 
$tabs.tabs({ 
    create: function(event, ui) { 
    // Adjust hashes to not affect URL when clicked. 
    var widget = $tabs.data("uiTabs"); 
    widget.panels.each(function(i){ 
     this.id = "uiTab_" + this.id; // Prepend a custom string to tab id. 
     widget.anchors[i].hash = "#" + this.id; 
     $(widget.tabs[i]).attr("aria-controls", this.id); 
    }); 
    }, 
    activate: function(event, ui) { 
    // Add the original "clean" tab id to the URL hash. 
    window.location.hash = ui.newPanel.attr("id").replace("uiTab_", ""); 
    }, 
}); 
+0

Hice una modificación a esto. No quiero que el cambio de nombre de ID suceda en pageload/create. Quiero que suceda cuando el usuario hace clic por primera vez en una pestaña. Esto asegura que las URL marcadas funcionan normalmente. Dividí el ID de cambio de nombre en una función separada, luego lo envolví en una construcción 'ejecutar solo una vez' y lo agregué como la primera línea dentro de 'activar'. http://davidwalsh.name/javascript-once – mastaBlasta

2

estoy usando jQuery 1.11 .1. Esto funciona bien para mí.

$("#tabs").tabs(); //initialize tabs 
$(function() { 
    $("#tabs").tabs({ 
     activate: function(event, ui) { 
      var scrollTop = $(window).scrollTop(); // save current scroll position 
      window.location.hash = ui.newPanel.attr('id'); // add hash to url 
      $(window).scrollTop(scrollTop); // keep scroll at current position 
     } 
    }); 
}); 

jQuery UI tabs, update url when clicking on a different tab

Gracias a Jeff B para señalar mí aquí http://jsfiddle.net/jtbowden/ZsUBz/44/

+0

Funciona bien para mí también. Para jQuery versión 1.12.4. ¡Gracias! – DpEN

0

Este sencillo método funcionó para mí:

/* Prevent scroll to tab on click */ 
$(document).ready(function(){ 
    $("a.ui-tabs-anchor").click(function(e){ 
     e.preventDefault(); 
     return false; 
    }); 
}); 
+0

¡Gran solución! – IonicBurger

-1

Hay muchas respuestas en esta página, y en mi mente , la mayoría complican mucho un simple problema.

Básicamente, la solución de david-thomas es la más simple y efectiva. Básicamente, todo lo que desea hacer es evitar el comportamiento del enlace predeterminado en un enlace de pestaña (etiqueta <a>).

La misma respuesta se aplica a las pestañas de arranque, donde se tiene que especificar el controlador de clic

$('.nav-tabs a').click(function(e){ 
     e.preventDefault(); 
     $(this).tab('show'); 
    }); 
+0

¡esto definitivamente no funciona! –

+0

Gracias por su comentario perspicaz y útil. Lamento que mi respuesta haya hecho que tu aplicación se caiga de sus elevadas alturas ... – IonicBurger

Cuestiones relacionadas