3 votes

iOS Safari : Les ancres dans un élément à position fixe ne fonctionnent qu'une fois

Veuillez consulter ce fichier : http://fiddle.jshell.net/ikmac/q7gkx

Utilisez ce lien pour tester dans le navigateur : http://fiddle.jshell.net/ikmac/q7gkx/show/

HTML :

<div class="nav">
    <a href="#test1">test1</a>
    <a href="#test2">test2</a>
    <a href="#test3">test3</a>
</div>

<div id="test1" class="test">test1</div>
<div id="test2" class="test">test2</div>
<div id="test3" class="test">test3</div>

CSS :

.nav {
    position: fixed;
    top: 20px;
    left: 0;
    width: 100%;
    height: 20px;
    background: #000;
}

.nav a {
    float: left;
    font-size: 20px;
    color: #fff;
}

#test1 {
    margin-top: 1000px;
    height: 1000px;
    background: red;
}

#test2 {
    height: 1000px;
    background: blue;
}

#test3 {
    height: 1000px;
    background: green;
}

C'est ce qui se passe dans Safari sous iOS 5.0 (la version 4.3 ne prend pas en charge la position fixe) :

La première fois que je clique sur l'une des ancres, la page saute vers l'ancre correcte. Après cela, je ne peux plus cliquer sur l'un des autres liens. Lorsque je fais défiler la page un peu vers le haut ou vers le bas, les liens redeviennent cliquables.

Tous les autres navigateurs de bureau se comportent bien.

Est-ce que quelqu'un a déjà eu ce problème ou sait comment le résoudre ?

2voto

nikek Points 91

J'ai aussi ce problème. Et je l'ai à moitié résolu en laissant javascript faire le défilement de la nav lorsque l'on clique sur une ancre de nav. Et comme le défilement tactile normal ne donne pas d'événement tant que le doigt ne lâche pas l'écran, j'utilise position:fixed qui rend le défilement tactile plus agréable que ne peut le faire javascript. Site de développement des pommes .

Ce n'est pas la solution ultime, mais à mon avis, c'est mieux que de ne pas travailler du tout. Ce script vérifie également la largeur de la fenêtre pour s'assurer qu'il ne s'applique qu'aux petits écrans, enfin, aux appareils.

Voici mon code, et si vous le trouvez utile, l'améliorez ou trouvez une meilleure solution, merci de partager :)

/* NAV POSITION */

var specScroll = false; // If special scrolling is needed

/* Check what kind of position to use.*/
(function navPos() {
    var width = checkWidth();

    if (width <= 480 || navigator.userAgent.match(/iPad/i) != null) {
        specScroll = true;
    }else{
        specScroll = false;
        window.onscroll = NaN;
    }
})();

$(window).resize( function(){ navPos(); } ); // After resizing, check what to use again.

/* When clicking one of the nav anchors */
$(function() {
    $('a').bind('click',function(e){
        var $anchor = $(this);

        if(specScroll){
            $('#nav').css('position', "absolute");
            window.onscroll = anchorScroll;
        }
        $('html, body').stop().animate({
            scrollTop: $($anchor.attr('href')).offset().top
        }, 700,'easeOutExpo', function(){
            if(specScroll){setTimeout("window.onscroll = touchScroll;", 100);} 
            // the set timeout is needed for not overriding the clickability of the anchors after anchor-scrolling.
        });

        e.preventDefault();
    });
});

/* While the user clicks and anchors in nav */
function anchorScroll() { $('#nav').css('top', window.pageYOffset); }

/* the first time the user scrolls by touch and lift the finger from screen */
function touchScroll() { 
    $('#nav').css('position', 'fixed');
    $('#nav').css('top', 0);
    window.onscroll = NaN;
}

/* CHECK WIDTH OF WINDOW */
function checkWidth() {
    myWidth = 0;
    if( typeof( window.innerWidth ) == 'number' ) {
        myWidth = window.innerWidth;    //Non-IE
    } else if( document.documentElement && ( document.documentElement.clientWidth ) ) {
        myWidth = document.documentElement.clientWidth; //IE 6+ in 'standards compliant mode'
    } else if( document.body && ( document.body.clientWidth ) ) {
        myWidth = document.body.clientWidth;    //IE 4 compatible
    }
    return myWidth;
}

J'utilise cette solution sur une page de projet, essayez-la : dare.niklasek.se

0voto

Erik Runyon Points 26

J'ai rencontré le même problème en utilisant une navigation à position fixe qui fait défiler l'utilisateur sur la page en utilisant une animation jQuery. Ce que j'ai découvert, c'est que même si l'élément à position fixe est visible à la nouvelle position, l'inspecter avec js rapporte qu'il est toujours à la position d'origine jusqu'à ce que l'utilisateur déplace l'écran manuellement. Jusque-là, même si la nav est présente visuellement, on ne peut pas la toucher pour interagir avec elle. Plus d'informations et une démo ici : http://bit.ly/ios5fixedBug

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X