I'm trying to hide the mouse if it hasn't moved for a period of time.
This is the code I'm using:
$(document).ready(function() {
var j;
$(document).mousemove(function() {
clearTimeout(j);
$('html').css({cursor: 'default'});
j = setTimeout('hide();', 1000);
});
});
function hide() {
$('html').css({cursor: 'none'});
}
When the hide() function is called the cursor is hidden, but unhides a split second later. Any help is appreciated.
Your initial problem is that the hiding of the mouse triggers mousemove and thus immediately resets it back to default. So you could solve that like this...
var justHidden = false;
$(document).ready(function() {
var j;
$(document).mousemove(function() {
if (!justHidden) {
justHidden = false;
console.log('move');
clearTimeout(j);
$('html').css({cursor: 'default'});
j = setTimeout('hide();', 1000);
}
});
});
function hide() {
$('html').css({cursor: 'none'});
justHidden = true;
}
...BUUUUUT...
You face a problem here which at the moment seems unsolvable to me. That is, a hidden mouse does not trigger mousemove ever, so once it's hidden you will not be able to unhide it as far as I can tell.
I'll keep investigating to see if there's a solution I'm missing.
I found this thread when I was looking for solution for this challenge in 2019. Based on answer here and in 'Hiding the mouse cursor when idle using JavaScript' I made a slightly different solution:
var DEMO = {
INI: {
MOUSE_IDLE: 3000
},
hideMouse: function() {
$("#game").css('cursor', 'none');
$("#game").on("mousemove", DEMO.waitThenHideMouse);
},
waitThenHideMouse: function() {
$("#game").css('cursor', 'default');
$("#game").off("mousemove", DEMO.waitThenHideMouse);
setTimeout(DEMO.hideMouse, DEMO.INI.MOUSE_IDLE);
},
showMouse: function() {
$("#game").off("mousemove", DEMO.waitThenHideMouse);
$("#game").css('cursor', 'default');
},
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
This simple and clear example gives you the option to start hiding mouse (DEMO.hideMouse()) and also to turn this off (DEMO.showMouse()). It does not create multiple events on same element. This example shows hiding mouse pointer over #game div element. Just change this to the div of your choice or body.
As of fully updated Chrome and FF in October 2019: it works on both.
I'm 8 years late but I have a solution:
• First of all download an image of a cursor from the internet or copy my svg code:
<svg id="cursor" width="20" height="20" viewBox="0 0 95 92" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M84.6925 46.0105L40.25 20.3516C35.25 17.4648 29 21.0733 29 26.8468L29 78.1645C29 84.9879 37.3721 88.2664 42.0056 83.2575L58.1424 65.8134C58.4853 65.4427 58.9324 65.1846 59.4249 65.0729L82.6003 59.8201C89.255 58.3118 90.6017 49.4222 84.6925 46.0105Z" fill="black" stroke="white" stroke-width="5"/></svg>
And add it to your html file.
•Of course, if you want to made it in jQuery, you need to add this script above your js file:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
•Then add this (in your JavaScript file):
let timedelay = 1;
function delayCheck() {
if (timedelay == 2) { //Here you can change this value which changes the time it takes the mouse to hide
$('#cursor').fadeOut();
timedelay = 1;
}
timedelay += 1;
}
$(document).mousemove(function() {
$('#cursor').fadeIn();
timedelay = 1;
clearInterval(_delay);
_delay = setInterval(delayCheck, 1000);
});
_delay = setInterval(delayCheck, 1000);
Now you'll see just a cursor on the top left of the screen that does what you asked but it's not YOUR cursor, to replace the cursor with the svg do the following:
//in the same js file as before
$(document).mousemove(function (e) {
$('#cursor').offset({
left: e.clientX,
top: e.clientY
});
});
/* on the css */
html {
cursor: none;
}
If it doesn't work, make sure that you put the jquery file ABOVE the file you wrote.
I hope I have helped someone!
You might want to check if this really works, here's the demo.
(Sorry if my English was bad, I'm italian).
(Tip) You will notice that there are two identical functions, if you want to merge them just replace them with this:
$(document).mousemove(function(e) {
$('#cursor').fadeIn();
timedelay = 1;
clearInterval(_delay);
_delay = setInterval(delayCheck, 1000);
$('#cursor').offset({
left: e.clientX,
top: e.clientY
});
});
Related
As the title suggests I want to detect the start and end of a scrollable element built using overflow.
The following code works:
var scrollAmount = 150;
var scrollBox = $('.js-compare_scroll');
var arrowLeft = $('.js-compare_scroll_left');
var arrowRight = $('.js-compare_scroll_right');
var inactive = 'm-inactive';
$(arrowLeft).on('click', function () {
$(this).parent().find(scrollBox).stop().animate({
scrollLeft: '-='+scrollAmount
}, function() {
arrowRight.removeClass(inactive);
if(scrollBox.scrollLeft() === 0) {
arrowLeft.addClass(inactive);
}
});
});
$(arrowRight).on('click', function () {
$(this).parent().find(scrollBox).stop().animate({
scrollLeft: '+='+scrollAmount
}, function() {
arrowLeft.removeClass(inactive);
if(scrollBox.scrollLeft() + scrollBox.innerWidth() >= scrollBox[0].scrollWidth) {
arrowRight.addClass(inactive);
}
});
});
However the class to style the inactive colour of the arrows only appears once the animation completes. I need to add the class before the animation completes because it has a delay. I believe by default it is 400.
Is there anyway to detect this and apply the arrow classes where needed?
Thanks.
Came back from a break and realised I should take the checking if its at the end off the click event and onto a scroll event. This works a lot better now.
I want to rotate an image every time I click on it.. I've created a function to do this but the image only rotate the first time I click on it... Moreover, once the image rotate it change automatically the width and height.. How can I keep the same width and height every time??
This is the function:
$(document).ready(function () {
$("img").click(function () {
$(this).rotate(45)
})
})
This can easily be done by using just javascript, working example would be like this
<div id="imgWrapper">
<img src="Desert.jpg" id="image" onclick="rotateBy10Deg(this)">
</div>
<script>
var delta =0;
function rotateBy10Deg(ele){
ele.style.webkitTransform="rotate("+delta+"deg)";
delta+=10;
}
</script>
The plugin converts the img into a canvas, that's the reason the click not working for second time. Change your jQuery or refer this demo
$(document).ready(function() {
$("img").click(function() {
$(this).rotate(45);
});
$('body').on('click', 'canvas', function() {
$(this).rotate(45);
});
});
I suggest setting max-height and max-width in your CSS file. This will ensure the image doesn't exceed a certain size.
This link might help you out:
Rotate image with onclick
Taken straight from that link in case you don't want to click:
Javascipt
var rotate_factor = 0;
function rotateMe(e) {
rotate_factor += 1;
var rotate_angle = (180 * rotate_factor) % 360;
$(e).rotate({angle:rotate_angle});
}
HTML
<img src='blue_down_arrow.png' onclick='rotateMe(this);' /></a>
I think the angle (45 degree) is calculated in reference to its initial angle that is 0. Once the image is in 45 degree it will only have to rotate if the angle changes (eg 90). So the below code may work
$(document).ready(function () {
var angle = 0;
$("img").click(function () {
angle = angle+45;
$(this).rotate(angle);
})
})
I did it as you suggested, I used css in JQuery:
css:
.rotate:active {
transform: rotate(180deg)
}
JQuery:
$(document).ready(function () {
$("img").click(function () {
//forcing img to rotate every time on click()
if ($(this).css("transform")=='none') {
$(this).css("transform", "rotate(180deg)");
}
else {
$(this).css("transform","")
}
})
})
This may be a little too specific, but I have a jquery slider that I am using <p> classes instead of images to cycle through customer quotes. Basically the problem I am running into right now is when it is static and non moving (JS code is commeneted out) they are aligned how I want them to be. As soon as the JS is un commented, they stretch out of view and you just see a white box?
Any ideas?
How I want each panel to look like:
jsfiddle
So I sort of made this my Friday project. I've changed a whole lot of your code, and added a vertical-align to the quotes and authors.
Here's the fiddle http://jsfiddle.net/qLca2fz4/49/
I added a whole lot of variables to the top of the script so you could less typing throughout.
$(document).ready(function () {
//rotation speed and timer
var speed = 5000;
var run = setInterval(rotate, speed);
var slides = $('.slide');
var container = $('#slides ul');
var elm = container.find(':first-child').prop("tagName");
var item_width = container.width();
var previous = 'prev'; //id of previous button
var next = 'next'; //id of next button
Since you used a % based width I'm setting the pixel widths of the elements in case the screen is reszed
slides.width(item_width); //set the slides to the correct pixel width
container.parent().width(item_width);
container.width(slides.length * item_width); //set the slides container to the correct total width
As you had, I'm rearranging the slides in the event the back button is pressed
container.find(elm + ':first').before(container.find(elm + ':last'));
resetSlides();
I combined the prev and next click events into a single function. It checks for the ID of the element targeted in the click event, then runs the proper previous or next functions. If you reset the setInterval after the click event your browser has trouble stopping it on hover.
//if user clicked on prev button
$('#buttons a').click(function (e) {
//slide the item
if (container.is(':animated')) {
return false;
}
if (e.target.id == previous) {
container.stop().animate({
'left': 0
}, 1500, function () {
container.find(elm + ':first').before(container.find(elm + ':last'));
resetSlides();
});
}
if (e.target.id == next) {
container.stop().animate({
'left': item_width * -2
}, 1500, function () {
container.find(elm + ':last').after(container.find(elm + ':first'));
resetSlides();
});
}
//cancel the link behavior
return false;
});
I've found mouseenter and mouseleave to be a little more reliable than hover.
//if mouse hover, pause the auto rotation, otherwise rotate it
container.parent().mouseenter(function () {
clearInterval(run);
}).mouseleave(function () {
run = setInterval(rotate, speed);
});
I broke this in to its own function because it gets called in a number of different places.
function resetSlides() {
//and adjust the container so current is in the frame
container.css({
'left': -1 * item_width
});
}
});
//a simple function to click next link
//a timer will call this function, and the rotation will begin :)
And here's your rotation timer.
function rotate() {
$('#next').click();
}
It took me a little bit, but I think I figured out a few things.
http://jsfiddle.net/qLca2fz4/28/
First off, your console was throwing a few errors: first, that rotate wasn't defined and that an arrow gif didn't exist. Arrow gif was probably something you have stored locally, but I changed the 'rotate' error by changing the strings in the code here to your actual variables.
So, from:
run = setInterval('rotate()', speed);
We get:
run = setInterval(rotate, speed);
(No () based on the examples here: http://www.w3schools.com/jsref/met_win_setinterval.asp)
But I think a more important question is why your text wasn't showing up at all. It's because of the logic found here:
$('#slides ul').css({'left' : left_value});
You even say that this is setting the default placement for the code. But it isn't..."left_vaule" is the amount that you've calculated to push left during a slide. So if you inspect the element, you can see how the whole UL is basically shifted one slide's worth too far left, unable to be seen. So we get rid of 'left_value', and replace it with 0.
$('#slides ul').css({'left' : 0});
Now, there's nothing really handling how the pictures slide in, so that part's still rough, but this should be enough to start on.
Let me know if I misunderstood anything, or if you have any questions.
So, a few things:
1) I believe you are trying to get all of the lis to be side-by-side, not arranged up and down. There are a few ways to do this. I'd just make the ul have a width of 300%, and then make the lis each take up a third of that:
#slides ul {
....
width: 300%;
}
#slides li {
width: calc(100% / 3);
height:250px;
float:left;
}
2) You got this right, but JSFiddle automatically wraps all your JS inside a $(document).ready() handler, and your function, rotate needs to be outside, in the normal DOM. Just change that JSFiddle setting from 'onload' to 'no wrap - in head'
3) Grabbing the CSS value of an element doesn't always work, especially when you're dealing with animating elements. You already know the width of the li elements with your item_width variable. I'd just use that and change your code:
var left_indent = parseInt($('#slides ul').css('left')) - item_width;
$('#slides ul').animate({'left' : left_indent}, 1500, function () {
to:
$('#slides ul').stop().animate({'left' : -item_width * 2}, 1500, function () {
4) Throw in the .stop() as seen in the above line. This prevents your animations from overlapping. An alternative, and perhaps cleaner way to do this, would be to simply return false at the beginning of your 'next' and 'prev' functions if #slides ul is being animated, like so:
if ($('#slides ul').is(':animated')) return false;
And I think that's everything. Here's the JSFiddle. Cheers!
EDIT:
Oh, and you may also want to clearInterval at the beginning of the next and prev functions and then reset it in the animation callback functions:
$('#prev').click(function() {
if ($('#slides ul').is(':animated')) return false;
clearInterval(run);
$('#slides ul').stop().animate({'left' : 0}, 1500,function(){
....
run = setInterval('rotate()', speed);
});
});
What I'm trying to do is that when the page loads I'm resetting an image to my desired small size.
If the user clicks on the image later it should enlarge with an animation, I'm done up to this part.
When the user again clicks on that image it should be resized to the size that I assigned after loading the page, I have tried toggle event, but that's not working, toggle just makes my images disappear from the page. So I created an alternate to toggle event by using if and else condition and a flag variable called "small" but the problem is that click event is working only once i.e: If the image is in the small size and I click on it, the image gets enlarged but when I click on it again the click event is fired but it doesn't work, I wish if there is any way that I could make it work with toggle event, otherwise I would like to do it by using if and else condition in click event.
Here's the HTML:
<html>
<head>
<title></title>
<script src="jquery-1.10.1.min.js"></script>
<script src="index.js"></script>
</head>
<body>
<img src="wordpress.jpg" class="small-Img" id="test"> <br>
<img src="store.jpg" class="small-Img">
</body>
</html>
Here's the script:
$(document).ready(function() {
var small;
$('.small-Img').on('load',function(){
$(".small-Img").attr('width','200');
small=Number(1);
});
$('.small-Img').on('click',function () {
alert("event fired");
if(small==1){
var obj=$(this);
var originalWidth=obj[0].naturalWidth;
var originalHeight=obj[0].naturalHeight;
$(this).animate({ height: originalHeight, width: originalWidth }, 1000, function() { });
small=Number(0);
}
if(small==0){
$(".small-Img").attr('width','200');
small=Number(1);
}
});
});
Your code
$(".small-Img").attr('width','200');
sets a width attribute on the image, similar to <img src="url" width="200"> which probably doesn't result in a size change. Try
$('.small-Img').css('width','200px');
or animate the shrinking
$('.small-Img').animate({ width: '200px' }, 1000);
You may also get better results making small an attribute of your image rather than a property of the window object
jsfiddle
It sounds like the problem isn't that the event isn't fired multiple times, but that it doesn't enter your if statement. Try making small a boolean variable instead of a number, that way you can avoid all the == vs === messyness
EDIT:
Also, you probably want an else if so that it doesn't shrink once it enlarges on each click.
DEMO
for setting or getting css value we use .css() not .attr()
== only checks the value
=== checks the value and the datatype
$(document).ready(function () {
var small;
$('.small-Img').on('load', function () {
$(".small-Img").css('width', '200'); //changed attr to css
small = 1;
});
$('.small-Img').on('click', function () {
if (small === 1) { //changed == to ===
var obj = $(this);
var originalWidth = obj[0].naturalWidth;
var originalHeight = obj[0].naturalHeight;
$(this).animate({
height: originalHeight,
width: originalWidth
}, 1000, function () {});
small = 0;
}
if (small === 0) { //changed == to ===
$(".small-Img").css('width', '200'); //changed attr to css
small = 1;
}
});
});
How about first making "small" a data-attribute on the image itself? Not a big deal, but a little more convenient (IMHO). The next thing is, when you want to check the second click, you might consider doing an else if rather than just an if. Not sure if it makes a difference, but it is a clear logical differentiation, you can have one or the other -- not both. Third, if you animate the width back down, you might also animate the height, calculated by your small height divided by your original height times the original width. Seems to work, see it here: http://jsfiddle.net/snowMonkey/7nCMF/1/
$('.small-Img').css('width','200px').data("small", 1);
$('.small-Img').on('click',function () {
var that=this;
this.smallWidth = "200px";
this.smallHeight = (200/$(this)[0].naturalWidth) * $(this)[0].naturalHeight+"px";
if($(this).data("small")===1 ){
var obj=$(that);
var originalWidth=obj[0].naturalWidth;
var originalHeight=obj[0].naturalHeight;
$(that).animate({
height: originalHeight,
width: originalWidth
}, 1000, function() { });
$(that).data("small",0);
} else if($(this).data("small")===0){
$(that).animate({
width: that.smallWidth,
height: that.smallHeight
}, 1000, function(){}).data("small", 1);
}
});
Best of luck!
I have the following code on my page.
http://jsfiddle.net/SO_AMK/r7ZDm/
As you see it's a list of links, and every time a link is clicked, the popup box opens up right underneath the link in question.
Now, what I need to do is basically the same, except I need to use the .hover event and delay the execution by 2 seconds. So instead of clicking, the user should keep the cursor over a link for 2 seconds.
Sounds simple enough but I can't get the positioning to work properly. here's what I tried:
$('a.showreranks').hover(function()
{
$(this).data('timeout', window.setTimeout(function()
{
position = $(this).position();
$('#rerank_details').css('top', position.top + 17);
$('#rerank_details').slideToggle(300);
}, 2000));
},
function()
{
clearTimeout($(this).data('timeout'));
});
Can someone modify this to make it work?
Try like this:
$('a.showreranks').hover(function()
{
var self = this;
$(this).data('timeout', window.setTimeout(function() {
var position = $(self).offset();
$('#rerank_details').css('top', position.top + 17);
$('#rerank_details').slideToggle(300);
}, 2000));
},
function()
{
clearTimeout($(this).data('timeout'));
});
DEMO
jsFiddle demo
$('ul').on('mousemove','li',function(e){
var m = {x: e.pageX, y: e.pageY};
$('#rerank_details').css({left: m.x+20, top: m.y-10});
}).on('mouseenter','li',function(){
var t = setTimeout(function() {
$('#rerank_details').stop().slideDown(300);
},2000);
$(this).data('timeout', t);
}).on('mouseleave','li',function(){
$('#rerank_details').stop().slideUp(300);
clearTimeout($(this).data('timeout'));
});
The setTimeout will act like a hover intent that actually delays the execution for 2 seconds and counts the time hovered inside a data attribute of the hovered element - that gets 'nulled' on mouseleave.
I added also a few lines of code that will make your tooltip follow the mousemove.