Popstate with Hashtags? - javascript

I have a site that uses AJAX to dynamically load content into a div.
The links to do so are anchors with href="#" and an onclick event to trigger the AJAX.
This leaves me without a history when I click back, so if I load one page, then another and click back, it does nothing.
A basic version of the code is this:
<script type="text/javascript">
function loadXMLDoc(url)
{
<!-- Load XML Script here. -->
}
</script>
</head>
<body>
<div id="myDiv">
<!-- Target div. -->
</div>
Click Me.
Click Me.
Click Me.
</body>
What I would like to know is, can I give each link a different "#" and then use a popstate handler to call the appropriate event, so if I click link 1, 2 and then 3 and then start hitting the back button, it'll go back to 2 and then 1 etc..
I was going to use history.js and start using pushstate in the loadXML script but I think the whole manipulating history thing is a bit dirty and unreliable.
Am I thinking on the right lines or is there a better way?
Currently all my links just use "#" so that it pops back to the top of the page when loading more content but I'd like to be able to go back if possible.
Any help would be great.

Browser saves hashtags to history properly. Just add hashtag #1 to this question page, hit enter, change it to #2, hit enter, change it to #3, hit enter. Now click back button, and you'll see hash changes from #3 to #2. I recommend to change only hash itself on link click and react on page hash change and page load events.
function react() {
var hash = window.location.hash.replace("#", "");
loadXMLDoc(hash + ".txt");
};
document.body.onload = function() {
react();
window.onhashchange = react;
};
Click me
Click me
Click me
Please note that onhashchange event does not supported by old IE. The only way to deal with it if you want is to define timer with setInterval and check hashes equality.

Try to use combination of LocalStorage and HistoryAPI.
When you load XMLDoc store it in LocatStorage, when back is pressed - load data from storage, not from web.
A bit code above.
/* Handling history.back added */
window.onpopstate = function(event) {
yourHandleBackFunction(event.state);
};
function yourHandleBackFunction(renderTs) {
/*Check TS and load from localStorage if needed*/
};

Related

javascript: history.go(-1) doesnt work for the whole window

i have an unusual problem. I have a page which contains an iframe, which is controlled by the dropdown. So selection of the dropdown loads different iframes. Anyway - on the bottom I have a button to return to the previous page (I mean the whole page, not previously loaded iframe on that page).
<a href="javascript: history.go(-1)">
Unfortunately it also includes the history of these iframes, so when I click on that button, it loads up the previous iframe instead of taking me back.
Here is how to explain it well:
go to this page: Click here
go to the hyperlink on that page
make couple of selections from the drop down (play with it)
click the return button on the very bottom of the page.
I want it to take me back to the first page (here.html), not go back to the previously loaded iframe on 1.html.
I have to use javascript history.go or similar script. I can't use direct link to here.html, as this page is a part of many other pages, so when the user clicks return, he is forwarded to his specific landing page.
I greatly appreciate any help.
It's a life-saving question
Use document.referer
var referrer = document.referrer;
window.location = referrer;
Check if it works !
<a href="javascript: window.location = document.referrer;">
You need to remove the newly iframe before sending browser back to the actual page.
Add click event on the return link
HTML:
<a id="return_link" href="#">
Javascript:
$(document).ready(function() {
$('#return_link').on('click', function(e) {
e.preventDefault();
$('#iframeId').remove();
window.location = document.referrer;
});
});
try this , Just remove extra spaces from statements.
href="javascript:history.go(-1)

Javascript: history not loading page

