history.js
上传用户:jqyjoan
上传日期:2018-02-02
资源大小:1773k
文件大小:24k
源码类别:

Ajax

开发平台:

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