#javascript #jquery
Вопрос:
Я хочу измерить время, в течение которого курсор мыши находится в определенной области (div-контейнер). См. Код ниже.
До сих пор время выхода и входа (время наведения) измерялось только тогда, когда курсор мыши входил и выходил из соответствующего контейнера (из-за события mouseleave и mouseenter), но не тогда, когда пользователь использует колесо мыши или прокручивает окно. Моя цель состоит в том, чтобы изменить код таким образом, чтобы время наведения также измерялось при прокрутке окна (например, пользователь использует колесо мыши).
Я уже пытался реализовать событие .scroll() с помощью селектора «документ».
Кто-нибудь уже сталкивался с такой же проблемой и у кого есть решение этой проблемы?
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>
Комментарии:
1. курсор мыши в области, когда окно прокручивается — вы имеете в виду, что если окно прокрутилось, то вы хотите измерить время наведения? или вы имеете в виду измерение расстояния прокрутки окна при наведении курсора?
2. Я отредактировал свой вопрос. Я имею в виду, что я хочу измерить время наведения, даже если окно прокручивается.
3. Наверное, я не понимаю, что сейчас не работает в вашем коде
4. mouseleave и mouseenter работают только при перемещении курсора мыши. В случае, если вы не перемещаете мышь, это означает, что курсор мыши остается в точно таком же положении, то код не оценивает время входа или выхода. В простом примере это не вызывает большого беспокойства. Однако в реальном проекте я реализовал несколько направлений. Поэтому, если кто-то прокручивает страницу (например, использует колесо мыши), Я не могу измерить время зависания.
5. Мне кажется, я понял вашу задачу. Необходимо, чтобы события мыши запускались при прокрутке окна, в тот момент, когда курсор мыши попадает в светло-голубое поле. Я прав?
Ответ №1:
Я нашел этот вопрос интересным для работы… И потратьте на это немало времени.
Вот как я об этом подумал:
- Используется
mouseenter
для записиtime_enter
. - используйте
mouseleave
для вычисления atime_spent
для элемента и очиститеtime_enter
. - Вкл
mousemove
., запишите положение мыши x/y. - Включите
scroll
для всех элементов, получите позиции (относительно порта просмотра), сравните их с записанным положением мыши, чтобы вызвать amouseenter
или amouseleave
на нем.
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 amp;amp;
mouse_pos.x < item.right amp;amp;
mouse_pos.y > item.top amp;amp;
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>