Prevent Mouseenter and Mouseleave Firing Within Element Without Using Pointer-Events - javascript

I'm using 'mouseenter' and 'mouseleave' to change the visibility of an image when I enter and leave an element. My issue is these events keep firing even when I'm within the element. Using 'pointer-events = none' works but it turns off another animation I have on the image. Is there a solution to this that either doesn't use pointer-events nor mousenter/leave and allows me to have animations on my image? DEMO
HTML:
<img id="image" src=""/>
<div id='box' class="box"></div>
CSS:
.box {
border: 2px solid red;
height: 400px;
width: 60%;
margin: 10px auto;
}
#image {
position:absolute;
width: 60px;
height: 60px;
display: none;
}
JS:
$(document).mousemove(function(e){
const height = $('#image').height() / 2;
const width = $('#image').width() / 2;
$("#image").css({
left:e.pageX-width,
top:e.pageY-height
});
});
$('.box').mouseenter(_=> {
$('#image').show();
});
$('.box').mouseleave(_=> {
$('#image').hide();
});

I'm not sure if this accomplishes what you're looking for - but you could change the z-index of the image and the background of the parent container, like:
$(document).mousemove(function(e){
const height = $('#image').height() / 2;
const width = $('#image').width() / 2;
$("#image").css({
left:e.pageX-width,
top:e.pageY-height
});
});
let entries = 0;
let exits = 0
$('.box').mouseenter(_=> {
$('#image').show();
entries += 1;
document.getElementById("entries").textContent=entries;
});
$('.box').mouseleave(_=> {
$('#image').hide();
exits += 1;
document.getElementById("exits").textContent=exits;
});
.box {
border: 2px solid red;
height: 400px;
width: 60%;
margin: 10px auto;
background: transparent;
}
#image {
position:absolute;
width: 60px;
height: 60px;
display: none;
z-index: -1;
}
#display {
position: absolute;
top:0;
left: 0;
border: 1px solid black;
width: 100px;
height: 100px;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="image" src="https://i5.walmartimages.ca/images/Large/580/6_r/875806_R.jpg"/>
<div id='box' class="box"></div>
<div id= 'display'>
<div id= 'entries'>00</div>
<div id= 'exits'>00</div>
</div>
Which will cause the .box to always be on top, even though the image is under your cursor.

Have you tried maybe setting a value to indicate the current state of the image?
Something like this:
var showImage = false;
$(document).mousemove(function(e){
const height = $('#image').height() / 2;
const width = $('#image').width() / 2;
$("#image").css({
left:e.pageX-width,
top:e.pageY-height
});
});
$('.box').mouseenter(_=> {
if (showImage)
return;
showImage = true;
$('#image').show();
});
$('.box').mouseleave(_=> {
showImage = false;
$('#image').hide();
});

Related

Problems with moving a div by cursor if I move it too fast

to specify my question I wrote an standalone example of my problem. I want to precisely move a div inside a wrapping container (only in x-direction), like a trackbar. The wrapping div should specify the space for the slider.
My script works, if I slowly move the cursor. But if I move the cursor too fast I kind of loose the slider div somewhere inside the container. Especially in the right and left corner.
How can I improve the code to have a stable solution, without the need of librarys? I know that there is a kind of simple solution with jQuery, but I would be very happy if we could find a way in plain javascript.
var x_mouse_position;
var x_offset;
var isDown = false;
var new_slider_left_position;
var container = document.getElementById("container");
var slider = document.getElementById("slider");
slider.addEventListener('mousedown', function (e) {
isDown = true;
x_offset = slider.offsetLeft - e.clientX;
}, true);
document.addEventListener('mouseup', function () {
isDown = false;
}, true);
document.addEventListener('mousemove', function (event) {
if (isDown) {
x_mouse_position = event.clientX;
new_slider_left_position = x_mouse_position + x_offset;
if (new_slider_left_position >= 0 && new_slider_left_position <= container.offsetWidth - slider.offsetWidth) {
slider.style.left = new_slider_left_position + 'px';
}
}
}, true);
html,
body {
height: 100%;
width: 100%;
}
body {
background-color: antiquewhite;
display: flex;
justify-content: center;
align-items: center;
}
#container {
position: relative;
width: 400px;
height: 30px;
background-color: cornflowerblue;
border-radius: 5px;
overflow: hidden;
}
#slider {
position: absolute;
top: 0;
left: 0;
box-sizing: border-box;
border: 1px solid black;
width: 50px;
height: 100%;
border-radius: 5px;
background-color: rgba(0, 0, 0, 0.2);
cursor: move;
}
<div id="container">
<div id="slider"></div>
</div>

