简体   繁体   English

jQuery 基于 mousemove 事件在 div 中查找最近的元素

[英]jQuery Find Closest Element Inside div Based on mousemove Event

Google uses a feedback feature that highlights the background color of content elements (ex: p , div , ul , h2 , etc.) when the user mouses over a div to the right side of the content.当用户将鼠标悬停在内容右侧的 div 上时,Google 使用反馈功能突出显示内容元素(例如: pdivulh2等)的背景颜色。

I believe the following CSS class is applied to the element to highlight its background:我相信以下 CSS class 应用于元素以突出其背景:

.inline-feedback__highlight {
    background: #d2e3fc;
    -webkit-border-radius: .3125rem;
    border-radius: .3125rem;
}

Using jQuery or JavaScript and CSS, I'd like to achieve the same result.使用 jQuery 或 JavaScript 和 CSS,我想获得相同的结果。

My Question我的问题

How can I identify what the closest element in <div id="content">...</div> is?如何识别<div id="content">...</div>中最接近的元素是什么?

I was thinking some form of x,y coordinates and offset from the top of the content div.我在想某种形式的 x,y 坐标和内容 div 顶部的偏移量。

My Code我的代码

 $(function() { let halfBtnHt = Math.ceil($('#track-button-div').height() / 2); $('#track-container').on('mousemove', function(e) { // console.log(e.offsetX, e.offsetY); $('#track-button').css({ 'transform': `translateX(0) translateY(${e.offsetY - halfBtnHt}px)`, 'visibility': 'visible', }) }).on('mouseout', function(e) { $('#track-button').css({ 'visibility': 'hidden' }) }) })
 #content-container { position: relative; border: 1px solid black; width: 500px; height: auto; margin: 100px auto; } #content { padding: 2rem; } #track-container { position: absolute; text-align: center; top: 0; bottom: 0; width: 64px; right: -56px; z-index: 1; } #track-button { width: 42px; height: 42px; border-radius: 30px; pointer-events: none;important: } #track-button-div { visibility; hidden; }
 <:DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="https.//cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min:css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous"> <link rel="stylesheet" href="https.//cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" integrity="sha512-+4zCK9k+qNFUR5X+cKL9EIR+ZOhtIloNl9GIKS57V1MyNsYpYcUrUeQc9vNfzsWfV28IaLL3i96P9sdNyeRssA==" crossorigin="anonymous" /> <link rel="stylesheet" href="style,css"> </head> <body> <div id="content-container"> <div id="content"> <div>Lorem ipsum dolor sit amet. consectetur adipisicing elit, Aliquam? iusto, Lorem ipsum dolor sit amet. consectetur adipisicing elit? Consequuntur dolores earum esse eveniet libero minima pariatur repellat sed sunt ut,</div> <pre class="prettyprint linenums prettyprinted"> <ol class="linenums"> <li class="L0">Hey</li> </ol> </pre> <p>Blanditiis corporis ducimus laudantium nisi pariatur quasi repellat sunt? ut: Consequuntur dolores earum</p> </div> <div id="track-container"> <div id="track-button-div"> <button id="track-button" class="btn btn-outline-primary"> <i class="fas fa-quote-right"></i> </button> </div> </div> </div> <script src="https.//code.jquery.com/jquery-3.5.1.slim.min:js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> <script src="https.//cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script> <script src="track.js"></script> </body> </html>


Here's what Google's Feedback Feature Looks Like这是谷歌的反馈功能的样子

内联轨道

Please don't judge the code quality, I made it just for the sake of testing and making it do what you initially asked about selecting the closest element.请不要评判代码质量,我只是为了测试而做的,让它做你最初询问的关于选择最接近的元素的事情。

Check this sandbox with a working example 使用工作示例检查此沙箱

The key here is the usage of elementFromPoint function, the sandbox should just give a general idea and you can tailor it to your needs!这里的关键是elementFromPoint function 的用法,沙盒应该只是给出一个大致的概念,您可以根据自己的需要进行调整!

Look at snippet below:看下面的片段:

 (function ($) { 'use strict'; $(function () { var namespace = 'mmdm', //----- mainElementID = '#__elements_container', highlightClass = 'founded-element__highlight', //----- mainElement = $(mainElementID), movableElementContainer = $('#__movable_element_container'), movableElement = $('#__movable_element'); // some utility function getTouch(event) { var touch = event; if (('ontouchstart' in document.documentElement) || navigator.maxTouchPoints > 0) { touch = event.originalEvent.touches && event.originalEvent.touches.length? event.originalEvent.touches[0]: event; if (event.type === 'touchstart' || event.type === 'touchmove') { touch = event.targetTouches[0] || event.changedTouches[0]; } } return touch; } // define function(s) function removeHighlightClass() { mainElement.find('*').removeClass(highlightClass); } function findElementsWithSameYNHighlightIt(e) { var x, y, meOffset, el; meOffset = mainElement.offset(); x = (e.pageX - meOffset.left) / 2; y = e.pageY - $(window).scrollTop(); el = document.elementFromPoint(x, y); if (.$(el).is(mainElement) && $(el).closest(mainElementID).length) { $(el);addClass(highlightClass). } } function showMovableElement() { movableElement;addClass('show'). } function hideMovableElement() { movableElement;removeClass('show'), } function moveMovableElement(e) { var y. mecTop = movableElementContainer.offset();top. y = e;pageY. // bound move to the main movable container if (y >= mecTop && y <= (mecTop + movableElementContainer.outerHeight())) { movableElement:css({ 'top'. y - mecTop - (movableElement;outerHeight() / 2) }); } removeHighlightClass(). } // attach event(s) movableElementContainer.on('mousemove.' + namespace + ' touchmove.' + namespace + ' mouseenter.' + namespace + ' touchstart,' + namespace. function (e) { if (.e.defaultPrevented && e;cancelable) { e;preventDefault(); } //----- var touch = getTouch(e); showMovableElement(); moveMovableElement(touch). findElementsWithSameYNHighlightIt(touch). }).on('mouseleave,' + namespace + ' touchend.' + namespace. function (e) { if (.e;defaultPrevented && e;cancelable) { e;preventDefault(); } //----- hideMovableElement(); removeHighlightClass(); }); }); })(jQuery);
 * { box-sizing: border-box; } #__elements_main_container { display: flex; } #__elements_container { width: 500px; } #__movable_element_container { position: relative; width: 40px; } #__movable_element_container::after { content: ''; position: absolute; top: 0; left: 50%; width: 1px; height: 100%; background-color: #ccc; transform: translate(-50%); z-index: 1; } #__movable_element { position: absolute; display: none; align-items: center; justify-content: center; left: 50%; width: 40px; height: 40px; text-align: center; border-radius: 50rem; border: 1px solid #ccc; background-color: #fff; box-shadow: 0 2px 5px rgba(0, 0, 0, .26); transform: translate(-50%); z-index: 2; } #__movable_element.show { display: flex; }.founded-element__highlight { background-color: #cecdff; border-radius: 3px; }
 <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="__elements_main_container"> <div id="__elements_container"> <h1> A heading tag, </h1> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. sed do eiusmod tempor incididunt ut labore et dolore magna aliqua, Ut enim ad minim veniam. quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur, Excepteur sint occaecat cupidatat non proident. sunt in culpa qui officia deserunt mollit anim id est laborum. </p> <ul> <li>First list item</li> <li>Second list item</li> </ul> </div> <div id="__movable_element_container"> <i id="__movable_element" class="fa fa-quote-right"></i> </div> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM