web-dev-qa-db-fra.com

iphone/ipad déclenchant des événements de redimensionnement inattendus

Je travaille sur une version mobile de mon site. J'utilise autant que possible les requêtes multimédia et les CSS, mais j'utilise également du javascript pour, par exemple, transformer ma navigation en une liste de réduction/développement sur de plus petits appareils pour gagner de la place.

Pour gérer tout cela, j'ai essayé d'utiliser l'événement window.resize. Cela laisse la magie se passer sur les navigateurs de bureau lorsqu'ils sont redimensionnés, mais je reçois des événements de redimensionnement sur iPad/iPhone quand je ne les attend pas.

Sur les navigateurs de bureau, je ne reçois un événement de redimensionnement que si je redimensionne réellement la fenêtre. Sur les navigateurs mobiles, je reçois l'événement de redimensionnement lorsque je change d'orientation (attendu), mais je le reçois également lorsque je bascule pour développer/réduire quelque chose.

Voici un exemple simple:

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<title>Resize test</title>
<style>
.box {height: 10000px; background: green; display: none;}
</style>
<script>
$(function(){
    $(".opener").click(function(){
        $(".box").slideToggle();
    });
    $(window).resize(function(){
        alert("resized");
    });
});
</script>
</head>

<body>
<a href="#" class="opener">Open/close me</a>
<div class="box"></div>
</body>
</html>

Lorsque vous cliquez sur le lien dans un navigateur de bureau, aucune alerte. Cliquez sur le lien sur iPhone/iPad, vous obtenez l'alerte. Quel est le problème?

45
rdoyle720

Enregistrez la largeur de la fenêtre et vérifiez qu’elle a réellement changé avant de passer à la fonction $(window).resize:

jQuery(document).ready(function($) {

    // Store the window width
    var windowWidth = $(window).width();

    // Resize Event
    $(window).resize(function(){

        // Check window width has actually changed and it's not just iOS triggering a resize event on scroll
        if ($(window).width() != windowWidth) {

            // Update the window width for next time
            windowWidth = $(window).width();

            // Do stuff here

        }

        // Otherwise do nothing

    });

});
104
James Greig

Voici la version javascript de Vanilla de la réponse acceptée

document.addEventListener('DOMContentLoaded', function() {

    // Store the window width
    var windowWidth = window.innerWidth

    // Resize Event
    window.addEventListener("resize", function() {

        // Check window width has actually changed and it's not just iOS triggering a resize event on scroll
        if (window.innerWidth != windowWidth) {

            // Update the window width for next time
            windowWidth = window.innerWidth

            // Do stuff here

        }

        // Otherwise do nothing
    })

})
2
Brian Jacobs

J'avais besoin de spécifier une largeur:

   <meta name="viewport" content="width=1000, initial-scale=1.0, user-scalable=yes">

Modes:

html, body
{
       height:100%;
       width:100%;
       overflow:auto;
}
2
Kees C. Bakker

L'hypothèse est-elle fausse, à savoir que vous ne voulez que l'effet de l'événement de redimensionnement sur un périphérique non tactile? Si tel est le cas, vous pouvez simplement utiliser Modernizr et effectuer une vérification du type: 

    $(window).resize(function(e){
       if(Modernizr.touch) {
         e.preventDefault();
       }
    });
1
Felix

J'ai trouvé la réponse dans StackOverflow lui-même lien de la solution . c’est la réponse de sidonaldson qui m’a aidé à résoudre un problème que nous avons déjà rencontré plus tôt. ty

la réponse est:

var cachedWidth = $(window).width();
    $(window).resize(function(){
        var newWidth = $(window).width();
        if(newWidth !== cachedWidth){
            //DO RESIZE HERE
            cachedWidth = newWidth;
        }
    });
1
weBBer

@ 3stripe a la bonne réponse.

Il ne s'agit que d'une légère modification qui le rend plus efficace en mettant en cache l'objet window plutôt qu'en instanciant plusieurs fois jQuery (gardez à l'esprit que l'événement resize peut être appelé rapidement lors d'un redimensionnement réel).

jQuery(document).ready(function($) {

    // Cached window jQuery object
    var $window = $(window);

    // Store the window width
    var windowWidth = $window.width();

    // Resize Event
    $window.resize(function(){

        // Check window width has actually changed and it's not just iOS triggering a resize event on scroll
        if ($window.width() != windowWidth) {

            // Update the window width for next time
            windowWidth = $window.width();

            // Do stuff here

        }

        // Otherwise do nothing

    });

});
0
anthonygore

Il est difficile de vérifier la taille de la fenêtre pour voir si elle a changé. Utilisez plutôt les ressources que jQuery vous fournit!

Dans le gestionnaire d'événements, vous pouvez vérifier le champ target de l'événement jQuery, qui est toujours défini sur l'élément DOM à l'origine de l'événement. Si l'utilisateur redimensionne la fenêtre, target sera la fenêtre. Si l'utilisateur redimensionne #someDiv, target sera le #someDiv.

$(window).on('resize', function(event) {
    if ($(event.target).is($(window))) {
       doTheThing();
    }
});
0
MegaMatt

Vérifiez si vous faites explicitement défiler le wrapper HTML pour masquer la barre d'adresse lors du chargement de la page.

0
Abhidev