Adjusting position in relation to the cursor's movements

I have searched extensively for similar questions but have been unable to resolve my issue. Here, I am sharing just a single list item from my code. The task at hand is to create a span element on the mousemove event over the list item, and dynamically set its left offset relative to its parent as the mouse moves. Since this is new territory for me, I have experimented quite a bit with the following code snippet:

document.querySelector("li a").addEventListener("mousemove",(event)=> {

let span;
let alreadyHasSpan =    event.target.hasChildNodes().length > 1; //default length=1

if(!alreadyHasSpan) {
span = $(`<span class="a-effect"></span>`);
span.appendTo(event.target);
}

let targetLeftPos = event.target.getBoundingClientRect().left;

span.css("left",`${event.clientX-targetLeftPos}px`);


$(this).mouseleave(function () { 
span.remove();
});
}, false);
a {
  position: relative;
}
.a-effect {
position: absolute; left: 0;
height: 100%;
width: 2%;
background: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<li class="nav-item active">
<a href="/" class="nav-link">Product</a>
</li>

Despite the functionality of the span moving along with the mouse cursor, it leaves behind trailing remnants:

https://i.sstatic.net/kDaCm.png

In addition to the trailing remnants, there are occasions when the span fails to display altogether. This problem is exacerbated in the snippets provided for this question.

What could be causing these issues and how can they be rectified?

Answer №1

Upon reviewing your inquiry, it appears that the issue arises from adding a new span each time the mouse moves. It seems like you only intend to add the span when the mouse enters and remove it upon mouse exit.

I have attempted to retain most of your original code while addressing the specific issue causing the problem.

document.querySelector("li a").addEventListener("mouseenter", (event) => {

  let span;
  let alreadyHasSpan = event.target.childNodes.length > 1; //default length=1

  if (!alreadyHasSpan) {
    span = $(`<span class="a-effect"></span>`);
    span.appendTo(event.target);
  }
});

document.querySelector("li a").addEventListener("mousemove", (event) => {
  let targetLeftPos = event.target.getBoundingClientRect().left;
  if (event.target.childNodes.length > 1) {
    let span = event.target.childNodes[1];
    $(span).css("left", `${event.clientX-targetLeftPos}px`);
  }
});

document.querySelector("li a").addEventListener("mouseleave", (event) => {
  if (event.target.childNodes.length > 1) {
    let span = event.target.childNodes[1];
    span.remove();
  }
});
a {
  position: relative;
}

.a-effect {
  position: absolute;
  left: 0;
  height: 100%;
  width: 2%;
  background: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<li class="nav-item active">
  <a href="/" class="nav-link">Product</a>
</li>

Answer №2

I'm a bit uncertain about the exact placement you're looking for with your span element, but there are a few issues in your code that need addressing first. Once those are fixed, adjusting the positioning of the element should be relatively straightforward.

Firstly, you currently append the span element within a mousemove function and then check on every event trigger if the span is already present. I suggest modifying this to utilize the mouseenter event for creating the span. Additionally, consider establishing a separate mouseleave handler for your link outside of the mousemove event.

In terms of where you'd like the element to appear or follow your mouse, you can customize the offsetX and offsetY variables within the moveSpan() function to suit your requirements.

Keep in mind that when positioning the element, the calculation is based on the position of your a element.

function moveSpan( e ) {
let $el = $(e.target);
let xPos = e.pageX;
  let yPos = e.pageY;
  let offsetX = $el.width() / 2;
  let offsetY = $el.height() / 2;
  let $span = $el.find('span');
 $span.css({
    'left': (xPos - offsetX) + 'px',
    'top': (yPos - offsetY) + 'px'
  });
}

$('li a').on('mouseenter', function( e ) {
let span = $('<span />').addClass('a-effect');
  $(this).append( span );
  moveSpan( e );
}).on('mousemove', function( e ) {
moveSpan( e );
}).on('mouseleave', function( e ) {
$(this).find('span').remove();
});
ul {
  list-style-type: none;
}
a {
  position: relative;
}

.a-effect {
  position: absolute;
  height: 100%;
  width: 10px;
  background: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li class="nav-item active">
    <a href="/" class="nav-link">Product</a>
  </li>
</ul>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Changing the CSS property from "display: none" to "display: block" using JavaScript causes all the div elements to overlap

My issue involves several radio inputs where clicking one should reveal a hidden div containing information. However, when this div appears, it overlaps with the footer instead of staying positioned between the footer and radio input as intended. I am str ...

Retrieve data from MongoDB using the unique identifier (_id) and additional conditions with Express

Below is the code I am currently working with: PostCategory.find({categoryid:category._id.str},function(err,postcategories){ if(err) return next(err); Post.find({_id:postcategories.postid},function(err,posts){ if(err) ...

Vuejs failing to update data

Let me begin by describing my scenario. I have a fee_map attribute in my data, which is a list of objects containing information about the fees students have to pay, their balances, payment methods, etc. Additionally, there is a computed property called &a ...

Changing the Button Background in Richfaces

I am attempting to modify the background-image of a h:commandButton element located within a RichFaces:panel. To achieve this, I created a CSS file with the following styling rule: .sButton { background-image:url('../imgs/btnTexture2.jpg') ...

Having trouble retrieving response content in Mithril

I've been experimenting with making a request to a NodeJS API using the Mithril framework in my client application. I attempted to fetch data by following their example code: var Model = { getAll: function() { return m.request({method: "G ...

sole active component present

In my redux store, I have an array called rooms that is fetched from the server. In my component, I fetch this array from the store, map it, and display elements with the value of room['foo']. However, I am facing a problem where when a user clic ...

Combining HTML with multiple .ts files in Angular

I've been dedicating time to enhancing an Angular application, particularly a sophisticated table with intricate styling and functionality. Within my component file, there is a whopping 2k lines of code that includes functions for text formatting, ta ...

Connecting promises to build upon past outcomes

Can someone help me figure out how to access previous results in promises? I've been following the guidance on this stackoverflow thread. I had success with 2 promises, but things got tricky when I added a 3rd promise that makes a POST request to an ...

Use an if statement in Angular to conditionally add a title attribute with an empty value to HTML

How can I conditionally add the title attribute to a div without creating another div and using ngIf? If the permission is true, I want to include a title in my div. Here's what my current div looks like: <div (click)="goToChangelog()&quo ...

Retrieving information from a database with AJAX in CodeIgniter

After clicking on a button in this code, the data is supposed to be fetched from a database and dynamically displayed within the appropriate div using jquery and ajax. However, I am not seeing any output. See below for the code snippet: Controller defi ...

The AJAX response is not functioning as expected

I've encountered an issue with my AJAX code for an online food store. Every time I run it, a pop-up message saying something went wrong appears instead of the expected output. I suspect there might be an error in either the connection handlers or the ...

Delivering a JSON response containing an item within an array

I am struggling to find the correct way to access the error message related to the 'firstname' field in the JSON-encoded object. The error message states that the length of the value for 'firstname' must be at least 3 characters long. ...

Dynamic value for href in div using Angular

Implementing a dynamic submenu using Angular is my current project. At the moment, I have set the href attribute with hardcoding as shown below: <ng-template #preSelectionMenuItem let-preSelections="preSelections"> <div class=' ...

floating downward inside the container

Check out my website at . Everything looks great in Firefox, but when I view it in IE, the "top" button that should be floated inside the h2 titled "Unit 301: Pre-production skills" is floating to the right and getting pushed outside of the heading. Any i ...

"Exploring the world of WordPress: Developing plugins with Ajax for database integration and admin email

Currently, I am in the process of developing my first Wordpress contact us plugin for a website project. Here is the progress I have made so far: The plugin shows up in the plugin list on the WP dashboard Upon activation, a new table is created in the d ...

Updating the status of a 2D array with N elements in React: A step-by-step guide

Before I dive into the topic, I must acknowledge that I have come across questions similar to this one before but was unable to find a solution on my own. Updating React state as a 2d array? Let's imagine this as my state object state = { graph ...

Exploring nested arrays with recursive looping

I have been working on solving this challenge using recursion because I enjoy the challenge. The task at hand involves taking an array of arrays and transforming it into a single array with all the values combined. While I have made good progress, I am e ...

The Stripe payment form effortlessly updates in real-time thanks to the powerful @stripe/react-stripejs module

I am experiencing some difficulties with implementing Stripe payment in my Medusa-JS Next JS frontend. Whenever I enter card details in the checkoutForm, the entire StripePayment component keeps re-rendering every time I click on anything within the form ...

What could be the reason for the variable not resetting in my event handler?

Check out the code I've written below: $(document).ready(function () { var default_var = 2; var show_var = default_var; var total_var = 8; var increment_var = 2; var start_var = show_var+1; var end_var = show_var+increment_v ...

Using jQuery to show array elements with unique formatting or separator

Using the jQuery map/get function, I am able to retrieve an array of values from multiple checked checkboxes: $('input[type=checkbox]:checked').map(function(_, el) { return $(el).val(); }).get(); After executing this code, I will get an arr ...