Is it possible to conceal any spans that are in close proximity to the cursor when hovered over?

Currently, I am working on a project that involves multiple spans placed side by side, with each span containing a letter of the text. My aim is to create a functionality where hovering over one of these spans will not only hide that particular span but also others nearby.

This setup produces an image resembling the following:

@@@@@@@@@@@@@@  
@@@@@@@@@@@@@@  
@@@@@@@@@@@@@@  
@@@@@@@@@@@@@@

The objective here is to conceal all spans within a specific distance from the mouse pointer, as illustrated in this example:

In terms of HTML structure:

<span id="overlay-1">@</span>
<!-- ... -->
<span id="overlay-142">@</span>
<span id="overlay-143">@</span>

I have managed to hide individual spans by targeting their IDs upon mouseover and modifying the style property to display=none. However, my main challenge lies in hiding all spans located close to the mouse cursor. Do you have any suggestions or solutions for this issue?

Answer №1

I attempted to tackle this challenge using JavaScript. Below is the code I came up with:

function draw() {
    let content = "";
    for (let col = 0; col < 100; col++) {
        content += "<div>"
        for (let row = 0; row < 100; row++) {
            content += `<span onmouseout="hoverOff()" onmouseover="hoverOver(this)" id="overlay-${row}-${col}">@</span>`
        }
        content += "</div>"
    }
    document.getElementById('drawing').innerHTML += content
}

function hoverOver(element) {
    let id = element.id;
    let row = element.id.split('-')[1];
    let col = element.id.split('-')[2];
    
    for (let x = -2; x <= 2; x++) {
        for (let y = -1; y <= 1; y++) {
            const item = document.getElementById(`overlay-${row-x}-${col-y}`);
            item ? item.style.opacity = 0 : null;
        }
    }
    element.style.opacity = '0';
}

function hoverOff() {
    for (let i = 0; i < document.getElementsByTagName('span').length; i++) {
        document.getElementsByTagName('span')[i].style.opacity = 1;
    }
}
<body onload="draw()">
    <div id="drawing">
    </div>
</body>

Answer №2

To achieve this without relying on specific ids, an alternative method involves utilizing the Element.getBoundingClientRect() function to determine the size and location of the element being hovered over. Subsequently, the use of Document.elementFromPoint() within a loop allows for accessing elements in close proximity to the target:

const main = document.querySelector('main')
for (let i = 0; i < 800; i++) main.innerHTML += '<span>@</span>'
const spans = document.querySelectorAll('span')

const areaWidth = 50
const areaHeight = 50
const hidden = []

function getElements(currentSpan, color) {
  const { top, right, bottom, left, width, height } = currentSpan.getBoundingClientRect()

  for (let col = left - areaWidth / 2; col < right + areaWidth / 2; col += width || 14) {
    for (let row = top - areaHeight / 2; row < bottom + areaHeight / 2; row += height || 14) {
      const el = document.elementFromPoint(col, row)
      if (el?.tagName === 'SPAN') {
        el.style.color = color
        hidden.push(el)
      }
    }
  }
}

spans.forEach(span => {
  span.addEventListener('mouseover', () => getElements(span, 'transparent'))
  span.addEventListener('mouseout', () => {
    hidden.forEach(el => (el.style.color = ''))
    hidden.length = 0
  })
})
main {
  display: flex;
  flex-wrap: wrap;
  width: 640px;
  cursor: default;
}
<main></main>

Answer №3

If you're looking to hide adjacent characters upon clicking, one solution could be using CSS to overwrite those characters with a pseudo element.

This code snippet utilizes a monospace font and defines line height and letter spacing as CSS variables, allowing for easy customization.

function clicked(ev) {
  ev.target.classList.add('obscure');
}
const container = document.querySelector('.container');
for (let i = 0; i < 200; i++) {
  const span = document.createElement('span');
  span.innerHTML = '@';
  if (i % 10 == 0) {
    container.innerHTML += '<br>';
  }
  container.appendChild(span);
}
container.addEventListener('click', clicked);
.container {
  width: 50vw;
  height: auto;
  font-family: Courier, monospace;
  --line-height: 20px;
  --letter-spacing: 5px;
  line-height: var(--line-height);
  letter-spacing: var(--letter-spacing);
}

