How to suppress JavaScript function with eg. hasClass? - javascript

I'm building on a WordPress theme and wants to load posts and pages with AJAX. I got that sorted out through the snippet below, but now I just need to suppress the function when clicking on the logo, obviously linking to the home url. So when clicking on the logo it should force a normal reload, instead of using the function.
I figure it would have something to do with "if hasClass(logo) then use default"... Yeah, I'm fairly new to JavaScript, but I have been searching a lot, so any help in the right direction will be much appreciated. Thanks!
The snippet:
$(".home li.home").removeClass("home").addClass("current_page_item");
var $wrapperAjax = $("#wrapper-ajax"),
URL = '',
siteURL = "http://" + top.location.host.toString(),
$internalLinks = $("a[href^='"+siteURL+"']"),
hash = window.location.hash,
$ajaxSpinner = $("#ajax-loader"),
$el, $allLinks = $("a");
function hashizeLinks() {
$("a[href^='"+siteURL+"']").each(function() {
$el = $(this);
if ($.browser.msie) {
$el.attr("href", "#/" + this.pathname)
.attr("rel", "internal");
} else {
$el.attr("href", "#" + this.pathname)
.attr("rel", "internal");
}
});
};
hashizeLinks();
$("a[rel='internal']").live("click", function() {
$ajaxSpinner.fadeIn();
$wrapperAjax.animate({ opacity: "0.1" });
$el = $(this);
$(".current_page_item").removeClass("current_page_item");
$allLinks.removeClass("current_link");
URL = $el.attr("href").substring(1);
URL = URL + " .entry";
$wrapperAjax.load(URL, function() {
$el.addClass("current_link").parent().addClass("current_page_item");
$ajaxSpinner.fadeOut();
$wrapperAjax.animate({ opacity: "1" });
hashizeLinks();
});
});
$("#searchform").submit(function(e) {
$ajaxSpinner.fadeIn();
$wrapperAjax.animate({ opacity: "0.1" });
$el = $(this);
$(".current_page_item").removeClass("current_page_item");
$allLinks.removeClass("current_link");
URL = "/?s=" + $("#s").val() + " .entry";
$wrapperAjax.load(URL, function() {
$ajaxSpinner.fadeOut();
$wrapperAjax.animate({ opacity: "1" });
hashizeLinks();
});
e.preventDefault();
});
if ((hash) && (hash != "#/")) {
$("a[href*='"+hash+"']").trigger("click");
}

I'm guessing you mean the script from this line: $("a[rel='internal']")
In that case, $("a[rel='internal']").not('.logo') should do the trick.
I should've read the entire code. Replace $("a[href^='"+siteURL+"']") with $("a[href^='"+siteURL+"']").not('.logo') as well.

If it has the class .logo you could add this at the top of the function:
if ($(this).hasClass('logo')) return true;
See the simple example.

Related

Page loading is gradually getting slower using jQuery script

