2015-07-03 32 views
10

Hy,problemi di scorrimento con ExtJS 5 app all'interno IFrame

questo è ciò che la mia pagina di prova assomiglia:

enter image description here

L'area blu è la pagina principale e l'area verde è un IFrame che esegue un'applicazione ExtJS (finestra di visualizzazione semplice con all'interno un'etichetta).

Se il sito viene eseguito su un dispositivo touch (IPad, tablet Android, ecc.) Non è possibile scorrere la pagina "pulendo" sull'IFrame (l'area verde). Uno deve pulire sull'area blu per scorrere la pagina.

Questo funzionava correttamente in ExtJS v4.2.1 (vedere i collegamenti seguenti).

Test-Pagine:

https://skaface.leo.uberspace.de/ScrollTest/Ext510/ (non funziona come previsto, usando ExtJS v5.1.1)
https://skaface.leo.uberspace.de/ScrollTest/Ext421/ (funziona come previsto, lo stesso codice ma usando ExtJS V4.2.1)

il codice di prova:

sito Parent (index.html):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" style="height: 100%;"> 
<head> 
    <title>Test</title> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/> 
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> 
</head> 
<body style="margin: 50px; background-color: blue;"> 
    <iframe src="frame.html" width="100%" height="1400" style="border: none;"></iframe> 
</body> 
</html> 

IFrame (frame.html):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" style="height: 100%;"> 
<head> 
    <title>Test</title> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/> 
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> 

    <link rel="stylesheet" type="text/css" href="https://extjs.cachefly.net/ext/gpl/5.1.0/packages/ext-theme-neptune/build/resources/ext-theme-neptune-all-debug.css" /> 
    <script type="text/javascript" src="https://extjs.cachefly.net/ext/gpl/5.1.0/build/ext-all-debug.js"></script> 

    <script type="text/javascript"> 
     Ext.onReady(function() { 
      Ext.create('Ext.container.Viewport', { 
       style: { 'background-color': 'yellowgreen' }, 
       layout: 'fit', 
       items: [{ 
        xtype: 'label', 
        text: 'Ext version: ' + Ext.versions.extjs.version, 
        margin: 16 
       }] 
      }); 
     }); 
    </script> 
</head> 
<body> 
</body> 
</html> 

mi piacerebbe davvero apprezzare una soluzione per questo dal momento che rende praticamente inutile miei siti su dispositivi mobili, anche se aveva lavorato perfettamente bene con ExtJS 4.2.1.

Grazie & migliori saluti

Ps .: Ho già postato un bug report in the sencha forums, ma dal momento che non ho avuto alcun aiuto fino al sapere, sto anche cercando la mia fortuna su StackOverflow ...

+0

[Eventi delegati e gesti in Ext JS 5] (https://www.sencha.com/blog/delegated-events-and-gestures-in-ext-js-5/) – davidcondrey

+0

Perché non puoi rimuovere completamente il contenitore esterno e mostrare direttamente il contenuto interno, usando una imbottitura 50px sul corpo o simili? – BoffinbraiN

+0

@davidcondrey Grazie per il collegamento, ho intenzione di dargli un'occhiata la prossima settimana. – suamikim

risposta

1

Dopo un sacco di scavare intorno all'interno del quadro, ho finalmente trovato una soluzione che, almeno per me funziona e si compone di 2 fasi:

1) ExtJS imposta la proprietà CSS touch-action del viewport (l'elemento html di base dell'IFrame) e il suo corpo sul valore none. Ho semplicemente sovrascritte con il valore auto:

.x-viewport, .x-viewport > .x-body { 
    touch-action: auto; 
} 

2) La classe Ext.container.Viewport chiamate Ext.plugin.Viewport.decorate(this); nella sua creazione di callback, che aggiunge un listener per l'evento touchmove della finestra stessa.

Tutto ciò che fa l'ascoltatore chiama preventDefault(); dell'evento, che è il motivo per cui lo scorrimento non funziona più nella pagina padre o nell'IFrame stesso. mio correzione rimuove semplicemente la preventDefault() e restituisce invece false dal gestore touchmove eventi di lasciare la bolla evento a monte della catena del browser:

Ext.define('Cbn.overrides.container.Viewport', { 
    override: 'Ext.container.Viewport' 
}, function() { 
    Ext.override(this, { 
     onRender: function() { 
      this.mon(Ext.getDoc(), { 
       touchmove: function(e) { 
        // e.preventDefault(); // Original ExtJS code 
        return false; 
       }, 
       translate: false, 
       delegated: false 
      }); 
      this.callParent(arguments); 
     } 
    }); 
}); 

io non sono molto sicuro se quei 2 correzioni hanno implicazioni negative ma finora sembrano fare il lavoro per me.

Una cosa che ho capito è che l'utilizzo di componenti con la configurazione scrollable: true all'interno del IFrame-App rende ancora problemi, ma dato che posso evitare che un po 'ovunque non è un problema per me finora ...

prova di lavoro -site: https://skaface.leo.uberspace.de/ScrollTest/Ext510_fixed/


Edit:
soluzione rettificato un po 'per non costantemente gettare non gestita errori JavaScript durante touch-scorrimento (vedi Error: Failed to execute 'dispatchEvent' on 'EventTarget')

1

Il behavious è strano, ho visto che prima di utilizzare niceScroll plug-in, e molti altri plugin avuto anche lo stesso problema con il iframe, in ogni caso controllare this workaround

ho usato Hammer.js plug-in jQuery per rilevare i gesti tattili su iframe, se si riscontrano problemi relativi alla sensibilità (poiché non so quali restrizioni si stanno cercando), è possibile regolare le opzioni hammer.js presenti sul repository (come la soglia di panoramica, i puntatori .etc)

e il codice è molto semplice:

<body id="mainbody" style="margin: 50px; background-color: blue;"> 
    <iframe id="myframe" src="frame.html" width="100%" height="1400" style="border: none;"></iframe> 
</body> 
<script> 
var myBody 
$('iframe').load(function(){ 
    myBody=$(this).contents().find("body"); 
    myBody.css({"height":"100%","overflow":"hidden"}).hammer({threshold:1}).bind("pan", myPanHandler); 
}); 
function myPanHandler(ev) 
{ 
    $("#mainbody").scrollTop($("#mainbody").scrollTop()-ev.gesture.deltaY) 
console.log(($("#mainbody").scrollTop()-ev.gesture.deltaY*0.5)+".."+$("#mainbody").scrollTop()) 
} 
</script> 
+0

Non ho contrassegnato questa risposta come quella ormai accettata poiché sembra una soluzione piuttosto hacky e sto ancora cercando qualcosa di più elegante come il fissaggio di cose direttamente nel framework ExtJS. Tuttavia, fornisce almeno un modo che probabilmente funzionerebbe e quindi ho dato la taglia. – suamikim