2013-02-23 3 views
3

L'utilitaire Ext.History (version 3.4.0) fonctionne correctement dans IE8 +. Il fonctionne en mode Quirks, mais pas avec le mode document en mode IE8 Standards (IE8) ou en mode IE9 Standards (IE9). Le mode Quirks ne fonctionne pas pour nous car il ne rend pas notre CSS correctement.Bouton Précédent à l'aide d'Extjs 3.4 Historique avec le mode document normes ie8 & ie9

J'ai dépouillé tout de l'application, sauf l'utilitaire d'histoire et ont maintenant deux fichiers (en plus des fichiers ExtJs):

index.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"> 
<html> 

<head> 
     <script type="text/javascript" src="ext-base.js"></script> 
     <script type="text/javascript" src="ext-all.js"></script> 
     <script type="text/javascript" src="myapp.js"></script> 
</head> 

<body> 

<div> 
    <div align="center"> 
     <table width="97%" border="0" cellpadding="0" cellspacing="0" > 
      <tr> 
       <td> 
        <a href="#link1">Link1</a> | 
        <a href="#link2">Link2</a> | 
        <a href="#link3">Link3</a> | 
        <a href="#link4">Link4</a> | 
        <a href="#link5">link5</a> 
       </td> 
      </tr> 
     </table> 
    </div> 
</div> 

<!-- Fields required for history management --> 
<form id="history-form" class="x-hidden"> 
    <input type="hidden" id="x-history-field"/> 
    <iframe id="x-history-frame"></iframe> 
</form> 

</body> 
</html> 

myapp.js:

Ext.ns('MyApp'); 

Ext.onReady(function() 
{ 
Ext.History.init(); 
    Ext.History.on('change', function(token){}, this); 
}); 

Lorsque je charge l'application sur un serveur Web, accédez à index.html et cliquez sur link1, la barre d'adresse affiche # link1. Je clique ensuite sur link2 et la barre d'adresse affiche # link2. Je clique ensuite sur link3 et la barre d'adresse montre # link3. En utilisant le bouton Précédent dans IE avec IE7 Emulation, dans Chrome ou Firefox, la barre d'adresse va de # link3 à # link2. Lorsque j'appuie sur le bouton de retour une deuxième fois, la barre d'adresse va de # link2 à # link1. C'est le comportement auquel je m'attends. Cependant, en utilisant IE8 ou IE 9 dans le mode standard de document approprié, lorsque je clique deux fois sur le bouton retour, la barre d'adresse va de # link2 à # link3. D'autres clics sur le bouton retour basculeront l'utilisateur entre # link2 et # link3. Ce comportement est inattendu et empêche notre application de fonctionner correctement.

Notez que c'est la façon que l'exemple Sencha fonctionne pour 3.4.0:

Sencha 3.4 Sample

(la page rend en mode Quirks, mais si vous changer aux normes IE8 ou IE9 normes, il ne fonctionne pas).

Il fonctionne semblent fonctionner correctement dans 4.1:

(seulement me laisser les messages 2 liens, mais vous pouvez probablement trouver ...)