I have a menu that loads a new html file in a div. The loading is done by a click event attached to the menu's <a> tags. The loading works well and I add the new load to the history by constructing a new href with a hash tag.
But when I use the back button, the URL is updated correct in the browsers address field, but the page is never loaded. If I focus the address field and press enter it loads.
This is the javascript located in the mypage.html header.
<script type="text/javascript">
$(document).ready(function() {
// replace menu link click
$(".right-menu a").live('click', function(ev) {
ev.preventDefault();
ev.stopPropagation();
window.location.href = $(this).attr('href');
$("#content-right").load('mypage'+window.location.hash.substring(1)+'.html');
return false;
});
// If page loads, load the content area according to the hash.
var hrtag = window.location.hash.substring(1);
if(hrtag=="")
hrtag='about';
$("#content-right").load('mypage'+hrtag+'.html');
window.location.hash = hrtag;
});
</script>
This is the menu
<ul class="right-menu">
<li>About</li>
<li>Screens</li>
<li>License</li>
<li>Download</li>
<li>Donate</li>
</ul>
If I load the page as mypage.html, the javascript will append the hash #about and load the div id "content-right" with mypageabout.html
If I click the menu, for example download, it will load the div id "content-right" with mypagedownload.html
In both cases, the window.location will be set to the hash version of the page, mypage.html#about and mypage.html#download to register them in the history.
If i click the menu in the following order; license, about, screens and then click the browser's back button, the address field will show; mypage.html#about, mypage.html#license but it will NOT load the pages!?!
The URLs are obviously in the history, but they don't load.
Any clue to what might be wrong here?
// Thanks
EDIT - The solution
Thanks to Andres Gallo's article I came up with this solution:
<script type="text/javascript">
$(document).ready(function() {
// Make sure the page always load #about
LoadIDWithURL('#content-right','myPageAbout.html');
window.addEventListener('hashchange',function() {
if (window.location.hash != "") {
// We have a hash, use it!
LoadIDWithURL('#content-right','MyPage'+window.location.hash.substring(1)+'.html');
} else {
// We do not have a hash, force page reload!
window.history.go(0);
}
});
});
// Load the targetID with the URL loadURL.
function LoadIDWithURL(targetID,loadURL) {
$(targetID).load(loadURL);
}
</script>
I wrote a very detailed article on this exact topic. It explains how to build exactly what you are trying to do.
Furthermore my article also explains how you can pass parameters in your links to have javascript do special things
Here is a link to the article http://andresgallo.com/2012/06/08/ajaxifying-the-web-the-easy-way/
The best method is to attach your functionality to your hashchanges rather than to you click events. This allows any changes in history to take advantage of your javascript functionalities.
This is normal behaviour when navigating between pages which differ only in their hash. You have two options:
Use the hashchange event, or an emulation of it, to detect when the user changes the hash by navigation back or forward and update the page appropriately
Use the HTML5 history API.
you can try with hashchange
$(function(){
$(window).hashchange(function(){
// some event
})
})

How to disable back,forward and Refresh functionality in browser?

Can anyone help me to disable browser back,forward, back button and right click menu functionality using JavaScript or JQuery? I have tried disabling the back button like this:
function disableBackButton() {
window.history.forward();
}
setTimeout("disableBackButton()", 0);
I have called this function in the Body onload event. I have a doubt that where we need to put this code in the Calling page or Called Page.Suppose i have two pages like this FirstPage.aspx and SecondPage.aspx. When I navigate from the First Page to Second Page when I click back button of the browser it should not go to FirstPage.aspx.
Have a look at A Thorough Examination of "Disabling the Back Button."

Global Javascript link handler

Here's what I have:
A web application that runs in a single HTML page (call it myapp.req), with content coming and going via AJAX
The application can be entered externally with a link such as myapp.req?id=123, and the application opens a tab with the item at id 123
The content on the page is mostly user's content, and many times has inner-application links to myapp.req?id=123
The problem is that clicking a link to myapp.req?id=123 reloads the browser, and removes any content or state that the user had loaded
What I want is to be able to catch link clicks whose destination is myapp.req?id=123, and instead of reloading the page, just open the tab for item 123, leaving anything else currently loaded alone. If the link is for an external website, though, obviously just let the browser leave.
So my question really: Can I have a global link handler that checks if I want to handle the link click, and if so, run some Javascript and don't leave?
I understand I could find all <a>s and add listeners, but my hope is that the solution would only require setting up the listener once, and not adding link handlers every time new content is loaded on the page. Since content can be loaded many different ways, it would be cumbersome to add code to all those places.
Does that make sense?
jQuery's live is what you need:
$('a').live("click", function () {
var myID = $(this).attr('href').match(/id=([a-zA-Z0-9_-]*)\&?/)[1];
if (myID) {
//run code here
alert(myID);
return false;
}
});
Any link will now have this click handler whether it's been added after this is called or not.
Sure you can. Add a clickhandler on the body. So you catch all clicks. Then you have to check if the target of the event or one of its parent is a link with your specific href. In this case stop the event and open the tab.
updated to use .live instead of .click
If you use jQuery, you can add a "live" click event handler to every a href at once:
<body>
click here
<br/>
whatever
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">
$('a').live('click',function() {
var myID = $(this).attr('href').match(/id=([a-zA-Z0-9_-]*)\&?/)[1];
if (myID) {
//run code here
alert(myID);
return false;
}
});
</script>
This should extract the id from the href's query string and let you do whatever you want with it.

