I aim to create multiple mouseover functions using the least amount of code possible

I have a challenge where I need 10 unique links that behave in a specific way when the user hovers over them. Essentially, I want the background image of the containing div to change and for a tooltip text to fade-in on top of each link.

I've attempted to achieve this functionality using JavaScript, but it's resulted in lengthy and repetitive code. I'm looking for a more efficient solution that avoids unnecessary repetition.

 // JS functions for mouseover and mouseout behavior
document.getElementById("d1").onmouseover = function() {
  mouseOver(1);
};
document.getElementById("d2").onmouseover = function() {
  mouseOver(2);
};
document.getElementById("d3").onmouseover = function() {
  mouseOver(3);
};
document.getElementById("d1").onmouseout = function() {
  mouseOut(1);
};
document.getElementById("d2").onmouseout = function() {
  mouseOut(2);
};
document.getElementById("d3").onmouseout = function() {
  mouseOut(3);
};

function mouseOver(num) { // Function to handle hover behaviors based on link number
  document.getElementById("dogs").style.background = getColor(num); // Get color based on link number
  document.getElementById("tooltiptext" + num).style.visibility = "visible";
}

function mouseOut(num) { // Function to handle mouseout behaviors based on link number
  document.getElementById("dogs").style.background = "black";
  document.getElementById("tooltiptext" + num).style.visibility = "hidden";
}
#dogs {
  float: right;
  margin-top: 5%;
  background: black;
  width: 150px;
  height: 150px;
}

#d-list {
  color: white;
  direction: ltr;
  float: right;
  width: 60%;
  height: 60%;
}

#tooltiptext1,
#tooltiptext2,
#tooltiptext3 {
  color: black;
  background-color: gray;
  width: 120px;
  height: 30px;
  border-radius: 6px;
  text-align: center;
  padding-top: 5px;
  visibility: hidden;
}
<div id="animals">
  <div id="dogs"></div>
  <div id="d-list">
    <pre style="font-size:22px; color:darkorange">dogs</pre><br />

    <pre><a href="#burger" id="d1">white Husky</a></pre>
    <p id="tooltiptext1">Tooltip text1</p>

    <pre><a href="#burger" id="d2">black Bull</a></pre>
    <p id="tooltiptext2">Tooltip text2</p>

    <pre><a href="#burger" id="d3">brown Rex</a></pre>
    <p id="tooltiptext3">Tooltip text3</p>
  </div>
</div>

Please consider that all links will update the same outer container div, with the intention of changing its background image and displaying tooltips above the links. So, do you have any suggestions for achieving this efficiently?

Answer №1

update: included the requested animation effect. When dealing with CSS, it is often better to handle it through classes in scripts, especially when multiple elements require similar function manipulation. In this case, I utilized data attributes for colors instead of implementing complex logic, allowing the functionality to extend seamlessly to any new elements that may be added.

I must admit that I found your choice of markup somewhat unconventional, and I would have personally structured it differently. However, since that was not part of the original question, I did not delve into it further.

To streamline maintenance and organization, I transferred the `style` attribute from your `dogs` element to the CSS file. This consolidation ensures that all styles are contained within one location rather than scattering them across markup and CSS, facilitating future modifications.

Given your inclusion of the jQuery tag, here is a sample script:

$(function() {
  $('#d-list').on('mouseenter', 'a', function(event) {
    $('#dogs').css('backgroundColor', $(this).data('colorin'));
    $(this).parent().next('.tooltip').animate({
      opacity: 1
    });
  }).on('mouseleave', 'a', function(event) {
    $('#dogs').css('backgroundColor', $(this).data('colorout'));
    $(this).parent().next('.tooltip').animate({
      opacity: 0
    });
  });
});
#dogs {
  float: right;
  margin-top: 5%;
  background: black;
  width: 150px;
  height: 150px;
}

#d-list {
  color: white;
  direction: ltr;
  float: right;
  width: 60%;
  height: 60%;
}
/* Additional CSS properties */

