Javascript function that uses mouse position to change div style - javascript

I'm working with a div in an HTML page that I need to switch the css style of as I move the mouse throughout the page.
Is there any function I can use to constantly track the mouse location? I need to switch the particular div's css style to a different css style as soon as the mouse is at least 30 px from the top of the page. While the mouse cursor is within 30px distance from the top of the page, I want the div to have a particular style. If it is farther than 30 px from the top of the page, I want it to switch styles.
assume i have 2 different styles in my css I can switch back and forth.

Use a mousemove event listener, and switch your styles by editing the href of a link attribute:
document.body.addEventListener("mousemove" event => {
if (event.clientY >= 30) {
document.querySelector("link").setAttribute("href", "style1.css");
} else {
document.querySelector("link").setAttribute("href", "style2.css");
}
});

You can attach "mousemove" event and use 'event.clientY' to get current mouse top postion and write your requirements accordingly.
Here is an example below:
(function(){
document.body.addEventListener("mousemove", function() {
if (event.clientY >= 30) {
document.querySelector(".myDiv").classList.remove('class2');
document.querySelector(".myDiv").classList.add('class1');
} else {
document.querySelector(".myDiv").classList.remove('class1');
document.querySelector(".myDiv").classList.add('class2');
}
});
})();
.myDiv {
height: 200px;
width: 200px;
border:1px solid #f00;
}
.class1 {
border-radius: 50%;
}
.class2 {
border-radius: 10%;
}
<!DOCTYPE html>
<head>
</head>
<body>
<div class="myDiv"></div>
</body>
</html>

Related

Show element on scroll (both up and down) - hide element when page is static (not scrolling)

I would like to make a svg image of a computer mouse appear at the bottom of the viewport when user scrolls the page (both up and down scrolling). When the page is static (no scroll) I would like the element to be hidden. It is the same effect as the scrollbar on the right in the browser. Is it possible to apply this effect to a html element? Many thanks for your help in advance.
This can be achieved by listening for the "scroll" event, window.addEventListener('scroll', someFunction).
We can show the div by changing its display style from "none" to "block" box.style.display = 'block'.
And setting a timeout that, in five seconds, will call another function to hide the div again setTimeout(hideBox, 5000).
You can find the definition and explanation for all of these functions in the Mozilla docs: https://developer.mozilla.org/en-US/
I've also included a simple but working example:
(function () {
let timeoutHandle = 0;
const box = document.getElementById("box");
// add the scroll event
window.addEventListener("scroll", (e) => {
box.style.display = "block";
clearTimeout(timeoutHandle);
// call function to hide box after 5 seconds
timeoutHandle = setTimeout(hideBox, 5000);
});
// hides box by setting display to 'none'
hideBox = () => {
box.style.display = "none";
};
})();
#box {
position: fixed;
bottom: 2px;
right: 2px;
line-height: 95px;
height: 100px;
width: 100px;
border: 3px solid red;
text-align: center;
display: none;
}
#box p {
display: inline-block;
vertical-align: middle;
}
<div>
<a id="top">
<!-- hidden anchor --></a>
<p> This is just some sample text.</p>
<p> You should pay attention to the tiny box at the bottom right corner. It appears when you scroll.</p>
<p> Now we add a very long image to make scrolling possible.</p>
<img src="https://i.pinimg.com/564x/75/b7/8a/75b78ae86b6f81ed20f41f57e2a3a7f2.jpg">
</div>
<div id="box">
jump top
</div>

How to change cursor on multiple mouseovers

