I have a simple site, which slides the content off the page before taking you to the URL. However, I need to be able to determine the slide direction, depending on which page you're currently on.
I need to do this, but I'm not sure how to articulate it properly with jQuery:
if (current page == about.php) {
animate right then go to target URL }
else {
do default behaviour }
At the moment, I have this function which doesn't work well, because it animates in a certain way regardless of which URL you're going to:
function animateLeftAndGo(x) {
$(x).click(function (e) {
e.preventDefault();
var href = this.href;
$('.pop-up').fadeOut(function(){
$('.wrapper').animate({left: "+=150%"}, "slow", function(){
window.location = href;
});
});
});
}
Which is called by:
animateLeftAndGo('a.archive');
How can I set up an if statement that asks if the current URL is about.php?
In JavaScript use the location object: http://www.w3schools.com/jsref/obj_location.asp
if (location.pathname == '') {
}
Related
I am playing with jquery and js, trying to build an ajax overlay image viewer for a PHP website. With this code included at the bottom of the 'gallery page', the viewer opens and i can navigate with next and previous links inside the viewer. But the back button and the history is hard to understand. The browser often shows only the response of the ajax call, without the underlying page and css files, after some clicks back.
Perhaps somebody knows what is generally happening in such a case? I would like to understand why back sometimes results in a broken page, i.e. only the ajax response.
<script type="text/javascript">
$(document).ready(function() {
function loadOverlay(href) {
$.ajax({
url: href,
})
.done(function( data ) {
var theoverlay = $('#flvr_overlay');
theoverlay.html( data );
var zoompic = $('#zoompic');
zoompic.load(function() {
var nih = zoompic.prop('naturalHeight');
var photobox = $('#photobox');
if($(window).width() >= 750){
photobox.css('height',nih);
}
theoverlay.show();
$('body').css('overflow-y','hidden');
$(window).resize(function () {
var viewportWidth = $(window).width();
if (viewportWidth < 750) {
photobox.css('height','auto');
zoompic.removeClass('translatecenter');
}else{
photobox.css('height',nih);
zoompic.addClass('translatecenter');
}
});
});
});
return false;
}
var inithref = window.location.href;
$(window).on('popstate', function (e) {
if (e.originalEvent.state !== null) {
//load next/previous
loadOverlay(location.href);
} else {
//close overlay
$('#flvr_overlay').hide().empty();
$('body').css('overflow-y','scroll');
history.replaceState(null, inithref, inithref);
}
});
$(document).on('click', '.overlay', function () {
var href = $(this).attr('href');
history.pushState({}, href, href);
loadOverlay(href);
return false;
});
});
</script>
edit
clicking forward works:
/photos (normal page)
/photos/123 (overlay with '/photos' below)
/locations/x (normal page)
/photos/567 (overlay with '/locations/x' below)
clicking back gives me the broken view at point 2.
Do you need to prevent the default behaviour in your popstate to prevent the browser from actually navigating back to the previous page?
you have to manage it by own code.
You have a few options.
Use localstorage to remember the last query
Use cookies (but don't)
Use the hash as you tried with document.location.hash = "last search" to update the url. You would look at the hash again and if it is set then do another ajax to populate the data. If you had done localstorage then you could just cache the last ajax request.
I would go with the localstorage and the hash solution because that's what some websites do. You can also copy and paste a URL and it will just load the same query. This is pretty nice and I would say very accessible
Changing to document.location.hash = "latest search" didn't change anything.t.
This goes into the rest of the jQuery code:
// Replace the search result table on load.
if (('localStorage' in window) && window['localStorage'] !== null) {
if ('myTable' in localStorage && window.location.hash) {
$("#myTable").html(localStorage.getItem('myTable'));
}
}
// Save the search result table when leaving the page.
$(window).unload(function () {
if (('localStorage' in window) && window['localStorage'] !== null) {
var form = $("#myTable").html();
localStorage.setItem('myTable', form);
}
});
Another solution is that use INPUT fields to preserved while using back button. So, I do like that :
My page contains an input hidden like that :
Once ajax content is dynamicaly loaded, I backup content into my hidden field before displaying it:
function loadAlaxContent()
{
var xmlRequest = $.ajax({
//prepare ajax request
// ...
}).done( function(htmlData) {
// save content
$('#bfCache').val( $('#bfCache').val() + htmlData);
// display it
displayAjaxContent(htmlData);
});
}
And last thing to do is to test the hidden field value at page loading. If it contains something, that because the back button has been used, so, we just have to display it.
jQuery(document).ready(function($) {
htmlData = $('#bfCache').val();
if(htmlData)
displayAjaxContent( htmlData );
});
I just can't figure out this problem.
The circumstances:
Website (Wordpress with Genesis and Altitude-Pro theme) with 4 pages with anchor-sections on it.
The problem:
If a link got clicked it loads the url with the hash (.../#section1) but it is not on the correct position. After hitting enter in the URL it jumps to the correct position.
I think this is because of Images that are loaded and the site jumps to the location before that.
What I tried:
I used this code, but it doesn change anything:
$( window ).load(function() {
alert("LOADED");
hash = document.location.hash;
alert(hash);
if (hash !="") {
setTimeout(function() {
if (location.hash) {
window.scrollTo(0, 0);
window.location.href = hash;
}
}, 1);
}
else {
return false;
}
});
Here's the link to the Demosite -> DEMOSITE
//Gather AJAX links
var ajaxLink = $("#logo, .navLink, .tableLink, .footerLink");
//Mark the recent state as null (because there is none yet)
var recentState = null;
//Initialize the page state based on the URL (bookmarking compatibility)
window.onload = function() {
//If no page state exists, assume the user is at index.html
if (window.location.hash == "") {
window.location.hash = "page=index";
}
//Load the page state based on the URL
loadStateFromURL();
//Keep the page state synchronized (back/forward button compatibility)
setInterval(loadStateFromURL, 500);
//Exit
return;
}
//Use AJAX for certain links
ajaxLink.click(function() {
//Update the URL
window.location.hash = "page=" + $(this).attr("id");
//Load the page state based on the URL
loadStateFromURL();
//Return false or else page will refresh
return false;
});
//Load the page state based on the URL
function loadStateFromURL() {
//If nothing has changed, exit
if (window.location.hash == recentState) {
return;
}
//Mark the recent state
recentState = window.location.hash;
//Go through an array of all AJAX links and check their IDs
for (var i = 0; i < ajaxLink.length; i++) {
//If we find a link's ID that matches the current state, load the relevant content
if ("#page=" + ajaxLink[i].id == window.location.hash) {
//Load contents into article.main
$("article.main").fadeOut(0).load(ajaxLink[i].href, function(response, status, xhr) {
//Show an error if the request fails
if (status == "error") {
$("article.main").load("./404.html");
window.location.hash = "page=404";
}
}).fadeIn(500);
//Update the page title
document.title = "\u2622 My Website Name \u2622 " + ajaxLink[i].text;
document.getElementById("headH2").textContent = ajaxLink[i].text;
//State has been fixed, exit
return;
}
}
}
This code works flawlessly when I run it locally!!!
But when I throw it on the web server my AJAX'd links will refresh the page when I first visit. However, if I use the back button then try the link again (or I'm assuming if the page is already in the browser cache), it will work properly.
I cannot allow this, because when people first visit my page the first link they click on will not operate as intended.
One of things I've also been testing is I'll bookmark my own site with a breadcrumb bookmark (example.com/#page=14) and see if it updates without my page already being in the browser cache. Again, it works on my local machine but not on my web server.
use event.preventDefault()
ajaxLink.click(function(e) {
e.preventDefault();
//Update the URL
window.location.hash = "page=" + $(this).attr("id");
//Load the page state based on the URL
loadStateFromURL();
//Return false or else page will refresh
return false;
});
The issue maybe is that when you are applying your click event to these links, they may not be loaded to the DOM. So the possible solution is to put ajaxLink.click(function() { ... }); part inside window.load event or document.ready event. Since you have used window.load event, you can do something like this.
//Initialize the page state based on the URL (bookmarking compatibility)
window.onload = function() {
//If no page state exists, assume the user is at index.html
if (window.location.hash == "") {
window.location.hash = "page=index";
}
//Load the page state based on the URL
loadStateFromURL();
//Keep the page state synchronized (back/forward button compatibility)
setInterval(loadStateFromURL, 500);
//Use AJAX for certain links
ajaxLink.click(function() {
//Update the URL
window.location.hash = "page=" + $(this).attr("id");
//Load the page state based on the URL
loadStateFromURL();
//Return false or else page will refresh
return false;
});
//Exit
return;
}
Solved my own question, had to continuously parse the AJAX links to stay updated with the DOM as it changes.
First I put the ajaxLink declaration into a function:
//Gather AJAX links
function parseAjaxLinks() {
var ajaxLink = $("#logo, .navLink, .tableLink, .footerLink");
return ajaxLink;
}
Then I had to put the ajaxLink click events into a function:
//Load the page state from an AJAX link click event
function loadStateFromClick() {
//Update the AJAX links
var ajaxLink = parseAjaxLinks();
ajaxLink.click(function() {
//Update the URL
window.location.hash = "page=" + $(this).attr("id");
//Load the page state based on the URL
loadStateFromURL();
//Return false or else page will refresh
return false;
});
}
Then I added a line in my window.onload event to keep my AJAX click events synchronized with the DOM (this adds overhead, but oh well):
//Initialize the page state based on the URL (bookmarking compatibility)
window.onload = function() {
//If no page state exists, assume the user is at index.html
if (window.location.hash == "") {
window.location.hash = "page=index";
recentState = window.location.hash;
}
//Load the page state based on the URL
loadStateFromURL();
//Keep the page state synchronized (back/forward button compatibility)
setInterval(loadStateFromURL, 250);
//Keep AJAX links synchronized (with DOM)
setInterval(loadStateFromClick, 250);
//Exit
return;
}
If you have a keen eye, you saw I had called the new parseAjaxLinks in my new loadStateFromClick function, so I added a line to the top of my loadStateFromURL function to keep the links updated in there as well:
//Load the page state based on the URL
function loadStateFromURL() {
//Update the AJAX links
var ajaxLink = parseAjaxLinks();
...
What I learned from this is the variables which are dependent on the DOM need to be continuously updated. While the DOM is loading, things are unpredictable and kind of sucks. **Drinks beer**
This code fades each page out, before going to the URL's destination. However, there are some instances where the user doesn't go to a new page, but goes to a PDF in the browser, or it opens the default mail application. On Safari it seems, if you go to an external site (www.twitter.com) and press the back button, the .wrapper is still faded out. (Perhaps a cache thing?)
function fadeAndGo(x) {
$(x).click(function (e) {
e.preventDefault();
var href = this.href;
$('.wrapper').fadeOut(function(){
window.location = href;
});
// $('.wrapper').delay()fadeIn();
});
}
fadeAndGo('a');
Is it possible to either:
Fade out, only if the URL does not contain 'PDF, mailto', or is an external link?
Fade in after a certain amount of time (it faded out, but faded back in after a couple of seconds, in case it was a PDF/mailto).
Try this:
function fadeAndGo(x) {
$(x).click(function (e) {
e.preventDefault();
var href = $(this).attr("href");
if (!/PDF|mailto/gi.test(href)) {
$('.wrapper').fadeOut(function () {
window.location = href;
}).delay(2000).fadeIn();
} else {
window.location = href;
}
});
}
fadeAndGo('a');
In the code below when the anchor element is clicked I am trying to update the url with the anchor's 'href' and scroll down to the relevant 'id':
jQuery(document).ready(function($) {
(function() {
function update_url(id, url, scroll) {
this.id = id;
this.url = url;
this.scroll = scroll;
this.update();
}
update_url.prototype.update = function() {
var url = this.url;
$(this.id).click(function() {
var append = $(this).attr('href');
testing.scrollTo();
document.location.href = url + append;
return false;
});
}
update_url.prototype.scrollTo = function() {
$('html,body').animate({
scrollTop: $("#" + this.scroll).offset().top
},'slow');
}
var testing = new update_url('a', document.URL, 'people');
})(); });
The problem is when you click the anchor the return false; doesn't kick in quick enough so the page jerks for a second before scrolling down.
Is there a way of updating the page's url and still avoiding this jerky movement?
The problem is not that the return false; is triggered too late, but rather that the change you make to document.location.href causes the page reload no matter what.
HTML5 pushState is what you're looking for. If you're using HTML5, that is.
If not, you'll want to resort to hash navigation.
There's also a plugin for that, of course. It supports pushState as well as hash navigation - one less thing for you to worry about.