Reduce HTTP requests - javascript

I'm using this code to dynamically load external pages
$(function() {
$('#nav a').click(function() {
var page = $(this).attr('href');
$('#content').load(page + '.php');
return false;
});
});
I've noticed that each time I click on one of the menu tabs, a new HTTP request is sent and the page is loaded again. I'm wondering how to make each page load once so when I go through the tabs, the pages that have been already loaded display without sending new requets ?

You could "tag" tabs that are already loaded with a flag using .data() and only issue the HTTP request when the tag is non-existent.
Edit: Regarding Kryptonite's comment this would be a simple approach to the problem:
var pages = {};
$(function() {
$('#nav a').click(function() {
var page = $(this).attr('href');
if (!(page in pages)) {
$.get(page, function (data) {
pages[page] = data;
});
}
$('#content').html(pages[page]);
return false;
});
});

$('#nav a').click(function(e) {
e.preventDefault();
$this = $(this);
if ($this.data('loaded') !== true) {
// Load it.
$this.data('loaded', true);
} else {
alert('Already loaded that one!');
}
});
This will do what you need. You'll need to throw your load code in where I have the // Load it. comment, and might want to remove the else block as well. http://jsfiddle.net/rRumK/

Related

jQuery Issue about Continue button opens external link in multiple browser tabs

I am doing one feature about showing alert on external link(apart from current domain) click. For that, I have written below code. All is working fine except below scenario.
$('a').each(function() {
var $a = jQuery(this);
if ($a.get(0).hostname && getDomain($a.get(0).hostname) != currentDomain) {
$a.click(function(event) {
//console.log($a.get(0));
//var myClasses = this.classList;
//console.log(myClasses.length + " " + myClasses['0']);
$("#redirectconfirm-modal").removeClass('hide');
if (!confirmed) {
event.preventDefault();
event.stopPropagation();
$modal.on('show', function() {
$modal.find('.btn-continue').click(function() {
confirmed = true;
$a.get(0).click();
$modal.modal('hide');
location.reload();
});
});
$modal.on('hide', function() {
$a.get(0).removeClass("selected");
confirmed = false;
});
$modal.modal('show');
}
});
}
});
Scenario which produces this issue:
Click on any external link from the site, it open a modal popup for redirection confirmation with continue & return button.
If I click on "Return" button it closes the modal popup.
Now, I am clicking on external link from my site, it open the modal again but this time I am clicking on "Continue" button & guess what, it open that external link in 3 different tabs
Actually on each anchor tag click, it saves whole anchor tag value. I think, if remove all these anchor tag values on modal close code i.e. $modal.on('hide', function() { }) it will resolve problem. I had tried with many different ways but still facing this issue.
Can you please provide solution/suggestion on that?
Problem is when you have 3 external links (as you probably have), than you set 3 times this part of code:
$modal.on('show', function() { ... });
$modal.on('hide', function() { ... });
which is wrong. Those events listeners should be set only once.
Some simplified code would look like this:
var $modal = $("#redirectconfirm-modal");
var currentDomain = 'blabla';
$modal.on('click', '.btn-continue', function(e) {
window.location = $modal.data('redirectTo');
});
$('a').each(function() {
var $a = jQuery(this);
if( $a.get(0).hostname && getDomain($a.get(0).hostname)!=currentDomain ) {
$a.click(function(e) {
$modal.data('redirectTo', $a.attr('href'));
$modal.modal('show');
});
};
});
Don't inline your events, you may try something like this:
$('a').each(function() { //add a class to all external links
var $a = jQuery(this);
if ($a.get(0).hostname && getDomain($a.get(0).hostname) != currentDomain) {
$a.addClass('modalOpen');
}
});
$('.modalOpen').not(".selected").click(function(event) { //open the modal if you click on a external link
event.preventDefault();
$('.modalOpen').addClass('selected'); //add class selected to it
$modal.modal('show');
});
$modal.on('hide', function() {
$('.selected').removeClass("selected");//remove the class if you close the modal
});
$('.btn-continue').click(function() {
$('.selected').click();//if the users clicks on continue open the external link and hide the modal
$modal.modal('hide');
});

Can't load JSON when loading pages with Ajax and hash url