I am trying to change my cursor into different images depending on the object that it is hovering over inside my banner. Currently I only know to change the cursor style in CSS. But the cursor stays the same throughout. How do I replace the cursor image on mouseover in my javascript? I am only using jQuery and TweenMax as this is for an assignment.
Using CSS cursor property
Without using any pseudo-selectors in CSS, you can have a pretty good result by playing around with the cursor property. For example, you can select one cursor style from a range of available ones. Or even add your own by linking the URL of the icon.
For example, the code below will show a heart when you hover over the grey area:
.heart {
cursor: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/9632/heart.png"), auto;
width: 200px;
height: 200px;
background: grey;
}
<div class="heart"></div>
You can change the origin of the image's position relative to the actual mouse position by setting the x and y position along with the URL in the cursor property:
cursor: url(<URL>) [x y|auto];
Using JavaScript
Of course, you can handle this feature with JavaScript code. Here are several things we will need to achieve this:
creating an HTML element with the image of the cursor you want as background
using the onmouseenter, onmousemove and onmouseleave events
getting the position of the mouse on the page: properties pageX, pageY
setting the position of our cursor element to be at the position of the mouse (the actual mouse pointer will be hidden): with the transform CSS property.
There are several other tricks I have used to get it right: for example setting the boxes' overflow to be hidden so that the cursor elements can't be seen outside the box. Also, listening to the onmouseleave event allows us to hide the cursor element when the mouse is outside the box area.
I have made a little demo here, click Show code snippet > Run code snippet:
const showCursor = function(event) {
let cursor = event.target.querySelector('.cursor');
event.target.onmousemove = function(e) {
cursor.style.display = 'block'
let [x, y] = [e.pageX - e.target.offsetLeft - 20, e.pageY - e.target.offsetTop - 20]
cursor.style.transform = `translate(${x}px, ${y}px)`
}
event.target.onmouseleave = function(e) {
cursor.style.display = 'none'
}
}
.box {
cursor: none;
overflow: hidden;
width: 200px;
height: 200px;
background: pink;
display: inline-block;
margin: 10px;
}
.box:nth-child(1) {
background: aquamarine;
}
.box:nth-child(2) {
background: pink;
}
.box:nth-child(3) {
background: cornflowerblue;
}
.box:nth-child(4) {
background: lightcoral;
}
.cursor {
display: none;
width: 100px;
height: 100px;
}
#heart {
background: no-repeat url("https://png.icons8.com/color/50/000000/hearts.png");
}
#diamond {
background: no-repeat url("https://png.icons8.com/color/50/000000/diamonds.png")
}
#spade {
background: no-repeat url("https://png.icons8.com/metro/50/000000/spades.png")
}
#clubs {
background: no-repeat url("https://png.icons8.com/ios/50/000000/clubs-filled.png")
}
<div onmousemove="showCursor(event)" class="box">
<div id="diamond" class="cursor"></div>
</div>
<div onmouseenter="showCursor(event)" class="box">
<div id="heart" class="cursor"></div>
</div>
<div onmousemove="showCursor(event)" class="box">
<div id="spade" class="cursor"></div>
</div>
<div onmousemove="showCursor(event)" class="box">
<div id="clubs" class="cursor"></div>
</div>
The function showCursor() is called when the user's mouse enters one of the boxes with the attribute onmouseenter="showCursor(event)" (see HTML markup above).
Below I have provided the JavaScript code with comments explaining how it works:
const showCursor = function(event) {
// get the element object of the cursor of this box
let cursor = event.target.querySelector('.cursor');
// function that will be execute whenever the user moves inside the box
event.target.onmousemove = function(e) {
// the user is moving inside the box
// show the cursor element
cursor.style.display = 'block'
// calcultate the translate values of the cursor element
let [x, y] = [e.pageX - e.target.offsetLeft - 20, e.pageY - e.target.offsetTop - 20]
// apply these values to the style of the cursor element
cursor.style.transform = `translate(${x}px, ${y}px)`
}
// function that will be executed when the user leaves the box
event.target.onmouseleave = function(e) {
// the user's mouse left the box area
// hide the cursor element
cursor.style.display = 'none'
}
}
With a <svg> element
A while ago I answered a post on how to add an <svg> element as the cursor of the mouse. It's a little bit more advanced though. It's still a JavaScript solution but it involves using a <svg> element as the cursor instead of it being a simple <div> (as seen in the second point).

Issues using custom cursor with draggable element

