Javascript - conditional formatting breaks after element reload using ".load" - javascript

I'm very new to JavaScript / JQuery and having some issues with what should be a simple conditional formatting function. The conditional formatting function itself works fine, on initial page load; however, after performing an element reload set to run every 60 seconds, it breaks the conditional formatting again.
Here's the JavaScript:
$(document).ready(function(){
$('.ticker-item:contains("-")').css('color', 'red');
$('.ticker-item:contains("+")').css('color', '#2FA702');
$('.carousel-item h3:contains("Closed")').css('color', 'red');
$('.carousel-item h3:contains("Open")').css('color', '#2FA702');
});
var refreshTickers = setInterval(function () {
$("#top-bar").load(location.href+" #top-bar>*","");
}, 60000);
It's probably worth mentioning that it's only the ticker-item formatting that's going wrong after the element reload. The carousel-item formatting works fine. The ticker-items are inside the #top-bar element, whereas the carousel-items are not, so to me it's clear that the issue is within the #top-bar element as a result of the reload.
I've also tried the below code, to no avail:
$(document).ready(function(){
$('.ticker-item:contains("-")').css('color', 'red');
$('.ticker-item:contains("+")').css('color', '#2FA702');
$('.carousel-item h3:contains("Closed")').css('color', 'red');
$('.carousel-item h3:contains("Open")').css('color', '#2FA702');
});
var refreshTickers = setInterval(function () {
$("#top-bar").load(location.href+" #top-bar>*","");
$('.ticker-item:contains("-")').css('color', 'red');
$('.ticker-item:contains("+")').css('color', '#2FA702');
}, 60000);
What's more strange is that with this code, if I change the interval for the reload to 10 seconds, it seems to break the formatting for a few seconds but then fix it again, almost as though it is waiting for the rest of the function to execute before catching up with itself.
As I said, I'm new to JS and I've searched everywhere for a solution to this. Am I doing something wrong?
If you need anything else (i.e. HTML), please let me know.
Thanks in advance for your help.

if you want it to be done again and again you should create a separate function to that.
And the load function will trigger a callback whenever it completes you can use that callback to reformat it again.
function reFormat(){
$('.ticker-item:contains("-")').css('color', 'red');
$('.ticker-item:contains("+")').css('color', '#2FA702');
$('.carousel-item h3:contains("Closed")').css('color', 'red');
$('.carousel-item h3:contains("Open")').css('color', '#2FA702');
}
$(document).ready(function(){
reFormat();
var refreshTickers = setInterval(function () {
$("#top-bar").load(location.href+" #top-bar>*", function(){
reFormat();
});
}, 60000);
});

