history.js
上传用户:chunsheng
上传日期:2022-06-13
资源大小:1476k
文件大小:24k
源码类别:

FlashMX/Flex源码

开发平台:

Flex

  1. BrowserHistoryUtils = {
  2.     addEvent: function(elm, evType, fn, useCapture) {
  3.         useCapture = useCapture || false;
  4.         if (elm.addEventListener) {
  5.             elm.addEventListener(evType, fn, useCapture);
  6.             return true;
  7.         }
  8.         else if (elm.attachEvent) {
  9.             var r = elm.attachEvent('on' + evType, fn);
  10.             return r;
  11.         }
  12.         else {
  13.             elm['on' + evType] = fn;
  14.         }
  15.     }
  16. }
  17. BrowserHistory = (function() {
  18.     // type of browser
  19.     var browser = {
  20.         ie: false, 
  21.         firefox: false, 
  22.         safari: false, 
  23.         opera: false, 
  24.         version: -1
  25.     };
  26.     // if setDefaultURL has been called, our first clue
  27.     // that the SWF is ready and listening
  28.     //var swfReady = false;
  29.     // the URL we'll send to the SWF once it is ready
  30.     //var pendingURL = '';
  31.     // Default app state URL to use when no fragment ID present
  32.     var defaultHash = '';
  33.     // Last-known app state URL
  34.     var currentHref = document.location.href;
  35.     // Initial URL (used only by IE)
  36.     var initialHref = document.location.href;
  37.     // Initial URL (used only by IE)
  38.     var initialHash = document.location.hash;
  39.     // History frame source URL prefix (used only by IE)
  40.     var historyFrameSourcePrefix = 'history/historyFrame.html?';
  41.     // History maintenance (used only by Safari)
  42.     var currentHistoryLength = -1;
  43.     var historyHash = [];
  44.     var initialState = createState(initialHref, initialHref + '#' + initialHash, initialHash);
  45.     var backStack = [];
  46.     var forwardStack = [];
  47.     var currentObjectId = null;
  48.     //UserAgent detection
  49.     var useragent = navigator.userAgent.toLowerCase();
  50.     if (useragent.indexOf("opera") != -1) {
  51.         browser.opera = true;
  52.     } else if (useragent.indexOf("msie") != -1) {
  53.         browser.ie = true;
  54.         browser.version = parseFloat(useragent.substring(useragent.indexOf('msie') + 4));
  55.     } else if (useragent.indexOf("safari") != -1) {
  56.         browser.safari = true;
  57.         browser.version = parseFloat(useragent.substring(useragent.indexOf('safari') + 7));
  58.     } else if (useragent.indexOf("gecko") != -1) {
  59.         browser.firefox = true;
  60.     }
  61.     if (browser.ie == true && browser.version == 7) {
  62.         window["_ie_firstload"] = false;
  63.     }
  64.     // Accessor functions for obtaining specific elements of the page.
  65.     function getHistoryFrame()
  66.     {
  67.         return document.getElementById('ie_historyFrame');
  68.     }
  69.     function getAnchorElement()
  70.     {
  71.         return document.getElementById('firefox_anchorDiv');
  72.     }
  73.     function getFormElement()
  74.     {
  75.         return document.getElementById('safari_formDiv');
  76.     }
  77.     function getRememberElement()
  78.     {
  79.         return document.getElementById("safari_remember_field");
  80.     }
  81.     /* Get the Flash player object for performing ExternalInterface callbacks. */
  82.     function getPlayer(objectId) {
  83.         var objectId = objectId || null;
  84.         var player = null; /* AJH, needed?  = document.getElementById(getPlayerId()); */
  85.         if (browser.ie && objectId != null) {
  86.             player = document.getElementById(objectId);
  87.         }
  88.         if (player == null) {
  89.             player = document.getElementsByTagName('object')[0];
  90.         }
  91.         
  92.         if (player == null || player.object == null) {
  93.             player = document.getElementsByTagName('embed')[0];
  94.         }
  95.         return player;
  96.     }
  97.     
  98.     function getPlayers() {
  99.         var players = [];
  100.         if (players.length == 0) {
  101.             var tmp = document.getElementsByTagName('object');
  102.             players = tmp;
  103.         }
  104.         
  105.         if (players.length == 0 || players[0].object == null) {
  106.             var tmp = document.getElementsByTagName('embed');
  107.             players = tmp;
  108.         }
  109.         return players;
  110.     }
  111. function getIframeHash() {
  112. var doc = getHistoryFrame().contentWindow.document;
  113. var hash = String(doc.location.search);
  114. if (hash.length == 1 && hash.charAt(0) == "?") {
  115. hash = "";
  116. }
  117. else if (hash.length >= 2 && hash.charAt(0) == "?") {
  118. hash = hash.substring(1);
  119. }
  120. return hash;
  121. }
  122.     /* Get the current location hash excluding the '#' symbol. */
  123.     function getHash() {
  124.        // It would be nice if we could use document.location.hash here,
  125.        // but it's faulty sometimes.
  126.        var idx = document.location.href.indexOf('#');
  127.        return (idx >= 0) ? document.location.href.substr(idx+1) : '';
  128.     }
  129.     /* Get the current location hash excluding the '#' symbol. */
  130.     function setHash(hash) {
  131.        // It would be nice if we could use document.location.hash here,
  132.        // but it's faulty sometimes.
  133.        if (hash == '') hash = '#'
  134.        document.location.hash = hash;
  135.     }
  136.     function createState(baseUrl, newUrl, flexAppUrl) {
  137.         return { 'baseUrl': baseUrl, 'newUrl': newUrl, 'flexAppUrl': flexAppUrl, 'title': null };
  138.     }
  139.     /* Add a history entry to the browser.
  140.      *   baseUrl: the portion of the location prior to the '#'
  141.      *   newUrl: the entire new URL, including '#' and following fragment
  142.      *   flexAppUrl: the portion of the location following the '#' only
  143.      */
  144.     function addHistoryEntry(baseUrl, newUrl, flexAppUrl) {
  145.         //delete all the history entries
  146.         forwardStack = [];
  147.         if (browser.ie) {
  148.             //Check to see if we are being asked to do a navigate for the first
  149.             //history entry, and if so ignore, because it's coming from the creation
  150.             //of the history iframe
  151.             if (flexAppUrl == defaultHash && document.location.href == initialHref && window['_ie_firstload']) {
  152.                 currentHref = initialHref;
  153.                 return;
  154.             }
  155.             if ((!flexAppUrl || flexAppUrl == defaultHash) && window['_ie_firstload']) {
  156.                 newUrl = baseUrl + '#' + defaultHash;
  157.                 flexAppUrl = defaultHash;
  158.             } else {
  159.                 // for IE, tell the history frame to go somewhere without a '#'
  160.                 // in order to get this entry into the browser history.
  161.                 getHistoryFrame().src = historyFrameSourcePrefix + flexAppUrl;
  162.             }
  163.             setHash(flexAppUrl);
  164.         } else {
  165.             //ADR
  166.             if (backStack.length == 0 && initialState.flexAppUrl == flexAppUrl) {
  167.                 initialState = createState(baseUrl, newUrl, flexAppUrl);
  168.             } else if(backStack.length > 0 && backStack[backStack.length - 1].flexAppUrl == flexAppUrl) {
  169.                 backStack[backStack.length - 1] = createState(baseUrl, newUrl, flexAppUrl);
  170.             }
  171.             if (browser.safari) {
  172.                 // for Safari, submit a form whose action points to the desired URL
  173.                 if (browser.version <= 419.3) {
  174.                     var file = window.location.pathname.toString();
  175.                     file = file.substring(file.lastIndexOf("/")+1);
  176.                     getFormElement().innerHTML = '<form name="historyForm" action="'+file+'#' + flexAppUrl + '" method="GET"></form>';
  177.                     //get the current elements and add them to the form
  178.                     var qs = window.location.search.substring(1);
  179.                     var qs_arr = qs.split("&");
  180.                     for (var i = 0; i < qs_arr.length; i++) {
  181.                         var tmp = qs_arr[i].split("=");
  182.                         var elem = document.createElement("input");
  183.                         elem.type = "hidden";
  184.                         elem.name = tmp[0];
  185.                         elem.value = tmp[1];
  186.                         document.forms.historyForm.appendChild(elem);
  187.                     }
  188.                     document.forms.historyForm.submit();
  189.                 } else {
  190.                     top.location.hash = flexAppUrl;
  191.                 }
  192.                 // We also have to maintain the history by hand for Safari
  193.                 historyHash[history.length] = flexAppUrl;
  194.                 _storeStates();
  195.             } else {
  196.                 // Otherwise, write an anchor into the page and tell the browser to go there
  197.                 addAnchor(flexAppUrl);
  198.                 setHash(flexAppUrl);
  199.             }
  200.         }
  201.         backStack.push(createState(baseUrl, newUrl, flexAppUrl));
  202.     }
  203.     function _storeStates() {
  204.         if (browser.safari) {
  205.             getRememberElement().value = historyHash.join(",");
  206.         }
  207.     }
  208.     function handleBackButton() {
  209.         //The "current" page is always at the top of the history stack.
  210.         var current = backStack.pop();
  211.         if (!current) { return; }
  212.         var last = backStack[backStack.length - 1];
  213.         if (!last && backStack.length == 0){
  214.             last = initialState;
  215.         }
  216.         forwardStack.push(current);
  217.     }
  218.     function handleForwardButton() {
  219.         //summary: private method. Do not call this directly.
  220.         var last = forwardStack.pop();
  221.         if (!last) { return; }
  222.         backStack.push(last);
  223.     }
  224.     function handleArbitraryUrl() {
  225.         //delete all the history entries
  226.         forwardStack = [];
  227.     }
  228.     /* Called periodically to poll to see if we need to detect navigation that has occurred */
  229.     function checkForUrlChange() {
  230.         if (browser.ie) {
  231.             if (currentHref != document.location.href && currentHref + '#' != document.location.href) {
  232.                 //This occurs when the user has navigated to a specific URL
  233.                 //within the app, and didn't use browser back/forward
  234.                 //IE seems to have a bug where it stops updating the URL it
  235.                 //shows the end-user at this point, but programatically it
  236.                 //appears to be correct.  Do a full app reload to get around
  237.                 //this issue.
  238.                 if (browser.version < 7) {
  239.                     currentHref = document.location.href;
  240.                     document.location.reload();
  241.                 } else {
  242. if (getHash() != getIframeHash()) {
  243. // this.iframe.src = this.blankURL + hash;
  244. var sourceToSet = historyFrameSourcePrefix + getHash();
  245. getHistoryFrame().src = sourceToSet;
  246. }
  247.                 }
  248.             }
  249.         }
  250.         if (browser.safari) {
  251.             // For Safari, we have to check to see if history.length changed.
  252.             if (currentHistoryLength >= 0 && history.length != currentHistoryLength) {
  253.                 //alert("did change: " + history.length + ", " + historyHash.length + "|" + historyHash[history.length] + "|>" + historyHash.join("|"));
  254.                 // If it did change, then we have to look the old state up
  255.                 // in our hand-maintained array since document.location.hash
  256.                 // won't have changed, then call back into BrowserManager.
  257.                 currentHistoryLength = history.length;
  258.                 var flexAppUrl = historyHash[currentHistoryLength];
  259.                 if (flexAppUrl == '') {
  260.                     //flexAppUrl = defaultHash;
  261.                 }
  262.                 //ADR: to fix multiple
  263.                 if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
  264.                     var pl = getPlayers();
  265.                     for (var i = 0; i < pl.length; i++) {
  266.                         pl[i].browserURLChange(flexAppUrl);
  267.                     }
  268.                 } else {
  269.                     getPlayer().browserURLChange(flexAppUrl);
  270.                 }
  271.                 _storeStates();
  272.             }
  273.         }
  274.         if (browser.firefox) {
  275.             if (currentHref != document.location.href) {
  276.                 var bsl = backStack.length;
  277.                 var urlActions = {
  278.                     back: false, 
  279.                     forward: false, 
  280.                     set: false
  281.                 }
  282.                 if ((window.location.hash == initialHash || window.location.href == initialHref) && (bsl == 1)) {
  283.                     urlActions.back = true;
  284.                     // FIXME: could this ever be a forward button?
  285.                     // we can't clear it because we still need to check for forwards. Ugg.
  286.                     // clearInterval(this.locationTimer);
  287.                     handleBackButton();
  288.                 }
  289.                 
  290.                 // first check to see if we could have gone forward. We always halt on
  291.                 // a no-hash item.
  292.                 if (forwardStack.length > 0) {
  293.                     if (forwardStack[forwardStack.length-1].flexAppUrl == getHash()) {
  294.                         urlActions.forward = true;
  295.                         handleForwardButton();
  296.                     }
  297.                 }
  298.                 // ok, that didn't work, try someplace back in the history stack
  299.                 if ((bsl >= 2) && (backStack[bsl - 2])) {
  300.                     if (backStack[bsl - 2].flexAppUrl == getHash()) {
  301.                         urlActions.back = true;
  302.                         handleBackButton();
  303.                     }
  304.                 }
  305.                 
  306.                 if (!urlActions.back && !urlActions.forward) {
  307.                     var foundInStacks = {
  308.                         back: -1, 
  309.                         forward: -1
  310.                     }
  311.                     for (var i = 0; i < backStack.length; i++) {
  312.                         if (backStack[i].flexAppUrl == getHash() && i != (bsl - 2)) {
  313.                             arbitraryUrl = true;
  314.                             foundInStacks.back = i;
  315.                         }
  316.                     }
  317.                     for (var i = 0; i < forwardStack.length; i++) {
  318.                         if (forwardStack[i].flexAppUrl == getHash() && i != (bsl - 2)) {
  319.                             arbitraryUrl = true;
  320.                             foundInStacks.forward = i;
  321.                         }
  322.                     }
  323.                     handleArbitraryUrl();
  324.                 }
  325.                 // Firefox changed; do a callback into BrowserManager to tell it.
  326.                 currentHref = document.location.href;
  327.                 var flexAppUrl = getHash();
  328.                 if (flexAppUrl == '') {
  329.                     //flexAppUrl = defaultHash;
  330.                 }
  331.                 //ADR: to fix multiple
  332.                 if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
  333.                     var pl = getPlayers();
  334.                     for (var i = 0; i < pl.length; i++) {
  335.                         pl[i].browserURLChange(flexAppUrl);
  336.                     }
  337.                 } else {
  338.                     getPlayer().browserURLChange(flexAppUrl);
  339.                 }
  340.             }
  341.         }
  342.         //setTimeout(checkForUrlChange, 50);
  343.     }
  344.     /* Write an anchor into the page to legitimize it as a URL for Firefox et al. */
  345.     function addAnchor(flexAppUrl)
  346.     {
  347.        if (document.getElementsByName(flexAppUrl).length == 0) {
  348.            getAnchorElement().innerHTML += "<a name='" + flexAppUrl + "'>" + flexAppUrl + "</a>";
  349.        }
  350.     }
  351.     var _initialize = function () {
  352.         if (browser.ie)
  353.         {
  354.             var scripts = document.getElementsByTagName('script');
  355.             for (var i = 0, s; s = scripts[i]; i++) {
  356.                 if (s.src.indexOf("history.js") > -1) {
  357.                     var iframe_location = (new String(s.src)).replace("history.js", "historyFrame.html");
  358.                 }
  359.             }
  360.             historyFrameSourcePrefix = iframe_location + "?";
  361.             var src = historyFrameSourcePrefix;
  362.             var iframe = document.createElement("iframe");
  363.             iframe.id = 'ie_historyFrame';
  364.             iframe.name = 'ie_historyFrame';
  365.             //iframe.src = historyFrameSourcePrefix;
  366.             try {
  367.                 document.body.appendChild(iframe);
  368.             } catch(e) {
  369.                 setTimeout(function() {
  370.                     document.body.appendChild(iframe);
  371.                 }, 0);
  372.             }
  373.         }
  374.         if (browser.safari)
  375.         {
  376.             var rememberDiv = document.createElement("div");
  377.             rememberDiv.id = 'safari_rememberDiv';
  378.             document.body.appendChild(rememberDiv);
  379.             rememberDiv.innerHTML = '<input type="text" id="safari_remember_field" style="width: 500px;">';
  380.             var formDiv = document.createElement("div");
  381.             formDiv.id = 'safari_formDiv';
  382.             document.body.appendChild(formDiv);
  383.             var reloader_content = document.createElement('div');
  384.             reloader_content.id = 'safarireloader';
  385.             var scripts = document.getElementsByTagName('script');
  386.             for (var i = 0, s; s = scripts[i]; i++) {
  387.                 if (s.src.indexOf("history.js") > -1) {
  388.                     html = (new String(s.src)).replace(".js", ".html");
  389.                 }
  390.             }
  391.             reloader_content.innerHTML = '<iframe id="safarireloader-iframe" src="about:blank" frameborder="no" scrolling="no"></iframe>';
  392.             document.body.appendChild(reloader_content);
  393.             reloader_content.style.position = 'absolute';
  394.             reloader_content.style.left = reloader_content.style.top = '-9999px';
  395.             iframe = reloader_content.getElementsByTagName('iframe')[0];
  396.             if (document.getElementById("safari_remember_field").value != "" ) {
  397.                 historyHash = document.getElementById("safari_remember_field").value.split(",");
  398.             }
  399.         }
  400.         if (browser.firefox)
  401.         {
  402.             var anchorDiv = document.createElement("div");
  403.             anchorDiv.id = 'firefox_anchorDiv';
  404.             document.body.appendChild(anchorDiv);
  405.         }
  406.         
  407.         //setTimeout(checkForUrlChange, 50);
  408.     }
  409.     return {
  410.         historyHash: historyHash, 
  411.         backStack: function() { return backStack; }, 
  412.         forwardStack: function() { return forwardStack }, 
  413.         getPlayer: getPlayer, 
  414.         initialize: function(src) {
  415.             _initialize(src);
  416.         }, 
  417.         setURL: function(url) {
  418.             document.location.href = url;
  419.         }, 
  420.         getURL: function() {
  421.             return document.location.href;
  422.         }, 
  423.         getTitle: function() {
  424.             return document.title;
  425.         }, 
  426.         setTitle: function(title) {
  427.             try {
  428.                 backStack[backStack.length - 1].title = title;
  429.             } catch(e) { }
  430.             //if on safari, set the title to be the empty string. 
  431.             if (browser.safari) {
  432.                 if (title == "") {
  433.                     try {
  434.                     var tmp = window.location.href.toString();
  435.                     title = tmp.substring((tmp.lastIndexOf("/")+1), tmp.lastIndexOf("#"));
  436.                     } catch(e) {
  437.                         title = "";
  438.                     }
  439.                 }
  440.             }
  441.             document.title = title;
  442.         }, 
  443.         setDefaultURL: function(def)
  444.         {
  445.             defaultHash = def;
  446.             def = getHash();
  447.             //trailing ? is important else an extra frame gets added to the history
  448.             //when navigating back to the first page.  Alternatively could check
  449.             //in history frame navigation to compare # and ?.
  450.             if (browser.ie)
  451.             {
  452.                 window['_ie_firstload'] = true;
  453.                 var sourceToSet = historyFrameSourcePrefix + def;
  454.                 var func = function() {
  455.                     getHistoryFrame().src = sourceToSet;
  456.                     window.location.replace("#" + def);
  457.                     setInterval(checkForUrlChange, 50);
  458.                 }
  459.                 try {
  460.                     func();
  461.                 } catch(e) {
  462.                     window.setTimeout(function() { func(); }, 0);
  463.                 }
  464.             }
  465.             if (browser.safari)
  466.             {
  467.                 currentHistoryLength = history.length;
  468.                 if (historyHash.length == 0) {
  469.                     historyHash[currentHistoryLength] = def;
  470.                     var newloc = "#" + def;
  471.                     window.location.replace(newloc);
  472.                 } else {
  473.                     //alert(historyHash[historyHash.length-1]);
  474.                 }
  475.                 //setHash(def);
  476.                 setInterval(checkForUrlChange, 50);
  477.             }
  478.             
  479.             
  480.             if (browser.firefox || browser.opera)
  481.             {
  482.                 var reg = new RegExp("#" + def + "$");
  483.                 if (window.location.toString().match(reg)) {
  484.                 } else {
  485.                     var newloc ="#" + def;
  486.                     window.location.replace(newloc);
  487.                 }
  488.                 setInterval(checkForUrlChange, 50);
  489.                 //setHash(def);
  490.             }
  491.         }, 
  492.         /* Set the current browser URL; called from inside BrowserManager to propagate
  493.          * the application state out to the container.
  494.          */
  495.         setBrowserURL: function(flexAppUrl, objectId) {
  496.             if (browser.ie && typeof objectId != "undefined") {
  497.                 currentObjectId = objectId;
  498.             }
  499.            //fromIframe = fromIframe || false;
  500.            //fromFlex = fromFlex || false;
  501.            //alert("setBrowserURL: " + flexAppUrl);
  502.            //flexAppUrl = (flexAppUrl == "") ? defaultHash : flexAppUrl ;
  503.            var pos = document.location.href.indexOf('#');
  504.            var baseUrl = pos != -1 ? document.location.href.substr(0, pos) : document.location.href;
  505.            var newUrl = baseUrl + '#' + flexAppUrl;
  506.            if (document.location.href != newUrl && document.location.href + '#' != newUrl) {
  507.                currentHref = newUrl;
  508.                addHistoryEntry(baseUrl, newUrl, flexAppUrl);
  509.                currentHistoryLength = history.length;
  510.            }
  511.            return false;
  512.         }, 
  513.         browserURLChange: function(flexAppUrl) {
  514.             var objectId = null;
  515.             if (browser.ie && currentObjectId != null) {
  516.                 objectId = currentObjectId;
  517.             }
  518.             pendingURL = '';
  519.             
  520.             if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
  521.                 var pl = getPlayers();
  522.                 for (var i = 0; i < pl.length; i++) {
  523.                     try {
  524.                         pl[i].browserURLChange(flexAppUrl);
  525.                     } catch(e) { }
  526.                 }
  527.             } else {
  528.                 try {
  529.                     getPlayer(objectId).browserURLChange(flexAppUrl);
  530.                 } catch(e) { }
  531.             }
  532.             currentObjectId = null;
  533.         }
  534.     }
  535. })();
  536. // Initialization
  537. // Automated unit testing and other diagnostics
  538. function setURL(url)
  539. {
  540.     document.location.href = url;
  541. }
  542. function backButton()
  543. {
  544.     history.back();
  545. }
  546. function forwardButton()
  547. {
  548.     history.forward();
  549. }
  550. function goForwardOrBackInHistory(step)
  551. {
  552.     history.go(step);
  553. }
  554. //BrowserHistoryUtils.addEvent(window, "load", function() { BrowserHistory.initialize(); });
  555. (function(i) {
  556.     var u =navigator.userAgent;var e=/*@cc_on!@*/false; 
  557.     var st = setTimeout;
  558.     if(/webkit/i.test(u)){
  559.         st(function(){
  560.             var dr=document.readyState;
  561.             if(dr=="loaded"||dr=="complete"){i()}
  562.             else{st(arguments.callee,10);}},10);
  563.     } else if((/mozilla/i.test(u)&&!/(compati)/.test(u)) || (/opera/i.test(u))){
  564.         document.addEventListener("DOMContentLoaded",i,false);
  565.     } else if(e){
  566.     (function(){
  567.         var t=document.createElement('doc:rdy');
  568.         try{t.doScroll('left');
  569.             i();t=null;
  570.         }catch(e){st(arguments.callee,0);}})();
  571.     } else{
  572.         window.onload=i;
  573.     }
  574. })( function() {BrowserHistory.initialize();} );