.container span {
  position: relative;
  margin: 0;
  padding: 0;
}

.obscure::before {
  content: '';
  width: calc(5ch + (6 * var(--letter-spacing)));
  height: calc(3 * var(--line-height));
  background-color: white;
  position: absolute;
  top: 0;
  transform: translate(calc(-50% + 0.5ch), calc(-50% + (1ch)));
  left: 0;
  z-index: 1;
  display: inline-block;
}
<body>
  <div class="container"></div>
</body>

Answer №4

It seems like you're looking to make the span disappear without affecting the layout. Using display:none won't achieve this, but visibility:hidden will do the trick.

Hiding the hovered element and its adjacent elements is straightforward. The real challenge lies in hiding elements above or below it.

To accomplish this, some calculations are necessary.

If an exact solution isn't required, you could try something like this:

  1. Determine the center positions of all spans and store them in an array to avoid recalculating each time.
  2. When a span is hovered over, identify all spans within a certain radius of that span's center point - whether above, below, left, or right.
  3. Create a new array of spans to hide based on the previous step.
  4. Review all currently hidden spans and unhide any that aren't included in the new array (set visibility:visible).
  5. Finally, loop through the new array and set visibility:hidden for all spans in that array.

Answer №5

Here is a unique and customizable approach:

// Customizing Variables
const ROW = 10; // Total number of rows available
const COL = 35; // Total number of items in each row
const RANGE = 2; // Number of items to be selected in each direction
const values = []; // Array to store ids of selected items

// Utility Function to add values to the array
const push = (value) => {
  if (value > 0 && value <= ROW * COL && !values.includes(value)) values.push(value);
};

// Adding items in the root div
const root = document.querySelector("#root");

for (let i = 0; i < ROW; i++) {
  root.innerHTML += `<div id="row-${i + 1}"></div>`;

  for (let j = 0; j < COL; j++) {
    document.querySelector(`#row-${i + 1}`).innerHTML += `<span id="item-${COL * i + (j + 1)}">@</span>`;
  }
}

// Adding class to the items based on the RANGE
root.addEventListener("mouseover", (e) => {
  values.length = 0;

  const id = e.target.id;
  if (!id.includes("item-")) return;

  const current = +id.replace("item-", "");
  push(current);

  for (let i = -RANGE; i < RANGE; i++) {
    push(current + i);

    for (let j = -RANGE; j <= RANGE; j++) {
      push(current + COL * i + j);
      push(current - COL * i + j);
    }
  }

  for (let i = 0; i < values.length; i++) {
    const item = document.querySelector(`#item-${values[i]}`);
    item.classList.add("selected");
  }
});

// Removing class from the items once the mouse is out as per the RANGE
root.addEventListener("mouseout", () => {
  for (let i = 0; i < values.length; i++) {
    const item = document.querySelector(`#item-${values[i]}`);
    item.classList.remove("selected");
  }
});
/* Styling purpose only */
body {
  background-color: #111;
  color: #fff;
}

#root [id*="item-"] {
  padding: 1px;
}

/* Styles for the selected item */
#root [id*="item-"].selected {
  /* color: transparent; */ /* You can uncomment this line for desired effect */
  color: #ffa600;
}
<div id="root"></div>

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

Adjusting the background color of a MuiList within a React Material-UI Select component

Looking to customize the background color of the MuiList in a react material-ui Select component without affecting other elements. Specifically targeting the Select element with the name 'first'. Despite setting className and trying different cl ...

The JavaScript script to retrieve the background color is malfunctioning

I am currently working on developing a highlighting feature for an HTML table that will dynamically change the row colors on mouseover. Below is the code snippet I have been using, but it seems to be experiencing some issues. Any assistance would be greatl ...

Ways to turn off hover highlighting

Is there a way to disable the highlighting effect of the <select> element in HTML? When you hover over items in the dropdown list, a blue color strip moves with your mouse. I need to find a way to get rid of this effect. Here is an example of the c ...

What is the best way to send information using an array of objects?

