I have this code, I'd like to make all a's .ita, .eng, .rus visible on hovering the .all. After mouseleave, I'd like to fade out the a's, and shrink back .languages to the size of just .all.
<nav class="languages">
L
ITA
ENG
RUS
</nav>
In the mouseleave event in the code below I would like to first tween the languages element, then bring the width of the container to 60px. Since it happens async, I cannot manage to see the fadeout of the element.
$$('nav.languages').addEvents({
'mouseenter': ->
this.setStyle('width', "400px")
languages.tween('opacity', 0, 1)
, 'mouseleave': ->
languages.tween('opacity', 1, 0)
this.setStyle('width', "60px")
})
I am reading about the chain method but it refers to a class, not an event, as I have understood.
Thanks
you can set link: chain to the instance of Fx.Tween
as for the rest, its more complex but something like this will work.
http://jsfiddle.net/d201npL2/1/
(function(){
var languages = document.getElement('nav.languages span');
languages.set('tween', {
link: 'chain'
});
var nav = document.getElement('nav.languages').addEvents({
'mouseenter:relay(a.all)': function(){
nav.setStyle('width', 400);
languages.fade(0, 1);
},
'mouseleave': function(){
languages.fade(1, 0);
this.setStyle('width', 60)
}
});
}());
you can do all this in pure CSS3, you know that, right?
I use this jQuery code to set the mouse pointer to its busy state (hourglass) during an Ajax call...
$('body').css('cursor', 'wait');
and this corresponding code to set it back to normal...
$('body').css('cursor', 'auto');
This works fine... on some browsers.
On Firefox and IE, as soon as I execute the command, the mouse cursor changes. This is the behavior I want.
On Chrome and Safari, the mouse cursor does not visibly change from "busy" to "auto" until the user moves the pointer.
What is the best way to get the reluctant browsers to switch the mouse pointer?
It is a bug in both browsers at the moment. More details at both links (in comments as well):
http://code.google.com/p/chromium/issues/detail?id=26723
and
http://code.google.com/p/chromium/issues/detail?id=20717
I would rather do it more elegantly like so:
$(function(){
$("html").bind("ajaxStart", function(){
$(this).addClass('busy');
}).bind("ajaxStop", function(){
$(this).removeClass('busy');
});
});
CSS:
html.busy, html.busy * {
cursor: wait !important;
}
Source: http://postpostmodern.com/instructional/global-ajax-cursor-change/
I believe this issue (including the mousedown problem) is now fixed in Chrome 50.
But only if you are not using the developer tools!!
Close the tools and the cursor should immediately respond better.
I got inspired from Korayem solution.
Javascript:
jQuery.ajaxSetup({
beforeSend: function() {
$('body').addClass('busy');
},
complete: function() {
$('body').removeClass('busy');
}
});
CSS:
.busy * {
cursor: wait !important;
}
Tested on Chrome, Firefox and IE 10. Cursor changes without moving the mouse. "!important" is needed for IE10.
Edit: You still have to move cursor on IE 10 after the AJAX request is complete (so the normal cursor appear). Wait cursor appears without moving the mouse..
Working solution on CodeSandbox
Some of the other solutions do not work in all circumstances. We can achieve the desired result with two css rules:
body.busy, .busy * {
cursor: wait !important;
}
.not-busy {
cursor: auto;
}
The former indicates that we are busy and applies to all elements on the page, attempting to override other cursor styles. The latter applies only to the page body and is used simply to force a UI update; we want this rule to be as non-specific as possible and it doesn't need to apply to other page elements.
We can then trigger and end the busy state as follows:
function onBusyStart() {
document.body.classList.add('busy');
document.body.classList.remove('not-busy');
}
function onBusyEnd() {
document.body.classList.remove('busy');
document.body.classList.add('not-busy');
}
In summary, although we have to change the cursor style to update the cursor, directly modifying document.body.style.cursor or similar does not have the intended effect, on some engines such as Webkit, until the cursor is moved. Using classes to affect the change is more robust. However, in order to reliably force the UI to update (again, on some engines), we have to add another class. It seems removing classes is treated differently from adding them.
First of all, you should be aware that if you have a cursor assigned to any tag within your body, $('body').css('cursor', 'wait'); will not change the cursor of that tag (like me, I use cursor: pointer; on all my anchor tag). You might want to look at my solution to this particular problem first : cursor wait for ajax call
For the problem that the cursor is only updated once the user move the mouse on webkit browsers, as other people said, there is no real solution.
That being said, there is still a workaround if you add a css spinner to the current cursor dynamically. This is not a perfect solution because you don't know for sure the size of the cursor and if the spinner will be correctly positioned.
CSS spinner following the cursor: DEMO
$.fn.extend(
{
reset_on : function(event_name, callback)
{ return this.off(event_name).on(event_name, callback); }
});
var g_loader = $('.loader');
function add_cursor_progress(evt)
{
function refresh_pos(e_)
{
g_loader.css({
display : "inline",
left : e_.pageX + 8,
top : e_.pageY - 8
});
}
refresh_pos(evt);
var id = ".addcursorprog"; // to avoid duplicate events
$('html').reset_on('mousemove' + id, refresh_pos);
$(window).
reset_on('mouseenter' + id, function(){ g_loader.css('display', 'inline'); }).
reset_on('mouseleave' + id, function(){ g_loader.css('display', 'none'); });
}
function remove_cursor_progress(evt)
{
var id = ".addcursorprog";
g_loader.css('display', 'none');
$('html').off('mousemove' + id);
$(window).off('mouseenter' + id).off('mouseleave' + id);
}
$('.action').click(add_cursor_progress);
$('.stop').click(remove_cursor_progress);
You will need to check if it is a touch device as well var isTouchDevice = typeof window.ontouchstart !== 'undefined';
In conclusion, you better try to add in your page a static spinner or something else that shows the loading process instead of trying to do it with the cursor.
Korayem's solution works for me in 100% cases in modern Chrome, Safari, in 95% cases in Firefox, but does not work in Opera and IE.
I improved it a bit:
$('html').bind('ajaxStart', function() {
$(this).removeClass('notbusy').addClass('busy');
}).bind('ajaxStop', function() {
$(this).removeClass('busy').addClass('notbusy');
});
CSS:
html.busy, html.busy * {
cursor: wait !important;
}
html.notbusy, html.notbusy * {
cursor: default !important;
}
Now it works in 100% cases in Chrome, Safari, Firefox and Opera.
I do not know what to do with IE :(
I don't think you'll be able to do it.
However, try changing the scroll position; it might help.
HERE is my solution:
function yourFunc(){
$('body').removeClass('wait'); // this is my wait class on body you can $('body').css('cursor','auto');
$('body').blur();
$('body').focus(function(e){
$('body')
.mouseXPos(e.pageX + 1)
.mouseYPos(e.pageX - 1);
});
}
As of jquery 1.9 you should ajaxStart and ajaxStop to document. They work fine for me in firefox. Have not tested in other browsers.
In CSS:
html.busy *
{
cursor: wait !important;
}
In javaScript:
// Makes the mousecursor show busy during ajax
//
$( document )
.ajaxStart( function startBusy() { $( 'html' ).addClass ( 'busy' ) } )
.ajaxStop ( function stopBusy () { $( 'html' ).removeClass( 'busy' ) } )
Try using the correct css value for the cursor property:
$('body').css('cursor','wait');
http://www.w3schools.com/CSS/pr_class_cursor.asp
I haven't tried this, but what about if you create a transparent div that is absolutely positioned and fills the viewport just before changing the CSS. Then, when the css is changed on the body, remove the div. This might trigger a mouseover event on the body, which might cause the cursor to update to the latest CSS value.
Again, I haven't tested this, but it's worth a shot.
Hey Guys, I have a nitty gritty solution which works on all browsers. Assumption is protoype library is used. Someone can write this as plain Javascript too. The solution is to have a div on top of all just after you reset the cursor and shake it a little bit to cause the cursor to move. This is published in my blog http://arunmobc.blogspot.com/2011/02/cursor-not-changing-issue.html.
$('*').css('cursor','wait'); will work everywhere on the page including links
I'm using MooTools and I've got the following code that I can't seem to get to execute. I'm expecting it to increase the width of the #bar element to 50px, then alert() with a "hi!", and then continue increasing the width of #bar to 200px. For whatever reason, it stops after "hi!" and won't continue to execute. What's up?
var myFx = new Fx.Tween($('bar'), {
duration: '500ms',
transition: 'sine:out',
link: 'chain'
});
myFx.start('width', '50').chain(
function() { alert('hi!'); },
function() { myFx.start('width', '200'); }
);
Fiddle
that's because your 2nd function does not call a method of the myFx class - which means, it won't advance the chain.
chain is a mixin into the Fx class. if you do an animation, it will auto try to callChain. since you do nothing of the sort, add this underneath the alert:
this.callChain();
this will work fine. perhaps the docs need changing as it's not obvious right now. http://jsfiddle.net/dimitar/nUWsU/8/
I made this fiddle
http://jsfiddle.net/nAb6N/10/
As you can see I have 2 animators , a element and body class,
I am adding class to body after the first click on a element but once I click on body is not closing it. If I define animators as
var animators = $$('#opendiv,body');
it works ok except that I do not want the div to open on body click. I need it to close on body click.
Any help is appreciated.
Thank you!
Right. Seems as if you really require an outerClick pattern to close. Here's the one that is most notably used within mootools devs, allowing you to create a custom event, based on click:
Element.Events.outerClick = {
base : 'click',
condition : function(event){
event.stopPropagation();
return false;
},
onAdd : function(fn){
this.getDocument().addEvent('click', fn);
},
onRemove : function(fn){
this.getDocument().removeEvent('click', fn);
}
};
The way it works is: it is based on a normal click. upon adding, it adds the callback as a click event on the document. when a click happens within the element itself,it stops bubbling via event.stopPropagation();, else, it will bubble and the callback will run.
here's how it ties together after the above:
http://jsfiddle.net/dimitar/nAb6N/13/
(function() {
var opener = $('opendiv');
var boxtoopen = $('box');
boxtoopen.set('morph', {
duration: 700,
transition: 'bounce:out'
});
boxtoopen.addEvent('outerClick', function(event) {
boxtoopen.morph(".openOff");
opener.removeClass("hide");
});
opener.addEvent('click', function(e) {
e.stop();
boxtoopen.morph(".openOn");
this.addClass("hide");
});
})();
I have also 'outsourced' the morph properties to the CSS as it makes more sense, semantically.
P.S. note that you need mootools 1.4.3 or 1.4.5, but not 1.4.4 as there's a morph bug to do with units in that release. the jsfiddle above uses 1.4.6 (mootools edge).
I think that the problem could be easily resolved...but not by me!
I want to create two different animations for my div:hover, the first uses CSS (for the people who won't active javascript in IE) and the second uses JS.
The choice between the two methods is simple, the activation of switchClass function using jqwery. But after this happened the selector for the new class doesn't work and not even the mouseover function!
HELP ME PLEASE!!
Here the code:
$(document).ready(function () {
$( ".plateMiddle" ).switchClass( "plateMiddle", "plateMiddleFX");
});
$(".plateMiddleFX").mouseover(function () {
$(this).stop().find('img').animate({opacity: '0'},{queue:false, duration:500}),
$(this).stop().animate({width: '265'},{queue:false, duration:500});
});
I don't kwow if could generate problem but inside the div there is an image with more or less the same dimensions.
An other information: if I select directly the image by a class selector the animation takes life!
THANKS!!
Try
$(".plateMiddleFX").live('mouseover', function () {
$(this).stop().find('img').animate({opacity: '0'},{queue:false, duration:500}),
$(this).stop().animate({width: '265'},{queue:false, duration:500});
});