When you execute .load(), it takes some amount of time to go get the new data and insert elements into the DOM. However, the subsequent Javascript code there doesn't know that it's supposed to wait until .load() has finished and created the new elements.
In timeline form, what's currently happening is:
call .load()
find and style any .ticker-item elements that are present
data received back from .load()
create new .ticker-item DOM elements
What you want to happen:
call .load()
wait until data received back from .load()
create new .ticker-item DOM elements
find and style any .ticker-item elements that are present
Anees' answer is exactly what you want: consolidate your formatting code into a single function, then call that as a callback function after .load() has finished.
As you progress in learning JavaScript, check out Promises and async/await as well.
EDIT:
There may still be a subtle delay between .load() finishing and those elements being present in the DOM.
One way to find out if that's the case would be to add a delay before calling reFormat() in the callback:
var elementCreationDelay = 500; // experiment with this duration
var refreshTickers = setInterval(function () {
$("#top-bar").load(location.href+" #top-bar>*", function(){
setTimeout(reFormat, elementCreationDelay);
}, 60000);

Related

How can I refresh a DIV and immediately scroll to the bottom?

I'm new to jQuery and I've tried these two functions:
function RefreshDiv() {
$('#box').load('messages.php #box');
}
var scrolled = false;
function Scroll() {
if(!scrolled){
var log = document.querySelector('#box');
log.scrollTop = log.scrollHeight - log.clientHeight;
}
}
$('#box').on('scroll', function(){
scrolled=true;
});
So far, I've tried multiple ways to articulate this like doing a setInterval function, a complete event inside of the .load() and a .on() function but neither seem to work in conjunction with each other, but they do work separately.
I would appreciate a solution on how to use my RefreshDiv() function every five seconds and then do Scroll() every second because I want to reload a box and then immediately have it scroll down, kind of something like this?:
setInterval(Scroll, 1000);
setInterval(RefreshDiv, 5000);
Obviously that doesn't work but I'm clueless on how else to structure this because .load() seems to always cancel out the rest of my code.
JQuery load is asynchronous, it will load data from the url into the jQuery element and, once complete, will execute the function passed as a second parameter.
The jQuery docs have a good page on the method here
As an example, try this snippet.
const url = 'https://jsonplaceholder.typicode.com/todos/1';
$(document).ready(() => {
$('#my-button').click(() => {
console.log('clicked');
$('#results').load(url, () => {
console.log('Everything loaded, can do something else');
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="results"></div>
<button id="my-button">Get stuff</button>
Keep in mind that is loading json, ideally it would request html or text.
per jQuery.load() documentation, you need to put your scrolling code inside the complete function so it gets executed after the load function has gathered and processed the data.
With this in mind, your load call would look something like:
$('#box').load('messages.php #box',function () { [code to perform the scroll]] });

How to Display value dynamically in a div tag using JS

I doing a little project which shows the internet speed by pinging the website and shows the network speed. but the problem is I have to reload every time to get the speed. How to make the div tag which contains the value of the speed to change dynamically.
I tried to load the value of the tag to itself but it doesn't work for me.
The HTML:
<h2> <span id="speed"></span> kbps</h2>
The JS:
kbitsPerSecond has the value of the speed.
$(document).ready( function () {
$('#speed').load('kbitsPerSecond');
refresh();
});
function refresh() {
setTimeout ( function() {
$('#speed').fadeOut('slow').load('kbitsPerSecond').fadeIn('slow);
refresh();
},200);
}
The tag has to be reloaded dynamically
First, you have two syntax problems.
The JQuery .load() method takes a URL as the first argument, you are passing the string 'kbitsPerSecond', which is not a URL:
$('#speed').load('kbitsPerSecond');
Your call to .fadeIn() is missing a closing quote and, if you want the fade in to happen after the .load has completed, you should not chain it after .load, but instead include it in the .load() callback:
$('#speed').fadeOut('slow').load('https://example.com').fadeIn('slow);
Now, setTimeout() is a one-time timer. Instead of making refresh() recursive, use setInterval() which is a continuous timer -- it counts to its supplied interval and then fires its callback function, then it counts again and fires again and so on. However, this will continue even after the page has finished loading, so you'll probably want to cancel the timer at some point.
Also, you don't need two separate .load() calls and a separate function as shown below:
let timer = null; // Will hold a reference to the timer
$(function () {
timer = setInterval (function() {
$('#speed').fadeOut('slow').load('https://example.com', function(){
$('#speed').fadeIn('slow');
});
},200);
});
// Uncomment and add the following to some callback that fires when you no longer want the timer to run
//clearInterval(timer);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h2> <span id="speed">TEST</span> kbps</h2>

How to select new loaded elements in jQuery without any event

I am working on a jQuery project which a part of page is loaded by choosing different options usign load() method.
I have this line in my application:
$('.pe').myFunction();
This code must be executed without any event. So I can not use any code like this:
$(document).on('click','.pe',function(){...});
It works well on all preloaded elements with pe class.But it does not work on new loaded contents which have same class.
Can you help me please?
The arguably correct way of doing it is using $(document).on('.pe','click',function(){...});; however, I did program a fair amount before I discovered that. So, I know there are a couple of work around. I'd use a class to mark an item as 'completed' after adding a click event.
If you have any 'hook' to know when the new html is added you can simply call a function that instead of using an interval.
Note regarding the question: you did say no events and this uses no events.
//Simulating ajax loading
setInterval(function () {
$(document.body).append('<button class="clickable">So clickable!</button><br />');
},1000);
//Your code
setInterval(function () {
$(".clickable:not(.completed)").click(function () {
console.log('works!');
}).addClass("completed");
},10);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<button class="clickable">So clickable!</button>
</div>
Finally I found the answer. I just put the same code inside the loaded page.
// New page which will be loaded with its all contents ...
<script>$('.pe').myFunction();</script>

Execute jQuery after Other JS file Dynamically loads content

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

time javascript

I have the following problem: on a customer's homepage the navibar is loaded by javascript, but I need to change some URL's on it. If I just start my script on $(document).ready() it runs before the customers script and has no effect. I only can use setTimeout for my function to wait until the other script is ready, but it's not good or safe at all. I can't change anything on the website, only add a javascript - is there a way to time it after the other one?
You can use repeated setTimeout, in order to check if menu is accessible.
function check_menu(){
if(document.getElementById('my_menu')==null){
setTimeout('check_menu()',500);
} else {
//do some stuff
}
}
If you have information about the menu like the id or class, use the onLoad() jQuery method on the element. For example if the code is loading asynchronously, and you add the onload to one of the last elements it should fire after the content has finished.
$.post('AsyncCodeLoad.php', function(data) {
$('#lastElementToLoad').onLoad(RunMyFunction);
});
Or if you have no chance to insert your code into the async loading just add to the bottom of the </body>:
$('#lastElementToLoad').onLoad(RunMyFunction);
Just a thought.
Yes, add your script at the bottom of the <body /> tag to ensure it does not run until all other scripts have run. This will only work however if your customer is loading the nav links synchronously.
If the nav is being loaded asynchronously, use JS's setInterval to repeatedly check the contents of the nav for links. When you determine the links have been added, cancel your interval check and call your script's logic entry point.
Cheers
Fiddle: http://jsfiddle.net/iambriansreed/xSzjA/
JavaScript
var
menu_fix = function(){
var menu = $('#menu');
if(menu.length == 0) return;
clearInterval(menu_fix_int);
$('a', menu).text('Google Search').attr('href','http://google.com');
},
menu_fix_int = setInterval(menu_fix, 100);
HTML
<div id="menu">Bing Search</div>​

Categories