web-dev-qa-db-fra.com

Les onglets de l'interface utilisateur JQuery provoquent un "saut" de l'écran

J'utilise la dernière version des onglets jQuery UI . J'ai des onglets positionnés vers le bas de la page.

Chaque fois que je clique sur un onglet, l'écran saute vers le haut.

Comment puis-je empêcher que cela se produise?

Veuillez voir cet exemple:

http://5bosses.com/examples/tabs/sample_tabs.html

48
Edward

Si vous animez vos transitions de tabulation (ie. .tabs({ fx: { opacity: 'toggle' } });), voici ce qui se passe:

Dans la plupart des cas, le saut n'est pas provoqué par le navigateur suivant le lien '#'. La page saute car au milieu de l'animation entre les deux volets d'onglets, les deux volets d'onglets sont entièrement transparents et masqués (comme dans l'affichage: aucun), de sorte que la hauteur effective de toute la section à onglets devient momentanément nulle.

Et si une section à onglets de hauteur nulle rend la page plus courte, la page semblera sauter pour compenser, alors qu'en réalité elle est simplement redimensionnée pour s'adapter au contenu (momentanément) plus court. Logique?

La meilleure façon de résoudre ce problème est de définir une hauteur fixe pour la section à onglets. Si cela n'est pas souhaitable (car le contenu de votre onglet varie en hauteur), utilisez-le à la place:

jQuery('#tabs').tabs({
    fx: { opacity: 'toggle' },
    select: function(event, ui) {
        jQuery(this).css('height', jQuery(this).height());
        jQuery(this).css('overflow', 'hidden');
    },
    show: function(event, ui) {
        jQuery(this).css('height', 'auto');
        jQuery(this).css('overflow', 'visible');
    }
});

Il définira la hauteur calculée du volet avant la transition de tabulation. Une fois que le nouvel onglet est apparu, la hauteur est ramenée à "auto". Le débordement est défini sur "masqué" pour empêcher le contenu de sortir du volet lors du passage d'un onglet court à un onglet plus grand.

C'est ce qui a fonctionné pour moi. J'espère que cela t'aides.

73
Mike Petrovich

Si vous avez quelque chose dans ce sens:

<a href="#" onclick="activateTab('tab1');">Tab 1</a>

Essayez d'ajouter return false; Après la commande d'activation de l'onglet:

<a href="#" onclick="activateTab('tab1'); return false;">Tab 1</a>
15
changelog

Je suppose que vous animez vos transitions de tabulation? J'ai le même problème, où le défilement de page revient en haut à chaque clic.

J'ai trouvé cela dans la source jquery:

 // Show a tab, animation prevents browser scrolling to fragment,

Effectivement, si j'ai ceci:

$('.tab_container > ul').tabs();    
$('.tab_container > ul').tabs({ fx: { height: 'toggle', opacity: 'toggle', duration: 'fast' } });