Je n'ai pas accès à Ext 3.4. 1, mais ce problème ne figure pas dans les corrections de bogues. J'ai vu un thread (here) qui suggère que changer le doctype fonctionnerait, mais cela ne semble pas être le cas (j'ai essayé tous les doctypes ...).

Notez que de nombreuses parties de notre application utilisent l'utilitaire Historique pour la navigation. Par conséquent, sa suppression n'est pas une solution acceptable.

Quelqu'un peut-il offrir des suggestions sur la façon dont je peux faire fonctionner cela?

Répondre

1

Voilà comment je fini par résoudre:

J'ai créé un nouveau fichier javascript patch et il inclus une fois les fichiers ext

/* 
@Author: RWR 20130224 

This fixes the issue with backward traversal of history in IE8 & higher in standard document mode. 

This class was challenging to override (http://www.sencha.com/forum/showthread.php?46306-Help-How-to-extend-Ext.History) 
I ended up pasting all of the source original code here and making the necessary changes. 

NOTE that this may be patched in version 3.4.1. It is definitely patched in 4.1. When upgrading, validate that this patch is still required. 
*/ 
NewHistory = (function() { 
var iframe, hiddenField; 
var ready = false; 
var currentToken; 
var oldIEMode = Ext.isIE6 || Ext.isIE7 || !Ext.isStrict && Ext.isIE8; 

function getHash() { 
    var href = location.href, i = href.indexOf("#"), 
     hash = i >= 0 ? href.substr(i + 1) : null; 

    if (Ext.isGecko) { 
     hash = decodeURIComponent(hash); 
    } 
    return hash; 
} 

function doSave() { 
    hiddenField.value = currentToken; 
} 

function handleStateChange(token) { 
    currentToken = token; 
    Ext.History.fireEvent('change', token); 
} 

function updateIFrame (token) { 
    var html = ['<html><body><div id="state">',Ext.util.Format.htmlEncode(token),'</div></body></html>'].join(''); 
    try { 
     var doc = iframe.contentWindow.document; 
     doc.open(); 
     doc.write(html); 
     doc.close(); 
     return true; 
    } catch (e) { 
     return false; 
    } 
} 

function checkIFrame() { 
    if (!iframe.contentWindow || !iframe.contentWindow.document) { 
     setTimeout(checkIFrame, 10); 
     return; 
    } 

    var doc = iframe.contentWindow.document; 
    var elem = doc.getElementById("state"); 
    var token = elem ? elem.innerText : null; 

    var hash = getHash(); 

    setInterval(function() { 

     doc = iframe.contentWindow.document; 
     elem = doc.getElementById("state"); 

     var newtoken = elem ? elem.innerText : null; 

     var newHash = getHash(); 

     if (newtoken !== token) { 
      token = newtoken; 
      handleStateChange(token); 
      location.hash = token; 
      hash = token; 
      doSave(); 
     } else if (newHash !== hash) { 
      hash = newHash; 
      updateIFrame(newHash); 
     } 

    }, 50); 

    ready = true; 

    Ext.History.fireEvent('ready', Ext.History); 
} 

function startUp() { 
    currentToken = hiddenField.value ? hiddenField.value : getHash(); 

    if (oldIEMode) { 
     checkIFrame(); 
    } else { 
     var hash = getHash(); 
     setInterval(function() { 
      var newHash = getHash(); 
      if (newHash !== hash) { 
       hash = newHash; 
       handleStateChange(hash); 
       doSave(); 
      } 
     }, 50); 
     ready = true; 
     Ext.History.fireEvent('ready', Ext.History); 
    } 
} 

return { 
    /** 
    * The id of the hidden field required for storing the current history token. 
    * @type String 
    * @property s 
    */ 
    fieldId: 'x-history-field', 
    /** 
    * The id of the iframe required by IE to manage the history stack. 
    * @type String 
    * @property s 
    */ 
    iframeId: 'x-history-frame', 

    events:{}, 

    /** 
    * Initialize the global History instance. 
    * @param {Boolean} onReady (optional) A callback function that will be called once the history 
    * component is fully initialized. 
    * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the callback is executed. Defaults to the browser window. 
    */ 
    init: function (onReady, scope) { 
     if(ready) { 
      Ext.callback(onReady, scope, [this]); 
      return; 
     } 
     if(!Ext.isReady){ 
      Ext.onReady(function(){ 
       Ext.History.init(onReady, scope); 
      }); 
      return; 
     } 
     hiddenField = Ext.getDom(Ext.History.fieldId); 
     if (oldIEMode) { 
      iframe = Ext.getDom(Ext.History.iframeId); 
     } 
     this.addEvents(
      /** 
      * @event ready 
      * Fires when the Ext.History singleton has been initialized and is ready for use. 
      * @param {Ext.History} The Ext.History singleton. 
      */ 
      'ready', 
      /** 
      * @event change 
      * Fires when navigation back or forwards within the local page's history occurs. 
      * @param {String} token An identifier associated with the page state at that point in its history. 
      */ 
      'change' 
     ); 
     if(onReady){ 
      this.on('ready', onReady, scope, {single:true}); 
     } 
     startUp(); 
    }, 

    /** 
    * Add a new token to the history stack. This can be any arbitrary value, although it would 
    * commonly be the concatenation of a component id and another id marking the specifc history 
    * state of that component. Example usage: 
    * <pre><code> 
    // Handle tab changes on a TabPanel 
    tabPanel.on('tabchange', function(tabPanel, tab){ 
    Ext.History.add(tabPanel.id + ':' + tab.id); 
    }); 
    </code></pre> 
    * @param {String} token The value that defines a particular application-specific history state 
    * @param {Boolean} preventDuplicates When true, if the passed token matches the current token 
    * it will not save a new history step. Set to false if the same state can be saved more than once 
    * at the same history stack location (defaults to true). 
    */ 
    add: function (token, preventDup) { 
     if(preventDup !== false){ 
      if(this.getToken() == token){ 
       return true; 
      } 
     } 
     if (oldIEMode) { 
      return updateIFrame(token); 
     } else { 
      location.hash = token; 
      return true; 
     } 
    }, 

    /** 
    * Programmatically steps back one step in browser history (equivalent to the user pressing the Back button). 
    */ 
    back: function(){ 
     history.go(-1); 
    }, 

    /** 
    * Programmatically steps forward one step in browser history (equivalent to the user pressing the Forward button). 
    */ 
    forward: function(){ 
     history.go(1); 
    }, 

    /** 
    * Retrieves the currently-active history token. 
    * @return {String} The token 
    */ 
    getToken: function() { 
     return ready ? currentToken : getHash(); 
    } 
}; 
})(); 
Ext.apply(NewHistory, new Ext.util.Observable()); 
Ext.apply(Ext.History, NewHistory); 
1

C'était en fait assez simple. J'ai téléchargé Ext 4.1 et j'ai regardé ce qu'ils faisaient avec la classe Ext.util.History. Ils définissent une variable pour oldIEMode et l'utilisent pour toutes les conditions où, en 3.4, ils utilisent Ext.isIE.

Je la classe Ext.History modifié en ext-all-debug.js et défini la variable suivante en haut:

var oldIEMode = Ext.isIE6 || Ext.isIE7 || ! Ext.isStrict & & Ext.isIE8;

Il y avait trois conditions dans la classe qui vérifiait Ext.isIE que j'ai remplacé par oldIEMode.

J'ai reconstruit et déployé l'application et le problème a été résolu.

Modifier ext-all.js n'est pas la meilleure pratique, mais je devrais être en mesure d'écraser cette classe à la place.

Questions connexes