I need a way of changing the mouse-cursor on a html-page. I know this can be done with css, but I need to be able to change it at runtime, like for instance having buttons on the page, and when they're clicked they change the cursor to a specific custom graphic. I think the best (or only?) way of doing this is through javascript? I hope there's a way of doing this nicely that will work on all of the major browsers. I would be very grateful if someone could help me with this.
Thanks in advance
I need a way of changing the mouse-cursor on a html-page. I know this can be done with css, but I need to be able to change it at runtime, like for instance having buttons on the page, and when they're clicked they change the cursor to a specific custom graphic. I think the best (or only?) way of doing this is through javascript? I hope there's a way of doing this nicely that will work on all of the major browsers. I would be very grateful if someone could help me with this.
Thanks in advance
Share Improve this question edited Mar 6, 2010 at 3:10 Jon Seigel 12.4k8 gold badges60 silver badges93 bronze badges asked Jul 31, 2009 at 2:07 CloxClox 1,9435 gold badges28 silver badges43 bronze badges7 Answers
Reset to default 6Thanks for the replies. I finally got it working. Here's how I did it:
<html>
<head>
<script type="text/javascript">
function changeToCursor1(){
document.body.style.cursor="url('cursor1.ani'),url('cursor1.cur'), default";
}
function changeToCursor2(){
document.body.style.cursor="url('cursor2.ani'),url('cursor2.cur'), default";
}
</script>
</head>
<body>
<form>
<input type="button" value="Change to cursor 1" onclick="changeToCursor1()" /><br>
<input type="button" value="Change to cursor 2" onclick="changeToCursor2()" />
</form>
</body>
I found out that to get it to work in Firefox you must pass at least 2 choices of cursors, e.g. cursor="url('cursor1.cur'), default" Or else it wont work. Also, in Firefox it doesn't work with ani-cursors, only cur. Which is why I've put a cur after ani. The ani will show up in IE, the cur in Firefox.
Does anyone know if it's possible to change the cursor in IE without the active-X warning showing up and the user having to accept?
http://www.javascriptkit./dhtmltutors/csscursors.shtml
Theres an example at the bottom.
It's easy if you want to do this on Links only. There you have some CSS like this:
a:hover { cursor: crosshair; } #this is when you mouseover the link
a:active { cursor: wait; } #this is the moment you click it
Since :active won't work for other Elements than a, you may want to use the Javascript stated by Prestaul and scunliffe.
Using JQuery:
$('.myButton').click(function(){
$(this).css('cursor', 'url(/url/to/cursor/image)');
});
I will describe the problem a little differently than the answers given here. A mon problem is that we want to run some function, for example, to press a button, which function can take a very long time. Before starting, we want the button to get the status disabled, and this can also be seen on the screen, or we want to change the cursor or other visual features on the screen before starting the function. The problem is that if we enter a style change unnecessarily, the JavaScript will perform the function and the changes will not be reflected on the screen, until after the JavaScript pletes the mentioned function, it gets someone to display something visually on the screen. For illustration, I will give an example:
function NewPageSize() {
var e=$('#table1-pagesize');
e.attr('disabled', true);
console.log('page-size change event');
$('#time').css('background-color',RGB('#ffff00'));
let mPageSize=e.val();
FillTable(-1, 1, mPageSize); //a function that can take a very long time
e.attr('disabled', false);
$('#time').css('background-color',RGB('#ffffff'));
};
In this example, the disabled button /"e.attr('disabled', true);"/ and the color change of the "time" element to "#ffff00" are not reflected on the screen, before FillTable() .
It took me 5 days to figure out how to solve such a problem. The solution is basically very simple, but it is very poorly explains. We need to make JS think that it has nothing to do and can render the css changes to the screen. Only then do we run the function that takes longer. But how to achieve this? For this you need to receive a regular signal. WORKER is ideal for this. You install a worker that after 500 milliseconds sends like the time or whatever and displays it on the web page with some element. If it works for you, add the call to an empty procedure. In my case, it's the PROC() function.
function startWorker() {
if(typeof(w) == "undefined") {
w = new Worker("/js/worker.js");
}
w.onmessage = function(event) {
document.getElementById("time").innerHTML = event.data;
PROC();
};
}
function stopWorker() {
w.terminate();
w = undefined;
}
function PROC() {return;} //empty function
Now it gets interesting. We will rewrite the empty PROC() function so that it always does what we want. First we rewrite it to make some changes to the screen ... Alfa(). Once that's done, we'll override it to run our long-running function.... Beta(). The intermediate problem is that we need to resolve the parameters to be globally accessible. For me, the gSet() and gGet() functions are used for this. That's about all, the rest should have been clear from the code.
function NewPageSize() {
var e=$("#table1-pagesize");
e.attr('disabled', true);
let mPageSize=e.val();
console.log('page-size change event');
$('#time').css('background-color',RGB('#ffff00'));
gSet('Beta',
`
FillTable(-1, 1,`+mPageSize+`);
$('#time').css('background-color',RGB('#ffffff'));
var e=$("#table1-pagesize");
e.attr('disabled', false);
`
);
PROC=Alfa;
};
function EmptyProc() {return;}
function Alfa() {
PROC=Beta;
}
function Beta() {
PROC=EmptyProc;
let s=gGet('Beta');
let arr=s.split(';');
for (var i=0; i<Len(arr); i++) {
let t=arr[i];
if (Len(Trim(t))>1) {
eval(t);
}
}
}
Of course, exists also very sophisticated code without functions: gSet(), gGet() and "eval()", but it should be enough to understand the principle. You can use something like this (but I won't explain why it also works for parameters, without gSet() and gGet():
function NewPageSize() {
var e=$("#table1-pagesize");
e.attr('disabled', true);
let mPageSize=e.val();
console.log('page-size change event');
$('#time').css('background-color',RGB('#ffff00'));
Beta=function () {
PROC=EmptyProc;
FillTable(-1, 1,eval(mPageSize)); //our long running function
$('#time').css('background-color',RGB('#ffffff'));
var e=$("#table1-pagesize");
e.attr('disabled', false);
}
PROC=Alfa;
}
//you can set all the normal cursors like this
someElem.style.cursor = 'progress';
What is the special cursor you want?... maybe there is a better option.
// Get the element you want to change the cursor for
var el = document.getElementById('yourID');
// This image url is relative to the page url
el.style.cursor="url(pathToImage.png)";