Javascript : Change the function of the browser's back button

Is there a way to make the user's back button on their browser, call a javascript function instead of going back a page?
You can't override the behaviour that if a user follows a link to your page, clicking Back will take them off it again.
But you can make JavaScript actions on your page add entries into the history as though they were clicks to new pages, and control what happens with Back and Forward in the context of those clicks.
There are JavaScript libraries to help with this, with Really Simple History being a popular example.
yes, you can. Use this js:
(function(window, location) {
history.replaceState(null, document.title, location.pathname+"#!/stealingyourhistory");
history.pushState(null, document.title, location.pathname);
window.addEventListener("popstate", function() {
if(location.hash === "#!/stealingyourhistory") {
history.replaceState(null, document.title, location.pathname);
setTimeout(function(){
location.replace("http://www.programadoresweb.net/");
},0);
}
}, false);
}(window, location));
That will redirect your back button to the location.replace you specify
I think this will do the trick.
you can write your custom code to execute on browser back button click inside onpopstate function.
This works in HTML5.
window.onpopstate = function() {
alert("clicked back button");
}; history.pushState({}, '');
I assume you wish to create a one-page application that doesn't reload the website as the user navigates, and hence you want to negate the back button's native functionality and replace it with your own. This can also be useful in mobile web-apps where using the back button inside apps is common to close an in-app window for example. To achieve this without a library, you need to:
1st. Throughout your application modify the window's location.hash instead of the location.href (which is what tags will do by default). For example, your buttons could fire on click events that modify the location.hash like this:
button.addEventListener('click', function (event) {
// Prevent default behavior on <a> tags
event.preventDefault()
// Update how the application looks like
someFunction()
// Update the page's address without causing a reload
window.location.hash = '#page2'
})
Do this with every button or tag you have that would otherwise redirect to a different page and cause a reload.
2nd. Load this code so that you can run a function every time the page history changes (both back and forward). Instead of the switch that I used in this example, you can use an if and check for other states, even states and variables not related to location.hash. You can also replace any conditional altogether and just run a function every time the history changes.
window.onpopstate = function() {
switch(location.hash) {
case '#home':
backFromHome()
break
case '#login':
backFromLogin()
break
default:
defaultBackAnimation()
}
}
This will work until the user reaches the first page they opened from your website, then it will go back to new tab, or whatever website they were in before. This can't be prevented and the teams that develop browsers are patching hacks that allow this, if a user wants to exit your website by going back, they expect the browser to do that.
If you are creating a one-page web application, where your html body has different sections and you want to nevigate through back button to the previous section you were. This answer will help you.
Where your website sections are differentiated by #. Such as:
your-web-address.com/#section-name
Just follow a few steps:
Add a class and a id in every section in you html body. Here it is ".section"
<section class="section" id="section-name">...</section>
Add two CSS class in your linked css (e.g., style.css) file to your html (e.g., index.html) file such:
.section .hide {
display: none;
}
.section .active{
dislplay: block;
}
Add this JavaScript function in you linked .js (e.g., main.js) file to your html file.
window.onpopstate = function () {
if (location.hash !== "") {
const hash = location.hash;
// Deactivating existing active 'section'
document.querySelector(".section.active").classList.add("hide");
document.querySelector(".section.active").classList.remove("active");
// Activating new 'section'
document.querySelector(hash).classList.add("active");
document.querySelector(hash).classList.remove("hide");
}
}

Categories