I'm using this jQuery script to show search results. Everything works fine, but when search results have more than one page and I'm browsing pages via paging then every page loading is gradually getting slower. Usually first cca 10 pages loads I get quickly, but next are getting avoiding loading delay. Whole website get frozen for a little while (also loader image), but browser is not yet. What should be the problem?
function editResults(def) {
$('.searchResults').html('<p class=\'loader\'><img src=\'images/loader.gif\' /></p>');
var url = def;
var url = url + "&categories=";
// Parse Categories
$('input[name=chCat[]]').each(function() {
if (this.checked == true) {
url = url + this.value + ",";
}
});
url = url + "&sizes=";
// Parse Sizes
$('input[name=chSize[]]').each(function() {
if (this.checked == true) {
url = url + this.value + ",";
}
});
url = url + "&prices=";
// Parse Prices
$('input[name=chPrice[]]').each(function() {
if (this.checked == true) {
url = url + this.value + ",";
}
});
$('.searchResults').load('results.php'+url);
$('.pageLinks').live("click", function() {
var page = this.title;
editResults("?page="+page);
});
}
$(document).ready(function(){
editResults("?page=1");
// Check All Categories
$('input[name=chCat[0]]').click(function() {
check_status = $('input[name=chCat[0]]').attr("checked");
$('input[name=chCat[]]').each(function() {
this.checked = check_status;
});
});
// Check All Sizes
$('input[name=chSize[0]]').click(function() {
check_status = $('input[name=chSize[0]]').attr("checked");
$('input[name=chSize[]]').each(function() {
this.checked = check_status;
});
});
// Edit Results
$('.checkbox').change(function() {
editResults("?page=1");
});
// Change Type
$(".sort").change(function() {
editResults("?page=1&sort="+$(this).val());
});
});
$('.pageLinks').live("click", function() {
var page = this.title;
editResults("?page="+page);
});
just a wild guess but... wouldn't this piece of code add a new event handler to the click event instead reaplacing the old one with a new one? causing the click to call all the once registered handlers.
you should make the event binding just once
var global_var = '1';
function editResults(def) {
// all your code
global_var = 2; // what ever page goes next
};
$(document).ready(function() {
// all your code ...
$('.pageLinks').live("click", function() {
var page = global_var;
editResults("?page="+page);
});
});

Change div content and hash url

