I have a site in development which uses ajax page loading. This all works as expected except when it comes to images.
If you visit the link below, you will see a page title "Brands" which has an svg icon followed by an img.
Now if you click "Brands" in the sidebar the page will fade out, fetch the same page via the .load method and then fade in the content. However you will notice in Chrome that the svg is seemingly missing. If you check in safari the svg is visible but the img is missing. If you check it in Firefox then you get the alt attribute displayed.
After inspecting the page you will notice that they have a height of 0px and a width of 0px.
Why is happening and how can I resolve it?
http://kga.creativelittledevs.co.uk/consultant/brands/
I did try an create a reduced test case but it wasnt very easy to replicate.
Here's my full ajax code:
Object.defineProperty(String.prototype, "decodeHTML", {
value: function () {
return $('<div>', {html: '' + this}).html();
}
});
var init = function() {
$('select').selectric({
arrowButtonMarkup:'<svg class="selectric__button"><use xlink:href="/images/icons.svg#icon-right-chevron"></use></svg>'
}, 'refresh');
},
ajaxLoad = function(html) {
document.title = html.match(/<title>(.*?)<\/title>/)[1].trim().decodeHTML();
init();
},
loadPage = function(href, get, put) {
$(put).fadeOut(200, function(){
$(put).load(href + ' ' + get, function(){
ajaxLoad;
$(put).fadeIn(200);
});
});
};
init();
$(window).on('popstate', function(e) {
var state = e.originalEvent.state;
if (state !== null) {
loadPage(location.href, state.get, state.put);
} else {
history.pushState({get: '.app-main > *', put: '.app-main'}, '', location.href);
}
});
kga.doc.on('click', '.js-ajax', function() {
var $this = $(this),
href = $this.attr('href'),
get = $this.data('ajax-get') ? $this.data('ajax-get') + ' > *' : '.app-main > *',
put = $this.data('ajax-put') ? $this.data('ajax-put') : '.app-main';
if (href.indexOf(document.domain) > -1 || href.indexOf(':') === -1) {
history.pushState({get: get, put: put}, '', href);
loadPage(href, get, put);
return false;
}
});
Any help would be very much appreciated, thanks.
Related
I have a piece of JQuery code that animates an inline link to scroll smoothly to a <section> with an assigned ID on the same page (below).
/*Smooth Scrolling effect*/
$('a[href*="#"]:not([href="#"])').click(function() {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
if (target.length) {
$('html, body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}
}
});
For some reason, this will only work when it is placed externally of the rest of my JavaScript code
//*Side Navigation Menu*//
/* Open Side Nav - Set the width of the side navigation to 250px when burger menu icon is clicked. This perhaps needs rehashing a whole bunch more to make it more my own*/
function openNav() {
document.getElementById("mySidenav").style.width = "300px";
}
/*Close Side Nav - Set the width of the side navigation to 0 when close button is clicked*/
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
}
//*Email Popup Form - Currently resets user's view to the top of the screen. This needs to be fixed.*//
$ = function(id) {
return document.getElementById("popup");
}
var show = function(id) {
$(id).style.display = 'block';
}
var hide = function(id) {
$(id).style.display = 'none';
}
//*On hover over images on homescreen, display a black opacity box - Needs transferring to a seperate 'homepage' specific JavaScript file*//
$(function() {
$('#img0').hover(function() {
$('#fadeBox0').fadeIn(500);
}, function() {
$('#fadeBox0').fadeOut();
});
});
$(function() {
$('#img1').hover(function() {
$('#fadeBox1').fadeIn(500);
}, function() {
$('#fadeBox1').fadeOut();
});
});
$(function() {
$('#img2').hover(function() {
$('#fadeBox2').fadeIn(500);
}, function() {
$('#fadeBox2').fadeOut();
});
});
$(function() {
$('#img3').hover(function() {
$('#fadeBox3').fadeIn(500);
}, function() {
$('#fadeBox3').fadeOut();
});
});
I think the comments adequately (to my knowledge, I'm a beginner) explain what the JavaScript is supposed to do, but for some reason, some of this has stopped working as well. I don't know what I could have possibly changed, or where, as the rest of the website relies purely on HTML and CSS. (Note:After just testing something out, it appears that ALL of the above JavaScript has stopped working except for the small section labelled 'Side Navigation Menu'). Any help as to why this is happening would be much appreciated.
Thank you in advance!
Edit: I neglected to mention, the Smooth Scrolling Effect works when in an external JavaScript file, but only when Defer is used in the script tag. I've yet to try this with my other segments of JavaScript, but I don't want my code fragmented into individual JavaScript files for each individual function.
OK, more than "what is broken" let's try to wrap your head around the code.
This says: (what happens in processing)
Get all elements that do not have an href attribute equal to "#" (ALL elements, really?)
THEN get all the a elements that have an href attribute with "#" in them in that set
$('a[href*="#"]:not([href="#"])').click(function() {
This says: (what happens in processing)
get all the "a" elements that have an href with # in them
THEN exclude those that do not have an href attribute equal to "#"
$('a[href*="#"]').not('[href="#"]').on('click', function(){
Thus that second form is more efficient:
$('a[href*="#"]').not('[href="#"]').on('click', function() {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
if (target.length) {
$('html, body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}
}
});
that $('html, body') - would $('body') work there? Why animate those/both?
$(someselector).click(function(){ is shortcut for $(someselector).on('click',function()( so just use the second form.
//Email Popup Form - Currently resets user's view to the top of the
screen. This needs to be fixed.//
In isolation this does nothing (DID overwrite jQuery alias $ before
// do NOT replace the alias:
var popme = function(id) {
return document.getElementById("popup");
};
These are broken:
var show = function(id) {
$(id).style.display = 'block';
};
var hide = function(id) {
$(id).style.display = 'none';
};
Fixed versions:
var show = function(id) {
$(id)[0].style.display = 'block';
};
var hide = function(id) {
$(id)[0].style.display = 'none';
};
show("#myid");
hide("#myid");
Why this and not just use jQuery since you have it already?
$("#myid").show();
$("#myid").hide();
//*On hover over images on homescreen, display a black opacity box - Needs transferring
ONE document ready event handler:
$(function() {
$('#img0').hover(function() {
$('#fadeBox0').fadeIn(500);
}, function() {
$('#fadeBox0').fadeOut();
});
$('#img1').hover(function() {
$('#fadeBox1').fadeIn(500);
}, function() {
$('#fadeBox1').fadeOut();
});
$('#img2').hover(function() {
$('#fadeBox2').fadeIn(500);
}, function() {
$('#fadeBox2').fadeOut();
});
$('#img3').hover(function() {
$('#fadeBox3').fadeIn(500);
}, function() {
$('#fadeBox3').fadeOut();
});
});
Alternate with classes (assumes the fadeBox class in on a child element)...
$('#img0,#img1,#img2').hover(function() {
$(this).find('.fadeBox').fadeIn(500);
}, function() {
$('.fadeBox').fadeOut();
});
Alternate 2, use classes on whatever those point to:
$('.myImages').hover(function() {
$(this).find('.fadeBox').fadeIn(500);
}, function() {
$('.fadeBox').fadeOut();
});
Note hover like this is short for mouseenter and mouseout event handlers. ref: https://api.jquery.com/hover/
I have been playing around with this for quite some time, and I do not know what is wrong. When I have a few links in a row, and keep fluttering my mouse cursor over them quickly every so often a tooltip will remain visible when it should go away (it is visible even after the cursor is no longer on the link).
I believe my code is logically valid, can someone else see if they know why a tooltip here and there would remain visible?
For a link of this type:
Link
Here is the code:
function tooltip(e) {
var ticketType = j$(e).data("ticket-type");
var ticketID = j$(e).data("ticket-id");
j$.post("/Some/Url/", { "ticketID":ticketID, "ticketType":ticketType },
function(r) {
var title = r["tt"];
var tooltip = j$(e).kendoTooltip( { content: title, position: "top" } ).data("kendoTooltip");
}).always(function() {
if (j$(e).is(":hover")) { j$(e).data("kendoTooltip").show(); }
else { j$(e).data("kendoTooltip").hide(); }
});
j$(e).hover(function() {},
// Handler for when the pointer is leaving an element
function(e) {
if (j$(e.target).data("kendoTooltip") != undefined) {
j$(e.target).data("kendoTooltip").hide();
.log(e.target.innerHTML + ": was hidden.");
}
}
);
}
I think the problem is that sometimes you mouseout before ajax post returns, therefore the tooltip is shown after you leave a link. As well as hiding on mouseout, how about setting a data attribute on the target link so that the AJAX return can check the attribute before showing the tooltip:
function tooltip(e) {
j$(e).data("hover", "true"); //turn on hover data-attribute
var ticketType = j$(e).data("ticket-type");
var ticketID = j$(e).data("ticket-id");
j$.post("/Some/Url/", { "ticketID":ticketID, "ticketType":ticketType },
function(r) {
var title = r["tt"];
var tooltip = j$(e).kendoTooltip( { content: title, position: "top" } ).data("kendoTooltip");
}).always(function() {
if (j$(e).data("hover") == "true") { j$(e).data("kendoTooltip").show(); }
else { j$(e).data("kendoTooltip").hide(); }
});
j$(e).hover(function() {},
// Handler for when the pointer is leaving an element
function(e) {
j$(e).data("hover", "false"); //turn offhover data-attribute
if (j$(e.target).data("kendoTooltip") != undefined) {
j$(e.target).data("kendoTooltip").hide();
.log(e.target.innerHTML + ": was hidden.");
}
}
);
}
DEMO
NOTE: demo uses a setTimeout to fake an ajax call
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);
});
});
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');
});
});
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.