Ok, so I have a draggable element that is contained by it's parent. I'm trying to add a custom cursor while dragging, including when the cursor moves off of the draggable element itself. And then when dragging stops, on mouseup, the cursor should return to default.
<div id="container">
<div class="draggable"></div>
</div>
$(document).ready(function() {
$(window).on("mouseup", function() {
$("*").removeClass("customcursor");
})
$(".draggable").on("mousedown", function() {
$("*").addClass("customcursor");
})
$(".draggable").draggable({
containment: "parent",
});
});
html {
background: lightblue;
}
body {
background-color: teal;
}
#container {
height: 400px;
width: 400px;
background-color: black;
}
.draggable {
height: 200px;
width: 200px;
background-color: red;
}
.customcursor {
cursor: url(http://media.fluke.com/images/8-icon-30x30.gif), default;
}
Here is a working fiddle.
However, this is giving me two issues.
First issue: While dragging, when the cursor moves onto the body element, the custom cursor is no longer in effect. However, when the cursor moves onto the html element, the custom cursor does work. Admittedly, this can be solved by adding a wrapper element, so the cursor is never on the body, but I'm still perplexed about why this is happening.
Second issue: After dragging for the first time, the cursor gets stuck with the custom cursor, even though the .customcursor class has been removed. This second issue can be solved if I add .customcursor class on the start and stop events of the draggable rather than on mousedown and mouseup, but I wanted the custom cursor on mousedown even if the draggable isn't moved.
If anyone has some insight into why these issues are occurring or good ways to fix them, I'd really appreciate the help.
Add !important to the the cursor change:
.customcursor {
cursor: url(http://media.fluke.com/images/8-icon-30x30.gif), default !important;
}
The body was being overrode by a direct element style:
element.style {
cursor: auto;
}
Also, for some reason, the cursor is being left behind as a direct style even after the class is removed. Remove it with JavaScript or jQuery:
$(window).on("mouseup", function() {
$("*").removeClass("customcursor");
//document.body.style.cursor = "";
$("body").css("cursor", "")
console.log("mouseup");
})
Fiddle: https://jsfiddle.net/ntyuuqq2/

Adjusting a div based on the size of the container

I have an HTML video player with Javascript generated controls(with background images of SVG graphics). I'm having an issue using the css calc() function, and need to resize the div's based on the video controls bar. So when the window is expanded/contracted, the controls need to adjust accordingly.
The controls div:
//Controls Wrapper
videoObj.controlsWrapper = document.createElement("div");
videoObj.controlsWrapper.className = "video-controls";
The controls are generated dynamically, so for instance, the play button is generated by this:
videoObj.playBtn = document.createElement("button");
videoObj.playBtn.className = "play btn";
So the question is how to adjust the size of the play button(which is a background of an SVG graphic), to a percentage(about 25%) of the height of the controls wrapper div.
jsfiddle
This is the easiest way... try resizing the box :)
The parent is relative. The child is absolute. Setting the top, left, right and bottom all to 0 will actually create a spider web effect ( or stretch effect ). I used different pixels so you could see the reaction. otherwise the child will cover the parent. Hope this helps.
http://jsfiddle.net/m5wm1rLs/
.parent{
position: relative;
width: 100px;
height: 100px;
background-color: red;
}
.child{
position: absolute;
top: 3px;
bottom: 20px;
left: 3px;
right: 20px;
background-color: green;
}
<div class="parent">
<div class="child"></div>
</div>
To test that this works, you can make parent resizable:
$('.parent').resizable();
Resizing it to 25% of the parent div height is relatively easy, but only doable with a scripting language. As far as CSS has come by allow calc(), it has no support for pulling the sizes of designated elements.
Here's a simple script I threw together for you:
window.onload = function() {
resize();
}
window.onresize = function() {
resize();
}
function resize() {
document.getElementsByClassName('play')[0].style.width = (document.getElementsByClassName('timeline')[0].offsetHeight * .25) + 'px';
}
JSFiddle: http://jsfiddle.net/zq2vzkk5/
I recommend you use ids to identify the elements you want to pull the values from, but if the positions of the elements won't change on the page, then classes are fine. You just have to update which instance of the class you want to pull the value from if it does change.
If you want a jQuery variation, I can supply that, too.
I hope this helps.
Edit:
Here's the jQuery variation:
$(function() {
resize();
$(window).resize(function() {
resize();
});
});
function resize() {
$('.play').first().width($('.timeline').first().outerHeight() * .25);
}
JSFiddle: http://jsfiddle.net/s51vrca2/
You can do this without JS :
.play {
height: 25%;
}

javascript window scroll issue

I am working on javascript scroll. I have following html code
JSFIDDLE
<div class="wrapper">
<div class="red div current"></div>
<div class="blue div"></div>
<div class="green div"></div>
<div class="yellow div"></div>
</div>
In above code I have four div tags red, blue, green and yellow. All of them are position in following css.
html, body {
height: 100%;
}
.wrapper {
overflow: hidden;
height: 100%;
}
.div {
position: relative;
height: 100%;
}
.red {
background: red;
}
.blue {
background: blue;
}
.green {
background: green;
}
.yellow {
background: yellow;
}
In above html and css the red div tag is the current one which means user is seeing the red div tag on the screen. Now what I am trying to do is when user scroll over window once, then the next div tag i.e. blue will be animated and moved to the top and will become visible to the user whereas the red div tag will be behind the blue one. This same process goes for both green and yellow.
The problem is that when user scroll once then the div tag should animate however my current javascript code is keep reading the scroll and animating the div tags one after another. What I want is when user scroll once then scroll should be disabled until the blue div tag is animated. Then scroll should be enabled. Again when user scroll second time, the scroll should disable until the green div tag completes its animation. Same goes for yellow.
How can I achieve above?
Here is my javascript
$(window).on("scroll", function () {
var next = $('.current').next();
var height = next.outerHeight();
next.animate({top: '-=' + height}, 500, function () {
$(this).prev().removeClass('current');
$(this).addClass('current');
});
});
Please have a look on update JsFiddle
$(window).on("scroll", function () {
var next = $('.current').next();
var height = $('.current').outerHeight();
$('.current').prevAll().each(function(){
height += $(this).outerHeight();
});
next.animate({top: '-=' + height}, 500, function () {
$(this).prev().css('top','');
$(this).prev().toggleClass('current');
$(this).toggleClass('current');
});
});
The main reason your example wasn't working as expected is because you were relatively positioning the divs, and not moving them to the correct spot.
Working JSFiddle:
http://jsfiddle.net/seanjohnson08/rVVuc/6/
.wrapper {
overflow: hidden;
height: 100%;
position: relative;
}
.div {
position: absolute;
height: 100%;
width: 100%;
top: 100%;
}
.current{
top: 0;
}
If you are looking for a way to limit the amount of scroll events fired, try throttling: http://benalman.com/projects/jquery-throttle-debounce-plugin/. My solution doesn't require this, because no matter how many times it is firing the scroll event, it only ever tells jquery to animate to top:0, there's no chance of it animating past that.

Categories