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

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]] });

Related

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

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);

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>

SetInterval and SetTimeout not working when trying to load a Partial View

I'm trying to use JQuery to reload a PartialView in an ASP.Net MVC application.
My code:
<div class="partial">
#Html.Action("GetRemainingSeats", "Layout")
</div>
<script src="#Url.Content("~/Scripts/jquery-1.10.2.min.js")"></script>
<script type="text/javascript">
setTimeout(
$(function () {
setInterval(function () { $('#partial').load('#Html.Action("GetRemainingSeats", "Layout")'); }, 5000)
}), 6000);
</script>
The partial view is loaded correctly, but immediately after that, it will again execute the action, without waiting for the setTimeout function timer to elapse. After that it will stop doing anything.
Edit:
Inside the PartialView there is a table with shows in a cinema together with how many seats are left for each show. So I want that to update very couple of seconds so the employees can see how many seats are left for a show.
I'm using the timeout and setinterval function because on pageload the action is called. After that I want it to wait a couple of seconds before starting the interval
You script is attempting to load html into an element which does not exist (you only have an element with class="partial", not id="partial". You also need to use #Url.Action(), not #Html.Action() (which is a helper that call a child action - it does not generate a url which is expected by the .load() method. You need to make the following changes
html
<div id="partial"> // change this to specify the id attribute
#Html.Action("GetRemainingSeats", "Layout")
</div>
script
$(function () {
setInterval(function () {
$('#partial').load('#Url.Action("GetRemainingSeats", "Layout")'); }, 5000) // use #Url.Action()
}), 6000);
I really don't understand why you use both timeout and setinterval methods as both work same for first time, if you want to refresh div after 4 sec, stick with setInterval method otherwise if you want to refresh only once, use setTimeout method
var wait = setTimeout(
$(function () {
var s = setInterval(function () {
clearInterval(s); // you need to remove the interval if you want to run it once
$('#partial').load('/Layout/GetRemainingSeats');
}, 4000)
}), 6000);
also, you need to change
<script src="#Url.Content("~/Scripts/jquery-1.10.2.min.js")"></script>
to
<script src='#Url.Content("~/Scripts/jquery-1.10.2.min.js")'></script>

More efficient way to wait for all images to load in jQuery

I'm using a mix of .ready() and .load() to execute my desired function.
jQuery(document).ready(function($) {
$("img").load(function() {
// Function goes here
});
});
As you can see, this waits for the DOM to be ready, then on each <img> load, it executes the code.
If I only had one image to load this would be simple.
But the problem is -- what if I have 10 images to be loaded? The function will be called 10 times due to each image loading one by one, and that's not a very efficient way to go about it just to achieve what I want.
So here's the question -- is there a more efficient way to wait for all images to load, then execute the function once?
You could do something like this to avoid having your function run multiple times.
jQuery(document).ready(function($) {
var nrOfImages = $("img").length;
$("img").load(function() {
if(--nrOfImages == 0)
{
// Function goes here
}
});
});
jQuery(window).load(function() {
alert("page finished loading now.");
});
jQuery(window).load(...) will be triggered after all content on the page has been loaded. This different from jQuery(document).load(...) which is triggered after the DOM has been loaded. I think this will solve your issue.
If anybody wants to know, my final result was this:
(function($) {
$(window).load(function(){
// Function goes here
});
})(jQuery);
that's because
jQuery(window).load(function($) {});
isn't a jQuery object, as referenced in this question:
Calling jQuery on (window).load and passing variable for 'No Conflict' code

How to call a function after a div is ready?

I have the following in my javascript file:
var divId = "divIDer";
jQuery(divId).ready(function() {
createGrid(); //Adds a grid to the html
});
The html looks something like:
<div id="divIDer"><div>
But sometimes my createGrid() function gets called before my divIder is actually loaded onto the page. So then when I try to render my grid it can't find the proper div to point to and doesn't ever render. How can I call a function after my div is completely ready to be used?
Edit:
I'm loading in the div using Extjs:
var tpl = new Ext.XTemplate(
'<div id="{divId}"></div>');
tpl.apply({
});
You can use recursion here to do this. For example:
jQuery(document).ready(checkContainer);
function checkContainer () {
if($('#divIDer').is(':visible'))){ //if the container is visible on the page
createGrid(); //Adds a grid to the html
} else {
setTimeout(checkContainer, 50); //wait 50 ms, then try again
}
}
Basically, this function will check to make sure that the element exists and is visible. If it is, it will run your createGrid() function. If not, it will wait 50ms and try again.
Note:: Ideally, you would just use the callback function of your AJAX call to know when the container was appended, but this is a brute force, standalone approach. :)
Thus far, the only way to "listen" on DOM events, like inserting or modifying Elements, was to use the such called Mutation Events. For instance
document.body.addEventListener('DOMNodeInserted', function( event ) {
console.log('whoot! a new Element was inserted, see my event object for details!');
}, false);
Further reading on that: MDN
The Problem with Mutation Events was (is) they never really made their way into any official spec because of inconcistencies and stuff. After a while, this events were implemented in all modern browser, but they were declared as deprecated, in other words
you don't want to use them.
The official replacement for the Mutation Events is the MutationObserver() object.
Further reading on that: MDN
The syntax at present looks like
var observer = new MutationObserver(function( mutations ) {
mutations.forEach(function( mutation ) {
console.log( mutation.type );
});
});
var config = { childList: true };
observer.observe( document.body, config );
At this time, the API has been implemented in newer Firefox, Chrome and Safari versions. I'm not sure about IE and Opera. So the tradeoff here is definitely that you can only target for topnotch browsers.
To do something after certain div load from function .load().
I think this exactly what you need:
$('#divIDer').load(document.URL + ' #divIDer',function() {
// call here what you want .....
//example
$('#mydata').show();
});
Through jQuery.ready function you can specify function that's executed when DOM is loaded.
Whole DOM, not any div you want.
So, you should use ready in a bit different way
$.ready(function() {
createGrid();
});
This is in case when you dont use AJAX to load your div
inside your <div></div> element you can call the $(document).ready(function(){}); execute a command, something like
<div id="div1">
<script>
$(document).ready(function(){
//do something
});
</script>
</div>
and you can do the same to other divs that you have.
this was suitable if you loading your div via partial view

Categories