How can I find current element on mouseover using jQuery? - javascript

How can I get the class name of the current element that is on mouseover? For example
When a mouse is over from div to a, I want to get the class name of a div element. How can I get it using jQuery?

you can give a try to this:
window.onmouseover=function(e) {
console.log(e.target.className);
};

This is my version:
function handler(ev) {
var target = $(ev.target);
var elId = target.attr('id');
if( target.is(".el") ) {
alert('The mouse was over'+ elId );
}
}
$(".el").mouseleave(handler);
Working fiddle: http://jsfiddle.net/roXon/dJgf4/
function handler(ev) {
var target = $(ev.target);
var elId = target.attr('id');
if( target.is(".el") ) {
alert('The mouse was over'+ elId );
}
}
$(".el").mouseleave(handler);
.el{
width:200px;
height:200px;
margin:1px;
position:relative;
background:#ccc;
float:left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Hover an element and refresh the page, than move your mouse away.</p>
<div id="element1" class="el"></div>
<div id="element2" class="el"></div>
<div id="element3" class="el"></div>
<div id="element4" class="el"></div>
<div id="element5" class="el"></div>
<div id="element6" class="el"></div>
<div id="element7" class="el"></div>
<div id="element8" class="el"></div>
<div id="element9" class="el"></div>

Do you want the class name of the div on which the mouseover event occurs?
If that is the case then refer this,
HTML
<div class="a">aaaaaaaa</div>
<div class="b">bbbbbbbbb</div>
jQuery
$(document).on('mouseover', 'div', function(e) {
console.log($(e.target).attr('class'));
});
jsFiddle
I have used mouseover event with target
e.target gives the element on which that event occurs
If you want to get the class name of div after leaving the mouse from it
then use "mouseleave" event instaed of "mouseover"

What most people have neglected is this request from the OP:
When mouse over div from a
Meaning you need to know you've hovered from a specific type of element, not just from any element.
I made a global var, changing to true on the mouseleave of specific elements, in your case an a element. Then, inside the hover function you need to check that it's true.
Here's a Demo
Edit: Updated fiddle demo with edge cases when hovering from a element not directly onto the div.

Get the position of element on mouseover and then get the class name
<div id="wrapper">
A<div class="divClass">DIV</div>
</div>
$('#wrapper').mouseover(function(e) {
var x = e.clientX, y = e.clientY,
elementOnMouseOver = document.elementFromPoint(x, y);
elementClass=$(elementOnMouseOver).attr('class');
alert(elementClass);
});
JSFiddle: http://jsfiddle.net/ankur1990/kUyE7/
If you don't want to apply this only on wrapper div but on whole window/document, then you can replace wrapper with window/document
$(window).mouseover(function(e){});

All depending on how you want it. This could also be an option:
»Fiddle 1«
With some more detail. This will only show as true after taking the direct path from a to div. (The tiny white space between a and div.) As in:
a -> div TRUE
a -> div -> white space in between -> div FALSE
»Fiddle 2«
Might hold up. This will also show as true if one go to the tiny white space between a and div, and then go back to div. As in:
a -> div -> white space in between -> div TRUE
var mode = 0;
$(window).on("mousemove", function(e) {
if (e.target.className === "d1") {
mode = 1;
} else {
var cc = e.target.className;
if (cc !== "d2" && mode) {
var el = $(".d1"),
d1 = {
x : el.offset().left,
y : el.offset().top,
w : el.width(),
h : el.height()
},
c = {
x : e.pageX,
y : e.pageY
};
if (c.x >= d1.x + d1.w && c.y >= d1.y && c.y <= d1.y + d1.h)
mode = 2;
else
mode = 0;
} else if (cc === "d2" && mode) {
mode = 3;
}
}
$("#status").html("Current: " + (mode == 3 ? "OVER" : "NOT OVER") + " from a" );
});

From jQuery API
<div class="className">
<span class="span">move your mouse</span>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript">
$(".className").mouseover(function() {
var n = $(this).attr("class");
$(".span").html("");
$(".span").html("The class :"+n);
});
</script>

this should work:
define a class in your style sheet:
.detectable-div{
border: white solid 1px;
}
.detectable-div:hover{
border: red solid 1px;
}
then in your js:
$('div.detectable-div:hover').mouseover(function () {
$(this) // this is your object
})

Related

how do i trigger onMouseEnter for elements behind other elements

I'm trying to trigger mouseEnter event when mouse is on top of multiple elements.
I want both mouseEnter events to trigger when the mouse is at the center, and preferably for both to turn yellow.
Run the code snippet below for an example:
<!DOCTYPE html>
<html>
<head>
<style>
div:hover {
background-color: yellow;
}
div {
width: 100px;
height:100px;
background:green;
border: 2px solid black;
}
.second {
transform:translateX(50%) translateY(-50%);
}
</style>
<script>
function onhover(){console.log('hovered')}
</script>
</head>
<body>
<div onmouseenter=onhover()></div>
<div onmouseenter=onhover() class='second'></div>
</body>
</html>
According to MDN, the mouseenter event does not bubble, whereas the mouseover event does. However, even if it DID bubble, your elements currently have no relation to one another, thus the mouse events are captured by the upper element.
One possible way around this is with the amazing elementsFromPoint function in JavaScript, which makes quick work of solving your issue:
// Only the IDs of the elments you are interested in
const elems = ["1", "2"];
// Modified from https://stackoverflow.com/a/71268477/6456163
window.onload = function() {
this.addEventListener("mousemove", checkMousePosition);
};
function checkMousePosition(e) {
// All the elements the mouse is currently overlapping with
const _overlapped = document.elementsFromPoint(e.pageX, e.pageY);
// Check to see if any element id matches an id in elems
const _included = _overlapped.filter((el) => elems.includes(el.id));
const ids = _included.map((el) => el.id);
for (const index in elems) {
const id = elems[index];
const elem = document.getElementById(id);
if (ids.includes(id)) {
elem.style.background = "yellow";
} else {
elem.style.background = "green";
}
}
}
div {
width: 100px;
height: 100px;
background: green;
border: 2px solid black;
}
.second {
transform: translateX(50%) translateY(-50%);
}
<div id="1"></div>
<div id="2" class="second"></div>
I think that you can not without javascript, and with it it's a bit tricky, you have to check on every mousemove if the coordinates of the mouse are in de bounding box of the element, this fill fail with elements with border radius but for the others it's ok
<script>
var hovered=[]
function addHover(element){hovered.push(element)}
function onhover(element){console.log("hovered",element)}
function onCustomHover(e){
hovered.forEach((el,i)=>{
let bounds=el.getBoundingClientRect()
if (e.pageX > bounds.left && e.pageX < bounds.bottom &&
e.pageY > bounds.top && e.pageY < bounds.right ) {
onhover(i);
}
})
}
</script>
</head>
<body>
<div id="div1"></div>
<div id="div2" class='second'></div>
<script>
document.body.addEventListener('mousemove', onCustomHover, true);//{capture :false});
addHover(document.getElementById("div1"))
addHover(document.getElementById("div2"));
</script>
I would appreciate if you could rate the answer if that was usefull to you because I can not make comments yet <3
It will be easier to change your code a little bit.
ex. Add to your div elements class box.
Add to your styles class with name hovered which will look like:
.hovered {
background-color: yellow;
}
Into JS(between script tag) add event listeners (code not tested, but idea is shown), also move script to place before closing body tag:
const boxes = document.querySelectorAll('.box');
boxes.forEach(box => {
box.addEventListener('mouseover', () => {
boxes.forEach(b => b.classList.add('hovered'));
});
box.addEventListener('mouseout', () => {
boxes.forEach(b => b.classList.remove('hovered'));
});
});
The problem is that elements are blocking the mouse such that elements in the background do not receive the event. With the exception that events bubble to the parent.
Given that you could change your markup slightly to get this effect.
First add a class to your boxes so we can easily find them in JavaScript:
<div class="box"></div>
<div class="box second"></div>
Then adapt the CSS such that this background change is toggled with a class instead:
.box.hovered {
background-color: yellow;
}
And then the JavaScript:
// Get all box elements
const boxes = document.querySelectorAll('.box');
boxes.forEach(box => {
// For each box attach a listener to when the mouse moves
box.addEventListener('mousemove', (ev) => {
// Get the position of the mouse
const { x, y } = ev;
boxes.forEach(b => {
// for each box get it's dimension and location
const rect = b.getBoundingClientRect();
// check if the pointed is in the box
const flag = x > rect.left && x < rect.right && y > rect.top && y < rect.bottom;
// toggle the class
b.classList.toggle('hovered', flag);
});
});
});
This can be improved a lot, especially if you have more boxes by getting the rectangles beforehand and then using the index in the forEach to link the box to it's rectangle:
const boxes = document.querySelectorAll('.box');
const rects = [...boxes].map(box => box.getBoundingClientRect());
Another improvement is to use the fact that events bubble to the parent, that means you could wrap all boxes in one parent and only add a listener to this parent.

How to prevent hard jumping and what is alternative to position: sticky?

Two questions:
Focus on the part of 'Get early access' bar. It is positioned with position:relative and I want to have it sticky once you move to the 2nd section. I've tried to add helper with the same height in order to get smooth transition when I change the .class to fixed. But not working.
This with helper in previous websites helped me but now it doesn't work and it really bothers me.
What would be alternative to position sticky which works in all browsers? In this particular case, how needs jquery to look like?
Thanks in advance.
/**
* Zirelco
* Custom JS functions
*/
jQuery(document).ready(function ( $ ) {
var mn = $("#sticky-wrapper");
mns = "nav--scrolled";
hdr = $("#top-wrapper-v1").height();
$(window).scroll(function() {
if( $(this).scrollTop() > hdr ) {
mn.addClass(mns);
} else {
mn.removeClass(mns);
}
});
$('.cookies .btn').on('click', function() {
if ($('.cookies').css('opacity') == 0) {
$('.cookies').css('opacity', 1);
}
else {
$('.cookies').addClass('none');
}
});
});
Edit V3
Try this Code instead of yours:
(function(selector) {
selector = selector || '#sticky-wrapper';
var stickyWrapper = document.querySelector(selector)
var stickyTrigger = document.createElement('div')
stickyTrigger.classList.add('sticky-trigger')
stickyWrapper.parentElement.insertBefore(stickyTrigger, stickyWrapper)
var listener = function (e) {
if (stickyTrigger.getBoundingClientRect().top < 0) {
stickyWrapper.classList.add('sticky');
} else {
stickyWrapper.classList.remove('sticky');
}
}
var onScroll = document.addEventListener('scroll', listener);
}('#sticky-wrapper'))
What this does is:
create a .sticky-trigger element
insert this right before #sticky-wrapper
watch for scroll event of document
check the top property of getBoundingClientRect of the .sticky-trigger element
toggle the sticky class of #sticky-wrapper depending on the sign (positive or negative) of that top value
You don't have to change your HTML output at all
Old V1
You use the height of the #top-wrapper-v1 <section> as trigger for the class toggle. But you totally forget the to calc the <header> height as well.
To prevent such mistakes just go for the top edge of the '#sticky-wrapper' as a trigger
// $(window).scroll(function(e) {
// if( $(this).scrollTop() > mn.offset().top ) {
// mn.addClass('sticky');
// } else {
// mn.removeClass('sticky');
// }
//});
Old V2
Because of the comment of the asker, this is an improved way of doing it.
In the previous example, the measurement of the offset().top of #sticky-wrapper is immediately set to 0 caused by position: fixed. In order to break this issue, we wrap the #sticky-wrapper in a trigger element, measure the offset().top of that element as trigger. This trigger element will remain in the document flow and will not be fixed
HTML
<!--
<section id="sticky-trigger">
<section id="sticky-wrapper" class="">
<div class="container" style="position: fixed;top: 0;">
Other content
</div>
</section>
</section>
-->
JavaScript
// var trigger = document.querySelector('#sticky-trigger')
// $(window).scroll(function(e) {
//
// if( $(this).scrollTop() > trigger.offset().top ) {
// mn.addClass('sticky');
// } else {
// mn.removeClass('sticky');
// }
// });

How can I make the height of a div bigger onclick of a button and then change back to it's original height when click again?

I have a div id="coding" set on height:300px on CSS.
when I click another div id="menu", I want #coding to change it's height to 800px. I managed to do that like this
<script>
function changec() {
document.getElementById('coding').style.height = "800px";
}
</script>
Now, when click the #menu again, I want the height to get back to it's original 300px value. Can someone help? The code is:
HTML
<div id="coding">
<div id="menu" onclick="changec()">≡</div>
...
</div>
CSS
#coding{
...
height:300px;
}
Simple check if the value is set - remove it (then CSS height will take over).
function changec() {
var xDiv = document.getElementById('coding');
if (xDiv.style.height == '')
xDiv.style.height = '800px'
else
xDiv.style.height = ''
}
Demo: http://jsfiddle.net/ygalanter/BLE6N/
one of the solution for your problem is as follows:
First count how many times you click on #menu
now depending on your expectation you can change the javascript as follows
<script type="text/javascript">
var count = 0;
function changec() {
count++;
if(count%2==1)
document.getElementById("coding").style.height = "800px";
else
document.getElementById("coding").style.height = "300px";
}
</script>
Another alternative solution is
<script type="text/javascript">
function changec() {
var currentheight = document.getElementById('coding').clientHeight;
if (currentheight == 300)
document.getElementById('coding').style.height = "800px";
else if (currentheight == 800)
document.getElementById('coding').style.height = "300px";
}
</script>
Not sure why you tagged jQuery since you didn't use it, but still...Considering the possibility that you are willing to use/learn it, I created a jsFiddle for it: http://jsfiddle.net/Tm2Hd/.
CSS:
#coding{
border:1px solid black; /*optional: Keep track of your div's expand*/
height:300px;
}
#coding.larger{
height:800px;
}
JS:
function changeHeight() {
if($('#coding.larger').length>0)
{
$('#coding').removeClass("larger");
}
else
{
$('#coding').addClass("larger");
}
}
HTML
<div id="coding">
<!--<div onclick="changeHeight()">≡</div>
Personally, I don't suggest using divs as clickable objects... Why don't you use buttons instead?
-->
<button onclick="changeHeight()">≡</button>
...
</div>
My solution to your problem is: Create a new class named larger, pointing to your div, and toggle between this and the original whenever you click the button.

