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");
}
Related
I request an external script by adding this to my HTML file:
<script>
$(document).on("turbolinks:load", function() {
$.getScript("https://example.com/script");
});
</script>
Say the content of the script is as follows:
doSomething = function() {
// ...
};
My website is a Ruby on Rails app with Turbolinks, which caches the content of the requested script between page visits. My script tag does not know about this, so if I revisit the page it will request the script again. How do I avoid this? My current solution is to check if the scripts content is known:
<script>
$(document).on("turbolinks:load", function() {
if (!window.doSomething) {
$.getScript("https://example.com/script");
}
});
</script>
But this depends on the content inside the script staying the same. So I would rather check if a script from the source https://example.com/script already exists? Or maybe some other approach. Any ideas?
Like epascarello commented, $.getScript appends to head so check that it's not in head before getting it.
if (!$('head script[src^="https://example.com/script"]').length){
$.getScript("https://example.com/script");
}
Use the Attribute Starts With Selector because $.getScript appends a timestamp to avoid getting an already cached version, i.e. it requests a new URL each time.
If you're going to use it more than once:
function getScriptOnce(url){
let selector = 'head script[src^="' + url + '"]';
if (!$(selector).length){
$.getScript(url);
}
}
getScriptOnce("https://example.com/script");
I am having an Anchor link, on click of Anchor link, I am registering new JavaScript file html page.
On registering the JavaScript file dynamically, document is reloaded partially (As I see reload icon in browser for some time).
I want to call my JavaScript function once the script got registered (Obviously when reload icon get stopped in the browser). But the function MyJavaScriptFunction got called while document is still reloading.
Using setTimeOut resolves the issue but I don't want to use it as page loading time is not fixed. Please help.
The code I am using is as follow:
function addScriptDynamically(src, callback) {
var s = document.createElement('script');
s.setAttribute('src', src);
s.onload = callback;
document.body.appendChild(s);
}
addScriptDynamically('URL Of JS File',function(){
MyJavaScriptFunction();
})
What I tried so far...
Option-1:
addScriptDynamically('URL Of JS File',function(){
$(document).ready(function(){
MyJavaScriptFunction();
});
})
Option-2:
addScriptDynamically('URL Of JS File',function(){
$(window).load(function(){
MyJavaScriptFunction();
});
})
jquery has a function for this purpose.
Using jquery
$(function () {
//write your function code here.
})
This function is called only when the content of the page are first loaded.
2)
Using Javascript
window.onload = function(){
//write your function code here.
}
I have an ajax function that is being called multiple times on click when it should just be firing once.
$(document).on('click', '.newGameItem', function() {
console.log('start click event');
var apiUrl = $(this).attr('data-api-string');
var callType = $(this).attr('data-api-post-call');
var apiKey = $(this).attr('data-api-key');
var dataType = $(this).attr('data-api-data-type');
var returnValue = $(this).attr('data-return-value');
var currentGameWrapper = $(this).parent().parent().parent();
console.log('before api call');
getNewItem(apiUrl, callType, apiKey, dataType, returnValue, currentGameWrapper);
console.log('after api call');
});
This click event is inside a turbolinks load event:
$(document).on('turbolinks:load', function() { ... }
I put in a console.log at the top of the turbolinks load event and can confirm that the JavaScript in this file is running 3 times. I've noticed this happens when I am on this page, click a link to another page and then hit the back button to this page but it also happens when I click to the page from somewhere else in the app.
This file is being compiled through the asset pipeline and we have data-no-turbolink on the body tag (which has actually never seemed to do anything.
Any ideas why this is happening or ways to get around it? Taking turbolinks out of my app completely is not an option for me at this time.
Thank you
That click event has to be outside the 'turbolinks:load' event, that's the point of attaching it to $(document) as opposed to the element. If you have it inside it will create it every time a page loads. Your javascript should look like this:
$(document).on('click', '.newGameItem', function() {
// ...
});
$(document).on('turbolinks:load', function() {
// ...
});
I'm working to modify some content which is dynamically loaded via another script(let's call is script #1) onto my site. Script #1 loads some markup and content and I've been using the setTimeout() function to call my script (Script #2) using a delay of a few seconds, in order to wait to be sure that Script #1 has executed and the content is present in the DOM.
My issue is that Script#1 has different loading times, based on the server load and can be slow or fast depending on these factors, and right now, playing it safe with setTimeout() I'm often left with a second or two where my scripts are still waiting to be fired and Script #1 has already loaded the content.
How can I execute my script as soon as Script#1 successfully loads it's dynamic content?
I've found this post which does seem to address the same issue but using the setInterval function as #Matt Ball has laid out there doesn't work at all for some reason. I'm using the code below where 'div.enrollment' is meant to find in the DOM which is dynamically loaded and execute..
jQuery(window).load(function ($)
{
var i = setInterval(function ()
{
if ($('div.enrollment').length)
{
clearInterval(i);
// safe to execute your code here
console.log("It's Loaded");
}
}, 100);
});
Any help on guidance on this would be greatly appreciated! Thanks for your time.
It seems that the healcode.js is doing a lot of stuff. There is a whole lot of markup added to the <healcode-widget> tag.
I would try to add another tag with an id inside and test for its existence:
<healcode-widget ....><div id="healCodeLoading"></div></healcode-widget>
Test in an interval for the existence of healCodeLoading inside <healcode-widget>: (Assuming jQuery)
var healCodeLoadingInterval = setInterval(function(){
var healCodeLoading = jQuery('healcode-widget #healCodeLoading');
if (healCodeLoading.length == 0) {
clearInterval(healCodeLoadingInterval);
// Everything should be loaded now, so you can do something here
}
}, 100);
healcode.js should replace everything inside <healcode-widget></healcode-widget> during init. So, if your <div>-element is no longer inside, the widget has loaded and initialized.
Hope that helps.
If you just want to load some markup and content and then run some script afterwards, you can use jQuery. You should use something like the following in script#1 to run a function in script#2
$.get( "ajax/test.html", function( data ) {
// Now you can do something with your data and run other script.
console.log("It's Loaded");
});
The function is called, after ajax/test.html is loaded.
Hope that helps
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
});