mon code saute en haut et est ennuyeux (mais il y a de l'animation). Si je change cela en ceci:

$('.tab_container > ul').tabs();    
//$('.tab_container > ul').tabs({ fx: { height: 'toggle', opacity: 'toggle', duration: 'fast' } });

il n'y a pas d'animation d'onglet, mais le passage d'un onglet à l'autre est fluide.

J'ai trouvé un moyen de le faire défiler en arrière, mais ce n'est pas une solution correcte, car le navigateur saute toujours en haut après avoir cliqué sur un onglet. Le défilement se produit entre les événements tabsselect et tabsshow, de sorte que le code suivant revient à votre onglet:

var scroll_to_x = 0;
var scroll_to_y = 0;
$('.ui-tabs-nav').bind('tabsselect', function(event, ui) {
    scroll_to_x = window.pageXOffset;
    scroll_to_y = window.pageYOffset;
});
$('.ui-tabs-nav').bind('tabsshow', function(event, ui) {
    window.scroll(scroll_to_x, scroll_to_y);
});

Je publierai plus de progrès que je fais.

5
Brian Ramsay

On m'a donné une solution pour cela ...

Comment empêcher l'écran de sauter lorsque l'onglet est cliqué:

Enveloppez le div qui contient les onglets dans un div avec une hauteur fixe.

Voir l'exemple ici: http://5bosses.com/examples/tabs/sample_tabs.html

5
edt

La solution de Mike a largement démontré le principe mais elle a un gros inconvénient - si la page résultante est courte, l'écran passera quand même au sommet! La seule solution est de rappelez-vous le scrollTop, et restaurez-le après que les onglets soient commutés. Mais avant la restauration, agrandir la page (balise html) approprié:

(modifier - modifié pour la nouvelle API Jquery UI + petite amélioration pour les grandes pages)

$(...).tabs({
    beforeActivate: function(event, ui) {
        $(this).data('scrollTop', $(window).scrollTop()); // save scrolltop
    },
    activate: function(event, ui) {
        if (!$(this).data('scrollTop')) { // there was no scrolltop before
            jQuery('html').css('height', 'auto'); // reset back to auto...
                    // this may not work on page where originally
                    // the html tag was of a fixed height...
            return;
        }
        //console.log('activate: scrolltop pred = ' + $(this).data('scrollTop') + ', nyni = ' + $(window).scrollTop());
        if ($(window).scrollTop() == $(this).data('scrollTop')) // the scrolltop was not moved
            return;                // nothing to be done
        // scrolltop moved - we need to fix it
        var min_height = $(this).data('scrollTop') + $(window).height();
            // minimum height the document must have to have that scrollTop
        if ($('html').outerHeight() < min_height) { // just a test to be sure
                            // but this test should be always true
            /* be sure to use $('html').height() instead of $(document).height()
               because the document height is always >= window height!
               Not what you want. And to handle potential html padding, be sure
               to use outerHeight instead!
                   Now enlarge the html tag (unfortunatelly cannot set
               $(document).height()) - we want to set min_height
               as html's outerHeight:
             */
            $('html').height(min_height -
                 ($('html').outerHeight() - $('html').height()));
        }
        $(window).scrollTop($(this).data('scrollTop')); // finally, set it back
    }
});

Fonctionne également avec l'effet fx.

4
TMS

J'ai eu le même problème avec le menu de jquery ui - un preventDefault () sur l'événement de clic de l'ancre empêche la page de défiler vers le haut:

 $("ul.ui-menu li a").click(function(e) {
      e.preventDefault();
 });
4
Zach Johnson

Essayez d'utiliser event.preventDefault();. Sur l'événement de clic qui change les onglets. Ma fonction ressemble à ceci:

    $(function() {
        var $tabs = $('#measureTabs').tabs();
        $(".btn-contiue").click(function (event) {
            event.preventDefault();
            $( "#measureTabs" ).tabs( "option", "active", $("#measureTabs").tabs   ('option', 'active')+1  );
        });
    });
3
Alexander Georgiev

Merci de votre aide. Bonne suggestion, mais j'ai essayé avant sans succès. Je pense que l'interface utilisateur JQuery peut remplacer mes efforts.

Voici le code par onglet:

<li class=""><a href="#fragment-2"><span>Two</span></a></li>

J'ai déjà essayé ça sans succès:

<li class=""><a href="#fragment-2" onclick="return false;"><span>Two</span></a></li>

Voici un exemple simple (sans retour false): http://5bosses.com/examples/tabs/sample_tabs.html

D'autres suggestions?

2
Edward

Essayez simplement d'ajouter une hauteur minimale à l'aide de css à chacune des zones de contenu des onglets (pas aux onglets eux-mêmes). Cela m'a arrangé. :)

2
BlogSiteDev

Je préfère avoir un href = "#" dans mes liens qui ne mènent l'utilisateur nulle part, mais vous pouvez le faire tant que vous ajoutez un onclick = "return false;". La clé, je suppose, n'envoie pas l'utilisateur à "#", qui, selon le navigateur, semble être par défaut le haut de la page actuelle.

1
Brian
> var scroll_to_x = 0; var scroll_to_y =
> 0;
> $('.ui-tabs-nav').bind('tabsselect',
> function(event, ui) {
>     scroll_to_x = window.pageXOffset;
>     scroll_to_y = window.pageYOffset; }); $('.ui-tabs-nav').bind('tabsshow',
> function(event, ui) {
>     window.scroll(scroll_to_x, scroll_to_y); });

Merci de votre aide! Veuillez me faire savoir ce que vous trouvez d'autre.

La fonction ci-dessus fonctionne (l'écran ne bouge pas de façon permanente) ... mais, l'écran est très instable au clic.

Voici un exemple simple montrant comment cliquer sur un onglet fait sauter l'écran vers le haut (sans le code ci-dessus): http://5bosses.com/examples/tabs/sample_tabs.html

Notez qu'aucune animation n'est utilisée.

1
edt

Il y a un moyen beaucoup plus simple que j'ai découvert dans les commentaires sur cette page qui est de simplement supprimer le href = "#" et il ne sautera plus en haut! J'ai vérifié et cela fonctionne pour moi. À votre santé

1
Sameer

remplacer le href = "#" par href = "javascript: void (0);" dans l'élément 'a'

fonctionne à 100%

0
mike

J'ai trouvé dans mon cas que l'onglet href=#example1 Faisait sauter la page à la position du id. L'ajout d'une hauteur fixe aux onglets n'a fait aucune différence, j'ai donc ajouté:

$('.nav-tabs li a').click( function(e) { e.preventDefault(); });

0
Bill Searle

J'ai eu le même problème, plus le mien tournait de lui-même, donc si vous étiez au bas de la page, la fenêtre du navigateur défilerait vers le haut. Avoir une hauteur fixe pour le conteneur à onglets a fonctionné pour moi. Une chose étrange est toujours que si vous quittez la fenêtre ou l'onglet et revenez en arrière, il défilera toujours. Mais pas la fin du monde.

0
Eric Lightbody

J'ai eu un tel problème. Mon code était:

$("#tabs").tabs({
  hide: {
    effect: "fade",
    duration: "500"
  },
  show: {
    effect: "fade",
    duration: "500"
  }
});

J'ai simplement supprimé show et cela a fonctionné comme un charme!

 $("#tabs").tabs({
      hide: {
        effect: "fade",
        duration: "500"
      }
 });
0
Zeihlis