Sviluppare per il web mobile finora è stato come esplorare una piccola isola felice, certo con pericoli nascosti a causa della elevata frammentazione su Android, ma da quando i sistemi del robottino e della mela si sono prepotentemente imposti sul mercato, con i loro browser predefiniti basati su WebKit, abbiamo avuto un momento di respiro.
Micro$oft però non è rimasta a guardare, Windows Phone sta acquisendo maggiore visibilità, ed il vecchio nemico si è infine affacciato anche sui dispositivi mobili, ebbene si perché Windows Phone 8 significa Internet Explorer, mobile ma comunque basato sul motore proprietario Trident presente anche su IE10 desktop e sui tablets surface, ciò significa solo una cosa : bugs.
Se credi che il tuo sito ottimizzato per iPhone e Android si veda benissimo anche su un Lumia nuovo di zecca, questa è la lista di problemi che sicuramente dovrai affrontare.
Il Viewport deve essere specificato via CSS, il meta non funziona
La gestione del viewport su smartphone ha una storia travagliata, mentre il settore doveva ancora nascere il W3C aveva creato come linea guida la gestione attraverso media query, inquadrando il viewport come una proprietà visuale. Tuttavia Apple nel 2007 aveva fretta e non poteva aspettare che in seno a webkit si stabilizzase la specifica CSS per cui optò come linea guida di sviluppo dei siti mobile per i loro nuovi fiammanti iPhone l’uso del tag meta.
1 2 |
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"> |
Microsoft questa volta si è adattata alle specifiche W3C, è vero, ma ignorando completamente lo standard de facto del settore, per cui se Chrome su smartphone renderizza correttamente il viewport della pagina specificato sia tramite meta che tramite CSS, su Internet Explorer mobile funzionerà solo se specificato via CSS, della serie come la fai la sbagli. Ricorda quindi di inserire nel tuo CSS, possibilmente tra le primissime regole, le seguenti righe :
1 2 3 4 5 6 7 |
@-ms-viewport{ width:device-width; zoom:1; min-zoom:1; max-zoom:1; user-zoom:fixed; } |
Una cosa da notare è che su Chrome desktop, in modalità emulazione smartphone, la compresenza delle due regole da luogo a degli strani comportamenti con testi randomicamente troppo grandi o troppo piccoli. Gli ultimi test che ho effettuato sia su Safari iOS 7 e Chrome KitKat non hanno dato luogo a queste stranezze ma per evitare spiacevoli sorprese è preferibile utilizzare il prefisso -ms-.
Se la larghezza del Viewport è equivalente alla larghezza del dispositivo l’evento JavaScript resize non funziona
Questa è la cosa più strana, e grave, che ho constatato su Windows Phone 8.1 (build 8.10.12397.895) sul NOKIA Lumia 630; impostando la larghezza del viewport sui valori device-width o 100% si ottiene in entrambi i casi che ruotando il dispositivo l’evento resize non viene mai innescato, in questo modo nessuna delle funzioni registrate su tale evento viene eseguita.
Per essere sicuro che non fosse un problema di jQuery o della specifica versione che stavo utilizzando ho provato anche con il metodo vanilla addEventListener senza successo.
Anche se poco elegante, ho pensato di aggirare il problema facendo affidamento al metodo $.resize() proxando la funzione in modo da inserire al suo interno un setInterval che entrerà in funzione solo su Windows Phone, il quale verificherà periodicamente che la larghezza rilevata non sia cambiata ed in caso contrario esegue la callback che sarebbe stata eseguita dall’evento resize.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
var isIEMobile = navigator.pointerEnabled || navigator.msPointerEnabled; //On IE mobile for Windows Phone 8.1 resize event is not fired //If viewport is set to device-width if(isIEMobile) { function resizeFix(theArgs) { var initialWindowWidth = $(window).width(); var currentWindowWidth = null; setInterval(function(){ currentWindowWidth = $(window).width(); if(currentWindowWidth!==initialWindowWidth) { initialWindowWidth = currentWindowWidth; theArgs(); } },100); }; //Extend jQuery resize method to include the WP8.1 fix (function($) { // maintain a reference to the existing function var oldResize = $.fn.resize; // ...before overwriting the jQuery extension point $.fn.resize = function() { // original behavior - use function.apply to preserve context var ret = oldResize.apply(this, arguments); // additional function // that doesn't affect/change // the way .resize() works resizeFix.apply(this, arguments); // preserve return value (the jQuery object) return ret; }; })(jQuery); }; |
Puoi testare il comportamento dalla seguente pagina di test : http://test.simonerescio.it/wp81resize.html
Il colore di selezione degli elementi interattivi si può solo disabilitare a livello di pagina
Ricordi la proprietà -webkit-tap-highlight-color che ti permetteva di decidere a livello del singolo elemento se inibire l’effetto o modificarne il colore con valori RGBA? È inutile che tenti con -ms-tap-highlight-color o altri prefissi disperati, non funzionerà.
L’unica cosa che Windows Phone permette di fare è disabilitare l’effetto a livello di pagina, su tutti gli elementi con un meta proprietario :
1 |
<meta name="msapplication-tap-highlight" content="no"/> |
Inoltre per funzionare il meta deve essere presente da subito nell’head della pagina HTML che viene inviata al client, aggiungendolo via JavaScript in runtime non funzionerà.
Bisognerà poi armarsi di pazienza e fornire una controparte :hover per dare un minimo di feedback all’utente.
Gli eventi touch devono essere mappati sul modello pointerEvent
Al fine di unificare la gestione degli eventi a prescindere dalla sorgente MicroSoft ha sottoposto al W3C il modello pointerEvent che all’atto pratico richiede di mappare gli eventi registrati sul modello touch anche sul modello di MicroSoft, come illustrato sulla pagina ufficiale :
1 2 3 4 5 6 7 8 |
if (window.navigator.msPointerEnabled) { this.element.addEventListener(“MSPointerDown”, eventHandlerName, false); this.element.addEventListener(“MSPointerMove”, eventHandlerName, false); this.element.addEventListener(“MSPointerUp”, eventHandlerName, false); } this.element.addEventListener(“touchstart”, eventHandlerName, false); this.element.addEventListener(“touchmove”, eventHandlerName, false); this.element.addEventListener(“touchend”, eventHandlerName, false); |
jQuery non supporta ancora questo modello di eventi, motivo per il quale bisogna usare addEventListener e l’adattamento potrebbe non essere indolore.
Le maschere di ritaglio CSS non sono supportate
Se come me hai usato la proprietà mask-image per creare un loader sappi che IE non l’ha mai supportata, e ancora non la supporta, avrai bisogno di un fallback png trasparente :
Creare effetti sfumati con le font icon non è possibile
Per creare un effetto visivo di rilievo con una font icon CSS il metodo che ho utilizzato fin ora consiste nel duplicare il simbolo con uno pseudo elemento che si sovrappone all’originale, impostare il colore trasparente in modo da lasciare visbile solo il colore della proprietà text-shadow a cui applico una sfumatura.
Ebbene su Explorer, a prescindere dalla versione, questo effetto non funziona perché qualora si imposta un valore di sfumatura per la proprietà text-shadow l’opacità dell’elemento viene regolata dal valore alpha della proprietà color, intuitivo eh?
I testi all’interno di elementi interattivi vengono selezionati troppo velocemente
Un comportamento abbastanza fastidioso è il fatto che toccando un elemento a cui corrisponde un azione, se il tocco cade proprio sul testo al suo interno questo viene immediatamente evidenziato per l’operazione di copia. Si può inibire usando la proprietà user-select.
1 2 3 |
.some-element { -ms-user-select: none; } |
Developer Tools, 404
Se hai avuto lo stomaco forte di leggere fino a qui pensando che “ok, ci sono tanti problemi da risolvere ma ci saranno anche degli strumenti nativi per debbuggare“, devo deluderti, siamo tornati ai tempi di IE6 in cui il miglior strumento di debug è il tasto F5.
Ad oggi non c’è uno strumento nativo di MicroSoft per ispezionare il DOM di Explorer mobile ne una REPL JavaScript per capire se qualcosa va storto, l’unico strumento valido attualmente è weinre, recentemente reso compatibile anche per Windows Phone, con tutti i limiti del caso (no breakpoints, no supporto agli pseudo elementi CSS etc).