I'm currently working on a project using jQuery and Ajax to load in content from local html files to my single page site. I've also got a JSON file that I'm trying to incorporate into the files being loaded in with jQuery and Ajax.
I'm using hash urls to keep the pages separate. This is the code I'm using:
//other cached links
var pageLinks = $(".pageLink");
if(window.location.hash) {
var hash = window.location.hash.replace("#", "");
loadPage(hash + ".html");
} else {
loadPage("index.html");
}
pageLinks
.click(function(){
var iid = $(this).attr("id");
loadPage(iid + ".html");
});
function loadPage(resource) {
window.location.hash = resource.replace(".html", "");
$.get("pages/" + resource, function (data) {
content.html(data);
});
}
//this makes sure the contents of hash in the url is loaded in the page
if(window.location.hash) {
var hash = window.location.hash.replace("#", "");
loadPage(hash + ".html");
} else {
loadPage("index.html");
}
This is how I'm putting my JSON data into the page:
function FooBar() {
this.foo;
this.barLinkTemplate;
}
var fooBar = new FooBar();
$(document).ready(function (){
fooBar.contentDiv = $("#fooContent");
fooBar.barDiv = $("#bars");
$.when(
$.getJSON('data/music.json'),
$.ajax('components/components.html')
).done( function(data, templateData) {
var templateHTML = $(templateData[0]);
fooBar.barLinkTemplate = Handlebars.compile( templateHTML.find("#barLinks").html() );
fooBar.data = data[0].foo;
fooBar.barDiv.html( fooBar.barLinkTemplate( data[0].bars ));
));
});
The Ajax loads just fine, hashes and all. However, nothing from my JSON file is loaded into the page. I think I've narrowed my problem down (at least I hope) to one bit of code. If I comment out the last if/else statement (above), the JSON is loaded in the first page (only the first page). If I click on any link, and I navigate back to that page, the JSON data is gone. I have to actually reload the page for the data to reappear.
Without that if/else statement, I lose the ability to load the page content from the hash in the url--though the links still work fine.
I've been googling, but I haven't seen anything similar to the problems I'm having. Any help is appreciated. Thanks!

click event delay and pre loader animation

I want to combine two techniques in page transition. first, when user click a link , the click event should be delayed about 200ms and displaying css animation (ex: fading), after that the new page will be loaded normally. Then, for visitors with slow internet connection, they will be presented with pre-loader right after the first animation. The problem is, it seems both techniques doesn't fit each others. Any advice guys?
PS: Actually I inspired by these guys website : http://rsq.com/
here's my code:
$body = $("body");
$(document).on({
ajaxStart: function () {
$body.addClass("loading"); //for slow connection, visitors with faster connection may not notice this...
},
ajaxStop: function () {
$body.removeClass("loading");
}
});
$('a').on("click", function () {
if ($(this).attr('href') != '#') {
var href = $(this).attr('href');
$('#wrapper').addClass('fade_animation'); //animation right before new page request
setTimeout(function () {
window.location = href
}, 200);
return false;
$.post($(this).attr('href'));
}
});
I think this is enough:
Instead of:
return false;
$.post($(this).attr('href'));
do this
$.post($(this).attr('href'));
return false;
So the $.post gets executed.
I think i found a solution , but don't know if it's a good way, but it works.
$('a').on("click", function(){
if($(this).attr('href') != '#')
{
var href = $(this).attr('href');
$('#wrapper, footer').addClass('fading animation');
setTimeout(function() {
// window.location = href
$.post(window.location = href) // this line works :)
}, 200);
return false;
// $.post($(this).attr('href'));
}
});

Javascript Queue commands