I made a fully functional Ajax Content Replacement script. The problem is that it adds forwards like /#about or /#work or /#contact to the adress but when I reload the site, the main page will be show. Why? How is it possible that when i type in the adress the right subpage will be show?
Someone told me that the problem is that I added the file manually when I use popstate. So I want a solution without popstate. I am not a Javascript expert but I would like to learn it. Because popstate but this is very circuitous.
window.location.hash = $(this).attr('href');
My .html files are in stored in /data/. The strange thing is that it finds the file but when I try to find it manually,the page show the main page or when I refresh the site with F5 the main page will be show,too.
Can you help me and show me how it works. We can use my code to find the error. Thanks a lot.
Here is the Websitelink : Demo Link
function refreshContent() {
var targetPage = 'home';
var hashMatch = /^#(.+)/.exec(location.hash);
// if a target page is provided in the location hash
if (hashMatch) {
targetPage = hashMatch[1];
}
$('#allcontent').load('data/' + targetPage + '.html');
}
$(document).ready(function(){
refreshContent();
window.addEventListener('hashchange', refreshContent, false);
$('.hovers').click(function() {
var page = $(this).attr('href');
$('#allcontent').fadeOut('slow', function() {
$(this).animate({ scrollTop: 0 }, 0);
$(this).hide().load('data/' + page +'.html').fadeIn('normal');
});
});
});
$('.hovers').click(function() {
window.location.hash = $(this).attr('href');
$.get('data/'+this.href, function(data) {
$('#allcontent').slideTo(data)
})
return false
})
You should load the initial page based on location.hash (if provided) on page load:
function refreshContent() {
var targetPage = 'home';
var hashMatch = /^#!\/(.+)/.exec(location.hash);
// if a target page is provided in the location hash
if (hashMatch) {
targetPage = hashMatch[1];
}
$('#allcontent').load('data/' + targetPage + '.html');
}
$(document).ready(function(){
refreshContent();
...
You can make back and forward work by listening to the Window.onhashchange event:
window.addEventListener('hashchange', refreshContent, false);
Do note that this doesn't work in Internet Explore 7 or lower.
Edit:
Okay, try this:
var $contentLinks = null;
var contentLoaded = false;
function refreshContent() {
var targetPage = 'home';
var hashMatch = /^#(.+)/.exec(location.hash);
var $content = $('#allcontent');
// if a target page is provided in the location hash
if (hashMatch) {
targetPage = hashMatch[1];
}
// remove currently active links
$contentLinks.find('.active').removeClass('active');
// find new active link
var $activeLink = $contentLinks.siblings('[href="' + targetPage + '"]').find('.navpoint');
// add active class to active link
$activeLink.addClass('active');
// update document title based on the text of the new active link
window.document.title = $activeLink.length ? $activeLink.text() + ' | Celebrate You' : 'Celebrate You';
// only perform animations are the content has loaded
if (contentLoaded) {
$content
.fadeOut('slow')
.animate({ scrollTop: 0 }, 0)
;
}
// after the content animations are done, load the content
$content.queue(function() {
$content.load('data/' + targetPage + '.html', function() {
$content.dequeue();
});
});
if (contentLoaded) {
$content.fadeIn();
}
contentLoaded = true;
}
$(document).ready(function() {
$contentLinks = $('.hovers');
refreshContent();
window.addEventListener('hashchange', refreshContent, false);
$contentLinks.click(function(e) {
e.preventDefault();
window.location.hash = '!/' + $(this).attr('href');
});
});

jquery ajax navigation within ajax navigation

I'm using this code for my main site navigation which loads each page via ajax and has fallback.
$(function() {
var newHash = '',
$contentWrap = $("#content-wrap");
$("nav").on("click", "a", function() {
window.location.hash = $(this).attr("href");
return false;
});
$(window).on('hashchange', function() {
newHash = window.location.hash.substring(1);
$contentWrap.load(newHash + " #content");
});
$(window).trigger('hashchange');
});​
this works fine but when i load in the content from another page for example about.html i am also loading in some more buttons for navigation within #content-wrap.
so #content-wrap now contains a data box and some more buttons for navigation. when i click on the new navigation it needs to load new data in the data box.
first i tried just pretty much copying the script above but with new anchors however i get a conflict.
i figure i need some sort of if statement, i have looked into something like if (function !== undefined) but cannot figure out what to do.
I'm not sure how well i have explained myself, i'm confused explaining it but basically i want to combine the code above with basically the same code below without a conflict.
$(function() {
var newHash = '',
$contentWrap = $("#content-wrap"),
$aboutWrap = $("#a-wrap");
$("#content-wrap").on("click", "a", function() {
window.location.hash = $(this).attr("href");
return false;
});
$(window).on('hashchange', function() {
newHash = window.location.hash.substring(1);
$aboutWrap.load(newHash + " #a-content");
});
$(window).trigger('hashchange');
});​
Update: kind of works a bit but changed my plan
$(function() {
var newHash = '',
$nav = $("nav a"),
$boxBtn = '',
$aboutWrap = '',
$contentWrap = $("#content-wrap");
$("nav").on("click", "a", function() {
$(this).addClass("nav-click");
window.location.hash = $(this).attr("href");
return false;
});
$contentWrap.on("click", "a", function() {
$(this).addClass("btn-click");
window.location.hash = $(this).attr("href");
return false;
});
$(window).on('hashchange', function() {
var $aboutWrap = $("#a-wrap"),
$boxBtn = $("div.btn a");
newHash = window.location.hash.substring(1);
if ($nav.hasClass("nav-click")){
$contentWrap.load(newHash + " #content");
$nav.removeClass("nav-click");
};
if ($boxBtn.hasClass("btn-click")){
$aboutWrap.load(newHash + " #a-content");
$boxBtn.removeClass("btn-click");
};
});
$(window).trigger('hashchange');
}); /*/end*/
I had a similar problem, basically in most cases the problem is with conflicting element ID's. In the DOM you can use an ID only once. You can workaround that by using classNames and ID's for only unique elements like wrappers.

setInterval with other jQuery events - Too many recursions

I'm trying to build a Javascript listener for a small page that uses AJAX to load content based on the anchor in the URL. Looking online, I found and modified a script that uses setInterval() to do this and so far it works fine. However, I have other jQuery elements in the $(document).ready() for special effects for the menus and content. If I use setInterval() no other jQuery effects work. I finagled a way to get it work by including the jQuery effects in the loop for setInterval() like so:
$(document).ready(function() {
var pageScripts = function() {
pageEffects();
pageURL();
}
window.setInterval(pageScripts, 500);
});
var currentAnchor = null;
function pageEffects() {
// Popup Menus
$(".bannerMenu").hover(function() {
$(this).find("ul.bannerSubmenu").slideDown(300).show;
}, function() {
$(this).find("ul.bannerSubmenu").slideUp(400);
});
$(".panel").hover(function() {
$(this).find(".panelContent").fadeIn(200);
}, function() {
$(this).find(".panelContent").fadeOut(300);
});
// REL Links Control
$("a[rel='_blank']").click(function() {
this.target = "_blank";
});
$("a[rel='share']").click(function(event) {
var share_url = $(this).attr("href");
window.open(share_url, "Share", "width=768, height=450");
event.preventDefault();
});
}
function pageURL() {
if (currentAnchor != document.location.hash) {
currentAnchor = document.location.hash;
if (!currentAnchor) {
query = "section=home";
} else {
var splits = currentAnchor.substring(1).split("&");
var section = splits[0];
delete splits[0];
var params = splits.join("&");
var query = "section=" + section + params;
}
$.get("loader.php", query, function(data) {
$("#load").fadeIn("fast");
$("#content").fadeOut(100).html(data).fadeIn(500);
$("#load").fadeOut("fast");
});
}
}
This works fine for a while but after a few minutes of the page being loaded, it drags to a near stop in IE and Firefox. I checked the FF Error Console and it comes back with an error "Too many Recursions." Chrome seems to not care and the page continues to run more or less normally despite the amount of time it's been open.
It would seem to me that the pageEffects() call is causing the issue with the recursion, however, any attempts to move it out of the loop breaks them and they cease to work as soon as setInterval makes it first loop.
Any help on this would be greatly appreciated!
I am guessing that the pageEffects need added to the pageURL content.
At the very least this should be more efficient and prevent duplicate handlers
$(document).ready(function() {
pageEffects($('body'));
(function(){
pageURL();
window.setTimeout(arguments.callee, 500);
})();
});
var currentAnchor = null;
function pageEffects(parent) {
// Popup Menus
parent.find(".bannerMenu").each(function() {
$(this).unbind('mouseenter mouseleave');
var proxy = {
subMenu: $(this).find("ul.bannerSubmenu"),
handlerIn: function() {
this.subMenu.slideDown(300).show();
},
handlerOut: function() {
this.subMenu.slideUp(400).hide();
}
};
$(this).hover(proxy.handlerIn, proxy.handlerOut);
});
parent.find(".panel").each(function() {
$(this).unbind('mouseenter mouseleave');
var proxy = {
content: panel.find(".panelContent"),
handlerIn: function() {
this.content.fadeIn(200).show();
},
handlerOut: function() {
this.content.slideUp(400).hide();
}
};
$(this).hover(proxy.handlerIn, proxy.handlerOut);
});
// REL Links Control
parent.find("a[rel='_blank']").each(function() {
$(this).target = "_blank";
});
parent.find("a[rel='share']").click(function(event) {
var share_url = $(this).attr("href");
window.open(share_url, "Share", "width=768, height=450");
event.preventDefault();
});
}
function pageURL() {
if (currentAnchor != document.location.hash) {
currentAnchor = document.location.hash;
if (!currentAnchor) {
query = "section=home";
} else {
var splits = currentAnchor.substring(1).split("&");
var section = splits[0];
delete splits[0];
var params = splits.join("&");
var query = "section=" + section + params;
}
var content = $("#content");
$.get("loader.php", query, function(data) {
$("#load").fadeIn("fast");
content.fadeOut(100).html(data).fadeIn(500);
$("#load").fadeOut("fast");
});
pageEffects(content);
}
}
Thanks for the suggestions. I tried a few of them and they still did not lead to the desirable effects. After some cautious testing, I found out what was happening. With jQuery (and presumably Javascript as a whole), whenever an AJAX callback is made, the elements brought in through the callback are not binded to what was originally binded in the document, they must be rebinded. You can either do this by recalling all the jQuery events on a successful callback or by using the .live() event in jQuery's library. I opted for .live() and it works like a charm now and no more recursive errors :D.
$(document).ready(function() {
// Popup Menus
$(".bannerMenu").live("hover", function(event) {
if (event.type == "mouseover") {
$(this).find("ul.bannerSubmenu").slideDown(300);
} else {
$(this).find("ul.bannerSubmenu").slideUp(400);
}
});
// Rollover Content
$(".panel").live("hover", function(event) {
if (event.type == "mouseover") {
$(this).find(".panelContent").fadeIn(200);
} else {
$(this).find(".panelContent").fadeOut(300);
}
});
// HREF Events
$("a[rel='_blank']").live("click", function(event) {
var target = $(this).attr("href");
window.open(target, "_blank");
event.preventDefault();
});
$("a[rel='share']").live("click", function(event) {
var share_url = $(this).attr("href");
window.open(share_url, "Share", "width=768, height=450");
event.preventDefault();
});
setInterval("checkAnchor()", 500);
});
var currentAnchor = null;
function checkAnchor() {
if (currentAnchor != document.location.hash) {
currentAnchor = document.location.hash;
if (!currentAnchor) {
query = "section=home";
} else {
var splits = currentAnchor.substring(1).split("&");
var section = splits[0];
delete splits[0];
var params = splits.join("&");
var query = "section=" + section + params;
}
$.get("loader.php", query, function(data) {
$("#load").fadeIn(200);
$("#content").fadeOut(200).html(data).fadeIn(200);
$("#load").fadeOut(200);
});
}
}
Anywho, the page works as intended even in IE (which I rarely check for compatibility). Hopefully, some other newb will learn from my mistakes :p.

jQuery .load (or $.ajax) to get and set page title?

So far...
$('#container').load(hash + ' #page','', function() {
$('#container').fadeIn('fast');
document.title = $('#title').load(hash + ' #title').text();
});
...doesn't work.
Is there a better/correct way to do this?
FYI: -
I've added the ID #title the tag (all pages/it's a PHP template).
The container is .fade(ed)Out beforehand (less important)
Thanks in advance.
The problem is that, at the time you assign to document.title, the $('#title').load(hash + ' #title').text() might not have finished yet. Try setting the new document.title in the callback of that .load.
UPDATE
Try:
$('#container').load(hash + ' #page','', function() {
$('#container').fadeIn('fast');
$('#title').load(hash + ' #title', '', function(data) {
document.title = $(this).text();
});
});
I had the same requirement, to update the title for the page after ajax loads and that's what I used – one request, no need to set special attributes in your HTML:
var contentWrap = $('#content-wrap'),
contentId = '#content';
$.ajax({
url: hash.replace(/^#!\//, '') + '.html',
success: function(text) {
var oldContent = contentWrap.find(contentId),
newPage = $(text),
newContent = newPage.find(contentId);
oldContent.remove();
contentWrap.append(newContent);
// Set New Title
document.title = newPage.filter('title').text();
}
});
Do this :
$('#container').load(hash + ' #page','', function(result) {
$('#container').fadeIn('fast');
document.title = $(result).find('#title').text();
});
:)
We wanted to have an effect such that when someone visits our website, one should see the individual page's Title but when you move away, you can see "We'll still miss you... :)" using the below code:
<!-- Active Navigation Script -->
<script>
var url = window.location;
$('ul.nav a[href="'+ url +'"]').parent().addClass('active');
$('ul.nav a').filter(function() {
return this.href == url;
}).parent().addClass('active');
</script>
<!-- Tab Title change Script -->
<script>
$(function() {
// Get page title
var pageTitle = $("title").text();
// Change page title on blur
$(window).blur(function() {
$("title").text("We'll still miss you... :)");
});
// Change page title back on focus
$(window).focus(function() {
$("title").text(pageTitle);
});
});
</script>
You can see this in action here: http://www.solutelabs.com
Try below code:
.**filter**('title').text()
$('#container').load(hash + ' #page','', function(result) {
$('#container').fadeIn('fast');
document.title = $(result).filter('title').text();
});

Categories