i am having trouble getting ajax loaded links to load other ajax content.
Basically this is my ajax code:
$(function () {
var api = $("#content").jScrollPane().data('jsp');
var reinitialiseScrollPane = function()
{
api.reinitialise();
}
// attaching click handler to links
$("#contentcontainer a[href]").click(function (e) {
// cancel the default behaviour
e.preventDefault();
// get the address of the link
var href = $(this).attr('href');
// getting the desired element for working with it later
var $wrap = $('#content');
$wrap
// removing old data
api.getContentPane()
// load the remote page
.load(href, reinitialiseScrollPane , function (){
}
);
});
});
Basically the links inside the navigation work fine since they are loaded when page is loaded, but links inside the ajax content (wich are supposed to load pages in the same place the navigation links load content) dont work, my understanding is that there needs some sort of ".live" function called as the js does not rescan the code once ajax loads content.
I found some solutions but none i could relate to the code im using.
The first part of the code is not ajax but for a scrollbar plugin, i did not remove it because id like to avoid it getting voided by a solution that dosent keep it into count.
Thanks.
Try using the .on() method (see jQuery documentation) when attaching the click handler:
$(document).on('click', '#contentcontainer a[href]', function (e) {
// Rest of your code here
});
Related
I am using Boostrap 5 and this Lightbox library https://trvswgnr.github.io/bs5-lightbox/
It works fine on pages loaded normally but it will not load on AJAX loaded content.
I have tried this code to make it work with AJAX but it did not work.
$(document).on('click', '[data-toggle="lightbox"]', function(event) {
event.preventDefault();
$(this).Lightbox();
});
It returned this error:
Uncaught TypeError: $(...).Lightbox is not a function
If you're using the vanilla JS version, the script only adds event handlers to elements with the data-toggle="lightbox" attribute that are present when the script loads, hence new elements loaded via AJAX calls not working.
If you're able to use Node (or hack around not using node with a module loader like RequireJS), you can instantiate a new Lightbox when each new element loads, per the docs:
$(document).on('click', '[data-toggle="foo"]', function (event) {
event.preventDefault();
const el = $(this);
const lightbox = new Lightbox(el);
lightbox.show();
});
Note that the correct syntax here is to create a new lightbox from the element and then use lightbox.show()... $(this).Lightbox() will never work.
I have a dynamic website where all links grab new sections via an ajax request from other pages and replace the current section.
My problem comes in two forms. When I load a new div from an Ajax get request. Some sections need js files too. For example, one uses a particles.js as a canvas background. After I complete the ajax request I then getScript"js file" and it works. However if you move onto other sections that getScript is still running and now unbinded because that section is gone. If I go back to that section again I need to getScript again and now I'm running it twice. This can be very CPU and GPU intensive and slows down my site.
Things like css files are easy because I can create an if statement to load if its not already loaded, script tags are different because the Dom only loads once. Appending/removing the script to the head is useless because the site is entirely Ajaxed.
here is example of a script
//pricing.html
$(".link-pricing").click(function (e) {
e.preventDefault();
$("#togglenav").collapse("hide");
$("#main").load("../../damonmedek/home/pricing.html #main-pricing");
$(document).ajaxComplete(function (event, xhr, settings) {
if (settings.url === "../../damonmedek/home/pricing.html") {
//Add CSS
if (!$("link[href='../assets/css/home%20css/pricing%20css/particles-js.css']").length)
$('<link href="../assets/css/home%20css/pricing%20css/particles-js.css" rel="stylesheet">').appendTo("head");
//Remove CSS
$('link[rel=stylesheet][href*="../assets/css/home%20css/best-carousel-slide.css"]').remove();
//Add JS
$.getScript("../assets/js/home/pricing%20js/modal%20popup.js", function () {});
**$.getScript("../assets/js/home/pricing%20js/particles.js", function () {});**
$.getScript("../assets/js/home/pricing%20js/pricing-animated%20heading.js", function () {});
$.getScript("../assets/js/members%20js/ajax%20members-only.js", function () {});
$.getScript("../assets/js/home/pricing%20js/app.js", function () {});
$.getScript("../assets/js/members%20js/ajax%20members-only.js", function () {});
}
});
});
How can I rebind page to js file, or stop getScript, or some smarter way to fix this problem?
Its not just cpu problems, duplicate getScripts can cause problems like posting twice on submit and weird stuff like that.
So this answer isn't as simple as I thought. Its involves event propagation which I encourage you too look up.
In order to grab the script just once its can't be through jquery but something like this.
function loadJSFile() {
if ($('script[src="' + jsFile + '"]').length > 0) {
//script exists
} else {
function loadScript(url, callback) {
// adding the script tag to the head as suggested before
var body = document.getElementsByTagName("body")[0];
var script = document.createElement("script");
script.classList.add("example");
script.type = "text/javascript";
script.src = url;
// then bind the event to the callback function
// there are several events for cross browser compatibility
script.onreadystatechange = callback;
script.onload = callback;
// fire the loading
body.appendChild(script);
}
var myPrettyCode = function () {
// here, do what ever you want
};
loadScript(jsFile, myPrettyCode);
}}```
Then you need to use a bubbling method to click on things. like a div that is flown in and out and flown in and out. the js file is only loaded once but you are clicking through the main div that is loaded on first page load. And into the div you flying in, that contains the ids and classes you have inside that div. kinda confusing I know.
```$("#home-div").on('click', '#ajaxedInDiv', function (e) {
$("#ajaxedInDiv").attr("something");
}
So, I have the following code:
$(document).ready(function(){
//Retrieve menu html
$.get('/modules/menu.php', function(data) {
//Load menu html
$('main#main').prepend(data);
});
//Initialize Menu
menuInit();
$('#menuToggle').click(function() {
$('#main_menu').fadeToggle();
});
});
menuInit() successfully modifies DOM elements when included in the html directly instead of using $.get(),so the intialization has no issues, however, when using ajax, the intialization of the menu starts before the DOM elements are fully loaded.
I've made a little research and .prepend() does not support callbacks, so not an option.
Surrounding menuInit() with a setTimeOut() with 100 ms works, but it will most certainly fail with slow connections, I need something more dynamic.
Just put the rest of the code inside the callback so it executes after the data has been added to the page:
$(document).ready(function(){
//Retrieve menu html
$.get('/modules/menu.php', function(data) {
//Load menu html
$('main#main').prepend(data);
//Initialize Menu
menuInit();
$('#menuToggle').click(function() {
$('#main_menu').fadeToggle();
});
});
});
I load a part of my basketpage inside an accordion div in my header. This works great and shows my basket in a nice dropdown.
The last problem I need to solve with this is to get the buttons in the loaded content to work. Is it possible to write an callback that make these works? Im not sure even what to google for this one..
This is how the buttons is setup in the loaded content:
checkout
Script Im using to load the content:
$('.dcjqg-accordion ul.sub-menu').load('/m4n?seid=etailer-basket div#centerbox.itembox.centerbox');
use the callback function of .load().
$('.dcjqg-accordion ul.sub-menu').load('/m4n?seid=etailer-basket div#centerbox.itembox.centerbox', function() {
$("#_ec_oie2").on("click", function() {
if (UI.pb_boolean(this, 'click')) { }
return false;
});
});
checkout
You need to use a child selector for the event. You can attach an event to the .sub-menu element that will fire on the content loaded in through the ajax. Something like the following could work:
$(".dcjqg-accordion ul.sub-menu").on("click", ".action.actionbasket.checkout", function() {
if( UI.pb_boolean(this, 'click') ) {}
return false;
});
Notice the second parameter to the on method. It is a selector that will be used to look at the target of the click event. I used .action.actionbasket.checkout since that is what is on your a tag.
This code may not work exactly, but this should help get you in the right direction.
Here is the link to the jQuery documentation for the on method: https://api.jquery.com/on/
If I want to be able to load in content (containing elements depending on jQuery) after main page has finish loading, the content will be retrived from another page on my site (div). How do I then get those element depending on jQuery to execute (work)?
How do I make these different jQuery elements to work with some easy method after they being loaded into the main page? I dont know much about jQuery, it would be great if I could just ad/edit a function on the scripts to make them work after inload, but ofcurse its propably more difficult than that. In the passed days I have tried initialize the different object that loads in but notice that it was quite difficult with complicated scripts.
The page load in new content like this (selectbox):
<select id="selectbox">
<option>1</option>
</select>
jQuery code to the selectbox:
$(document).ready(function(){
$("#selectbox").change(function(){
var selectedOption = $('#selectbox :selected').val();
$containerDiv = $('#div_that_will_get_content');
$containerDiv.html("");
switch (selectedOption)
{
case "1":$containerDiv.load( "Page.html #div1 );break;
}
return true;
});
});
Selected option in selectbox (1) collects data from Page.html #div1, then send the data to div "#div_that_will_get_content". So the div get loaded in after the main page have finish loading.
Now if I want to put a jQuery element in this div and then load that div into the main page via the selectbox and to "#div_that_will_get_content", those elements dont work. Can anybody show a easy jQuery example with a smal explanation how the script was written from the begining and what you changed to make it work after it was loaded in?
Thanks.
Not entirely sure what you are needing but part of the answer lies in using the success callback of load()
/* define this cached elemn outside change handler so don't have to search DOM each time*/
$containerDiv = $('#div_that_will_get_content');
$("#selectbox").change(function() {
/* val() of select is same as searching for selected option val() but less code*/
var url = 'Page.html #div' + $(this).val();
$containerDiv.load(url, function() {
/* new ajax loaded html exists you can run code here*/
$containerDiv.find('#someOtherDiv').doSomething()
})
});
API Reference: http://api.jquery.com/load/
If your problem relates to binding events to elements that will be loaded any time in the future such as click handlers, you can delegate these in your page load script using on()
$(document).on('click', '.className', function(){
doSomething();
})