web-dev-qa-db-fra.com

window.resize en raison d'un clavier virtuel provoque des problèmes avec jquery mobile

Je rencontre un problème inhabituel et je cherche des suggestions. En gros, j'utilise:

  • JQuery Mobile 1.1
  • JQuery 8.2
  • PhoneGap (Cordova) 2.1

Sur de nombreuses pages de mon application sur iPhone, si je mets mon curseur dans une zone de saisie, cela ouvre le clavier virtuel. C'est bien et prévu.

Voici le problème: Dans certains cas (mais pas tous), le fait de placer mon curseur dans une zone de saisie déclenche l'événement window.resize. J'ai vérifié cela via le code ci-dessous:

    $(window).resize(function(e) {
        alert('The window resize occurred!  Width: ' + $(window).width() + " Height: " + $(window).height());
        debugger;
        return false;
    });

Immédiatement après la résolution de l'événement window.resize, JQueryMobile décide de redimensionner la page à une hauteur incorrecte. Je peux dire que c'est la page parce que j'ai ajouté une bordure de couleur différente à chaque élément pour voir ce qui était quoi. Et dans de nombreux cas, cette action de redimensionnement provoque le débordement de la moitié de mon interface graphique sous le bas de la div, ce qui fait même parfois apparaître mon curseur sous le div. 

La meilleure façon de le comprendre est avec une capture d'écran:

window.resize() triggering page resize

Maintenant, je ne m'attends pas vraiment à ce que quelqu'un ait une réponse exacte à cela. Je cherche juste des astuces de débogage. J'ai ajouté une instruction "débogueur" à mon événement window.resize () et j'ai essayé de parcourir le code. J'espérais être amené à un autre programme d'écoute de redimensionnement conçu pour redimensionner la page. Si je peux trouver cela, je peux le paralyser temporairement lorsque quelqu'un sélectionne un élément de formulaire, puis réactiver le redimensionnement lors du changement de flou ou d'orientation. Le problème, c’est que j’ai parcouru chaque ligne de code et que le processus de débogage s’arrête juste avant le redimensionnement.

Cela me fait me demander si un autre événement est déclenché en dehors de window.resize. J'ai donc ajouté les deux lignes ci-dessous:

    document.addEventListener("throttledresize", function() { alert("throttledresize fired.") }, false);
    document.addEventListener("orientationchange", function() { alert("orientationchange fired.") }, false);

Ni tiré, cependant. Donc je suis un peu coincé. J'ai le sentiment de bien connaître le problème, mais je ne peux pas le situer à la source. Des suggestions sur où je peux trouver ce code mystérieux qui redimensionne la page sur window.resize ()?

24
Anthony

Je suis content de voir que je ne suis pas fou! Je suis heureux d'annoncer que j'ai mis en place une très bonne solution. Voici les étapes, au cas où vous voudriez faire la même chose:

1) Allez dans jquery.mobile-1.x.x.js

2) Recherchez $ .mobile = $ .extend () et ajoutez les attributs suivants:

last_width: null,
last_height: null,

3) Modifiez getScreenHeight pour qu’il fonctionne comme suit:

getScreenHeight: function() {
    // Native innerHeight returns more accurate value for this across platforms,
    // jQuery version is here as a normalized fallback for platforms like Symbian

    if (this.last_width == null || this.last_height == null || this.last_width != $( window ).width())
    {
        this.last_height = window.innerHeight || $( window ).height();
        this.last_width = $(window).width();
    }
    return this.last_height;
}

En gros, cela empêchera jQuery de recalculer la hauteur de la page à moins que la largeur ne change également. (c'est-à-dire un changement d'orientation) Etant donné que le clavier logiciel affecte uniquement la hauteur, cette méthode renvoie la valeur mise en cache au lieu d'une hauteur modifiée.