In my Angular 5 project, I am using the ngx select dropdown package (https://www.npmjs.com/package/ngx-select-dropdown) and I'm wondering how to pass an array of objects instead of an array of strings. Currently, when I do so, it displays [Object Obje ...

Is there a way to showcase whitespacing in HTML?

I have a database full of content that includes whitespace formatting for display on a webpage. However, when viewed on Stackoverflow using the code tag, the formatting changes. The second way shows how it is stored in the database and how I want it to app ...

What steps should I take to design and implement this basic search form?

Essentially, I have a three-page setup: - One page containing all possible search results such as: 'search result 1' 'search result 2' 'search result 3' - Another page with a search form and enter button. - And finally, a res ...

What is the method for specifying the HTML file extension within Visual Studio?

I am having issues with my project recognizing the CSS and other files in the HTML files I have created, even though I have double-checked the extension paths. How can I resolve this problem? https://i.stack.imgur.com/85ooE.png https://i.stack.imgur.com/F ...

"User-friendly Material-UI input field paired with a clear label

Seeking guidance on creating a text field with a label using the material-ui library. I am searching for something similar to this example: https://github.com/callemall/material-ui/blob/master/src/TextField/TextFieldLabel.jsx Unfortunately, I have been ...

What is the best way to emphasize a certain row within XSLT?

I am seeking a solution to emphasize rows containing the "year" element with a value exceeding "2000" in XML and XSLT. Here is the code snippet: XML <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="harrypotterbooks. ...

Using array map to create a centered table in a React web application

In my React project, I created a table using the array.map function. However, I'm facing an issue where the output of array.map is always aligned to the left, even before the table itself. I want to center the entire table. JSX: <div className=&qu ...

Leverage the retrieved configuration within the forRoot function

Currently working on an Angular app that uses @ngx-translate. In my implementation, I am using TranslateModule.forRoot(...) to set up a TranslateLoader: @NgModule({ imports: [ TranslateModule.forRoot({ loader: { provide: TranslateLoade ...

Stylish Sudoku Grid Design with CSS-Grid Borders

I have designed a sudoku puzzle and I am seeking assistance with CSS to style it. My goal for styling using CSS is illustrated here... https://i.stack.imgur.com/nrA47.png What I currently have appears like this... https://i.stack.imgur.com/zpNp6.png T ...

Storing information in a database using Phantomjs

My app is built on phantomjs and here's how it currently operates: 1. A php script retrieves data from my postgres database as an array, 2. The array of data is then passed as an argument to a shell_exec command running a phantomjs script, 3. Phantomj ...

Practical strategy for developing and launching a TypeScript/Node.js application

I'm currently developing a node.js app using Typescript, which requires compilation to JS before running. As someone with a background in java/jvm, I'm hesitant about the deployment process where code is pushed to git, built/compiled on the serve ...

Activate the button to effortlessly load pages with a visually engaging animation

I have been facing a problem for the past couple of days. I need help with achieving a specific functionality on my website. When button1 is clicked, I want to load the page in a div class named "loadpage" with an animation coming from the left. Similarl ...

Unable to retrieve the complete count of invitations made by a user

My goal is to retrieve the invites of the author of a specific command within one server. I have experimented with various solutions, but many appear outdated or incorrect. Here is my current approach: exports.run = async (client, message, args) => { ...

How can I access the id_lang variable in React JS from outside its scope?

How do I access the 'id_lang' variable outside of the render function in order to pass it down for checking? const Navbar = () => { const getID = async (id) => { let id_lang = id; console.log(id_lang); } ret ...

Steps for sending a request to the root resource

I've encountered a problem that stems from my limited knowledge of Express. Despite creating a project with Express, I'm unable to make calls to the root, only to the routes. I suspect the issue lies in my usage of app.use(...). app.js var inde ...

The webpage is unreachable on localhost after attempting to write to a file using node.js

I'm currently attempting to update a file using Node.js. I have a form that contains checkboxes, and upon form submission, the server should update the file based on which checkboxes are selected: a, b, or c. The JSON file structure is as follows: { ...

Struggling with the migration of routes from react-router v3 to v4

My route configuration using react-router v3 is as follows: <Route component={App}> <Route path="login" component={Login} /> <Route path="logout" component={Logout} /> <Route path="/" component={Admin}> <IndexRoute com ...