I want to measure the time that a mouse cursor is in a specific area (div-container). See code below.
Until now, the leave and enter times (hover-times) are only measures when the mouse cursor enters and leaves the respective container (due to the mouseleave and mouseenter event) but not when the user uses mouse wheel or scrolls the window. My goal is to change the code in a way that the hover time is also measured when the window is scrolled (e.g. the user uses the mouse wheel).
I already tried to implement a .scroll() event with the selector 'document'.
Has anyone already encountered the same problem and has a solution for the problem?
var hover_events = {};
var enter_time;
var leave_time;
$(".element").on('mouseenter', function(d) {
enter_time = Date.now();
hover_events[d.target.id] = {
element_id: d.target.id,
enter_time: enter_time,
leave_time: undefined,
};
});
$(".element").on('mouseleave', function(d) {
leave_time = Date.now();
hover_events[d.target.id]["leave_time"] = leave_time;
console.log(hover_events[d.target.id])
delete(hover_events[d.target.id]);
});
.element {
margin: 100px;
width: 100px;
height: 100px;
background-color: lightblue;
}
#scroll {
width: 1000px;
height: 1000px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="scroll">
<div class="element" id="test">
</div>
</div>
I found that question fun to work on... And spend quite a time on it.
Here is how I thought it:
mouseenter to record a time_enter.mouseleave to calculate a time_spent for the element and clear time_enter.mousemove, record the x/y mouse position.scroll for all elements, get the positions (relative to the view port) compare them with the recorded mouse position to trigger a mouseenter or a mouseleave on it.Codepen
console.clear();
var elements = {};
let mouse_pos = {};
// Save all element position relative to the viewport
function positions() {
$(".element").each(function () {
let bounding_rect = this.getBoundingClientRect();
elements[this.id] = elements[this.id] || {};
elements[this.id].top = bounding_rect.top;
elements[this.id].right = bounding_rect.right;
elements[this.id].bottom = bounding_rect.bottom;
elements[this.id].left = bounding_rect.left;
elements[this.id].time_spent = elements[this.id].time_spent || 0;
});
}
// Run once on load
positions();
let keys = Object.keys(elements);
$(window).on("scroll", function () {
positions();
// loop all elements
keys.forEach(function (id) {
let item = elements[id];
if (
mouse_pos.x > item.left &&
mouse_pos.x < item.right &&
mouse_pos.y > item.top &&
mouse_pos.y < item.bottom
) {
console.log("Hovering", id);
$(`#${id}`).trigger("mouseenter");
} else {
$(`#${id}`).trigger("mouseleave");
}
});
});
$(document).on("mousemove", function (e) {
mouse_pos.x = e.pageX;
mouse_pos.y = e.pageY;
//console.log(mouse_pos)
});
$(".element").on("mouseenter", function (e) {
elements[e.target.id].time_enter = Date.now();
//console.log(elements);
$(`#${e.target.id}`).addClass("hovered");
});
$(".element").on("mouseleave", function (e) {
if (elements[e.target.id].time_enter) {
elements[e.target.id].time_spent +=
Date.now() - elements[e.target.id].time_enter;
delete elements[e.target.id].time_enter;
//console.log(elements);
$(`#${e.target.id}`)
.text((elements[e.target.id].time_spent / 1000).toFixed(2) + " sec.")
.removeClass("hovered");
}
});
body {
height: 1000px;
}
.row {
display: flex;
justify-content: space-between;
margin-top: 100px;
}
.element {
width: 100px;
height: 100px;
background-color: lightblue;
display: flex;
justify-content: center;
align-items: center;
}
.hovered {
border: 1px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div class="element" id="el_1"></div>
<div class="element" id="el_2"></div>
<div class="element" id="el_3"></div>
<div class="element" id="el_4"></div>
</div>
<div class="row">
<div class="element" id="el_5"></div>
<div class="element" id="el_6"></div>
<div class="element" id="el_7"></div>
<div class="element" id="el_8"></div>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With