简体   繁体   中英

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.

I believe the following CSS class is applied to the element to highlight its background:

.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.

My Question

How can I identify what the closest element in <div id="content">...</div> is?

I was thinking some form of x,y coordinates and offset from the top of the content 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!

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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