How to check if the cursor is over an element? [duplicate]

This question already has answers here:
pure javascript to check if something has hover (without setting on mouseover/out)
(5 answers)
Closed 3 years ago.
How can I check whether the cursor is over a div on the html page with JQuery/Javascript?
I'm trying to get cursor coordinates to see if they are in the rectangle of my element. Maybe there are predefined methods?
UPD, don't say anything about hover events, etc. I need some method which will return true/false for some element at the page, like:
var result = underElement('#someDiv'); // true/false
I'm not really sure why you wish to avoid hover so badly: consider the following script
$(function(){
$('*').hover(function(){
$(this).data('hover',1); //store in that element that the mouse is over it
},
function(){
$(this).data('hover',0); //store in that element that the mouse is no longer over it
});
window.isHovering = function (selector) {
return $(selector).data('hover')?true:false; //check element for hover property
}
});
Basically the idea is that you use hover to set a flag on the element that the mouse is over it/no longer over it. And then you write a function that checks for that flag.
For the sake of completeness I will add a couple of changes that I believe will help a bit for performance.
Use delegation to bind the event to one element, instead of binding it to all existent elements.
$(document).on({
mouseenter: function(evt) {
$(evt.target).data('hovering', true);
},
mouseleave: function(evt) {
$(evt.target).data('hovering', false);
}
}, "*");
Add a jQuery pseudo-expression :hovering.
jQuery.expr[":"].hovering = function(elem) {
return $(elem).data('hovering') ? true : false;
};
Usage:
var isHovering = $('#someDiv').is(":hovering");
The simplest way would probably be to just track which element the mouse is over at all times. Try something like:
<div id="1" style="border:solid 1px red; width:50px; height:50px;"></div>
<div id="2" style="border:solid 1px blue; width:50px; height:50px;"></div>
<div id="3" style="border:solid 1px green; width:50px; height:50px;"></div>
<input type="hidden" id="mouseTracker" />
​$(document).ready(function() {
$('*').hover(function() {
$('#mouseTracker').val(this.id);
});
});
and then your function is simply
function mouseIsOverElement(elemId) {
return elemId === $('#mouseTracker').val();
}
Can't you just check $(select).is(':hover') ?
I did this with custom function:
$(document).mouseup(function(e) {
if(UnderElement("#myelement",e)) {
alert("click inside element");
}
});
function UnderElement(elem,e) {
var elemWidth = $(elem).width();
var elemHeight = $(elem).height();
var elemPosition = $(elem).offset();
var elemPosition2 = new Object;
elemPosition2.top = elemPosition.top + elemHeight;
elemPosition2.left = elemPosition.left + elemWidth;
return ((e.pageX > elemPosition.left && e.pageX < elemPosition2.left) && (e.pageY > elemPosition.top && e.pageY < elemPosition2.top))
}