.tooltip {
  color: black;
  background-color: gray;
  width: 120px;
  height: 30px;
  border-radius: 6px;
  text-align: center;
  padding-top: 5px;
  opacity: 0;
  position:relative;
  top:-4.5em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div id="animals">
  <div id="dogs"></div>
  <div id="d-list">
    <pre class="dog-header">dogs</pre>
    <pre><a href="#burger" id="d1" data-colorin="blue" data-colorout="black">white Husky</a></pre>
    <p id="tooltiptext1" class="tooltip">Tooltip text1</p>
    <pre><a href="#burger" id="d2" data-colorin="green" data-colorout="black">black Bull</a></pre>
    <p id="tooltiptext2" class="tooltip">Tooltip text2</p>
    <pre><a href="#burger" id="d3" data-colorin="red" data-colorout="black">brown Rex</a></pre>
    <p id="tooltiptext3" class="tooltip">Tooltip text3</p>
  </div>
</div>

Answer №2

Updated

This response was crafted prior to the question being revised to reflect the desired markup and style, as well as before all details were provided. The code has been adjusted accordingly to align with that structure.


In my opinion, a straightforward approach would be to create a configuration object outlining the variable elements, and then utilize common code for the remainder. Here's a suggested implementation:

const configurations = [
  ['d1', 'tooltiptext1', 'blue'], 
  ['d2', 'tooltiptext2', 'green'],
  ['d3', 'tooltiptext3', 'red'],
];

configurations.forEach(([id, tt, color]) => {
  const dogs = document.getElementById('dogs');
  const element = document.getElementById(id);
  const tipElement = document.getElementById(tt);
  element.onmouseover = (evt) => {
    dogs.style.background = color
    tipElement.style.visibility = "visible";
  }
  element.onmouseout = (evt) => {
    dogs.style.background = "black";
    tipElement.style.visibility = "hidden";
  }
})
#dogs{float:right;margin-top:5%;background:#000;width:150px;height:150px}#d-list{color:#fff;direction:ltr;float:right;width:60%;height:60%}#tooltiptext1,#tooltiptext2,#tooltiptext3{color:#000;background-color:gray;width:120px;height:30px;border-radius:6px;text-align:center;padding-top:5px;visibility:hidden}
<div id="animals"> <div id="dogs"></div><div id="d-list"> <pre style="font-size:22px; color:darkorange">dogs</pre><br/> <pre><a href="#burger" id="d1">white Husky</a></pre> <p id="tooltiptext1">Tooltip text1</p><pre><a href="#burger" id="d2">black Bull</a></pre> <p id="tooltiptext2">Tooltip text2</p><pre><a href="#burger" id="d3">brown Rex</a></pre> <p id="tooltiptext3">Tooltip text3</p></div></div>

You can easily extend this by adding new rows. If you wish to include more diverse properties, you can simply lengthen the rows. However, if the array grows large with many properties in each row, readability may suffer, and switching to an object format like

{id: 'demo', tt: 'dem', color: 'blue'}
might be preferable, along with adjusting the parameters in the forEach callback accordingly. With just three parameters, a concise array structure appears cleaner.


Previous code snippet based on hypothetical markup.

const configs = [
  ['demo', 'dem', 'blue'], 
  ['dd', 'dem1', 'green']
];

configs.forEach(([id1, id2, color]) => {
  const a = document.getElementById(id1)
  const b = document.getElementById(id2)
  a.onmouseover = (evt) => {
    a.style.background = color
    b.style.visibility = "visible";
  }
  a.onmouseout = (evt) => {
    a.style.background = "black";
    b.style.visibility = "hidden";
  }
})
div {width: 50px; height: 50px; float: left; margin: 10px; background: black; border: 1px solid #666; color: red; padding: 10px; text-align: center}
#dem , #dem1{visibility:hidden;}
<div id="demo">demo</div>
<div id="dem">dem</div>
<div id="dd">dd</div>
<div id="dem1">dem1</div>

Answer №3

my unique approach without any reliance on JavaScript:

div[data-info] {
  display: inline-block;
  margin:80px 20px 0 0;
  border:1px solid red;
  padding: 10px 20px;
  position: relative;
}
div[data-bg=blue]:hover {
  background-color: blue;
  color: red;
}
div[data-bg=green]:hover {
  background-color: green;
  color: red;
}
div[data-info]:hover:after {
  background: #333;
  background: rgba(0, 0, 0, .8);
  border-radius: 5px;
  bottom: 46px;
  color: #fff;
  content: attr(data-info);
  left: 20%;
  padding: 5px 15px;
  position: absolute;
  z-index: 98;
  min-width: 120px;
  max-width: 220px;
}
div[data-info]:hover:before {
  border: solid;
  border-color: #333 transparent;
  border-width: 6px 6px 0px 6px;
  bottom: 40px;
  content: "";
  left: 50%;
  position: absolute;
  z-index: 99;
}
<div data-info="Unique Tooltip for A Unique Tooltip for A" data-bg="blue">with Unique Tooltip CSS3 A</div>
<div data-info="Unique Tooltip for B" data-bg="green" >with Unique Tooltip CSS3 B</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

Creating a Login Form with Node.js and MongoDB

Currently, I am working on a node.js application that is connected to a remote mongoDB server. Inside the database are specific custom codes that have been created and shared with selected users. The main objective is to restrict access to the rest of the ...

I am experiencing an issue where the tooltip does not appear when I click the icon. What adjustments can be made to the code to ensure that the tooltip

I have created a feature to copy abbreviation definitions when the clipboard icon is clicked. A tooltip displaying 'Copied' should appear after clicking the icon, but for some reason, it's not visible. Here's the code: $(document).re ...

Fill in the Phone Number field with the area code corresponding to the chosen country

Hello, I need some assistance. I am currently working on creating a contact form using Bootstrap, and I would like to focus on this section of my code: <div class="form-group"> <label for="country">* Which country are you located in ?< ...

Troubleshooting: Angular 13 input radio not recognizing checked condition

Storing selectedKitchenId in localstorage, and checking if selectedKitchenId === kitchen.id to determine which radio button should be selected. Cannot figure out why the checked condition is not working as expected, even though when I use a strong tag to d ...

downsides of scrolling text functionality

Sure, it may seem evil. But what makes it so? Is it because all browsers support it? Which aspx asp.net controls are restricted in this tag? What are the reasons for avoiding this tag? ...

What could be preventing my bootstrap class from being applied as expected?

As a newcomer to HTML, CSS, and bootstrap, I am struggling with updating my stylesheet values in the preview. This is the button tag that I am working with: <button class="btn btn-primary btn-xl">Find out More</button> However, when ...

Removing error messages upon form reset initiated by an API request

Is there a way to clear error messages that appear beneath a text field when resetting form fields with values from an api call? In my Formik form, I have three fields that are loaded from an api database call along with a Reset button that reloads these ...

"Utilizing react.js allows for the direct access of DOM elements by the main parent component

Is there a way to trigger click events on deeply nested DOM elements within my component hierarchy without passing down callback functions to each individual component? I'm looking to execute these events from the top parent App component using EventT ...

The welcome message in Discord.js is displaying the user as a string of numbers instead of their real username

bot.on('guildMemberAdd', user =>{ const greetingMessage = new Discord.MessageEmbed() .setTitle(`Welcome to the server, ${user.user}! We're glad you've joined.`) const channel = user.guild.channels.cache.find(channel =&g ...

What are the steps to show that a bootstrap responsive table is able to scroll on an iOS device?

For instance, you can utilize Bootstrap 4 responsive table by following this example: <div class="table-responsive"> <table class="table"> ... </table> </div> On iOS, the table may not appear scrollable ...

Struggling to upload a file within a Jquery Dialog using AJAX. Any suggestions would be greatly appreciated

Hello, I am currently working with Zend Framework and encountering an issue with my index.phtml file. Here's a snippet of the code: <div id="edit-add-form" title="Insert"> <form id="main-form" name="main-form" action="" method="post" ...

I tried to import Bootstrap into my project, but it seems to be malfunctioning

Is there a way to display cards in a slider format? I want the carousel to show the next card on each click. I tried importing Bootstrap into my project but it doesn't seem to be functioning as expected. Here's the link to the tutorial I am usi ...

What could be causing my divs to overlap one another?

I can't seem to get these divs to stack properly, they keep overlapping. I've tried removing the float and checking every attribute in the code. I'm not sure where I'm going wrong. The structure of the rest of the page is similar, but ...

Retrieving JSON information from a PHP script with AJAX

I am currently experiencing an issue with my PHP script, 'getNews.php'. Despite working correctly in the terminal and returning the expected data, I am encountering difficulties when trying to retrieve this information through JavaScript. <?p ...

Adjusting the desktop view through media queries for mobile devices

As someone with no coding experience, I've been working on my portfolio using Cargo. Currently, I'm trying to adjust the mobile view of an article on my homepage through media queries. However, the code is unintentionally changing the layout on d ...

Is it possible to assign a specific value to a row within a table?

For each row (tr) generated from my database, I would like to assign a unique row value. Let's consider the table being created: while ($row = $database->fetch_array($result)) { $i=1-$i; $class = "row".$i; echo "<tr class='{$class} produ ...

Can we create a dynamic Context Menu?

I visited the following link: https://codepen.io/templarian/pen/VLKZLB After clicking on More Options, I need to display dynamically populated names like var Obj = [{name:"1st Item",taste:"sweet"},{name:"2nd item",taste:"spicy"}]; Instead of "Alert ...

What is the best way to change the content in a textarea field?

I am looking to create a functionality where a div is displayed below selected text inside a textarea. Below is the JavaScript code: function getSel() { var txtarea = document.getElementById("mytextarea"); var start = txtarea.selectionStart; ...

begin post loading resource three.js

In the process of developing a first-person shooter game with three.js, I encountered an issue regarding loading the gun model. Using the clone() method on a player mesh to create different players and then adding the gun model to the player mesh through t ...

identifying unused class names within an HTML codebase

Is there a way or tool available for detecting unused class names in HTML code? I have some HTML code with old Bootstrap, jQuery, and personalized CSS styles like below: <div class="clear fot-her likes tab-sub">content</div> But I n ...