I have ajax displaying posts (infinite scroll).
And I have a script which works prior to the ajax response but not after.
So when the new posts are loaded, the javascript is not executed in the ajax loaded posts.
document.addEventListener('DOMContentLoaded', function() {
jQuery(function($) {
$('.post-link-home').find('.elementor-post').each(function() {
let link = $(this).find('a').attr('href');
$(this).wrapAll(document.createElement('a'));
$(this).closest('a').attr('href', link);
});
});
});
Any ideas how to make this work after the ajax loaded posts?
This is what worked for me:
document.addEventListener('DOMContentLoaded', function PostLinkHome() {
jQuery(function($) {
$('.post-link-home').find('.elementor-post').each(function() {
let link = $(this).find('a').attr('href');
$(this).wrapAll(document.createElement('a'));
$(this).closest('a').attr('href', link);
});
});
jQuery(document).ajaxComplete(function() {
PostLinkHome();
});
});
Explanation
I gave the first function executed without Ajax a name: PostLinkHome()
I then called for that same function to be executed when Ajax is loaded:
jQuery(document).ajaxComplete(function() { PostLinkHome(); });
Source
Related
My code involves fetching some data using jQuery's Ajax. I then append the result I get from the server to html (in form of buttons). All buttons have a class name mybutton. A separate JavaScript file handles the button click events. Everything works okay for the first Ajax call but I then get an error on second Ajax call. The Ajax calls are made at an interval
HTML code
<button class="mybutton">Button 1</button>
Javascript Code in a SCRIPT1.js file
document.addEventListener("DOMContentLoaded", ready);
function ready() {
let buttons = document.querySelectorAll(".mybutton");
buttons.forEach((button) => {
button.addEventListener("click", () => {
//do some stuff
console.log("I was Clicked");
});
});
}
jQuery CODE in a SCRIPT2.js file
$(document).ready(() => {
//append the html to add more buttons after some time
setInterval(() => {
$.ajax({
method: "GET",
url: "/getButtons",
async: true,
success: function (data, status, xhr) {
data.forEach((item) => {
$("body").append(
'<button class="mybutton">' + item + "</button>"
);
});
const scriptsrc = document.createElement("script");
scriptsrc.setAttribute("type", "text/javascript");
scriptsrc.setAttribute("src", "//script location here");
$("head").append(scriptsrc);
},
});
}, 10000);
});
The JavaScript attached to the buttons only fires up only once after the first Ajax request.The second time I get an error:
Uncaught SyntaxError: Identifier 'buttons' has already been declared
Can you try with the following script? To clarify if the 'let buttons' is issue or the ready() function is overriding the existing one.
document.addEventListener("DOMContentLoaded", init_fun);
function init_fun() {
document.querySelectorAll(".mybutton").forEach((button) => {
button.addEventListener("click", () => {
//do some stuff
console.log("I was Clicked");
});
});
}
Updated due to the comment.
In this case, if you are injecting the script1 after your ajax call, you will have multiple script tags which include multiple variables with the same name.
Instead of adding the whole script, call the function after the success callback of the ajax call. That should avoid multiple variable issues.
The function below allows me to use an href link to POST request to the same page. It works for the first 2 times I click on the link, but this function doesn't seem to be recognized after a third POST request.
$(function() {
$('.sort-link').on('click', function(e) {
e.preventDefault();
$.post(this.href, function(data) {
$('.container').html(data);
});
});
});
I need to modify the function to have it work even after a POST request has been submitted.
As per #Elvin85's advice, I revised my function as follows:
$(function() {
$(document).on("click", '.sort-link', function(e) {
e.preventDefault();
$.post(this.href, function(data) {
$('.container').html(data);
});
});
});
It was a DOM-related issue.
I have two questions about this code. The first is why the modal is not shown before the alert? The second is how can i delay the modal, because the popup is so fast that i can't see nothing in the modal.
$('#myModal').modal('hide');
$(document).ajaxStart(function() {
$('#myModal').modal('show');
}).ajaxStop(function() {
$('#myModal').modal('hide');
//$('#myModal').delay(5000).modal('hide'); does not work
});
$(".generate_report").click(function(event) {
event.preventDefault();
$.post("xls.php", $(".form_report").serialize(), function() {
}).done(function(data) {
alert("should be executed only after modal");
});
});
demo
You can achieve the same with this code:
$(".generate_report").click(function (event) {
event.preventDefault();
$('#myModal').modal('show');
setTimeout(function(){
$.post("xls.php", $(".form_report").serialize(),function(data){
$('#myModal').modal('hide');
alert("after modal");
})
}, 2000);
});
And remove this code
$(document).ajaxStart(function() {
$('#myModal').modal('show');
}).ajaxStop(function() {
$('#myModal').modal('hide');
//$('#myModal').delay(5000).modal('hide'); does not work
});
What this code does is show a modal when the ajax call starts and instantly hide it when its done. You can use a timer to wait a while before closing it.
Also you've nested a callback function in your jQuery.post, but you don't use it which causes confusing code here. Theres no need to use .done() when you're just going to append it to the AJAX function directly. You can just use the callback function here.
$.post("xls.php", $(".form_report").serialize(), function(data) {
alert("should be executed only after modal");
});
But that is just a code styling concern. The done(), success(), fail() methods are used on a jQuery.Deferred promise object, which $.ajax happens to return. And since $.post/$.get are just pointers to $.ajax, they will too.
Secondly, if you want the modal to wait before it closes, you can do this:
var waitTimer;
var timeToWait = 2000; // Time to wait here
var $myModal = $('#myModal');
$myModal.modal('hide');
$(document).ajaxStart(function() {
$myModal.modal('show');
}).ajaxStop(function() {
if (waitTimer) {
clearTimeout(waitTimer);
}
waitTimer = setTimeout(function() {
$myModal.modal('hide');
}, msToWait);
});
The .delay() method you tried to use only works after you've animated something.
Also a quick tip: Cache your jQuery selectors. You're telling jQuery to jump in the DOM 3 times to search for the same element.
I am making few ajax requests in my jQuery file. On success of these jQuery requests, I wrote few on click events which are not working.
This is my code
$(document).ready(function (){
$.ajax ({
type: "POST",
url: 'myServlet',
async: false,
success: function (response) {
id = parseInt(response);
setOutputEvents();
}
});
function setOutputEvents() {
for (var queryNumber = 0; queryNumber <= id; queryNumber++) {
$.ajax({
type: "POST",
url: 'myOtherServlet',
data: {queryNumber: queryNumber},
success: success,
async: false
});
var success = function (response) {
//some code here
generateTable();
}
}
}
function generateTable () {
//some code here
pagination();
}
function pagination(){
$(".class").click(function(event) {
alert();
});
}
$("#me").on("click", function(){
alert("me is triggered");
});
});
I understand making multiple ajax requests is a bad programming practice but what could be the reason for on click events not getting triggered?
These are the onclick events which are not working.
function pagination(){
$(".class").click(function(event) {
alert();
});
}
$("#me").on("click", function(){
alert("me is triggered");
});
I am using Google Chrome Version 39.0.2171.95 on Windows 7.
Please do let me know if any further information is necessary.
Since you use ajax to load even the initial content it seems, .class / #me html elements likely do not exist on initial page load of the DOM. As you didn't post html, i'm guessing this is the case.
Thus, you need to use a delegated event click handler to respond to it
so, you would change
$("#me").on("click", function(){
to
$(document).on("click", "#me", function(){
and so forth to link it to the parent element that does exist, the document itself.
This would work:
$(".class").on("click", function(){
alert("me is triggered");
});
function generateTable () {
//some code here
pagination();
}
function pagination(){
$(".class").trigger("click");
}
Some notes:
Event handler must be registered before triggering click.
Triggered click selector must match the class which has the click event registered.
Functions must be defined before the usage.
After getting a new page with $.get none of the javascript will run on the new page.
Is there a way to make javascript use the new page too?
Many thanks
Dorjan
Edit: Example:
$(function() {
$('.viewPage').click(function() {
$('#mainarticle').fadeOut('slow')
$.get($(this).attr('href'), { js: "1" }, function(data) {
$('#mainarticle').html(data).fadeIn('slow');
});
return false;
});
});
Now this works fine however, the new page's anchor tags won't trigger (lets say it has a .viewPage).
I hope that clarify's the issue.
You need to bind events to your anchors using live:
$('a.something').live("click",function() {
alert('this will still work after a.something has been replaced via ajax');
});
Another way using $.get's callback:
$.get( "page.html", function(data) {
$('#someDiv').html(data);
$('a.something').click(function() {
alert('this will still work after a.something has been replaced via ajax');
});
});
Now that I've seen your code:
$(function() {
$('.viewPage').live("click",(function() {
$('#mainarticle').fadeOut('slow')
$.get($(this).attr('href'), { js: "1" }, function(data) {
$('#mainarticle').html(data).fadeIn('slow');
});
return false;
});
});
Yep; there is another jquery ajax method that will take the returned script from your page and execute it. Check the jquery docs.