On horizontal scroll of overflown div, fill in progress bar

I have a div which contains an image. The container of this image has overflow:scroll, so that the user can scroll left or right to see the rest of the image.
I've also implemented a progress bar, which should indicate how much of the image remains to scroll. I.e. if the user has scrolled 5% to the right, it'll fill up 5% of the progress bar (and vice versa).
I can get the function working based on scrollHeight, but can't get it working based on scrollWidth.
Where am I going wrong?
window.onscroll = function() {myFunction()};
function myFunction() {
var winScroll = document.body.scrollTop || document.documentElement.scrollTop;
var width = document.documentElement.scrollLeft - document.documentElement.clientWidth;
var scrolled = (winScroll / width) * 100;
document.getElementById("myBar").style.width = scrolled + "%";
}
.imgCont {
background: black;
overflow: scroll;
position: relative;
}
.imgCont img {
width: auto;
max-width: none;
}
.progress-container {
width: 100%;
height: 8px;
background: blue;
}
.progress-bar {
height: 8px;
background: red;
width: 0%;
}
<div class="imgCont">
<img src="https://i.imgur.com/KhWo66L.png">
</div>
<div class="progress-container">
<div class="progress-bar" id="myBar"></div>
</div>
You need to add listeners on the .imgCont element and use it's scrollLeft, scrollWidth and clientWidth properties
let scrEl = document.getElementById("scr-el")
scrEl.addEventListener('scroll', event => {
let scrolled = (scrEl.scrollLeft / (scrEl.scrollWidth - scrEl.clientWidth) ) * 100
document.getElementById("myBar").style.width = scrolled + "%"
});
.imgCont {
background: black;
overflow-x: scroll;
position: relative;
}
.imgCont img {
width: auto;
max-width: none;
}
.progress-container {
width: 100%;
height: 8px;
background: blue;
}
.progress-bar {
height: 8px;
background: red;
width: 0%;
}
<div id="scr-el" class="imgCont">
<img src="https://i.imgur.com/KhWo66L.png">
</div>
<div class="progress-container">
<div class="progress-bar" id="myBar"></div>
</div>
windows.onscroll won't emit any events while you scroll horizontally because scroll is happening in the element with class imgCont.
put an id imgCont
<div class="imgCont" id="imgCont">
<img src="https://i.imgur.com/KhWo66L.png">
</div>
and call the on scroll event as
document.getElementById("imgCont").onscroll
Jquery solution setps:
subtract the visible width of the image and the real image width
var winScroll = $(".imgCont img").width() - $(".imgCont").width();
get the left scroll position
var width = $(".imgCont").scrollLeft();
get the percentage from the width and position
var scrolled = ((width / winScroll) * 100);
Check the snippet:
$(function(){
$(".imgCont").scroll(function(){
var winScroll = $(".imgCont img").width() - $(".imgCont").width();
var width = $(".imgCont").scrollLeft();
var scrolled = ((width / winScroll) * 100);
$("#myBar").width(scrolled + "%");
});
});
.imgCont {
background: black;
overflow: scroll;
position: relative;
height:200px;
}
.imgCont img {
width: auto;
max-width: none;
}
.progress-container {
width: 100%;
height: 8px;
background: blue;
}
.progress-bar {
height: 8px;
background: red;
width: 0%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="imgCont">
<img src="https://static.toiimg.com/photo/msid-67868104/67868104.jpg?1368689">
</div>
<div class="progress-container">
<div class="progress-bar" id="myBar"></div>
</div>
Another solution.
let div = document.getElementById("theDiv")
div.addEventListener('scroll', function(e) {
let inner = window.innerWidth
let left = div.scrollLeft
let sWidth = div.scrollWidth
let total = sWidth - inner
let width = 1 * left / total * 100
if (width >= 100) {
return document.getElementById("myBar").style.width = "100%";
}
document.getElementById("myBar").style.width = `${width}%`;
});
body {
margin: 0;
}
.imgCont {
background: black;
overflow: auto;
position: relative;
}
.imgCont img {
width: auto;
max-width: none;
}
.progress-container {
width: 100%;
height: 8px;
background: blue;
}
.progress-bar {
height: 8px;
background: red;
width: 0%;
}
<div class="imgCont" id="theDiv">
<img src="https://i.imgur.com/KhWo66L.png">
</div>
<div class="progress-container">
<div class="progress-bar" id="myBar"></div>
</div>

Inline Javascript stoped adding class to element

Hey I have an inline javascript code that adds a class to an element and makes it slide up in the screen. But it suddenly stopped working and I don't know why. Here's the HTMl and JS:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 400) {
$(".converter").addClass("atcbottomactive");
} else {
$(".converter").removeClass("atcbottomactive");
}
});
.converter {
position: fixed;
height: 60px;
width: 100%;
bottom: -200;
background: #eeeeee;
transition: 1s;
z-index: 10000;
}
.ccontent {
display: inline-flex;
width: 100%;
padding: 10px 5%;
}
.atcbottomactive{
bottom:0;
transition: 1s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style="background: green; height: 1500px; width: 100%;"></div>
<div class="converter"><div class="ccontent">...</div></div>
Here's the link
Thanks in advance :)
In fact, trying to use it without including JQuery gives you the error. You can solve this easily with "JavaScript" without using jQuery.
var element = document.querySelector(".converter");
window.addEventListener('scroll', function() {
var scroll = window.pageYOffset || document.documentElement.scrollTop;
if (scroll >= 400) {
element.classList.add("atcbottomactive");
} else {
element.classList.remove("atcbottomactive");
}
});
.converter {
padding: 20px 20px 200%;
background: blue;
color: white;
}
.converter.atcbottomactive {
background: green;
}
<div class="converter">
<div class="ccontent">Scroll me: 400px</div>
</div>