Fire JavaScript Event When a DIV is in View

Is it possible to fire a specific JavaScript event when a certain DIV comes into view on the page?
Say, for example, I have a very large page, like 2500x2500 and I have a 40x40 div that sits at position 1980x1250. The div is not necessarily manually positioned, it could be there due to the content pushing it there. Now, is it possible to run a function when the user scrolls to a point where the div becomes visible?
Not automatically. You would have to catch scroll events and check for it being in view each time by comparing the co-ordinates of the div rectangle with the visible page rectangle.
Here's a minimal example.
<div id="importantdiv">hello</div>
<script type="text/javascript">
function VisibilityMonitor(element, showfn, hidefn) {
var isshown= false;
function check() {
if (rectsIntersect(getPageRect(), getElementRect(element)) !== isshown) {
isshown= !isshown;
isshown? showfn() : hidefn();
}
};
window.onscroll=window.onresize= check;
check();
}
function getPageRect() {
var isquirks= document.compatMode!=='BackCompat';
var page= isquirks? document.documentElement : document.body;
var x= page.scrollLeft;
var y= page.scrollTop;
var w= 'innerWidth' in window? window.innerWidth : page.clientWidth;
var h= 'innerHeight' in window? window.innerHeight : page.clientHeight;
return [x, y, x+w, y+h];
}
function getElementRect(element) {
var x= 0, y= 0;
var w= element.offsetWidth, h= element.offsetHeight;
while (element.offsetParent!==null) {
x+= element.offsetLeft;
y+= element.offsetTop;
element= element.offsetParent;
}
return [x, y, x+w, y+h];
}
function rectsIntersect(a, b) {
return a[0]<b[2] && a[2]>b[0] && a[1]<b[3] && a[3]>b[1];
}
VisibilityMonitor(
document.getElementById('importantdiv'),
function() {
alert('div in view!');
},
function() {
alert('div gone away!');
}
);
</script>
You could improve this by:
making it catch onscroll on all ancestors that have overflow scroll or auto and adjusting the top/left co-ords for their scroll positions
detecting overflow scroll, auto and hidden cropping putting the div off-screen
using addEventListener/attachEvent to allow multiple VisibilityMonitors and other things using the resize/scroll events
some compatibility hacks to getElementRect to make the co-ords more accurate in some cases, and some event unbinding to avoid IE6-7 memory leaks, if you really need to.
Here is a solution that is ideal in 2022. The current top answer only allows you to observe one item, and has performance issues because it fires many times every time the page scrolls.
var observer = new IntersectionObserver(function(entries) {
if(entries[0].isIntersecting === true) {
console.log('Item has just APPEARED!');
} else {
console.log('Item has just DISAPPEARED!');
}
}, { threshold: [0] });
observer.observe(document.querySelector("#DIV-TO-OBSERVE"));
This fires as soon as the item is partially on screen. Changing threshold to 1 will require the item to be fully on screen (so it will never fire if the item is bigger than the viewport). You can do values in between for example 0.25 to fire when at least 1/4 of the item is in view.
Here's an starter example using jQuery:
<html>
<head><title>In View</title></head>
<body>
<div style="text-align:center; font-size:larger" id="top"></div>
<fieldset style="text-align:center; font-size:larger" id="middle">
<legend id="msg"></legend>
<div> </div>
<div id="findme">Here I am!!!</div>
</fieldset>
<div style="text-align:center; font-size:larger" id="bottom"></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
var $findme = $('#findme'),
$msg = $('#msg');
function Scrolled() {
var findmeOffset = $findme.offset(),
findmeTop = findmeOffset.top,
scrollTop = $(document).scrollTop(),
visibleBottom = window.innerHeight;
if (findmeTop < scrollTop + visibleBottom) {
$msg.text('findme is visible');
}
else {
$msg.text('findme is NOT visible');
}
}
function Setup() {
var $top = $('#top'),
$bottom = $('#bottom');
$top.height(500);
$bottom.height(500);
$(window).scroll(function() {
Scrolled();
});
}
$(document).ready(function() {
Setup();
});
</script>
</body>
</html>
It only notifies once the div comes into view from the bottom. This example does not notify when the div scrolls out of the top.

Categories