Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >使用带有ie8和ie9标准文档模式的Extjs3.4历史记录的后退按钮

使用带有ie8和ie9标准文档模式的Extjs3.4历史记录的后退按钮
EN

Stack Overflow用户
提问于 2013-02-23 15:56:44
回答 2查看 1.6K关注 0票数 3

在IE8+中,我遇到了Ext.History实用程序(3.4.0版)正常工作的问题。它在Quirks模式下工作,但不能在IE8标准模式(IE8)或IE9标准模式(IE9)下使用文档模式。怪癖模式对我们不起作用,因为它不能正确地呈现我们的CSS。

我已经从应用程序中剥离了除历史实用程序之外的所有内容,现在有两个文件(除了extjs文件):

index.html:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!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:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Ext.ns('MyApp');

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

当我在web服务器中加载应用程序时,转到index.html,然后单击link1,地址栏显示#link1。然后单击link2,地址栏显示#link2。然后单击link3,地址栏显示#link3。

使用带有IE7仿真的IE中的后退按钮,在Chrome或火狐浏览器中,地址栏将从#link3转到#link2。当我再次点击后退按钮时,地址栏从#link2变成了#link1。这是我所期望的行为。

但是,在适当的文档标准模式下使用IE8或IE9时,当我再次单击“后退”按钮时,地址栏从#link2回到#link3。再单击back按钮,用户将在#link2和#link3之间切换。这种行为是意外的,并且会导致我们的应用程序无法正常工作。

请注意,这是Sencha示例在3.4.0中的工作方式:

Sencha 3.4 Sample

(页面以Quirks模式呈现,但如果您将其更改为IE8标准或IE9标准,它将不起作用)。

它在4.1中似乎工作正常:

(只允许我发布两个链接,但您可能可以找到它...)

我不能访问Ext3.4.1,但是这个问题没有在错误修复中列出。我见过一个线程(here),它建议更改文档类型会起作用,但事实似乎并非如此(我已经尝试了所有文档类型……)。

请注意,我们的应用程序的许多部分都在使用History实用程序进行导航,因此移除它不是一个可接受的解决方案。

有没有人能给我提点建议,让它正常工作?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-24 13:28:44

这就是我最终解决这个问题的方法:

我创建了一个新的补丁javascript文件,并将其包含在ext文件之后。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*
 @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
EN

Stack Overflow用户

发布于 2013-02-24 00:51:55

这实际上是非常简单的。我下载了Ext4.1并查看了他们对Ext.util.History类做了什么。他们为oldIEMode定义了一个变量,并将其用于3.4中使用Ext.isIE的所有条件句。

因此,我编辑了ext-all-debug.js中的Ext.History类,并在顶部定义了以下变量:

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

类中有三个条件语句在检查Ext.isIE,我用oldIEMode替换了它们。

我重新构建并部署了应用程序,问题得到了解决。

编辑ext-all.js不是最佳实践,但是我应该能够改写这个类。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15042460