How to make a div go over another div when clicking on it?

I have these 2 divs and when I click on div 1 I want it to go over the second div, and if I click on Div 1 again I want it to go back to its original position (I want Div 1 to increase its width so it goes over the second Div). Here is my code where I have my 2 divs next to each other. Can anyone point me in the right direction on how to accomplish this? Thanks a lot in advance!
NOTE:
- No jQuery please. I'm trying to accomplish this with javascript and css.
#parent {
display: flex;
}
#narrow {
width: 200px;
background: lightblue;
}
#wide {
flex: 1;
background: lightgreen;
}
<div id="parent">
<div id="wide">Div 1</div>
<div id="narrow">Div 2</div>
</div>
If you're willing to ditch flex, you can use a combination of float , postion:absolute and transition so that the main div "slides over" the other div
document.querySelector("#wide").onclick = toggleWidth;
function toggleWidth() {
this.classList.toggle("active");
}
#parent {
position: relative;
}
#narrow {
width: 200px;
background: lightblue;
float: right;
}
#wide {
position: absolute;
background: lightgreen;
width: calc(100% - 200px);
transition: width 2s;
}
#wide.active {
width: 100%;
opacity: 0.9;
}
<div id="parent">
<div id="wide">Div 1</div>
<div id="narrow">Div 2</div>
</div>
Note: Changing the opacity is purely optional, I've only done it to further illustrate the "slide over" effect.
Try this
#parent {
display: flex;
}
#narrow {
width: 20vw;
position: absolute;
left: calc(80vw - 10px);
background: lightblue;
z-index: 1;
margin: 0;
}
#wide {
width: calc(80vw - 10px);
background: lightgreen;
transition: all 0.3s ease-out;
}
.wider {
width: 100vw!important;
z-index: 2;
}
<div id="parent">
<div id="wide" onclick="myFunction()">Div 1</div>
<div id="narrow">Div 2</div>
</div>
<script>
function myFunction() {
var element = document.getElementById("wide");
element.classList.toggle("wider");
}
</script>
You can try it using JavaScript.
First, you prepare your CSS:
#narrow {
width: 200px;
transition: 0.32s;
overflow: hidden;
}
#wide.fullwidth ~ #narrow {
width: 0;
opacity: 0;
}
Then, the JavaScript, like this:
document.querySelector("#wide").onclick = changeDivWidth;
var wideFull = false;
function changeDivWidth () {
if (!wideFull) {
this.classList.add("fullwidth");
wideFull = true;
return; // if variable wideFull is false, function stops here
}
wideFull = false;
this.classList.remove("fullwidth");
}
Shorter approach using toggle();
document.querySelector("#wide").onclick = changeDivWidth;
function changeDivWidth () {
this.classList.toggle("fullwidth");
}
Are you looking for something like this : JSFiddle ?
JavaScript (Pure) :
function HideDivOne(){
var wide = document.getElementById("wide");
var narrow = document.getElementById("narrow");
if (wide.style.width == "70%"){
wide.style.width = "100%";
narrow.style.width = "0%";
narrow.style.opacity = "0";
}
else{
wide.style.width = "70%";
narrow.style.width = "30%";
narrow.style.opacity = "1";
}
}
CSS
#parent {
display: flex;
}
#narrow {
width: 30%;
background: lightblue;
height: 20px;
transition: 0.2s;
}
#wide {
width: 70%;
flex: 1;
background: lightgreen;
height: 20px;
transition: 0.2s;
}
HTML
<div id="parent">
<div id="wide" onclick="HideDivOne()">Div1</div>
<div id="narrow" onclick="HideDivTwo()">Div2</div>
</div>
You can change the z-index of the divs based on your desired effect. My suggestion is using jQuery. On click on div 1 add a class to the div that modify the zindex, that is, if the class is not already added, if so, remove it.

