【问题标题】:Delay with Internet Explorer noticing changes to location.hash延迟 Internet Explorer 注意到 location.hash 的变化
【发布时间】:2014-06-24 21:16:38
【问题描述】:

这可能是常识,但我似乎无法找到有关此问题的任何信息。这里有一点背景:

我有一些页面使用了 Bootstrap 的标签系统。在这些页面的$(document).ready() 函数中,有一些基本代码可以根据 URL 中的哈希值激活选项卡,还有一个附加到选项卡显示的函数的简短函数,该函数使用location.replace 更改位置的哈希值。结果是您可以链接到特定标签,并且刷新页面也可以让您保持在当前选项卡上。这在除 Internet Explorer 之外的所有应用中都可以正常工作。

在 Internet Explorer 中(我一直在使用 IE9 进行测试),在 IE 识别位置哈希已更改之前,似乎存在延迟(大约 10-15 秒)。当在地址栏中手动输入哈希并加载页面时,也会发生类似的事情——需要几次刷新才能识别。单击其中嵌入哈希的链接似乎可以正常加载。

我假设这是某种故障。我想我可以将一个 cookie 附加到处理持久选项卡状态的代码中,但是有没有其他人找到一种更优雅的方式来处理这个问题?

【问题讨论】:

    标签: javascript internet-explorer


    【解决方案1】:

    我不熟悉或不知道 Bootstrap 的标签系统有任何延迟,您可能需要验证问题不是由于您的特定用途或计算机造成的。在我熟悉的任何浏览器上使用 jQuery hashchange 插件,我都无法产生任何延迟。

    至于处理基于哈希的导航的其他方法,我编写了以下内容以使用 jQuery hashchange 插件更改 hashchange 事件的内容/页面;主要是为了干净地支持带有哈希的后退/前进/链接。我关注的是我正在使用的精简版。

    该示例提供了一个锚链接,并使用 onclick 事件生成。首选使用 onclick 事件,因为如果用户单击当前活动的选项卡,页面仍会重新加载。跟踪页面加载时间以确保页面在 100 毫秒内没有加载两次。

    jQuery 哈希插件:http://benalman.com/projects/jquery-hashchange-plugin/

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script type="text/javascript" src="http://benalman.com/code/projects/jquery-hashchange/jquery.ba-hashchange.js"></script>
    <script>
    var hashUris = [];
    var tabSet;
    var actPage = '';
    // bare tab array (use to populate tab html and hash array)
    tabSet = [{hash: 'page1', pageId:1, id: 1}, {hash: 'page10', pageId:10, id:2 }, {hash: 'page20' , pageId: 20, id: 3}];
    
    // handles the hash events
    $(function() {
        // loop all tab array, add items to hash array, determine primary page and active page
        $.each(tabSet, function(i, tab) {
            // using tabIndex to prevent looping hash array later
            tab.tabIndex = i;
            // first tab is primary by default
            if (typeof priTabId == 'undefined') priTabId = tab.id;
            // add tabs/page info to hash array
            hashUris.push({hash: tab.hash, pageId: tab.pageId, tabIndex: i, tabId: tab.id, priActive: priTabId == tab.id});
            // initial page to be loaded
            if (priTabId == tab.id) priTabIndex = i;
            // current hash
            if (location.hash && '#'+tab.hash == location.hash) activeTabIndex = i;
        });
        if (!location.hash && !actPage && typeof priTabIndex != 'undefined') {
            // page load, load primary tab
            loadTabPage(priTabIndex);
        } else if (location.hash && !actPage && typeof activeTabIndex != 'undefined') {
            // page refresh
            loadTabPage(activeTabIndex);
        }
        $(window).hashchange( function(){
            if (location.hash) {
                $.each(hashUris, function(index, hashUri) {
                    if ('#'+hashUri.hash == location.hash && actPage != hashUri.pageId + '#' + hashUri.hash) {
                        // found matching tab/page
                        loadTabPage(hashUri.tabIndex);
                    }
                });
            } else if (actPage) {
                // navigated to empty space, attempt to find a primary active page
                $.each(hashUris, function(index, hashUri) {
                    if (hashUri.priActive) loadTabPage(hashUri.tabIndex);
                });
            }
        });
    });
    function loadTabPage(tabIndex) {
        if (typeof tabSet[tabIndex] == 'undefined') return;
    
        // track when the page was loaded
        lastLoad = tabSet[tabIndex].lastLoad;
        tabSet[tabIndex].lastLoad = new Date().getTime();
        // load only once in 1ms-100ms
        if (tabSet[tabIndex].lastLoad - lastLoad < 100) return;
    
        // load page content/do actions here
        alert(tabSet[tabIndex].pageId);
        //$("#content").load('?pageId='+tabSet[tabIndex].pageId);
    
        // active page checked against hash during hashchange
        actPage = tabSet[tabIndex].pageId + '#' + tabSet[tabIndex].hash;
    };
    // user code to create tabs 
    $(function() {
        // use tabs array to display some tabs
        // this depends on the above code to set .tabIndex on the tabSet array
        tabsObj = $('<div/>');
        $.each(tabSet, function(i, tab) {
            if (!tab.hash) return true;
            tmpObj = $('<span>'+tab.hash+'</span>');
            tmpObj.data('tabIndex', tab.tabIndex);
    
            // use an onclick event to change the page
            tmpObj.bind('click', function(e) {
                if (typeof $(this).data('tabIndex') == 'undefined' || typeof tabSet[$(this).data('tabIndex')] == 'undefined') return;
    
                // load page directly if active hash, otherwise change to clicked hash
                if ('#'+tabSet[$(this).data('tabIndex')].hash == location.hash) {
                    loadTabPage($(this).data('tabIndex'));
                } else {
                    location.hash = tabSet[$(this).data('tabIndex')].hash;
                }
                e.stopPropagation();
                return false;
            });
            tmpObj.appendTo(tabsObj);
            delete tmpObj;
        });
        tabsObj.appendTo($("#tabs"));
        delete tabsObj;
    });
    </script>
    <div id="tabs"><a href="#page1" >Link to Hash</a></div>
    <div id="content"></div>
    

    【讨论】:

    • 延迟与 Bootstrap 无关。延迟是 Internet Explorer 识别 URL 哈希已更改。您只需使用基本的 Javascript 即可观察到这种效果。
    • 你能给我提供一个如何重现 Internet Explorer 延迟的例子吗?在 Internet Explorer 9 (x64) 中侦听 hashchange 事件时,我无法重现任何延迟/问题。
    • 我已经或多或少地通过使用cookie(除了哈希)解决了这个问题。经过进一步调查,我注意到问题并非总是容易重现。似乎随着页面中的 Javascript 越来越多,IE 在更新 window.location.hash 的值方面落后了,至少在从 window.location.replace 设置时是这样。
    【解决方案2】:

    一些运行 IE8 的客户刚刚遇到这个问题。我们有一个运行 sammy.js + knockout 和 bootstrap 的网页。每条路线(带有哈希的链接)大约需要 800-900 毫秒才能导航到。但是,当我从页面中删除所有 css/样式时,每个路线导航都需要大约 30 毫秒。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      • 1970-01-01
      • 2010-10-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多