I have a script that opens a popunder when any link is clicked. How can I change this to open the popunder when the page loads. Below is the script.
window.onload = function() {
var puURL = 'http://www.example.com';
var puTS = Math.round(+new Date()/1000);
console.log('T.'+localStorage.puTS+'/'+puTS);
if (typeof localStorage.puTS == 'undefined' || parseInt(localStorage.puTS) <= (puTS - 180)) {
var links = document.getElementsByTagName('a');
for(var i = 0, len = links.length; i < len; i++) {
links[i].onclick = function (e) {
var puHref = this.getAttribute("href");
var puTarget = this.getAttribute("target");
if (puHref !== '#' && puHref !== 'javascript:void(0)') {
e.preventDefault();
if (puTarget == '_blank') {
window.open(window.location.href);
}
window.open(puHref);
window.location.href = puURL;
localStorage.puTS = puTS;
}
}
}
}
};
Well, currently you're adding click handlers for all the target elements:
for(var i = 0, len = links.length; i < len; i++) {
links[i].onclick = function (e) { // <--- here
var puHref = this.getAttribute("href");
var puTarget = this.getAttribute("target");
if (puHref !== '#' && puHref !== 'javascript:void(0)') {
e.preventDefault();
if (puTarget == '_blank') {
window.open(window.location.href);
}
window.open(puHref);
window.location.href = puURL;
localStorage.puTS = puTS;
}
}
}
If you don't want to add click handlers but just want to invoke the logic within them right away, just put that logic in the loop without the click handler:
for(var i = 0, len = links.length; i < len; i++) {
var puHref = this.getAttribute("href");
var puTarget = this.getAttribute("target");
if (puHref !== '#' && puHref !== 'javascript:void(0)') {
if (puTarget == '_blank') {
window.open(window.location.href);
}
window.open(puHref);
window.location.href = puURL;
localStorage.puTS = puTS;
}
}
Of course, if this logic includes opening a new page or redirecting the user then that's going to happen immediately upon page load...
Related
I just started learning JavaScript, and I am trying to get two different EventListeners to do the opposite function. Right now, I have it so that you can click on a mark and then a word, letter, or space and the mark appears/disappears there. I want to be able to click a word, letter, or space then click on a mark to add/remove it. Sentence Punctuation Marks I've tried switching the .querySelector and .querySelectorAll, but that doesn't work. Any help would be much appreciated.
var classlist = el.querySelectorAll(".letter, .space");
for (var i = 0; i < classlist.length; i++) {
classlist[i].addEventListener("click", function(event) {
var element = this.parentNode;
console.log(this);
if (
tooltype === "longVowel" ||
tooltype === "shortVowel" ||
this.classList.contains("space") === true
) {
element = this;
console.log(element);
}
var add = true;
var checklist = element.querySelectorAll("." + tooltype);
if (checklist.length > 0) {
add = false;
}
socket0s6.emit("action", {
slide: demo6,
action: "markingWords",
element: element.id,
class: tooltype,
add: add,
});
});
}
var classlist = el.querySelector(".toolbar").querySelectorAll("li");
for (var i = 0; i < classlist.length; i++) {
classlist[i].addEventListener("click", function(event) {
tooltype = this.className;
});
}
document.getElementById("slideContainer").appendChild(el);
/*}
//var oReq = new XMLHttpRequest();
//oReq.addEventListener("load", reqListener);
//oReq.open("GET", "slides/lesson0/slide6.html");
//oReq.send();*/
/*************** Server action ******************/
//socket0s6.on('action', function(details) {
var socket0s6 = {
emit: function(a, details) {
// //console.log(details[1]);
if (details.slide === demo6 && details.action === "markingWords") {
//document.getElementById(details.element).classList.toggle("active");
if (details.add) {
var el = document.createElement("span");
el.className = details.class;
document.getElementById(details.element).appendChild(el);
} else {
//where we will put code to find and remove existing marks
var markList = document
.getElementById(details.element)
.querySelectorAll("." + details.class);
console.log(markList);
for (var i = 0; i < markList.length; i++) {
markList[i].parentNode.removeChild(markList[i]);
}
}
}
},
};
I am trying to bind photoswipe so that it continues to work even if a div is loaded, has anyone done this before or can tell how to do this?
I tried changing the
galleryElements[i].onclick = onThumbnailsClick;
line to a binding on click statement to #container. This worked until i clicked off the slideshow which then killed all other click events on the page and left a thumbnail stuck in the middle of the screen. any ideas?
Here is the photoswipe JS:
var initPhotoSwipeFromDOM = function(gallerySelector) {
// parse slide data (url, title, size ...) from DOM elements
// (children of gallerySelector)
var parseThumbnailElements = function(el) {
var thumbElements = el.childNodes,
numNodes = thumbElements.length,
items = [],
figureEl,
linkEl,
size,
item;
for(var i = 0; i < numNodes; i++) {
figureEl = thumbElements[i]; // <figure> element
// include only element nodes
if(figureEl.nodeType !== 1) {
continue;
}
linkEl = figureEl.children[0]; // <a> element
size = linkEl.getAttribute('data-size').split('x');
// create slide object
item = {
src: linkEl.getAttribute('href'),
w: parseInt(size[0], 10),
h: parseInt(size[1], 10)
};
if(figureEl.children.length > 1) {
// <figcaption> content
item.title = figureEl.children[1].innerHTML;
}
if(linkEl.children.length > 0) {
// <img> thumbnail element, retrieving thumbnail url
item.msrc = linkEl.children[0].getAttribute('src');
}
item.el = figureEl; // save link to element for getThumbBoundsFn
items.push(item);
}
return items;
};
// find nearest parent element
var closest = function closest(el, fn) {
return el && ( fn(el) ? el : closest(el.parentNode, fn) );
};
// triggers when user clicks on thumbnail
var onThumbnailsClick = function(e) {
e = e || window.event;
e.preventDefault ? e.preventDefault() : e.returnValue = false;
var eTarget = e.target || e.srcElement;
// find root element of slide
var clickedListItem = closest(eTarget, function(el) {
return (el.tagName && el.tagName.toUpperCase() === 'FIGURE');
});
if(!clickedListItem) {
return;
}
// find index of clicked item by looping through all child nodes
// alternatively, you may define index via data- attribute
var clickedGallery = clickedListItem.parentNode,
childNodes = clickedListItem.parentNode.childNodes,
numChildNodes = childNodes.length,
nodeIndex = 0,
index;
for (var i = 0; i < numChildNodes; i++) {
if(childNodes[i].nodeType !== 1) {
continue;
}
if(childNodes[i] === clickedListItem) {
index = nodeIndex;
break;
}
nodeIndex++;
}
if(index >= 0) {
// open PhotoSwipe if valid index found
openPhotoSwipe( index, clickedGallery );
}
return false;
};
// parse picture index and gallery index from URL (#&pid=1&gid=2)
var photoswipeParseHash = function() {
var hash = window.location.hash.substring(1),
params = {};
if(hash.length < 5) {
return params;
}
var vars = hash.split('&');
for (var i = 0; i < vars.length; i++) {
if(!vars[i]) {
continue;
}
var pair = vars[i].split('=');
if(pair.length < 2) {
continue;
}
params[pair[0]] = pair[1];
}
if(params.gid) {
params.gid = parseInt(params.gid, 10);
}
return params;
};
var openPhotoSwipe = function(index, galleryElement, disableAnimation, fromURL) {
var pswpElement = document.querySelectorAll('.pswp')[0],
gallery,
options,
items;
items = parseThumbnailElements(galleryElement);
// define options (if needed)
options = {
// define gallery index (for URL)
galleryUID: galleryElement.getAttribute('data-pswp-uid'),
getThumbBoundsFn: function(index) {
// See Options -> getThumbBoundsFn section of documentation for more info
var thumbnail = items[index].el.getElementsByTagName('img')[0], // find thumbnail
pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
rect = thumbnail.getBoundingClientRect();
return {x:rect.left, y:rect.top + pageYScroll, w:rect.width};
}
};
// PhotoSwipe opened from URL
if(fromURL) {
if(options.galleryPIDs) {
// parse real index when custom PIDs are used
// http://photoswipe.com/documentation/faq.html#custom-pid-in-url
for(var j = 0; j < items.length; j++) {
if(items[j].pid == index) {
options.index = j;
break;
}
}
} else {
// in URL indexes start from 1
options.index = parseInt(index, 10) - 1;
}
} else {
options.index = parseInt(index, 10);
}
// exit if index not found
if( isNaN(options.index) ) {
return;
}
if(disableAnimation) {
options.showAnimationDuration = 0;
}
// Pass data to PhotoSwipe and initialize it
gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options);
gallery.init();
};
// loop through all gallery elements and bind events
var galleryElements = document.querySelectorAll( gallerySelector );
for(var i = 0, l = galleryElements.length; i < l; i++) {
galleryElements[i].setAttribute('data-pswp-uid', i+1);
galleryElements[i].onclick = onThumbnailsClick;
}
// Parse URL and open gallery if it contains #&pid=3&gid=1
var hashData = photoswipeParseHash();
if(hashData.pid && hashData.gid) {
openPhotoSwipe( hashData.pid , galleryElements[ hashData.gid - 1 ], true, true );
}
};
// execute above function
initPhotoSwipeFromDOM('.my-gallery');
I've written a small wrapper for PhotoSwipe in jQuery that lets you use dom elements to convert to gallery. It also does not require you to define image dimensions, just autodetects by itself. Check it out.
https://ergec.github.io/jQuery-for-PhotoSwipe/
I'd like to write a script for google docs to automatically highlight a set of words.
For one word I could use a script like this:
function myFunction() {
var doc = DocumentApp.openById('ID');
var textToHighlight = "TEST"
var highlightStyle = {};
highlightStyle[DocumentApp.Attribute.FOREGROUND_COLOR] = '#FF0000';
var paras = doc.getParagraphs();
var textLocation = {};
var i;
for (i=0; i<paras.length; ++i) {
textLocation = paras[i].findText(textToHighlight);
if (textLocation != null && textLocation.getStartOffset() != -1) {
textLocation.getElement().setAttributes(textLocation.getStartOffset(),textLocation.getEndOffsetInclusive(), highlightStyle);
}
}
}
But I need to search the text for a set of many more words and highlight them. (this is the list: https://conterest.de/fuellwoerter-liste-worte/)
How do I write a script for more words?
This seems to be a little bit too complicated:
function myFunction() {
var doc = DocumentApp.openById('ID');
var textToHighlight = "TEST"
var textToHighlight1 = "TEST1"
var highlightStyle = {};
highlightStyle[DocumentApp.Attribute.FOREGROUND_COLOR] = '#FF0000';
var paras = doc.getParagraphs();
var textLocation = {};
var i;
for (i=0; i<paras.length; ++i) {
textLocation = paras[i].findText(textToHighlight);
if (textLocation != null && textLocation.getStartOffset() != -1) {
textLocation.getElement().setAttributes(textLocation.getStartOffset(),textLocation.getEndOffsetInclusive(), highlightStyle);
}
}
for (i=0; i<paras.length; ++i) {
textLocation = paras[i].findText(textToHighlight1);
if (textLocation != null && textLocation.getStartOffset() != -1) {
textLocation.getElement().setAttributes(textLocation.getStartOffset(),textLocation.getEndOffsetInclusive(), highlightStyle);
}
}
}
Thanks for your help!
You could use a nested for loop:
var words = ['TEST', 'TEST1'];
// For every word in words:
for (w = 0; w < words.length; ++w) {
// Get the current word:
var textToHighlight = words[w];
// Here is your code again:
for (i = 0; i < paras.length; ++i) {
textLocation = paras[i].findText(textToHighlight);
if (textLocation != null && textLocation.getStartOffset() != -1) {
textLocation.getElement().setAttributes(textLocation.getStartOffset(), textLocation.getEndOffsetInclusive(), highlightStyle);
}
}
}
This way you can easily extend the array words with more words.
In my website (http://urlsaf.com/m8) I already added one Ajax based rating system but this system is not working properly. When ever I rate it, It's reloaded the page. In my past this Ajax based rating system was rated successfully without reload the page using XMLHttpRequest. Below I will give my rating.js and behavior.js for your reference. Anyone please give the solution for my Ajax conflict error. Thanks in advance.
1.rating.js
var xmlhttp if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
try {
xmlhttp = new XMLHttpRequest();
} catch (e) {
xmlhttp=false
}
}
function myXMLHttpRequest() {
var xmlhttplocal;
try {
xmlhttplocal= new ActiveXObject("Msxml2.XMLHTTP")
} catch (e) {
try {
xmlhttplocal= new ActiveXObject("Microsoft.XMLHTTP")
} catch (E) {
xmlhttplocal=false;
}
}
if (!xmlhttplocal && typeof XMLHttpRequest!='undefined') {
try {
var xmlhttplocal = new XMLHttpRequest();
} catch (e) {
var xmlhttplocal=false;
alert('couldn\'t create xmlhttp object');
}
}
return(xmlhttplocal);
}
function sndReq(vote,id_num,ip_num,units) {
var theUL = document.getElementById('unit_ul'+id_num); // the UL
// switch UL with a loading div
theUL.innerHTML = '<div class="loading"></div>';
xmlhttp.open('get', 'rpc.php?j='+vote+'&q='+id_num+'&t='+ip_num+'&c='+units);
xmlhttp.onreadystatechange = handleResponse;
xmlhttp.send(null);
}
function handleResponse() {
if(xmlhttp.readyState == 4){
if (xmlhttp.status == 200){
var response = xmlhttp.responseText;
var update = new Array();
if(response.indexOf('|') != -1) {
update = response.split('|');
changeText(update[0], update[1]);
}
}
}
}
function changeText( div2show, text ) {
// Detect Browser
var IE = (document.all) ? 1 : 0;
var DOM = 0;
if (parseInt(navigator.appVersion) >=5) {DOM=1};
// Grab the content from the requested "div" and show it in the "container"
if (DOM) {
var viewer = document.getElementById(div2show);
viewer.innerHTML = text;
} else if(IE) {
document.all[div2show].innerHTML = text;
}
}
/* =============================================================== */
var ratingAction = {
'a.rater' : function(element){
element.onclick = function(){
var parameterString = this.href.replace(/.*\?(.*)/, "$1"); // onclick="sndReq('j=1&q=2&t=127.0.0.1&c=5');
var parameterTokens = parameterString.split("&"); // onclick="sndReq('j=1,q=2,t=127.0.0.1,c=5');
var parameterList = new Array();
for (j = 0; j < parameterTokens.length; j++) {
var parameterName = parameterTokens[j].replace(/(.*)=.*/, "$1"); // j
var parameterValue = parameterTokens[j].replace(/.*=(.*)/, "$1"); // 1
parameterList[parameterName] = parameterValue;
}
var theratingID = parameterList['q'];
var theVote = parameterList['j'];
var theuserIP = parameterList['t'];
var theunits = parameterList['c'];
//for testing alert('sndReq('+theVote+','+theratingID+','+theuserIP+','+theunits+')'); return false;
sndReq(theVote,theratingID,theuserIP,theunits); return false;
}
}
};
Behaviour.register(ratingAction);
2.behavior.js
var Behaviour = {
list : new Array,
register : function(sheet){
Behaviour.list.push(sheet);
},
start : function(){
Behaviour.addLoadEvent(function(){
Behaviour.apply();
});
},
apply : function(){
for (h=0;sheet=Behaviour.list[h];h++){
for (selector in sheet){
list = document.getElementsBySelector(selector);
if (!list){
continue;
}
for (i=0;element=list[i];i++){
sheet[selector](element);
}
}
}
},
addLoadEvent : function(func){
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}
}
Behaviour.start();
function getAllChildren(e) {
// Returns all children of element. Workaround required for IE5/Windows. Ugh.
return e.all ? e.all : e.getElementsByTagName('*');
}
document.getElementsBySelector = function(selector) {
// Attempt to fail gracefully in lesser browsers
if (!document.getElementsByTagName) {
return new Array();
}
// Split selector in to tokens
var tokens = selector.split(' ');
var currentContext = new Array(document);
for (var i = 0; i < tokens.length; i++) {
token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');;
if (token.indexOf('#') > -1) {
// Token is an ID selector
var bits = token.split('#');
var tagName = bits[0];
var id = bits[1];
var element = document.getElementById(id);
if (tagName && element.nodeName.toLowerCase() != tagName) {
// tag with that ID not found, return false
return new Array();
}
// Set currentContext to contain just this element
currentContext = new Array(element);
continue; // Skip to next token
}
if (token.indexOf('.') > -1) {
// Token contains a class selector
var bits = token.split('.');
var tagName = bits[0];
var className = bits[1];
if (!tagName) {
tagName = '*';
}
// Get elements matching tag, filter them for class selector
var found = new Array;
var foundCount = 0;
for (var h = 0; h < currentContext.length; h++) {
var elements;
if (tagName == '*') {
elements = getAllChildren(currentContext[h]);
} else {
elements = currentContext[h].getElementsByTagName(tagName);
}
for (var j = 0; j < elements.length; j++) {
found[foundCount++] = elements[j];
}
}
currentContext = new Array;
var currentContextIndex = 0;
for (var k = 0; k < found.length; k++) {
if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) {
currentContext[currentContextIndex++] = found[k];
}
}
continue; // Skip to next token
}
// Code to deal with attribute selectors
if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
var tagName = RegExp.$1;
var attrName = RegExp.$2;
var attrOperator = RegExp.$3;
var attrValue = RegExp.$4;
if (!tagName) {
tagName = '*';
}
// Grab all of the tagName elements within current context
var found = new Array;
var foundCount = 0;
for (var h = 0; h < currentContext.length; h++) {
var elements;
if (tagName == '*') {
elements = getAllChildren(currentContext[h]);
} else {
elements = currentContext[h].getElementsByTagName(tagName);
}
for (var j = 0; j < elements.length; j++) {
found[foundCount++] = elements[j];
}
}
currentContext = new Array;
var currentContextIndex = 0;
var checkFunction; // This function will be used to filter the elements
switch (attrOperator) {
case '=': // Equality
checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
break;
case '~': // Match one of space seperated words
checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
break;
case '|': // Match start with value followed by optional hyphen
checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
break;
case '^': // Match starts with value
checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
break;
case '$': // Match ends with value - fails with "Warning" in Opera 7
checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
break;
case '*': // Match ends with value
checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
break;
default :
// Just test for existence of attribute
checkFunction = function(e) { return e.getAttribute(attrName); };
}
currentContext = new Array;
var currentContextIndex = 0;
for (var k = 0; k < found.length; k++) {
if (checkFunction(found[k])) {
currentContext[currentContextIndex++] = found[k];
}
}
// alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue);
continue; // Skip to next token
}
if (!currentContext[0]){
return;
}
// If we get here, token is JUST an element (not a class or ID selector)
tagName = token;
var found = new Array;
var foundCount = 0;
for (var h = 0; h < currentContext.length; h++) {
var elements = currentContext[h].getElementsByTagName(tagName);
for (var j = 0; j < elements.length; j++) {
found[foundCount++] = elements[j];
}
}
currentContext = found;
}
return currentContext;
}
/* That revolting regular expression explained
/^(\w+)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/
\---/ \---/\-------------/ \-------/
| | | |
| | | The value
| | ~,|,^,$,* or =
| Attribute
Tag
*/
I have a javascript file for history management. It is not supported by chrome when i am trying to navigate to back page with back button in the browser.I can see the url change but it doesnt go to preceeding page.
BrowserHistoryUtils = {
addEvent: function(elm, evType, fn, useCapture) {
useCapture = useCapture || false;
if (elm.addEventListener) {
elm.addEventListener(evType, fn, useCapture);
return true;
}
else if (elm.attachEvent) {
var r = elm.attachEvent('on' + evType, fn);
return r;
}
else {
elm['on' + evType] = fn;
}
}
}
BrowserHistory = (function() {
// type of browser
var browser = {
ie: false,
firefox: false,
safari: false,
opera: false,
version: -1
};
// if setDefaultURL has been called, our first clue
// that the SWF is ready and listening
//var swfReady = false;
// the URL we'll send to the SWF once it is ready
//var pendingURL = '';
// Default app state URL to use when no fragment ID present
var defaultHash = '';
// Last-known app state URL
var currentHref = document.location.href;
// Initial URL (used only by IE)
var initialHref = document.location.href;
// Initial URL (used only by IE)
var initialHash = document.location.hash;
// History frame source URL prefix (used only by IE)
var historyFrameSourcePrefix = 'history/historyFrame.html?';
// History maintenance (used only by Safari)
var currentHistoryLength = -1;
var historyHash = [];
var initialState = createState(initialHref, initialHref + '#' + initialHash, initialHash);
var backStack = [];
var forwardStack = [];
var currentObjectId = null;
//UserAgent detection
var useragent = navigator.userAgent.toLowerCase();
if (useragent.indexOf("opera") != -1) {
browser.opera = true;
} else if (useragent.indexOf("msie") != -1) {
browser.ie = true;
browser.version = parseFloat(useragent.substring(useragent.indexOf('msie') + 4));
} else if (useragent.indexOf("safari") != -1) {
browser.safari = true;
browser.version = parseFloat(useragent.substring(useragent.indexOf('safari') + 7));
} else if (useragent.indexOf("gecko") != -1) {
browser.firefox = true;
}
if (browser.ie == true && browser.version == 7) {
window["_ie_firstload"] = false;
}
// Accessor functions for obtaining specific elements of the page.
function getHistoryFrame()
{
return document.getElementById('ie_historyFrame');
}
function getAnchorElement()
{
return document.getElementById('firefox_anchorDiv');
}
function getFormElement()
{
return document.getElementById('safari_formDiv');
}
function getRememberElement()
{
return document.getElementById("safari_remember_field");
}
// Get the Flash player object for performing ExternalInterface callbacks.
// Updated for changes to SWFObject2.
function getPlayer(id) {
if (id && document.getElementById(id)) {
var r = document.getElementById(id);
if (typeof r.SetVariable != "undefined") {
return r;
}
else {
var o = r.getElementsByTagName("object");
var e = r.getElementsByTagName("embed");
if (o.length > 0 && typeof o[0].SetVariable != "undefined") {
return o[0];
}
else if (e.length > 0 && typeof e[0].SetVariable != "undefined") {
return e[0];
}
}
}
else {
var o = document.getElementsByTagName("object");
var e = document.getElementsByTagName("embed");
if (e.length > 0 && typeof e[0].SetVariable != "undefined") {
return e[0];
}
else if (o.length > 0 && typeof o[0].SetVariable != "undefined") {
return o[0];
}
else if (o.length > 1 && typeof o[1].SetVariable != "undefined") {
return o[1];
}
}
return undefined;
}
function getPlayers() {
var players = [];
if (players.length == 0) {
var tmp = document.getElementsByTagName('object');
players = tmp;
}
if (players.length == 0 || players[0].object == null) {
var tmp = document.getElementsByTagName('embed');
players = tmp;
}
return players;
}
function getIframeHash() {
var doc = getHistoryFrame().contentWindow.document;
var hash = String(doc.location.search);
if (hash.length == 1 && hash.charAt(0) == "?") {
hash = "";
}
else if (hash.length >= 2 && hash.charAt(0) == "?") {
hash = hash.substring(1);
}
return hash;
}
/* Get the current location hash excluding the '#' symbol. */
function getHash() {
// It would be nice if we could use document.location.hash here,
// but it's faulty sometimes.
var idx = document.location.href.indexOf('#');
return (idx >= 0) ? document.location.href.substr(idx+1) : '';
}
/* Get the current location hash excluding the '#' symbol. */
function setHash(hash) {
// It would be nice if we could use document.location.hash here,
// but it's faulty sometimes.
if (hash == '') hash = '#'
document.location.hash = hash;
}
function createState(baseUrl, newUrl, flexAppUrl) {
return { 'baseUrl': baseUrl, 'newUrl': newUrl, 'flexAppUrl': flexAppUrl, 'title': null };
}
/* Add a history entry to the browser.
* baseUrl: the portion of the location prior to the '#'
* newUrl: the entire new URL, including '#' and following fragment
* flexAppUrl: the portion of the location following the '#' only
*/
function addHistoryEntry(baseUrl, newUrl, flexAppUrl) {
//delete all the history entries
forwardStack = [];
if (browser.ie) {
//Check to see if we are being asked to do a navigate for the first
//history entry, and if so ignore, because it's coming from the creation
//of the history iframe
if (flexAppUrl == defaultHash && document.location.href == initialHref && window['_ie_firstload']) {
currentHref = initialHref;
return;
}
if ((!flexAppUrl || flexAppUrl == defaultHash) && window['_ie_firstload']) {
newUrl = baseUrl + '#' + defaultHash;
flexAppUrl = defaultHash;
} else {
// for IE, tell the history frame to go somewhere without a '#'
// in order to get this entry into the browser history.
getHistoryFrame().src = historyFrameSourcePrefix + flexAppUrl;
}
setHash(flexAppUrl);
} else {
//ADR
if (backStack.length == 0 && initialState.flexAppUrl == flexAppUrl) {
initialState = createState(baseUrl, newUrl, flexAppUrl);
} else if(backStack.length > 0 && backStack[backStack.length - 1].flexAppUrl == flexAppUrl) {
backStack[backStack.length - 1] = createState(baseUrl, newUrl, flexAppUrl);
}
if (browser.safari) {
// for Safari, submit a form whose action points to the desired URL
if (browser.version <= 419.3) {
var file = window.location.pathname.toString();
file = file.substring(file.lastIndexOf("/")+1);
getFormElement().innerHTML = '<form name="historyForm" action="'+file+'#' + flexAppUrl + '" method="GET"></form>';
//get the current elements and add them to the form
var qs = window.location.search.substring(1);
var qs_arr = qs.split("&");
for (var i = 0; i < qs_arr.length; i++) {
var tmp = qs_arr[i].split("=");
var elem = document.createElement("input");
elem.type = "hidden";
elem.name = tmp[0];
elem.value = tmp[1];
document.forms.historyForm.appendChild(elem);
}
document.forms.historyForm.submit();
} else {
top.location.hash = flexAppUrl;
}
// We also have to maintain the history by hand for Safari
historyHash[history.length] = flexAppUrl;
_storeStates();
} else {
// Otherwise, write an anchor into the page and tell the browser to go there
addAnchor(flexAppUrl);
setHash(flexAppUrl);
}
}
backStack.push(createState(baseUrl, newUrl, flexAppUrl));
}
function _storeStates() {
if (browser.safari) {
getRememberElement().value = historyHash.join(",");
}
}
function handleBackButton() {
//The "current" page is always at the top of the history stack.
var current = backStack.pop();
if (!current) { return; }
var last = backStack[backStack.length - 1];
if (!last && backStack.length == 0){
last = initialState;
}
forwardStack.push(current);
}
function handleForwardButton() {
//summary: private method. Do not call this directly.
var last = forwardStack.pop();
if (!last) { return; }
backStack.push(last);
}
function handleArbitraryUrl() {
//delete all the history entries
forwardStack = [];
}
/* Called periodically to poll to see if we need to detect navigation that has occurred */
function checkForUrlChange() {
if (browser.ie) {
if (currentHref != document.location.href && currentHref + '#' != document.location.href) {
//This occurs when the user has navigated to a specific URL
//within the app, and didn't use browser back/forward
//IE seems to have a bug where it stops updating the URL it
//shows the end-user at this point, but programatically it
//appears to be correct. Do a full app reload to get around
//this issue.
if (browser.version < 7) {
currentHref = document.location.href;
document.location.reload();
} else {
if (getHash() != getIframeHash()) {
// this.iframe.src = this.blankURL + hash;
var sourceToSet = historyFrameSourcePrefix + getHash();
getHistoryFrame().src = sourceToSet;
}
}
}
}
if (browser.safari) {
// For Safari, we have to check to see if history.length changed.
if (currentHistoryLength >= 0 && history.length != currentHistoryLength) {
//alert("did change: " + history.length + ", " + historyHash.length + "|" + historyHash[history.length] + "|>" + historyHash.join("|"));
// If it did change, then we have to look the old state up
// in our hand-maintained array since document.location.hash
// won't have changed, then call back into BrowserManager.
currentHistoryLength = history.length;
var flexAppUrl = historyHash[currentHistoryLength];
if (flexAppUrl == '') {
//flexAppUrl = defaultHash;
}
//ADR: to fix multiple
if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
var pl = getPlayers();
for (var i = 0; i < pl.length; i++) {
pl[i].browserURLChange(flexAppUrl);
}
} else {
getPlayer().browserURLChange(flexAppUrl);
}
_storeStates();
}
}
if (browser.firefox) {
if (currentHref != document.location.href) {
var bsl = backStack.length;
var urlActions = {
back: false,
forward: false,
set: false
}
if ((window.location.hash == initialHash || window.location.href == initialHref) && (bsl == 1)) {
urlActions.back = true;
// FIXME: could this ever be a forward button?
// we can't clear it because we still need to check for forwards. Ugg.
// clearInterval(this.locationTimer);
handleBackButton();
}
// first check to see if we could have gone forward. We always halt on
// a no-hash item.
if (forwardStack.length > 0) {
if (forwardStack[forwardStack.length-1].flexAppUrl == getHash()) {
urlActions.forward = true;
handleForwardButton();
}
}
// ok, that didn't work, try someplace back in the history stack
if ((bsl >= 2) && (backStack[bsl - 2])) {
if (backStack[bsl - 2].flexAppUrl == getHash()) {
urlActions.back = true;
handleBackButton();
}
}
if (!urlActions.back && !urlActions.forward) {
var foundInStacks = {
back: -1,
forward: -1
}
for (var i = 0; i < backStack.length; i++) {
if (backStack[i].flexAppUrl == getHash() && i != (bsl - 2)) {
arbitraryUrl = true;
foundInStacks.back = i;
}
}
for (var i = 0; i < forwardStack.length; i++) {
if (forwardStack[i].flexAppUrl == getHash() && i != (bsl - 2)) {
arbitraryUrl = true;
foundInStacks.forward = i;
}
}
handleArbitraryUrl();
}
// Firefox changed; do a callback into BrowserManager to tell it.
currentHref = document.location.href;
var flexAppUrl = getHash();
if (flexAppUrl == '') {
//flexAppUrl = defaultHash;
}
//ADR: to fix multiple
if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
var pl = getPlayers();
for (var i = 0; i < pl.length; i++) {
pl[i].browserURLChange(flexAppUrl);
}
} else {
getPlayer().browserURLChange(flexAppUrl);
}
}
}
//setTimeout(checkForUrlChange, 50);
}
/* Write an anchor into the page to legitimize it as a URL for Firefox et al. */
function addAnchor(flexAppUrl)
{
if (document.getElementsByName(flexAppUrl).length == 0) {
getAnchorElement().innerHTML += "<a name='" + flexAppUrl + "'>" + flexAppUrl + "</a>";
}
}
var _initialize = function () {
if (browser.ie)
{
var scripts = document.getElementsByTagName('script');
for (var i = 0, s; s = scripts[i]; i++) {
if (s.src.indexOf("history.js") > -1) {
var iframe_location = (new String(s.src)).replace("history.js", "historyFrame.html");
}
}
historyFrameSourcePrefix = iframe_location + "?";
var src = historyFrameSourcePrefix;
var iframe = document.createElement("iframe");
iframe.id = 'ie_historyFrame';
iframe.name = 'ie_historyFrame';
//iframe.src = historyFrameSourcePrefix;
try {
document.body.appendChild(iframe);
} catch(e) {
setTimeout(function() {
document.body.appendChild(iframe);
}, 0);
}
}
if (browser.safari)
{
var rememberDiv = document.createElement("div");
rememberDiv.id = 'safari_rememberDiv';
document.body.appendChild(rememberDiv);
rememberDiv.innerHTML = '<input type="text" id="safari_remember_field" style="width: 500px;">';
var formDiv = document.createElement("div");
formDiv.id = 'safari_formDiv';
document.body.appendChild(formDiv);
var reloader_content = document.createElement('div');
reloader_content.id = 'safarireloader';
var scripts = document.getElementsByTagName('script');
for (var i = 0, s; s = scripts[i]; i++) {
if (s.src.indexOf("history.js") > -1) {
html = (new String(s.src)).replace(".js", ".html");
}
}
reloader_content.innerHTML = '<iframe id="safarireloader-iframe" src="about:blank" frameborder="no" scrolling="no"></iframe>';
document.body.appendChild(reloader_content);
reloader_content.style.position = 'absolute';
reloader_content.style.left = reloader_content.style.top = '-9999px';
iframe = reloader_content.getElementsByTagName('iframe')[0];
if (document.getElementById("safari_remember_field").value != "" ) {
historyHash = document.getElementById("safari_remember_field").value.split(",");
}
}
if (browser.firefox)
{
var anchorDiv = document.createElement("div");
anchorDiv.id = 'firefox_anchorDiv';
document.body.appendChild(anchorDiv);
}
//setTimeout(checkForUrlChange, 50);
}
return {
historyHash: historyHash,
backStack: function() { return backStack; },
forwardStack: function() { return forwardStack },
getPlayer: getPlayer,
initialize: function(src) {
_initialize(src);
},
setURL: function(url) {
document.location.href = url;
},
getURL: function() {
return document.location.href;
},
getTitle: function() {
return document.title;
},
setTitle: function(title) {
try {
backStack[backStack.length - 1].title = title;
} catch(e) { }
//if on safari, set the title to be the empty string.
if (browser.safari) {
if (title == "") {
try {
var tmp = window.location.href.toString();
title = tmp.substring((tmp.lastIndexOf("/")+1), tmp.lastIndexOf("#"));
} catch(e) {
title = "";
}
}
}
document.title = title;
},
setDefaultURL: function(def)
{
defaultHash = def;
def = getHash();
//trailing ? is important else an extra frame gets added to the history
//when navigating back to the first page. Alternatively could check
//in history frame navigation to compare # and ?.
if (browser.ie)
{
window['_ie_firstload'] = true;
var sourceToSet = historyFrameSourcePrefix + def;
var func = function() {
getHistoryFrame().src = sourceToSet;
window.location.replace("#" + def);
setInterval(checkForUrlChange, 50);
}
try {
func();
} catch(e) {
window.setTimeout(function() { func(); }, 0);
}
}
if (browser.safari)
{
currentHistoryLength = history.length;
if (historyHash.length == 0) {
historyHash[currentHistoryLength] = def;
var newloc = "#" + def;
window.location.replace(newloc);
} else {
//alert(historyHash[historyHash.length-1]);
}
//setHash(def);
setInterval(checkForUrlChange, 50);
}
if (browser.firefox || browser.opera)
{
var reg = new RegExp("#" + def + "$");
if (window.location.toString().match(reg)) {
} else {
var newloc ="#" + def;
window.location.replace(newloc);
}
setInterval(checkForUrlChange, 50);
//setHash(def);
}
},
/* Set the current browser URL; called from inside BrowserManager to propagate
* the application state out to the container.
*/
setBrowserURL: function(flexAppUrl, objectId) {
if (browser.ie && typeof objectId != "undefined") {
currentObjectId = objectId;
}
//fromIframe = fromIframe || false;
//fromFlex = fromFlex || false;
//alert("setBrowserURL: " + flexAppUrl);
//flexAppUrl = (flexAppUrl == "") ? defaultHash : flexAppUrl ;
var pos = document.location.href.indexOf('#');
var baseUrl = pos != -1 ? document.location.href.substr(0, pos) : document.location.href;
var newUrl = baseUrl + '#' + flexAppUrl;
if (document.location.href != newUrl && document.location.href + '#' != newUrl) {
currentHref = newUrl;
addHistoryEntry(baseUrl, newUrl, flexAppUrl);
currentHistoryLength = history.length;
}
return false;
},
browserURLChange: function(flexAppUrl) {
var objectId = null;
if (browser.ie && currentObjectId != null) {
objectId = currentObjectId;
}
pendingURL = '';
if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
var pl = getPlayers();
for (var i = 0; i < pl.length; i++) {
try {
pl[i].browserURLChange(flexAppUrl);
} catch(e) { }
}
} else {
try {
getPlayer(objectId).browserURLChange(flexAppUrl);
} catch(e) { }
}
currentObjectId = null;
}
}
})();
// Initialization
// Automated unit testing and other diagnostics
function setURL(url)
{
document.location.href = url;
}
function backButton()
{
history.back();
}
function forwardButton()
{
history.forward();
}
function goForwardOrBackInHistory(step)
{
history.go(step);
}
//BrowserHistoryUtils.addEvent(window, "load", function() { BrowserHistory.initialize(); });
(function(i) {
var u =navigator.userAgent;var e=/*#cc_on!#*/false;
var st = setTimeout;
if(/webkit/i.test(u)){
st(function(){
var dr=document.readyState;
if(dr=="loaded"||dr=="complete"){i()}
else{st(arguments.callee,10);}},10);
} else if((/mozilla/i.test(u)&&!/(compati)/.test(u)) || (/opera/i.test(u))){
document.addEventListener("DOMContentLoaded",i,false);
} else if(e){
(function(){
var t=document.createElement('doc:rdy');
try{t.doScroll('left');
i();t=null;
}catch(e){st(arguments.callee,0);}})();
} else{
window.onload=i;
}
})( function() {BrowserHistory.initialize();} );
The script doesn't support chrome. Read through it in most of the functions like checkForUrlChange() it looks at the name of the browser to decide what to do.
Because chrome and safari are both based on webkit, you can try to change the line useragent.indexOf("safari") != -1 to useragent.indexOf("safari") != -1 || useragent.indexOf("chrome") != -1 to see if that works.
If not, try using unfocus history keeper. It supports Chrome.
(http://www.unfocus.com/projects/historykeeper/)