复制
相关文章
node+express构建后端项目
项目启动后,在浏览器就可以访问了localhost:3000,访问成功会出现以下页面
程序员不务正业
2019/09/29
1.3K0
《Node.js+Express+Vue项目实战》-- 1.安装和使用Express(笔记)
Express 是一个精简、灵活的 Node.js 的 Web 应用程序开发框架,为 Web 和移动应用程序提供了一组强大的功能,使用 Express 可以快速地开发一个 Web 应用。
爱学习的程序媛
2022/04/07
4.3K0
《Node.js+Express+Vue项目实战》-- 1.安装和使用Express(笔记)
TypeScript在node项目中的实践
TypeScript可以理解为是JavaScript的一个超集,也就是说涵盖了所有JavaScript的功能,并在之上有着自己独特的语法。 最近的一个新项目开始了TS的踩坑之旅,现分享一些可以借鉴的套路给大家。
贾顺名
2019/12/09
1.7K0
TypeScript在node项目中的实践
使用 Node.js 和 Express.js 搭建简易 HTTP/2 服务器
自从 1975 年左右使用 TCP/IP 协议的现代互联网诞生至今已经过了惊人的41年了。在它生涯的大部分时间里,我们使用 HTTP 以及它的继任者 HTTP/1.1 (1.1 版本) 在客户端和服务器之间进行通讯。它很好的支撑起了这个网络世界,但是开发者们构建网站的方式发生了巨大的变化。现在有无数的外部资源、图片、CSS 文件和 JavaScript 文件。这些资源的数量只增不减。
疯狂的技术宅
2019/03/27
2.9K0
使用 Node.js 和 Express.js 搭建简易 HTTP/2 服务器
node.js + express 后端项目小坑
PROTOCOL_CONNECTION_LOST PROTOCOL_ENQUEUE_AFTER_FATAL_ERROR
程序员不务正业
2020/02/18
1.5K0
node Express 框架
Express事实上Node内置的http模块上构建的一层抽象。理论上所有Express实现的功能都能用Node实现
mySoul
2018/07/29
5.3K0
Node.js 项目 TypeScript 改造指南
如果你有一个 Node.js 项目,并想使用 TypeScript 进行改造,那本文对你或许会有帮助。
五月君
2019/12/06
8.4K0
Node.js 项目 TypeScript 改造指南
Node.js项目TypeScript改造指南
如果你有一个 Node.js 项目,并想使用 TypeScript 进行改造,那本文对你或许会有帮助。
coder_koala
2019/12/05
4.6K0
使用Typescript开发node.js项目
typescript 通过构造函数的参数直接定义属性,为了证明,我们创建一个info.ts文件 内容如下
lilugirl
2019/05/28
2.6K0
Node.js项目TypeScript改造指南
如果你有一个 Node.js 项目,并想使用 TypeScript 进行改造,那本文对你或许会有帮助。
WecTeam
2019/12/24
4.4K0
如何运行github上面的node+express项目
在学习过程之中,除了看完教程之外,我们还需要完成一个重要的步骤,那就是做一个项目来巩固和联系,就像是学生时代那般,上完课是要找作业来练习加深印象是一个道理。
王小婷
2019/03/04
1.2K0
如何运行github上面的node+express项目
node框架express的研究
在node中,express可以说是node中的jQuery了,简单粗暴,容易上手,用过即会,那么我们来试一下怎么实现。下面我们基于4.16.2版本进行研究
lhyt
2022/09/21
9560
node框架express的研究
Node.js 项目 TypeScript 改造指南(二)
最近笔者把一个中等规模的 Koa2 项目迁移到 TypeScript,和大家分享一下 TypeScript 实践中的经验和技巧。
WecTeam
2019/12/26
3.6K0
Node | Express简单使用
express提供了一个非常好用的函数,叫做express.static(),通过它,我们可以非常方便地创建一个静态资源服务器,例如,通过如下代码就可以将static目录下的图片、CSS文件、JavaScript 文件对外开放访问了:
倾盖
2022/08/16
1K0
Node | Express简单使用
Node.js + express 的使用
变化的路由 我们再访问服务器时描绘涉及到许许多多的路由,这是我们不可能将他们都一一列举出来,所以我们就可以用 ‘ :’ 来解决,如下:
圆号本昊
2021/09/24
2.7K0
Node + Express + Mysql的CMS小结
因为之前用过上述的组合完成过很多系统,而这一次是为了实现一个帮助系统的静态网页发布。因为很久不写,重点说遇到的几个坑:
meteoric
2018/11/19
1.5K0
Vue.js + Node.js + Express + MySQL示例:构建全栈CRUD应用程序
上次修改时间:2020年10月16日 bezkoder Full Stack,Node.js,Vue.js
ccf19881030
2020/11/10
25.1K0
Vue.js + Node.js + Express + MySQL示例:构建全栈CRUD应用程序
express:node throwing error on mongodb
与此类似node throwing error on mongodb,一直报Db.open那里出错,查源代码,发现应该是有err参数传入,因为之前从来没接触过mongodb--在某些文章中看到稍微有些了解,觉得是不是没有安装mongodb的问题呢?试了一下,果然如此。
meteoric
2018/11/16
5390
Express,Sequelize和MySQL的Node.js Rest API示例
本文翻译自Node.js Rest APIs example with Express, Sequelize & MySQL
ccf19881030
2020/11/10
12.7K0
Express,Sequelize和MySQL的Node.js Rest API示例
一种不错的 BFF Microservice GraphQL/REST API 层的开发方式
云原生(Cloud Native)Node JS Express Reactive 微服务模板 (REST/GraphQL) 这个项目提供了完整的基于 Node JS / Typescript 的微服务模板,包括生产部署、监控、调试、日志记录、安全、CI/CD 所需的所有功能。还添加了基于响应性扩展的示例,以演示如何将其用于构建微服务 API 边缘服务(edge-service)、前端的后端(BFF)或将其用作构建任何类型微服务的基础。
为少
2021/05/27
2.4K0
一种不错的 BFF Microservice GraphQL/REST API 层的开发方式

相似问题

微软认可的带有node/express的TypeScript入门项目没有任何类吗?

10

设置node.js & express项目

115

TypeScript与现有Node js express项目的集成

112

为Node/Express/类型记录和Node设置一个项目

20

使用typescript项目设置node.js

11
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文