How can I detect page navigation without reloading? - javascript

I have script, what work one time when window loaded, it work on this page, but site use some navigation links what not fully reload page (see this answer for example: Modify the URL without reloading the page). How can I detect that and run my script again?
I have one idea: storing URL (without anchor) in variable and check it periodically with current url, but I think this is bad solution. May be you know better one?
JavaScript or JQuery is possible to use.

Use window.onpopstate or window.onpushstate if u are using pushState or replaceState ( from ur given example).
ex:-
To Navigate Without reload ( you already did this )
// Your code to fetch new URL body and title
// update the DOM then use following code to update URL also (don't use location.href, otherwise the page reloads)
// sorry u already know this because u provided the example ;)
let data = { title : "Current Title",
body : document.body.innerHTML" } // to store current page data
window.history.pushState(data, 0, "newURL");
To detect navigation ( i.e., you wanna do )
window.onpushstate: when above code runs for navigation to a new url and load new content without reload ...
window.onpushstate(function() {
// detects ur navigation
})
window.onpopstate: when you press back button
window.onpopstate(function (e) {
let { data } = e.state;
// data object that u gave in pushState method when u called ur last / latest pushState method...
// use this data to retrieve previous data content and title
let { title, body } = data;
document.title = title;
document.body.innerHTML = body
})
for more detail mdn docs

That's because the new pages are either
1 ) Already at the ready and simply being brought in-sight by jQuery
2 ) Ajax called in.
If you scout for your navigation (the links you click on to go to the other page), you should find click me or so.
If you look for wherever this is is bound (i.e.: $('#navigation a').on("click", function(){});, you can simply wrap your script within a function, and trigger this function together with loading the new page every time. (after it, obviously).
I wish I could be more clear, but you did not provide any code yourself, so I have absolutely no idea of what kind of example I should be giving here.
-- the point: Those page changes are triggered by something in your javascript. Find the trigger that makes the page-change happen, and simply insert myCustomFunction();.
If you want to make your bindings update with a new DOM, you could use this:
function setBindings(){
//removing the old bindings prevents the "click" from triggering twice.
$('a').off("click");
$('a').on("click", function(){
//load page and such here
//Apply script you want to run here
setbindings(); //rerun the function to set the bindings.
});
}

I think you are looking for hashchanges you can listen to this event onhashchange
window.onhashchange = function(e) {
var sublink = window.location.hash.substring(1);
//do your thing here
}
You can also check what updated the url after the hashchange
var sublink = window.location.hash.substring(1);

I think the URL of script is cached,do you used Ajax get method?if it is,please
like this write url "wwww.baidu.com?"+Math.random();if not is ,in the firefox ,you can used pageshow event.

Related

Load external page on div and getting a specific url at the same time

I am developing a new website and while I want to get it done as easy to navigate as possible, I also wanted to use some kind of navegation with overlapping pages.
My idea was to have articles on the current page that will open on a floating div over the rest when clicked. That´s not really the problem because using jquery .load() it gets quite easy to do, but my problem is that it doesn't modify the current url, so it remains as www.myweb.com for example and I would like to have it like www.myweb.com/current-article when the article is opened. Once you have that specific url to the article, if it is shared, whoever open that link will get to the website with the article opened over the it.
I hope it all makes sense, but a good example can be found in USA Today or Play.Spotify
I am using umbraco 7 and javascript for the site. Any idea of how it could be done?
its called hash base navigation
location.hash = "#myHash"; //sets the url plus hash
Below is fired if user manually changes the URL or by using the back button
window.onhashchange = function()
{
if (location.hash === "#myHash")
{
doSomething();
}
}
This is actually a big and complex task to implement correctly.
I would advise you to use Backbone.Router http://backbonejs.org/#Router. It use history api in "new" browsers, with a fallback to hashtags in older browsers.
Some pseudo code:
First define your route. It will catch all pages under www.myweb.com/articles/*
var MyRouter = Backbone.Router.extend({
routes: {
"articles/:page": "loadPage"
},
loadPage: function() {
var div = $("#overlay");
div.html($.load("your page"))
div.show()
}
});
You would need to implement some logic to test if the loaded page is not under articles/.*
Init MyRouter when the page is loaded:
var router = new MyRouter();
router.start()
The overlay page will now open when you hit www.myweb.com/articles/cool-article
If you want to open the page from a parent page, simply call
$("button").click(function(){
router.navigate("articles/cool-article", {trigger: true});
});

Detect which link was clicked with javascript that got user to specific page

Been searching on the web for a solution, but couldn't find anything, so maybe it's not possible, although I hope it still is.
What Im trying to do is detect the button (class or id) that was clicked when being redirected to another page on my site.
What I have is a portfolio page that contains a large amount of divs with different classes, so when someone clicks on a specific button on the homepage and gets redirected to the portfolio page, is it possible to detect on the portfolio page how the visitor got directed from. So detect which button got clicked.
no idea how to approach this, something maybe with if previous window.location last action find class or id.
Hopefully my question makes sense and someone can give me an idea if even possible.
I imagine it would rather be possible to do with php, but unfortunately server side languages are not an option in this case.
Thanks
Examples of methods you can use
add the information in the originating url - use location.search or location.hash depending on your choice of ? or #
Set a cookie (or use session/localStorage in modern browsers) in originating page and read it in the target page
Interrogate document.referrer (not always set)
You can't do it without either modifying the links (adding a query string or hash), or having code on the source pages (where the links are).
The former is pretty obvious: Just add a query string or hash (I'd use a hash) that identifies where the click came from, and look for the hash on the portfolio page. E.g., links:
Portfolio
Portfolio
and in the portfolio page:
var from = location.hash;
If you don't want to do that, and you can put code on those pages, it's easy: Add a click handler that sets information about the link in sessionStorage (very well-supported on modern browsers), and look for it in sessionStorage when you get to the portfolio page.
E.g.,:
$(document).on("click", "a", function(e) {
// Maybe check the link is going to portfolio, or refine the selector above
sessionStorage.setItem("linkFrom", this.className);
});
and then in the portfolio page:
var from = sessionstorage.getItem("linkFrom");
You can use window.localStorage to save the last id of the clicked element.
localStorage.setItem('last_clicked_id', id);
And then read it in the next page:
localStorage.last_clicked_id
Before running you should check for localStorage support:
if(typeof(Storage) !== "undefined") {
//localStorage code
} else {
//no localStorage support
}
this is how it works: the recent page or url is set on the URL parameters like a GET server request, but instead the client will receive it and parse it not the server. the recent page or url is on the "fromurl" parameter. on every page put this in (it's a javascript code):
function getURIparams(s) {
loc = window.location.href;
loc = loc.substring((loc.indexOf("?")+1));
loc = loc.split("&");
for (l = 0; l < loc.length; l++) {
lcc = loc[l].split("=");
if (lcc[0] == s) {
return lcc[1];
break;
}
}
}
next on every anchor link put this in href:
The Link to another page
after that, on every page execute this javascript:
from_url = getURIparams("fromurl");
the "from_url" variable will be the string variable of where the user clicked before it comes to that page.
if you are to lazy to put all those anchor one by one like this, do this work around but you need jquery for this. you dont need to put the parameter on the links for it to know where it comes from it will be automatically added by jquery.
$(document).on('click', 'a', function(e){
e.preventDefault();
window.location.href = e.target.href + "?fromurl=" + window.location.pathname;
});

jQuery Mobile - How to change page behaviour depending on previous page

I have three pages in my app: #main, #new and #existing.
Everytime #new is loaded, I want it to detect if it came from #menu or #existing. Depending on this information it should either do nothing or populate its form.
How can I achieve this both in terms of the right command for previous page and handling the DOM correctly?
According to your # these pages need to be dom elements. Just use the variable in javascript and check this in every step.
Create a new variable like lastPage
On every click, I prefer to use data-foo like HTML5 data attribute.
Change lastPage according to navigation.
And do after that what you really want.
var lastPage = '';
/* This code from jQuery Mobile, link is below the code. */
// Define a click binding for all anchors in the page
$( "a" ).on( "click", function( event ){
// Prevent the usual navigation behavior
event.preventDefault();
// Alter the url according to the anchor's href attribute, and
// store the data-foo attribute information with the url
$.mobile.navigate( this.attr( "href" ), {
lastPage: this.attr("data-foo") // store data here
});
// Hypothetical content alteration based on the url. E.g, make
// an AJAX request for JSON data and render a template into the page.
alterContent( this.attr("href") );
});
HTML Example
Main Page
New Page
Existing Page
You can make data-anythingyouwant. Only the data is important, after that you can use everything. It just an HTML5 DOM attribute.
Edit:
I suggest you to check navigation page. You can understand better the concept after that.
Code Source: http://view.jquerymobile.com/1.3.2/dist/demos/widgets/navigation/
Take advantage of jQuery-Mobile page events, such as pagebeforehide and pageshow.
Demo
Store current page's id before navigating away.
var prevPage;
$(document).on('pagebeforehide', function () {
prevPage = $.mobile.activePage[0].id;
});
When destination page is active, retrieve the stored previous page id.
$(document).on('pageshow', function () {
$(this).find('.destination').text('Previous Page: ' + prevPage);
});

jquery fail on DOM modify made with html()

In my website, I build the page navigation based on hashchange:
var hashHome;
$(window).bind( 'hashchange', function(e) {
var homeClass = "home";
var url = $.param.fragment();
if($('#page-content').hasClass(homeClass)){
hashHome = $('#page-content').html();
}
if(url ==''){
//homepage with nothing(no hash)
if(!$('#page-content').hasClass(homeClass)){
//alert("load frim cache ->#"+url);
$('#page-content').addClass(homeClass);
$('#page-content').html(hashHome);
}
}else{
//go to some page
if($('#page-content').hasClass(homeClass))
$('#page-content').removeClass(homeClass);
initAction(url);
}
})
$(window).trigger( 'hashchange' );
When the site loads its homepage, the homepage gets stored in hashHome. If user navigates away, the initAction(id) replaces the entire $('#page-content')'s content with other pages' content. When the uses navigates back to home, it restores the stored home back to the $('#page-content').
My problem is that all of the jQuery stopped working on the homepage.
I've read about live() already but it seems that it needs a event like click() for it to work. How do I fix this?
I figured out that i need to store my entire page before i change the content of the div that is surrounding it
var content$('#page-content').html();
then do the content change
that way, when i reinitialize all my jQuery plugins, they will loose all of their old reference and use the new content variable, instead of a double initialization
and finally, i've the original question's code also won't work since the script tag look like this: <script type="text/javascript">...</script>, IE for some reasons won't recognize this, so I have to change it to <script></script> in order to make it cross browser compatible

Prevent iFrame from changing location?

I've got a simple app that parses Tumblr blog templates. It's modeled after their customization screen and contains a header with some configurable options and an iframe. Every time an option changes, the app reloads the iframe, serializing the config form and updating the iframe's src with the serialized data as a query string.
This all works fine, except every time this happens, I am only able to reload the main index page with the changed options. If the user wants to view, say, a single post page by navigating away from the index, the template renders that page, only with the default options.
In other words, the changed options do no persist while the user navigates the blog.
I've been able to have 'persisting changes' with an $('iframe').load() event like so:
$('iframe').load(function(){
updateTheme();
});
The only problem is, as you can tell, this would wait for the iframe to fully render the page using the default options, then re-renders it with the updated options. I mean... it works, but it's not really a great solution.
Does anybody know how I can prevent the iframe from loading, capturing the users desired location, then re-render the frame with the current options as represented in the header?
Any help would be greatly appreciated. Thanks in advance!
Are you hosting both the top-level page and the embedded iframe page? If so, there are some games you can play, but it's not pretty. For example you can rewrite links within the embedded iframe in order to pre-fill the config options, e.g. with something like:
$('iframe').load(function(){
$('a', $('iframe')).each(function() {
var new_url = this.attr("href");
new_url += config_options;
this.attr("href", new_url);
});
});
Here's what I came up with:
var p = top || parent;
(function($){
$('a').click(function(e) {
var prevent = e.isDefaultPrevented(),
is_local = p.isLocal(this.href),
is_hash = $(this).attr('href').match(/^#/);
if(prevent || ! is_local || is_hash) return;
e.prevenDefault();
p.updateTheme(this.href);
return false;
});
})(jQuery);
My worry was that I would be affecting the javascript events attached to <a/> tags by the user, but apparently jQuery will detect default prevented events, even if they weren't prevented with jQuery itself. I tested it like this:
document.getElementById('test-link').onclick = function() {
return false;
}
jQuery detects that the original event has been prevented, so I am just assuming I shouldn't continue.

Categories

Resources