I'm using jQuery to dynamically load content in a div container.
The server side code detects if the request is AJAX or GET.
I want the browsers back/forward buttons to work with the code so I try to use history.pushState. I've got to following piece of code:
$('.ajax').on('click', function(e) {
e.preventDefault();
$this = $(this);
$('#ajaxContent').fadeOut(function() {
$('.pageLoad').show();
$('#ajaxContent').html('');
$('#ajaxContent').load($this.attr('href'), function() {
window.history.pushState(null,"", $this.attr('href'));
$('.pageLoad').hide();
$('#ajaxContent').fadeIn();
});
});
});
Everything works fine except when browsing with the browsers back/forward button, the adress in the bar changes according to plan but the page doesn't change. What am I doing wrong?
Updated script with the help from Clayton's answer
var fnLoadPage = function(url) {
$('#ajaxContent').fadeOut(function() {
$('.pageLoad').show();
$('#ajaxContent').html('').load(url, function() {
$('.pageLoad').hide();
$('#ajaxContent').fadeIn();
});
});
};
window.onpopstate = function(e) {
fnLoadPage.call(undefined, document.location.href);
};
$(document).on('click', '.ajax', function(e) {
$this = $(this);
e.preventDefault();
window.history.pushState({state: new Date().getTime()}, '', $this.attr('href'));
fnLoadPage.call(undefined, $this.attr('href'));
});
#Barry_127, see if this will work for you: http://jsfiddle.net/SX4Qh/
$(document).ready(function(){
window.onpopstate = function(event) {
alert('popstate fired');
$('#ajaxContent').fadeOut(function() {
$('.pageLoad').show();
$('#ajaxContent').html('')
.load($(this).attr('href'), function() {
$('.pageLoad').hide();
$('#ajaxContent').fadeIn();
});
});
};
$('.ajax').on('click', function(event) {
event.preventDefault();
alert('pushstate fired');
window.history.pushState({state:'new'},'', $(this).attr('href'));
});
});
If you take a look at the fiddle I provided and click the button, the alert will fire showing that you are pushing a new state. If you then proceed to click the back button once the pushstate has fired, you will see that the previous page (or popstate) will fire.
Related
I am trying to open the file dialog using jQuery but it's not opening inside the pop-up screen. If I am putting it outside the pop-up div it's working fine. I am providing my code below.
$(document).ready(function(){
$(document).on('click', '.brevent', function(e){
var file = $(this).parent().parent().parent().find('.file');
file.trigger('click');
e.stopImmediatePropagation();
e.preventDefault();
console.log('hello');
});
$(document).on('change', '.file', function(){
$(this).parent().find('.form-control').val($(this).val().replace(/C:\\fakepath\\/i, ''));
});
})
$(document).ready(function() {
$("#addeventdiv").on('click', function(e) {
e.stopPropagation();
});
$(".daterangepicker").on('click', function(e) {
e.stopPropagation();
});
$("#addeventclose").click(function() {
$("#addeventdiv").fadeToggle(400);
});
$("#addevent").on('click', function(e) {
$("#addeventdiv").fadeToggle(400);
e.stopPropagation();
});
$("body").on('click', function(e) {
if (e.target.className == "#addeventdiv") {
} else {
$('#addeventdiv').css("display", "none");
}
});
});
Here is my full plunkr code. I have one Add event button. When user will click on this button the form will display and there user has to click on Attachment button which is not working as per expected.
Your delegation fails. Likely because the dialog blocks the document click.
Just add this to any of the loads since the button click does not need to be delegated since it exists in the code at load time
$('.brevent').on("click", function(e){
e.preventDefault();
var file = $(this).parent().parent().parent().find('.file');
file.trigger('click');
e.stopImmediatePropagation();
console.log('hello');
});
Your handler for all clicks in #addeventdiv gets the event first and stops propagation. I think https://plnkr.co/edit/FWRAKwlUeIRarY6bZl9n?p=preview will work as you expect:
$(document).ready(function() {
$(".daterangepicker").on('click', function(e) {
e.stopPropagation();
});
$("#addeventclose").click(function() {
$("#addeventdiv").fadeToggle(400);
});
$("#addevent").on('click', function(e) {
$("#addeventdiv").fadeToggle(400);
e.stopPropagation();
});
$("#addeventclose").on('click', function(e) {
$('#addeventdiv').css("display", "none");
});
$("body").on('click', function(e) {
if (!$(e.target).parent("#addeventdiv").length) {
$('#addeventdiv').css("display", "none");
}
});
});
Just as a stylistic nitpick, you only need one document ready handler per file
I'm using Twitter Bootstrap's treeview plugin to generate a table of contents. The links I have for each node has the location of where the HTML is located and the anchor tag to go to. I parse this and load the HTML in a DIV on the current page and then scroll to the anchor tag. This works fine using the code below, but when I collapse or expand the nodes, it stops loading the HTML in the DIV and opens the page directly, basically ignoring the click event I have on the anchor tag. Any idea why that click event would not be triggered?
I have the following code to listen to buttons I have to expand or collapse the whole tree as follows:
var $treeview = $('#treeview');
$("#expand").click(function (e) {
e.preventDefault();
$treeview.treeview('expandAll', { silent: true });
});
$("#collapse").click(function (e) {
e.preventDefault();
$treeview.treeview('collapseAll', { silent: true });
});
I set silent to true to suppress events but then my listener for anchor tags with hrefs in them will no longer get called. Everything works as expected otherwise so I'm unsure why these event calls cause this problem. And unfortunately, I can't use the nodeSelected event because subsequent clicks on the anchor tags cause the other HTML page to load, which is undesired; it needs to remain on the current page so the following code is the only way I was able to achieve that.
$("a[href*='#']").click(function(e) {
e.preventDefault();
if (this && this.href !== "") {
// Split location and hash
var hash = this.hash;
var location = this.href.match(/[^#]*/g)[0];
$('#contents').load(location, function () {
$('html, body').animate({
scrollTop: $(hash).offset().top - 55
}, 200);
});
}
return false;
});
Maybe you can do like this
$("body").on("click", "#expand", function (e) {
e.preventDefault();
$treeview.treeview('expandAll', { silent: true });
});
$("body").on("click", "#collapse", function (e) {
e.preventDefault();
$treeview.treeview('collapseAll', { silent: true });
});
And
$("body").on("click", "a[href*='#']",function(e) {
e.preventDefault();
if (this && this.href !== "") {
// Split location and hash
var hash = this.hash;
var location = this.href.match(/[^#]*/g)[0];
$('#contents').load(location, function () {
$('html, body').animate({
scrollTop: $(hash).offset().top - 55
}, 200);
});
}
return false;
});
In my wordpress site I'm loading my posts via ajax.
But for some reason every other post the page chooses to refresh instead of loading through ajax.
So when I click on Next, the next post loads in perfectly. Then in the second post when I click Next again the page refreshes.
Any ideas why it only refreshes every second post?
JS:
jQuery(document).ready(function() {
jQuery('.arrows a').click(function() {
var url = jQuery(this).attr('href');
jQuery('#main-content').html('<h4>Loading...</h4>').load(url+ ' #main-content');
return false;
});
});
jQuery(document).ready(function() {
var clickHandler = function() {
var url = jQuery(this).attr('href');
jQuery('#main-content').html('<h4>Loading...</h4>').load(url+ ' #main-content', function() {
jQuery('.arrows a').click(clickHandler);
});
return false;
};
jQuery('.arrows a').click(clickHandler);
});
Delegate the click so that you aren't removing the element with the click handler.
For jQuery >= 1.7, use on.
jQuery(document).ready(function() {
jQuery('#main-content').on('click', '.arrows a', function(e) {
e.preventDefault();
var url = jQuery(this).attr('href');
jQuery('#main-content').html('<h4>Loading...</h4>').load(url+ ' #main-content');
});
});
For jQuery 1.4.2-1.7, use delegate instead of on.
jQuery(document).ready(function() {
jQuery('#main-content').delegate('.arrows a', 'click', function(e) {
e.preventDefault();
var url = jQuery(this).attr('href');
jQuery('#main-content').html('<h4>Loading...</h4>').load(url+ ' #main-content');
});
});
I have a working clickevent handler (don't know if it's the right word for it) on a page which uses show/hide (like tabs) if you click on one of the on-page links. This works perfectly, but now I walk into another issue.
When I link to one of the tabs from a different page, eg. /page-slug/#tabtoshow it won't show the right tab, it just shows the first (open) tab. I want it to show the right tab when a URL contains the same id, eg #tabtoshow. The tabs will have the same id as the link.
This is my current script.
$(function() {
$(".elevator a").click(function(evt) {
evt.preventDefault();
});
});
$(document).ready(function() {
$('a[href="#ondernemen"]').click(function() {
$(".active").removeClass("active");
$(this).parent('.label').addClass("active");
$('#ondernemen').slideDown(1000);
$('#ontdekken').slideUp(1000);
$('#groeien').slideUp(1000);
$('#spelen').slideUp(1000);
});
$('a[href="#groeien"]').click(function() {
$(".active").removeClass("active");
$(this).parent('.label').addClass("active");
$('#groeien').slideDown(1000);
$('#ontdekken').slideUp(1000);
$('#ondernemen').slideUp(1000);
$('#spelen').slideUp(1000);
});
$('a[href="#spelen"]').click(function() {
$(".active").removeClass("active");
$(this).parent('.label').addClass("active");
$('#spelen').slideDown(1000);
$('#ontdekken').slideUp(1000);
$('#groeien').slideUp(1000);
$('#ondernemen').slideUp(1000);
});
$('a[href="#ontdekken"]').click(function() {
$(".active").removeClass("active");
$(this).parent('.label').addClass("active");
$('#ontdekken').slideDown(1000);
$('#spelen').slideUp(1000);
$('#groeien').slideUp(1000);
$('#ondernemen').slideUp(1000);
});
$('body').on({
'mousewheel': function(e) {
if (e.target.id == 'el') return;
e.preventDefault();
e.stopPropagation();
}
})
$('a[href="#ontdekken"]').parent('.label').addClass("active");
});
Thanks in advance!!
If you're moving to another physical page, not a virtual page, you will need to handle the hash on the new page. You'd need to access location.hash or location.pathname and do something based on the hash value. You could handle it similarly to this:
$(document).ready(function() {
displayTab(location.hash);
});
Your code had some repetition, I have written a more general version for you. Also, I have used location.hash to determine what tab to activate.
$(document).ready(function() {
var selector = "#ondernemen, #ontdekken, #groeien, #spelen";
$(".elevator a").click(function(evt) {
evt.preventDefault();
});
$(selector).click(function() {
var that = this;
$(".active").removeClass("active");
$(this).parent('.label').addClass("active");
$(selector).each(function() {
if ($(this).attr("id") !== $(that).attr("id")) {
$(this).slideUp(1000);
}
});
$(this).slideDown(1000);
});
$('body').on({
'mousewheel': function(e) {
if (e.target.id == 'el') return;
e.preventDefault();
e.stopPropagation();
}
});
$(location.hash).parent('.label').addClass("active");
});
Here's the fiddle I'm working with: http://jsfiddle.net/Scd9b/
How can I delay the href function after the click?
For example a user clicks on the link, the message slides down One moment... and after 2 seconds the user continues to the page its linked to.
Sorry everybody forgot to mention there are some anchors that are not linked.
You can simulate navigating to a page by settings window.location. So we will block the normal function of the link with preventDefault and then in a setTimeout, we will set the correct window.location:
https://codepen.io/anon/pen/PePLbv
$("a.question[href]").click(function(e){
e.preventDefault();
if (this.href) {
var target = this.href;
setTimeout(function(){
window.location = target;
}, 2000);
}
});
Check this fiddle: http://jsfiddle.net/C87wM/1/
Modify your toggle like this:
$("a.question[href]").click(function(){
var self = $(this);
self.toggleClass("active").next().slideToggle(2000, function() {
window.location.href = self.attr('href'); // go to href after the slide animation completes
});
return false; // And also make sure you return false from your click handler.
});
Cancel the click and use setTimeout to change the location.
$(document).ready(function(){
$("span.answer").hide();
$("a.question").click(function(e){
$(this).toggleClass("active").next().slideToggle("slow");
e.preventDefault();
var loc = this.href;
if(loc){
window.setTimeout( function(){ window.location.href=loc; }, 2000 );
}
});
});
$(document).ready(function(){
$("span.answer").hide();
$("a.question").click(function(e){
e.preventDefault();
$(this).toggleClass("active").next().slideToggle("slow");
var Link = $(this).attr("href");
setTimeout(function()
{
window.location.href = Link;
},2000);
});
});
Prevent the default action of the link, first of all. Then add a timeout of 2 seconds, after which the page is redirected to the url found in the href attribute of the link.
$("a.question").click(function(e){
e.preventDefault();
$(this).toggleClass("active").next().slideToggle("slow");
setTimeout(function(){
location.href = $(this).prop("href");
}, 2000);
});
Example.
How about e.preventDefault in your click handler. Then do a setTimeout that takes you to your destination?
$("a.question").click(function(e){
e.preventDefault();
$(this).toggleClass("active").next().slideToggle("slow");
setTimeout('window.location.href=' + $(this).attr(href), 2000);
});
This should do it:
$("a[href]").click(function () {
var url = this.href;
setTimeout(function () {
location.href = url;
}, 2000);
return false;
});
Setting window location didn't sound like a good idea to me, So here's what I did
On click it checks whether the user clicked the link if yes it waits 2 seconds then triggers the click again and since it's not user-triggered it doesn't wait this time
document.getElementById("question").addEventListener("click", function(e) {
//if user clicked prevent default and trigger after 2 seconds
if(e.isTrusted) {
e.preventDefault();
//after 2 seconds click it and it'll not wait since it's not user triggered
setTimeout(function() {
e.target.click();
}, 2000);
}
});
Bing