How to get a-link (a href) background image in css to resize with javascript code

I've been racking my brain trying to get two problems figured out. One is an image cropping and the other is and image resizing one. Here is a overview of the code I have:
HTML code:
<script src="main.js"></script>
<div class="mainDiv">
<div class="columnDiv1">
<!-- a div here a div there -->
</div>
<div class="columnDiv2">
<div class="iconDiv1">Icon 1</div>
<div class="iconDiv2"><img src="/images/div2Icon.png" id="div2IconImg" width="1" /></div>
</div>
<div class="columnDiv3">
<!-- a div here a div there -->
</div>
<div class="bottomRowDiv">
<!-- a div here a div there -->
</div>
</div>
CSS code:
<style type="text/css">
.mainDiv {
z-index: 2;
float: left;
width: 1112px;
position: relative;
overflow: hidden;
}
.columnDiv1 {
z-index: 20;
position: absolute;
width: 33.36%;
padding: 0px;
float: left;
border: 0px solid;
}
.columnDiv2 {
z-index: 20;
position: absolute;
width: 30.31%;
padding: 0px;
float: left;
border: 0px solid;
}
.columnDiv3 {
z-index: 20;
position: absolute;
width: 36.33%;
padding: 0px;
float: left;
border: 0px solid;
}
.bottomRowDiv {
z-index: 20;
position: absolute;
width: 100%;
padding: 0px;
float: left;
border: 0px solid;
}
/* stuff in here for columnDiv1 */
.iconDiv1 {
z-index: 20;
position: absolute;
width: 100%;
left: 0px;
top: 0px;
padding-top: 0px;
padding-left: 0px;
padding-bottom: 75px;
padding-right: 0px;
float: left;
border: 0px solid;
}
.iconDiv2 {
z-index: 20;
position: absolute;
width: 100%;
left: 0px;
top: 0px;
padding: 0px;
float: left;
border: 0px solid;
}
/* stuff in here for columnDiv3 */
/* stuff in here for bottomRowDiv */
#iconDiv1_link {
display:block;
text-indent: -10000px;
background: url(/images/div1.png) no-repeat;
background-position: center top;
}
#iconDiv1_link:hover {
background-image: url(/images/div1hover.png);
}
</style>
JavaScript code:
_spBodyOnLoadFunctionNames.push('sizeImageMap()');
function sizeImageMap()
{
// get screen information
var currentScreenWidth = screen.width;
var currentScreenHeight = screen.height;
// get images' information
//define Image Icon Hash keys
var imgIconHash = {};
imgIconHash['image1_link'] = {};
...
...
imgIconHash['iconDiv1_link'] = {};
imgIconHash['div2IconImg'] = {};
...
...
for (var imgLinkName in imgIconHash){
var imgLink = document.getElementById(imgLinkName);
if (imgLink.nodeName === "A") {
imgLinkStyle = imgLink.currentStyle || window.getComputedStyle(imgLink, false);
imgIconHash[imgLinkName]['src']=imgLinkStyle.backgroundImage.replace(/url\((['"])?(.*?)\1\)/gi, '$2').split(',')[0];
} else if (imgLink.nodeName === "IMG") {
imgIconHash[imgLinkName]['src']=imgLink.getAttribute('src');
} else {
// not A or IMG nodes
}
// get image width and height
var tmpImg = new Image();
imgIconHash[imgLinkName]['width']=tmpImg.width;
imgIconHash[imgLinkName]['height']=tmpImg.height;
}
// initialize scaling factors
var imgScale = 1;
//set scaling factors
if(currentScreenHeight >= /*given amount*/ ) // set scale
{
imgScale = 0.5676; // reset image scale
} else {
imgScale = 0.3784; // reset image scale
}
//resize images
for (var imgLinkName in imgIconHash){
var imgLink = document.getElementById(imgLinkName);
if (imgLink.nodeName === "A") {
imgLink.style.background.width = imgIconHash[imgLinkName]['width'] * imgScale + "px";
imgLink.style.background.height = imgIconHash[imgLinkName]['height'] * imgScale + "px";
} else if (imgLink.nodeName === "IMG") {
imgLink.style.width = imgIconHash[imgLinkName]['width'] * imgScale + "px";
imgLink.style.height = imgIconHash[imgLinkName]['height'] * imgScale + "px";
}
}
}
Note, this is a webpage content part in SharePoint, hence the "_spBodyOnLoadFunctionNames.push('sizeImageMap()');" to perform an operation similar to document.onload.
So, two problems I am having:
The image in the 'columnDiv2' of 'iconDiv1' seems to be being cropped. It's size is 322px width and 128px height. The left and top don't appear to be being cropped, but the bottom and right do appear, or more so, don't appear, as though they have been cropped. I have seven other images in my code that are handled the same way, and have no problems with them, but this one appears to have the problem. It's not noticeable on the first loaded image, but on the image that shows after a 'hover', you can see the cropping.
I can get the IMG's width and height, but not the a-href link's background width and height. Any direction for this would be helpful. Also, I am doing this so that the images can be resized. Note the links are id's and not class's, as I was unable to find an easy way to access the existing images width and height, before loading, and then how to resize the a-href link's size after getting it. As said, the IMG works fine, just the A doesn't want to cooperate.
Thank you in advance.

Categories

Resources