I have a Tab widget set up on my website using JQuery 1.7.2 and JQuery UI 1.10.3.
I have written a JavaScript that parses the hash part of a URL in order that I can open a tab, load content into a div and scroll to a named anchor.
I can get the tab to open and content to load fine, however, scrolling to the anchor is proving to be a real pain.
I can get it to work if I trigger an alert before the scroll to the anchor (forcing you to click 'OK', but if I disable the alert (which I want to), it doesn't work.
I am guessing that it has something to do with waiting for the functions to finish processing first? But I'm quite inexperienced with JavaScript so would appreciate any help anyone could could give.
URL example: http://www.mysite.com/abc.html#tab=tab-3&#srv=includes/xyz&#anc=myanchor
My JavaScript is as follows:
$(document).ready(function () {
var parts = location.hash;
parts = parts.split('&'); // Hash parts of URL.
for (var i = 0; i < parts.length; i++) // Loop to separate variables.
{
if (parts[i].substr(1, 4).toUpperCase() == "TAB=") {
var tab = parts[i].substr(5).split("-").pop() - 1
} // Tab no. part from tab name.
if (parts[i].substr(1, 4).toUpperCase() == "SRV=") {
var srv = parts[i].substr(5)
} // Path to content to load.
if (parts[i].substr(1, 4).toUpperCase() == "ANC=") {
var anc = parts[i].substr(5)
} // Named anchor to locate.
};
// Tab found in URL so we'll check it exists and open it.
if (tab == -1) // Tab not found?
{
tab = 0 // Default to 1st tab if not.
};
$("#tabs").tabs("option", "active", tab); // Select the tab.
// Load content if provided in URL.
var href = $('.list li a').each(function () {
var href = $(this).attr('href');
if (srv == href.substr(0, href.length - 5)) {
var toLoad = srv + '.html .maint_content';
$('.maint_content').load(toLoad)
}
});
// Load content when selected from list.
$('.list li a').click(function () {
var toLoad = $(this).attr('href') + ' .maint_content';
$('.maint_content').fadeOut('normal', loadContent);
$('#load').remove();
$('.maint_content').fadeIn('normal', loadContent);
$('#load').fadeIn('normal');
window.location.hash = $(this).attr('href').substr(0, $(this).attr('href').length - 5);
function loadContent() {
$('.maint_content').load(toLoad, '', showNewContent());
}
function showNewContent() {
$('.maint_content').show('normal', hideLoader());
}
function hideLoader() {
$('#load').fadeOut('normal');
}
return false;
});
// Scroll to locate anchor.
//alert(anc);
$('html, body').animate({
'scrollTop': $('#' + anc).offset().top
}, 1000);
});
Thanks
I'm assuming the anchor you want to jump to is in the loaded content?
If so, just add a callback to the ajax call and do the jump there:
$('.maint_content').load(toLoad,'',showNewContent()).done(function () {
window.location.hash = $(this).attr('href').substr(0,$(this).attr('href').length-5);
});
You are ajaxing the content of the div. This means it is loading asynchronously. The animate function is thus called before the loading of the content has finished, and the anchor you are looking for is not yet there.
In order to fire the animation when the loading is complete, you can pass a function to .load()
$('.maint_content').load(toLoad,'',showNewContent());
so you allready got that: showNewContent is fired when the loading finishes.
So all you have to do is move your animation line to the end of that function.
function showNewContent()
{
$('.maint_content').show('normal',hideLoader());
$('html, body').animate({'scrollTop': $('#'+anc).offset().top}, 1000);
}

JQuery doesn't handle dynamic events with .load

On a webpage, when you click a link, the content of that page is fetched using the .load function. If nothing is found, then nothing happens.
The issue now is that if you go from one page to the next, and then back again, the code doesn't work.
Its a lot easier to go to my test site - http://joshblease.co.uk/JQuery/
Click on the orange link "Page"
Click on the header link "Index"
Now click on the orange "Page" link again
The page refreshes and I do not know why?
Edit: I am using Chrome to test this at the moment
Edit: My Code
function JLoad (url, elem, type) {
if(type != "ext"){
var $link = elem;
var uri = url + ' #content';
$("#content").load(uri, {'body_only': '1'}, function(response, status, xhr){
if (status != "error") {
if (window.history && window.history.pushState){
window.history.pushState({}, 'JoshBlease Test', url);
}else{
window.location.hash='!/'+url;
}
if(type == "menu"){
$("a").removeClass("active");
$link.addClass("active");
}
}else{
if(type == "menu"){
var linkText = $link.text();
$link.fadeOut(function(){$link.addClass("notFound").text("404 Error")}).fadeIn().delay(2000).fadeOut(function(){$link.removeClass("notFound").text(linkText)}).fadeIn();
}
}
});
}
};
This is in the header of the pages:
$(document).ready(function() {
$("a").on("click", function(event) {
console.log("Click");
event.preventDefault();
var url = $(this).attr("href").replace('./', '');
JLoad(url, $(this), $(this).attr("type"));
return false;
});
});
The Link being used:
Page
I am not sure why, but by using an old version of JQuery, I replaced the "on" event with "live". It now seems to work?

Categories