mac - javascript iphone 6




Application Web iPad: Détecter le clavier virtuel à l'aide de JavaScript dans Safari? (11)

Au cours de l'événement de mise au point, vous pouvez faire défiler la hauteur du document et, par magie, le window.innerHeight est réduit de la hauteur du clavier virtuel. Notez que la taille du clavier virtuel est différente pour les orientations paysage et portrait, vous devrez donc le redétecter lorsqu'il change. Je déconseille de mémoriser ces valeurs car l'utilisateur peut à tout moment connecter / déconnecter un clavier Bluetooth.

var element = document.getElementById("element"); // the input field
var focused = false;

var virtualKeyboardHeight = function () {
    var sx = document.body.scrollLeft, sy = document.body.scrollTop;
    var naturalHeight = window.innerHeight;
    window.scrollTo(sx, document.body.scrollHeight);
    var keyboardHeight = naturalHeight - window.innerHeight;
    window.scrollTo(sx, sy);
    return keyboardHeight;
};

element.onfocus = function () {
    focused = true;
    setTimeout(function() { 
        element.value = "keyboardHeight = " + virtualKeyboardHeight() 
    }, 1); // to allow for orientation scrolling
};

window.onresize = function () {
    if (focused) {
        element.value = "keyboardHeight = " + virtualKeyboardHeight();
    }
};

element.onblur = function () {
    focused = false;
};

Notez que lorsque l'utilisateur utilise un clavier Bluetooth, la propriété keyboardHeight est 44, ce qui correspond à la hauteur de la barre d'outils [précédente] [suivante].

Il y a un petit scintillement lorsque vous faites cette détection, mais il ne semble pas possible de l'éviter.

J'écris une application web pour l'iPad ( pas une application App Store ordinaire - elle est écrite en HTML, CSS et JavaScript). Comme le clavier remplit une grande partie de l'écran, il serait logique de modifier la disposition de l'application pour l'adapter à l'espace restant lorsque le clavier est affiché. Cependant, je n'ai trouvé aucun moyen de détecter quand ou si le clavier est affiché.

Ma première idée était de supposer que le clavier est visible quand un champ de texte a le focus. Cependant, lorsqu'un clavier externe est connecté à un iPad, le clavier virtuel n'apparaît pas lorsqu'un champ de texte reçoit le focus.

Dans mes expériences, le clavier n'a pas non plus affecté la hauteur ou la hauteur de défilement des éléments du DOM, et je n'ai trouvé aucun événement ou propriété propriétaire indiquant si le clavier est visible.


Au lieu de détecter le clavier, essayez de détecter la taille de la fenêtre

Si la hauteur de la fenêtre a été réduite et la largeur est toujours la même, cela signifie que le clavier est allumé. Sinon, le clavier est éteint, vous pouvez également ajouter à cela, tester si un champ d'entrée est sur le point ou non.

Essayez ce code par exemple.

var last_h = $(window).height(); //  store the intial height.
var last_w = $(window).width(); //  store the intial width.
var keyboard_is_on = false;
$(window).resize(function () {
    if ($("input").is(":focus")) {
        keyboard_is_on =
               ((last_w == $(window).width()) && (last_h > $(window).height()));
    }   
});     

Comme indiqué dans les réponses précédentes quelque part la variable window.innerHeight est mise à jour correctement maintenant sur iOS10 lorsque le clavier apparaît et puisque je n'ai pas besoin de la prise en charge des versions antérieures je suis venu avec le hack suivant qui pourrait être un peu plus facile "solutions".

//keep track of the "expected" height
var windowExpectedSize = window.innerHeight;

//update expected height on orientation change
window.addEventListener('orientationchange', function(){
    //in case the virtual keyboard is open we close it first by removing focus from the input elements to get the proper "expected" size
    if (window.innerHeight != windowExpectedSize){
        $("input").blur();
        $("div[contentEditable]").blur();     //you might need to add more editables here or you can focus something else and blur it to be sure
        setTimeout(function(){
            windowExpectedSize = window.innerHeight;
        },100);
    }else{
        windowExpectedSize = window.innerHeight;
    }
});

