Reputation: 181
I have this code set up that allows me to hover on links in different div and change images in another div. The HTML code in one section of the page is like this:
<div class="left-column">
<ul class="nav-lists">
<li class="menu-1 ">
<a href="#" title="The Studio">Home</a>
</li>
<li class="menu-2 ">
<a href="#" title="Services">About</a>
</li>
<li class="menu-3 ">
<a href="#" title="Portfolio">Services</a>
</li>
<li class="menu-4 ">
<a href="#" title="Contact">Contact</a>
</li>
</ul>
</div>
The on another section of the page, we have the images
<div class="right-column menu-img">
<img class="fade menu-img1 " src="images/5.jpg" alt="" />
<img class="fade menu-img2 " src="images/4.jpg" alt="" />
<img class="fade menu-img3 " src="images/6.jpg" alt="" />
<img class="fade menu-img4 " src="images/7.jpg" alt="" />
</div>
I have this CSS that hides the images when the page loads
.menu-img {
position: relative;
width: 100%;
height: 500px
}
.menu-img img {
opacity: 0;
max-width: none;
position: absolute;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
Finally, I had this jquery added to show the images when the list is hovered. It works well but I have a feeling that the jquery code is not optimally written (I am still a learner). Especially, if we want to add more links and images, the codes will get longer. Can anyone help me optimize this code in a way that it would not have negative impact on the page loading?
jQuery(function($) {
$('.menu-1').hover(function () {
$(".menu-img1").css("opacity", "1");
},
function () {
$(".menu-img1").css("opacity", "0");
});
$('.menu-2').hover(function () {
$(".menu-img2").css("opacity", "1");
},
function () {
$(".menu-img2").css("opacity", "0");
});
$('.menu-3').hover(function () {
$(".menu-img3").css("opacity", "1");
},
function () {
$(".menu-img3").css("opacity", "0");
});
$('.menu-4').hover(function () {
$(".menu-img4").css("opacity", "1");
},
function () {
$(".menu-img4").css("opacity", "0");
});
})
Upvotes: 1
Views: 1335
Reputation: 371
Since I saw your response to being open to vanilla JavaScript as:
Sure! I am opened to that too as long as I achieve the same result
I'll go with the vanilla JS way!
Here's a codepen demoing it https://codepen.io/nateonguitar/pen/bGNWdmM
It looks like you've created a class for each image and then you're controlling each one individually. The beauty of classes is that they can make the same behavior happen to multiple elements without re-writing anything, so I feel like classes are being a little misused here.
Try this out
(I'm using placeholder images so they show up on my own machine)
(notice the lack of classes on the <li>
elements)
I attached a data attribute onto each element of the <ul>
so we can use it like a parallel array to the image list:
<div class="left-column">
<ul class="nav-list">
<li data-index="0">
<a href="#" title="The Studio">Home</a>
</li>
<li data-index="1">
<a href="#" title="Services">About</a>
</li>
<li data-index="2">
<a href="#" title="Portfolio">Services</a>
</li>
<li data-index="3">
<a href="#" title="Contact">Contact</a>
</li>
</ul>
</div>
And we don't need the corresponding values in the other list.
<div class="right-column menu-img">
<img class="fade" src="https://via.placeholder.com/150/0000FF/808080" alt="" />
<img class="fade" src="https://via.placeholder.com/150/00FFFF/808080" alt="" />
<img class="fade" src="https://via.placeholder.com/150/FF00FF/808080" alt="" />
<img class="fade" src="https://via.placeholder.com/150/00FF00/808080" alt="" />
</div>
And here's the JS adding event listeners for mouse enter and leave
document.addEventListener("DOMContentLoaded", function(event) {
let navList = document.querySelector(".nav-list").children;
let imgList = document.querySelector(".menu-img").children;
for (let li of navList) {
li.addEventListener('mouseenter', () => {
let img = imgList[li.dataset.index];
img.style.opacity = 1;
});
li.addEventListener('mouseleave', () => {
let img = imgList[li.dataset.index];
img.style.opacity = 0;
});
}
});
We also could have achieved the same effect without the data-index
attributes if our for loop was the traditional for, [you know, for (let i=0, i<navList.length; i++) . . .
]
Upvotes: 1
Reputation: 3010
I this is what u r expecting
Assign unique id to the li elements and same class name to all li elements.
$('.menu').hover(function () {
$(".menu-"+this.id).css("opacity", "1");
},
The above function is used to get the id of the hovered element. And then it is concatenated with the class name (.menu).
Example: If the first li element is hovered, then the id of that element can be obtained i.e. this.id gives img1 and then it is concatenated with the class name .menu ,it gives .menu-img1. finally .menu-img opacity will be set 1.
jQuery(function($) {
$('.menu').hover(function () {
$(".menu-"+this.id).css("opacity", "1");
},
function () {
$(".menu-"+this.id).css("opacity", "0");
});
})
.menu-img {
position: relative;
width: 100%;
height: 500px
}
.menu-img img {
opacity: 0;
max-width: none;
position: absolute;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
<script
src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous"></script>
<div class="left-column">
<ul class="nav-lists">
<li class="menu" id="img1">
<a href="#" title="The Studio">Home</a>
</li>
<li class="menu" id="img2">
<a href="#" title="Services">About</a>
</li>
<li class="menu" id="img3">
<a href="#" title="Portfolio">Services</a>
</li>
<li class="menu" id="img4" >
<a href="#" title="Contact">Contact</a>
</li>
</ul>
</div>
<div class="right-column menu-img">
<img class="fade menu-img1 " src="https://dummyimage.com/600x400/000/fff&text=1" alt="" />
<img class="fade menu-img2 " src="https://dummyimage.com/600x400/000/fff&text=2" alt="" />
<img class="fade menu-img3 " src="https://dummyimage.com/600x400/000/fff&text=3" alt="" />
<img class="fade menu-img4 " src="https://dummyimage.com/600x400/000/fff&text=4" alt="" />
</div>
Upvotes: 1
Reputation: 142
I’d add add a data attribute to the image that matches the class value on the <li>
. For example, data-menu-class=“menu-1”
. Then, use a single hover function on the menu list items. Use var menuClass = $(this).attr(“class”)
to get the class of the hovered element and then update the opacity of the corresponding image using the matching data attribute from the image - $(‘img[data-menu-class=“‘+menuClass+’”]’
. The goal of all this being to not have to repeat yourself and have the hover event functionality apply to all the menu items.
Excuse the absence of the fully typed function. Currently on my phone without a real keyboard.
Upvotes: 0