Je vais créer un article séparé pour demander comment remplacer correctement la méthode $ .mobile.getScreenHeight. J'ai essayé d'ajouter le code ci-dessous dans un fichier JS séparé, mais cela n'a pas fonctionné:

delete $.mobile.getScreenHeight;
$.mobile.last_width = null;
$.mobile.last_height = null;
$.mobile.getScreenHeight = function() 
{
   ... the code listed above
}

Il a tiré la plupart du temps, mais a également déclenché la fonction d'origine. Plutôt étrange. J'ai posté un sujet distinct concernant la manière d'étendre correctement $ .mobile ici: Méthode appropriée pour remplacer une méthode JQuery Mobile dans $ .mobile

10
Anthony

J'ai eu un problème similaire essayez ceci:

  $('#main-browse').bind("orientationchange", function(event) {
    //Put the page dimensions for example with minimum height property

  }
3
mram888

J'avais le même problème sous Cordova (3.x) avec JQuery Mobile 1.4 - ce n'est donc pas quelque chose qui risque d'être abordé par les auteurs de la bibliothèque. J'ai essayé beaucoup de solutions différentes - mais aucune ne l'a vraiment corrigée. Le candidat le plus proche impliquait de lier des gestionnaires simples liés aux événements "throttleresize" et "pageshow" sur les objets window et document, respectivement. 

Pourtant, je perdais toujours la sensation de "verrouillage" de l'interface utilisateur et l'utilisateur pouvait faire glisser toute l'interface utilisateur vers le haut après la sortie du clavier. Bien sûr, l'en-tête et le pied de page n'ont pas bougé, mais mon arrière-plan et la zone de contenu principale étaient désormais déplaçables et des barres de défilement apparaissaient. Totalement inacceptable si vous essayez de ressentir cette application native ...

Alors j'ai décidé de regarder dans Chrome/Safari firebug et de savoir où les pixels supplémentaires sont ajoutés au modèle de boîte. Bizarrement, j'ai remarqué que la hauteur n'était pas modifiée du tout, dans mon cas, c'était le remplissage de la page active. j'ai donc adapté une solution d'une autre publication Stack:

function resetActivePageHeight() {
var aPage = $( "." + $.mobile.activePageClass ),
  aPagePadT = parseFloat( aPage.css( "padding-top" ) ),
  aPagePadB = parseFloat( aPage.css( "padding-bottom" ) ),
  aPageBorderT = parseFloat( aPage.css( "border-top-width" ) ),
  aPageBorderB = parseFloat( aPage.css( "border-bottom-width" ) );
aPage.css( "min-height", deviceInfo.height - aPagePadT - aPagePadB - aPageBorderT - aPageBorderB )
.css("top","0px").css("padding","0px");}

Ensuite, je les ai liés aux événements de document et de fenêtre sur le périphérique.

  $( document ).bind( "pageshow", resetActivePageHeight );
  $( window ).bind( "throttledresize", resetActivePageHeight );

Encore une fois, bien que j'aimerais prendre le crédit, je pense que je viens de trouver un angle supplémentaire à la bonne idée de quelqu'un d'autre.

2
Robert Sherman

allez dans votre fichier androidmanifest et dans l'activité, modifiez ou mettez à jour cette valeurAndroid:windowSoftInputMode="adjustResize "

je sais pertinemment que adjustPan casse la page pour que les contrôles soient masqués. la valeur par défaut (non spécifiée) peut être ok et il y a d'autres options ici . Je pense que si ce n'est pas à redimensionner, il ne communique pas à jqm que kb est affiché

alors laissez jqm tel quel, sans vos modifications et il fera son travail btw, j'utilise cordova 2.2, jqm 1.2 et jquery 1.8.2

1

J'ai eu un problème où le clavier virtuel étendait la fenêtre d'affichage, montrant le contenu en dessous (un panneau externe).

J'ai résolu en réglant la hauteur css en fonction de la hauteur de la fenêtre:

$('#page').css('height', $(window).height());
0
Joe Lannen