//and update the "expected" height on screen resize - funny thing is that this is still not triggered on iOS when the keyboard appears
window.addEventListener('resize', function(){
    $("input").blur();  //as before you can add more blurs here or focus-blur something
    windowExpectedSize = window.innerHeight;
});

alors vous pouvez utiliser:

if (window.innerHeight != windowExpectedSize){ ... }

pour vérifier si le clavier est visible. Je l'utilise depuis un moment dans mon application web et cela fonctionne bien, mais (comme toutes les autres solutions) vous pourriez trouver une situation où elle échoue parce que la taille "attendue" n'est pas mise à jour correctement ou quelque chose.


Edit: Documenté par Apple bien que je ne puisse pas vraiment le faire fonctionner: Comportement WKWebView avec les affichages clavier : "Dans iOS 10, les objets WKWebView correspondent au comportement natif de Safari en mettant à jour leur propriété window.innerHeight lorsque le clavier est affiché et n'appellent pas redimensionner les événements "(peut-être utiliser focus ou focus plus delay pour détecter le clavier au lieu d'utiliser resize).

Edit: le code présume le clavier à l'écran, pas le clavier externe. Laissant cela parce que l'information peut être utile à d'autres qui se soucient seulement des claviers à l'écran. Utilisez http://jsbin.com/AbimiQup/4 pour afficher les paramètres de la page.

Nous testons pour voir si le document.activeElement est un élément qui montre le clavier (input type = text, textarea, etc).

Le code suivant fudges choses pour nos fins (mais pas généralement correct).

function getViewport() {
    if (window.visualViewport && /Android/.test(navigator.userAgent)) {
        // https://developers.google.com/web/updates/2017/09/visual-viewport-api    Note on desktop Chrome the viewport subtracts scrollbar widths so is not same as window.innerWidth/innerHeight
        return {
            left: visualViewport.pageLeft,
            top: visualViewport.pageTop,
            width: visualViewport.width,
            height: visualViewport.height
        };
    }
    var viewport = {
            left: window.pageXOffset,   // http://www.quirksmode.org/mobile/tableViewport.html
            top: window.pageYOffset,
            width: window.innerWidth || documentElement.clientWidth,
            height: window.innerHeight || documentElement.clientHeight
    };
    if (/iPod|iPhone|iPad/.test(navigator.platform) && isInput(document.activeElement)) {       // iOS *lies* about viewport size when keyboard is visible. See http://.com/questions/2593139/ipad-web-app-detect-virtual-keyboard-using-javascript-in-safari Input focus/blur can indicate, also scrollTop: 
        return {
            left: viewport.left,
            top: viewport.top,
            width: viewport.width,
            height: viewport.height * (viewport.height > viewport.width ? 0.66 : 0.45)  // Fudge factor to allow for keyboard on iPad
        };
    }
    return viewport;
}


function isInput(el) {
    var tagName = el && el.tagName && el.tagName.toLowerCase();
    return (tagName == 'input' && el.type != 'button' && el.type != 'radio' && el.type != 'checkbox') || (tagName == 'textarea');
};

Le code ci-dessus n'est qu'approximatif: il est incorrect pour un clavier partagé, un clavier non ancré, un clavier physique. Selon le commentaire en haut, vous pourriez être en mesure de faire un meilleur travail que le code donné sur Safari (depuis iOS8?) Ou WKWebView (depuis iOS10) en utilisant la propriété window.innerHeight .

J'ai trouvé des échecs dans d'autres circonstances: par exemple donner la priorité à la saisie puis aller à l'écran d'accueil puis revenir à la page; iPad ne devrait pas rendre la fenêtre plus petite; vieux navigateurs IE ne fonctionnera pas, Opera n'a pas fonctionné parce que Opera gardé la concentration sur l'élément après la fermeture du clavier.

Toutefois, la réponse étiquetée (modification du scrolltop pour mesurer la hauteur) a des effets secondaires désagréables si la fenêtre d'affichage est zoomable (ou si le zoom forcé est activé dans les préférences). Je n'utilise pas l'autre solution suggérée (changer le scrolltop) parce que sur iOS, quand le viewport est zoomable et défilant vers l'entrée focalisée, il y a des interactions buggées entre scrolling & zoom & focus (qui peuvent laisser une entrée juste focalisée en dehors de viewport visible).


Essaye celui-là:

var lastfoucsin;

$('.txtclassname').click(function(e)
{
  lastfoucsin=$(this);

//the virtual keyboard appears automatically

//Do your stuff;

});


//to check ipad virtual keyboard appearance. 
//First check last focus class and close the virtual keyboard.In second click it closes the wrapper & lable

$(".wrapperclass").click(function(e)
{

if(lastfoucsin.hasClass('txtclassname'))
{

lastfoucsin=$(this);//to avoid error

return;

}

//Do your stuff 
$(this).css('display','none');
});`enter code here`

J'ai fait quelques recherches, et je n'ai rien trouvé de concret pour un "sur le clavier montré" ou "sur un clavier rejeté". Voir la liste officielle des événements supportés . Voir aussi la note technique TN2262 pour iPad. Comme vous le savez probablement déjà, il existe un événement d' onorientationchange corps onorientationchange vous pouvez câbler pour détecter un paysage ou un portrait.

De même, mais une supposition sauvage ... avez-vous essayé de détecter le redimensionnement? Les changements de fenêtre peuvent déclencher cet événement indirectement à partir du clavier étant montré / caché.

window.addEventListener('resize', function() { alert(window.innerHeight); });

Ce qui serait simplement alerter la nouvelle hauteur sur tout événement de redimensionnement ....


Je n'ai pas essayé cela moi-même, donc c'est juste une idée ... mais avez-vous essayé d'utiliser des requêtes de médias avec CSS pour voir quand la hauteur de la fenêtre change et ensuite changer le design pour cela? J'imagine que Safari mobile ne reconnaît pas le clavier comme faisant partie de la fenêtre, donc ça devrait marcher.

Exemple:

@media all and (height: 200px){
    #content {height: 100px; overflow: hidden;}
}

Le problème est que, même en 2014, les périphériques gèrent les événements de redimensionnement de l'écran, ainsi que les événements de défilement, de manière incohérente lorsque le clavier virtuel est ouvert.

J'ai trouvé que, même si vous utilisez un clavier Bluetooth, iOS en particulier déclenche d'étranges bogues de mise en page; donc, au lieu de détecter un clavier logiciel, j'ai dû cibler des appareils très étroits et dotés d'écrans tactiles.

J'utilise des requêtes média (ou window.matchMedia ) pour la détection de largeur et Modernizr pour la détection d'événements tactiles.


S'il existe un clavier à l'écran, la mise au point d'un champ de texte situé près du bas de la fenêtre entraînera Safari à faire défiler le champ de texte vers la vue. Il pourrait y avoir un moyen d'exploiter ce phénomène pour détecter la présence du clavier (avoir un petit champ de texte au bas de la page qui gagne momentanément le focus, ou quelque chose comme ça).


Seulement testé sur Android 4.1.1:

L'événement blur n'est pas un événement fiable pour tester le clavier de haut en bas, car l'utilisateur a la possibilité de masquer explicitement le clavier qui ne déclenche pas d'événement de flou sur le champ qui a provoqué l'affichage du clavier.

Resize Event fonctionne cependant comme un charme si le clavier monte ou descend pour une raison quelconque.

café:

$(window).bind "resize", (event) ->  alert "resize"

déclenche à tout moment le clavier est affiché ou caché pour une raison quelconque.

Notez toutefois que dans le cas d'un navigateur Android (plutôt que d'une application), il existe une barre d'URL rétractable qui ne se redimensionne pas quand elle est rétractée, mais modifie la taille de la fenêtre disponible.


peut-être une solution légèrement meilleure est de lier (avec jQuery dans mon cas) l'événement "flou" sur les différents champs de saisie.

Ceci parce que lorsque le clavier disparaît, tous les champs de formulaire sont flous. Donc, pour ma situation, cela a résolu le problème.

$('input, textarea').bind('blur', function(e) {

       // Keyboard disappeared
       window.scrollTo(0, 1);

});

J'espère que cela aide. Michele







web-applications