I have a script which is dynamically adding a class every time the user moves their mouse in/out of the box (whenever they do, it makes the box larger). I am hoping to make this process loop, so that the large box goes back to a small box. I have attempted to use a if statement to check if the box has the class of "large" then it will revert the class back to "small" in the hopes that the document would repeat itself. Didnt work. Can you suggest any way of achieving this using similar code? I would hope to get this to work with 4 separate classes. Fiddle here: http://jsfiddle.net/cs31g61q/1/
var container=$("#container");
var box=$("#box");
box.mouseenter(function(){
$('#box').removeClass("small");
$('#box').addClass("medium");
});
box.mouseleave(function(){
container.on("mouseenter", "#box", function(){
$(this).removeClass("medium");
$(this).addClass("large");
});
});
<div id="container">
<div id="box" class="small">
</div>
</div>
Does the below snippet produce your desired result?
Snippet:
var box = $('#box');
var classes = ['small', 'medium', 'large'];
var iterator = 0;
box.mouseenter(function () {
$(this).removeClass();
$(this).addClass(classes[iterator]);
iterator += 1;
iterator = iterator > classes.length - 1 ? 0 : iterator;
});
.small {
width: 100px;
height:100px;
background: #000;
}
.medium {
width: 200px;
height: 200px;
background: green;
}
.large {
width:400px;
height: 400px;
background: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="container">
<div id="box" class="small"></div>
</div>
This is basically iterating through a set of classes, applying them one by one on every single time mouse enters #box.
Hope this helps.
Fiddle here.
Check your logic: you only need one event listener - it should respond to either mouseenter or mouseleave and cycle through the classes (small, medium, large).
Below is a very simple approach, as demonstrated in the Fiddle above.
// Set up the event listener: every mouseenter or mouseleave
$(document).on('mouseenter mouseleave', "#box", function(){
var currentClass = $('#box').attr("class");
var newClass = ''; // TBD in switch statement.
switch(currentClass) {
case('small'):
newClass = 'medium';
break;
case('medium'):
newClass = 'large';
break;
case('large'):
default:
newClass = 'small';
break;
}
// Remove the current class, add new one.
$('#box').removeClass();
$('#box').addClass(newClass);
});
Related
I'm trying to write a function that upon each button click, it changes the shape of the triangle.
I'm a novice, and I could probably do this quicker with toggle() but I want to get better at writing functions because it's holding me back. Any help would be appreciated. You don't have to give me the answer, but a point in the right direction would be so appreciated! Thank you.
I have the first two shapes but I don't know how to bring in the last two.
https://jsfiddle.net/gs0c30vd/2/
$(document).ready(function(){
$("#tri").click(function(){
$('#triangleup').hide();
$('#triangleright').show();
}) ;
});
A very simple and small jQuery script can do it like below - the only requirement for this is that you add the same class to the elements (see HTML beneath):
$(document).ready(function(){
// declare the first element in the range w. respect to the order of the HTML
var firstElement = $(".firstTriangle");
// declare the last element in the range here to reset the "loop" of elements
var lastElement = $(".lastTriangle");
$("#tri").click(function() {
if ($(lastElement).is(":hidden")){
$(".triangle").filter(":visible").hide().next().show();
} else {
$(lastElement).hide();
$(firstElement).show();
};
});
// ------------------------------------------------------------
// The original uni-directional method is above.
// Beneath I have added "support" for a bi-directional method;
// i.e. going either up or down in the HTML
// ------------------------------------------------------------
$("#counterclockwise").click(function() {
if ($(firstElement).is(":hidden")){
$(".triangle").filter(":visible").hide().prev().show();
} else {
$(firstElement).hide();
$(lastElement).show();
};
});
});
You can check it out in this fiddle. The real benefit of this little method is that you dont have to declare every element in the range which you would like to show. If you apply it for a slider with a lot of images it gets tiresome to type in every element (at least in my opinion); and especially if you change some of the elements. To make this method even easier to maintain you could just use some fixed classes which you always hold as the first and last element; such as "firstTriangle" and "lastTriangle" and then adjust the variables accordingly. I've also added this approach to the script and the HTML for future reference and ease-of-use.
However the drawbacks should also be noted:
You must have your elements which u wish to toggle inside a container with no other siblings (such as shown in the HTML). Otherwise it will move on to other elements and showing/hiding these, thereby breaking the function.
There can only be one direction in which you switch between the elements (downwards in the HTML document).
However, with regard to the unidirectional "drawback" you could easily reverse the function and add another button to make up for this. Such an example can be seen here: Change slides/elements in both directions.
This effectively grants you a pretty much fully functional slider.
HTML:
<div class="myContainer">
<div id="triangleup" class="triangle firstTriangle"></div>
<div id="triangleright" style="display: none;" class="triangle"></div>
<div id="triangledown" style="display: none;" class="triangle"></div>
<div id="triangleleft" style="display: none;" class="triangle lastTriangle"></div>
</div>
<button id="tri">Click me to change the direction of the triangle</button>
<!-- Button for changing direction beneath -->
<button id="counterclockwise">Change direction <b>counter-clockwise</b></button>
Interpretation of the function:
If the last element in the range is hidden (we're not through the range yet) then find the visible one (.filter(":visible")) and hide it, and afterwards find its next (next()) sibling and show (show()) this.
However, if the last Element is visible (then you are at the end of the range), manually hide this and show the first element - thereby starting the range over again.
Note: Pardon my lengthy answer (although that might not be a bad thing) but this was also a learning process for me as well - I wasn't even aware that a "slideshow" effectively could be made that easy with jQuery until I found the .filter() parameter in connection with this question.
You can use a Switch statement to track the current position of the triangle from 0..3 like so:
$(document).ready(function() {
var rot = 0
$("#tri").click(function() {
switch (rot) {
case 0:
$('#triangleup').hide();
$('#triangleright').show();
rot += 1;
break;
case 1:
$('#triangleright').hide();
$('#triangledown').show();
rot += 1;
break;
case 2:
$('#triangledown').hide();
$('#triangleleft').show();
rot += 1;
break;
case 3:
$('#triangleleft').hide();
$('#triangleup').show();
rot = 0;
break;
}
});
});
If your html looks like this
<div id="container">
<div class="shape visible"></div>
<div class="shape"></div>
<div class="shape"></div>
<div class="shape"></div>
</div>
And your css class for .shape is display:none and .visible is display:block
Than your js can be
$("#tri").click(function() {
var current = $(".visible");
var options = $("#container");
var index = options.index(current);
$(".visible").removeClass("visible");
If(index<options.length -1){
options[index + 1].addClass("visible");
}else{
options[0].addClass("visible");
}
});
Forgive me for the typeos I did this on my phone.
One way to do it is to store the names of the shapes in an array then have some sort of counter that increases each time you click the button. The modulus/remainder from that counter as compared to the array length will enable you to loop through them.
Code example:
var index = 0
var shapeArr = [
'#triangleup',
'#triangleright',
'#triangledown',
'#triangleleft'
]
var len = shapeArr.length
$(document).ready(function(){
$("#tri").click(function(){
$(shapeArr[index % len]).hide();
$(shapeArr[++index % len]).show();
}) ;
});
$(document).ready(function(){
var count = 0;
$("#tri").click(function(){
if( count == 0)
{
$('#triangleup').hide();
$('#triangleright').show();
count++;
}
else if(count == 1)
{
$('#triangleright').hide();
$('#triangledown').show();
count++;
}
else if(count == 2)
{
$('#triangledown').hide();
$('#triangleleft').show();
count++;
}
else
{
$('#triangleleft').hide();
$('#triangleup').show();
count = 0;
}
}) ;
});
this is not a good way you make upon this
You can use a flag isUp to know the current status and negate it on every click
$(document).ready(function(){
var isUp = true;
$("#tri").click(function(){
if (isUp) {
$('#triangleup').hide();
$('#triangleright').show();
} else {
$('#triangleup').show();
$('#triangleright').hide();
}
isUp = !isUp;
}) ;
});
EDIT:
I have seen you have four triangles. If you want a full rotation, then you might want to do this:
$(document).ready(function(){
var directions = ["up", "right", "down", "left"];
var directionIndex = 0;
$("#tri").click(function(){
$("#triangle" + directions[directionIndex]).hide();
$("#triangle" + directions[directionIndex = ((directionIndex + 1) % directions.length)]).show();
}) ;
});
You could have an alternative solution using just a few lines of CSS and a small addition in your jQuery code. The point is to simply rotate the triangle by using CSS transform attribute.
Example using jQuery
$(document).ready(function() {
var degrees = 0;
$("#tri").click(function() {
degrees = degrees + 90;
$('#triangle').css("transform", "rotate(" + degrees + "deg)");
});
});
#triangle {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="triangle"></div>
<br>
<button id="tri">Click me to change the direction of the triangle</button>
You can also check this out in this updated Fiddle.
Example using only Javascript
var degrees = 0;
var triangle = document.getElementById("triangle");
document.getElementById("tri").addEventListener("click", function() {
degrees = degrees + 90;
var style = triangle.style;
style.transform = "rotate(" + degrees + "deg)";
});
#triangle {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}
<div id="triangle"></div>
<br>
<button id="tri">Click me to change the direction of the triangle</button>
Edit: What I want is for the nested div to not be moved when the mouse leaves both it and the parent div. I'm pretty sure it is currently moving because the border somehow extends the parent further out than the nested div. I'd like to keep the border.
Like someone once said, a demo is worth a 1000 words.
I have a div nested in a div
<div class='parent'>
<div>Check me out</div>
</div>
That has some styling
.parent {
width: 100%;
border: 1px solid black;
}
.parent div {
display: inline-block;
position: relative
}
And some accompanying Javascript
var navBar = document.querySelector('div.parent');
var navItems = navBar.querySelector('div');
var moveNav = false;
var overItems = false;
navBar.addEventListener('mouseout', function() { moveNav = false; });
navItems.addEventListener('mouseover', function() { overItems = true; });
navItems.addEventListener('mouseout', function() { overItems = false; });
navBar.addEventListener('mouseover', function() { moveNav = !overItems && true; });
navBar.addEventListener('mousemove', moveToMouse);
function moveToMouse(e) {
if(!moveNav)
return;
navItems.style.left = (e.offsetX - Math.floor((e.offsetX+navItems.offsetWidth)/navBar.offsetWidth) * (e.offsetX + navItems.offsetWidth - navBar.offsetWidth + 10)) + 'px'
}
The purpose is to keep some part of the child div under the mouse while the mouse is inside the .parent div.*
What I'd like to know is how to make the child div not be moved as the mouse exits the .parent div?
In other words, I want it to act like it does in this fiddle. The difference between the fiddles is that the first has a border around .parent and the second is borderless.
And of course, I've noticed that child div jerks around instead of moving smoothly. Suggestions as to how to avoid that are welcome but not expected.
*if there's some better way to accomplish that, please do point it out**
**don't say "use jQuery"
In the example of the div with border, I used mouseenter event instead of mouseover and it seems to be working the way you want it.
navBar.addEventListener('mouseenter', moveToMouse);
I am trying to use this menu for my wordpress site.
I am just wondering how can I make the float line change color for each nav item hovered/selected, cos it is red (background-color:#800; height:2px;) for all at the moment.
This is what I am trying to achieve:
Menu 1 - the hovering float line is green,
Menu 2 - the float line is yellow,
Menu 3 - red, menu4 - blue and so on.
Any help is appreciated.
Thank you.
There is a more "CSS" way to achieve this but with some javascript you can get something quite readable. With this approach, your pages will need to correctly initialize the float line (.hightlight) and the nav border (#sses1 > ul).
The ideal solution would be a class for each float lines but here's what I got with javascript only :
<!-- added individual classes for nav items -->
<div id="sse1">
<div id="sses1">
<ul>
<li><a class="nav-item-1" href="?menu=1&skin=2&p=Javascript-Menus">Javascript Menus</a></li>
<li><a class="nav-item-2" href="?menu=1&skin=2&p=Horizontal-Menus">Horizontal Menus</a></li>
<li><a class="nav-item-3" href="?menu=1&skin=2&p=Web-Menus">Web Menus</a></li>
</ul>
</div>
</div>
Before the body or window is loaded :
function customHandleMenu() {
// get nav selector
var nav = $('#sses1 > ul');
// get float line selector
var floatLine = $('.highlight'); // .hightlight must exist at this point
// get colors for the current page
var defaultBGcolor = floatLine.css('background-color');
var defaultBorderColor = floatLine.css('border-color');
var defaultNavBorderColor = nav.css('border-bottom-color');
// change background-color and border-color on mouseenter event
$('.nav-item-1').on({
mouseenter: function () {
setColors({floatColor:'#0f0', borderColor:'#0f0'});
}
});
$('.nav-item-2').on({
mouseenter: function () {
setColors({floatColor:'#ee0', borderColor:'#ee0'});
}
});
$('.nav-item-3').on({
mouseenter: function () {
setColors({floatColor:'#05f', borderColor:'#05f'});
}
});
/*
...
*/
// put back default colors on the mouseleave event
$('#sses1 > ul > li').on({
mouseleave: function() {
setColors({floatColor:defaultBGcolor, borderColor:defaultNavBorderColor});
}
});
function setColors(args) {
if (typeof args.floatColor != "undefined") {
floatLine.css('background-color', args.floatColor);
}
if (typeof args.borderColor != "undefined") {
floatLine.css('border-color', args.borderColor);
nav.css('border-bottom-color', args.borderColor);
}
}
}
To ensure that the selector is only use once .highlight exists, I suggest to modify the end of the original javascript to this:
function initMenu() {
sse1.builMenu();
customHandleMenu();
}
if (window.addEventListener) {
window.addEventListener("load", initMenu, false);
}
else if (window.attachEvent) {
window.attachEvent("onload", initMenu);
}
else {
window["onload"] = initMenu;
}
Take a look at this jsfiddle.
P.S.: the event chain is slighly modified to fit into jsfiddle.
What you're asking for is actually non-trivial. The author of the plugin is actually animating an li element's, "li.highlight", width and left positioning based on where you hover the mouse. You can easily change the color of this thing by altering the CSS definition for this item. For example to make it yellow, just include this css definition below the menu's css file:
#sses1 li.highlight {
background-color: yellow;
top: 36px;
height: 2px;
border-bottom: solid 1px yellow;
z-index: 1;
position: absolute;
overflow: hidden;
}
I know this isn't the complete solution... but, if you're ambitious you could alter the javascript add a new class depending on which li element the .highlight element is under.
I'd like to create an animation on a website to mimic a scrolling log file or tail -f. I'd feed it a list of fake log messages and they would be written to the bottom of the div and scroll up and off the top as new messages are displayed and then loop around. It needs to look authentic, white on black using a fixed width font etc.
Does anyone know of any javascript or jQuery libraries which could help me with this? I'm a beginner with javascript, so any advice on how to approach this would be much appreciated.
I've made a simple example for you
http://jsfiddle.net/manuel/zejCD/1/
// some demo data
for(var i=0; i<100; i++) {
$("<div />").text("log line " + i).appendTo("#tail")
}
// scroll to bottom on init
tailScroll();
// add button click
$("button").click(function(e) {
e.preventDefault();
$("<div />").text("new line").appendTo("#tail");
tailScroll();
});
// tail effect
function tailScroll() {
var height = $("#tail").get(0).scrollHeight;
$("#tail").animate({
scrollTop: height
}, 500);
}
#tail {
border: 1px solid blue;
height: 500px;
width: 500px;
overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="tail">
<div>some line of text</div>
</div>
<button>Add Line</button>
Here is a great solution
This uses an ajax request, and the HTTP Range: header to request only the last ~30KB of a log file. It then polls for data appended to that file, and only ever retrieves new data (no refreshing the whole file, or even the last 30KB). Handles file truncation too.
https://github.com/ukhas/js-logtail#readme
I've updated Manuel van Rijn's script to include a timer and a toggle switch, along with some minor changes to the log lines. hope this helps.
http://jsfiddle.net/5rLw3LoL/
html:
<div id="tail">
<div>some line of text</div>
</div>
<button>Add Line</button>
js:
var tailcounter = 100;
var tailswitch = false;
// scroll to bottom on init
tailScroll();
// add line to log
function tailappend() {
$("<div />").text("log line " + tailcounter).appendTo("#tail");
tailcounter++;
tailScroll();
}
// auto update every second
var t = setInterval(tailappend, 1000);
// toggle updates button click
$("button").click(function (e) {
e.preventDefault();
switch (tailswitch) {
case false:
clearInterval(t); // turns off auto update
tailswitch = true;
alert("auto update off");
break;
case true:
t = setInterval(tailappend, 1000); // restarts auto update
tailswitch = false;
alert("auto update on");
break;
}
});
// tail effect
function tailScroll() {
var height = $("#tail").get(0).scrollHeight;
$("#tail").animate({
scrollTop: height
}, 500);
}
css: (important for formatting)
#tail {
border: 1px solid blue;
height: 400px;
width: 500px;
overflow: hidden;
}
This can be achieved with CSS by simply flipping the outer and inner container using transform: rotateX(180deg); https://jsfiddle.net/tnrn6h59/2/
Only issue here is that the scroll is also reversed, not an issue for mobile.
Is it possible to set the cursor to 'wait' on the entire html page in a simple way? The idea is to show the user that something is going on while an ajax call is being completed. The code below shows a simplified version of what I tried and also demonstrate the problems I run into:
if an element (#id1) has a cursor style set it will ignore the one set on body (obviously)
some elements have a default cursor style (a) and will not show the wait cursor on hover
the body element has a certain height depending on the content and if the page is short, the cursor will not show below the footer
The test:
<html>
<head>
<style type="text/css">
#id1 {
background-color: #06f;
cursor: pointer;
}
#id2 {
background-color: #f60;
}
</style>
</head>
<body>
<div id="id1">cursor: pointer</div>
<div id="id2">no cursor</div>
Do something
</body>
</html>
Later edit...
It worked in firefox and IE with:
div#mask { display: none; cursor: wait; z-index: 9999;
position: absolute; top: 0; left: 0; height: 100%;
width: 100%; background-color: #fff; opacity: 0; filter: alpha(opacity = 0);}
<a href="#" onclick="document.getElementById('mask').style.display = 'block'; return false">
Do something</a>
The problem with (or feature of) this solution is that it will prevent clicks because of the overlapping div (thanks Kibbee)
Later later edit...
A simpler solution from Dorward:
.wait, .wait * { cursor: wait !important; }
and then
Do something
This solution only shows the wait cursor but allows clicks.
If you use this slightly modified version of the CSS you posted from Dorward,
html.wait, html.wait * { cursor: wait !important; }
you can then add some really simple jQuery to work for all ajax calls:
$(document).ready(function () {
$(document).ajaxStart(function () { $("html").addClass("wait"); });
$(document).ajaxStop(function () { $("html").removeClass("wait"); });
});
or, for older jQuery versions (before 1.9):
$(document).ready(function () {
$("html").ajaxStart(function () { $(this).addClass("wait"); });
$("html").ajaxStop(function () { $(this).removeClass("wait"); });
});
I understand you may not have control over this, but you might instead go for a "masking" div that covers the entire body with a z-index higher than 1. The center part of the div could contain a loading message if you like.
Then, you can set the cursor to wait on the div and don't have to worry about links as they are "under" your masking div. Here's some example CSS for the "masking div":
body { height: 100%; }
div#mask { cursor: wait; z-index: 999; height: 100%; width: 100%; }
This seems to work in firefox
<style>
*{ cursor: inherit;}
body{ cursor: wait;}
</style>
The * part ensures that the cursor doesn't change when you hover over a link. Although links will still be clickable.
I have been struggling with this problem for hours today.
Basically everything was working just fine in FireFox but (of course) not in IE.
In IE the wait cursor was showing AFTER the time consuming function was executed.
I finally found the trick on this site:
http://www.codingforums.com/archive/index.php/t-37185.html
Code:
//...
document.body.style.cursor = 'wait';
setTimeout(this.SomeLongFunction, 1);
//setTimeout syntax when calling a function with parameters
//setTimeout(function() {MyClass.SomeLongFunction(someParam);}, 1);
//no () after function name this is a function ref not a function call
setTimeout(this.SetDefaultCursor, 1);
...
function SetDefaultCursor() {document.body.style.cursor = 'default';}
function SomeLongFunction(someParam) {...}
My code runs in a JavaScript class hence the this and MyClass (MyClass is a singleton).
I had the same problems when trying to display a div as described on this page. In IE it was showing after the function had been executed. So I guess this trick would solve that problem too.
Thanks a zillion time to glenngv the author of the post. You really made my day!!!
Easiest way I know is using JQuery like this:
$('*').css('cursor','wait');
css: .waiting * { cursor: 'wait' }
jQuery: $('body').toggleClass('waiting');
Why don't you just use one of those fancy loading graphics (eg: http://ajaxload.info/)? The waiting cursor is for the browser itself - so whenever it appears it has something to do with the browser and not with the page.
To set the cursor from JavaScript for the whole window, use:
document.documentElement.style.cursor = 'wait';
From CSS:
html { cursor: wait; }
Add further logic as needed.
Try the css:
html.waiting {
cursor: wait;
}
It seems that if the property body is used as apposed to html it doesn't show the wait cursor over the whole page. Furthermore if you use a css class you can easily control when it actually shows it.
Here is a more elaborate solution that does not require external CSS:
function changeCursor(elem, cursor, decendents) {
if (!elem) elem=$('body');
// remove all classes starting with changeCursor-
elem.removeClass (function (index, css) {
return (css.match (/(^|\s)changeCursor-\S+/g) || []).join(' ');
});
if (!cursor) return;
if (typeof decendents==='undefined' || decendents===null) decendents=true;
let cname;
if (decendents) {
cname='changeCursor-Dec-'+cursor;
if ($('style:contains("'+cname+'")').length < 1) $('<style>').text('.'+cname+' , .'+cname+' * { cursor: '+cursor+' !important; }').appendTo('head');
} else {
cname='changeCursor-'+cursor;
if ($('style:contains("'+cname+'")').length < 1) $('<style>').text('.'+cname+' { cursor: '+cursor+' !important; }').appendTo('head');
}
elem.addClass(cname);
}
with this you can do:
changeCursor(, 'wait'); // wait cursor on all decendents of body
changeCursor($('#id'), 'wait', false); // wait cursor on elem with id only
changeCursor(); // remove changed cursor from body
I used a adaptation of Eric Wendelin's solution. It will show a transparent, animated overlay wait-div over the whole body, the click will be blocked by the wait-div while visible:
css:
div#waitMask {
z-index: 999;
position: absolute;
top: 0;
right: 0;
height: 100%;
width: 100%;
cursor: wait;
background-color: #000;
opacity: 0;
transition-duration: 0.5s;
-webkit-transition-duration: 0.5s;
}
js:
// to show it
$("#waitMask").show();
$("#waitMask").css("opacity"); // must read it first
$("#waitMask").css("opacity", "0.8");
...
// to hide it
$("#waitMask").css("opacity", "0");
setTimeout(function() {
$("#waitMask").hide();
}, 500) // wait for animation to end
html:
<body>
<div id="waitMask" style="display:none;"> </div>
... rest of html ...
My Two pence:
Step 1:
Declare an array. This will be used to store the original cursors that were assigned:
var vArrOriginalCursors = new Array(2);
Step 2:
Implement the function cursorModifyEntirePage
function CursorModifyEntirePage(CursorType){
var elements = document.body.getElementsByTagName('*');
alert("These are the elements found:" + elements.length);
let lclCntr = 0;
vArrOriginalCursors.length = elements.length;
for(lclCntr = 0; lclCntr < elements.length; lclCntr++){
vArrOriginalCursors[lclCntr] = elements[lclCntr].style.cursor;
elements[lclCntr].style.cursor = CursorType;
}
}
What it does:
Gets all the elements on the page. Stores the original cursors assigned to them in the array declared in step 1. Modifies the cursors to the desired cursor as passed by parameter CursorType
Step 3:
Restore the cursors on the page
function CursorRestoreEntirePage(){
let lclCntr = 0;
var elements = document.body.getElementsByTagName('*');
for(lclCntr = 0; lclCntr < elements.length; lclCntr++){
elements[lclCntr].style.cursor = vArrOriginalCursors[lclCntr];
}
}
I have run this in an application and it works fine.
Only caveat is that I have not tested it when you are dynamically adding the elements.
BlockUI is the answer for everything. Give it a try.
http://www.malsup.com/jquery/block/
This pure JavaScript seems to work pretty well ... tested on FireFox, Chrome, and Edge browsers.
I'm not sure about the performance of this if you had an overabundance of elements on your page and a slow computer ... try it and see.
Set cursor for all elements to wait:
Object.values(document.querySelectorAll('*')).forEach(element => element.style.cursor = "wait");
Set cursor for all elements back to default:
Object.values(document.querySelectorAll('*')).forEach(element => element.style.cursor = "default");
An alternative (and perhaps a bit more readable) version would be to create a setCursor function as follows:
function setCursor(cursor)
{
var x = document.querySelectorAll("*");
for (var i = 0; i < x.length; i++)
{
x[i].style.cursor = cursor;
}
}
and then call
setCursor("wait");
and
setCursor("default");
to set the wait cursor and default cursor respectively.
Lots of good answers already, but none of them mentions the <dialog> element.
Using this element we can create a solution similar to the masking <div>.
Here we use showModal() to "hide" elements, and we use ::backdrop to set the cursor style to wait on the entire page:
function showWaitDialog() {
document.getElementById('id_dialog').showModal();
}
#id_dialog, #id_dialog::backdrop {
cursor: wait;
}
<button onclick="showWaitDialog()">click me</button>
<dialog id="id_dialog">busy...</dialog>
The dialog is hidden by default, and can be shown using either the show() method, or the showModal() method, which prevents clicking outside the dialog.
The dialog can be forced to close using the close() method, if necessary.
However, if your button links to another page, for example, then the dialog will disappear automatically as soon as the new page is loaded.
Note that the dialog can also be closed at any time by hitting the Esc key.
CSS can be used to style the dialog however you like.
The example uses the html onclick attribute, just for simplicity. Obviously, addEventListener() could also be used.
Late to the party but simply give the Html tag an id by targeting
document.documentElement
and in the CSS place at the top
html#wait * {
cursor: wait !important;
}
and simply remove it when you want to stop this cursor.