jQuery - mouseOver change div - javascript

I have a menu that on each item's mouseover event an image loaded into a second div should change, and onMouseout it should replace with the original content.
At this point I am saving the original content into a var and creating a onMouseover & onMouseOut event each for each menu item.
Jquery:
$(document).ready(function(){
var heroSwap= $('#swapspace').html();
$('#menu1').mouseover(function(){
$('#swapspace').html('<img src="img/1.JPG"></img>');
});
$('#menu1').mouseout(function(){
$('#swapspace').html(heroSwap);
});
.... ..*ETC There are 7 More of these identical except for id*.. ....
});
Question:
Is there any way to create a generic function that can process a parameter from the menu tag?
Would it be easier.. instead of swapping the innerHTML img tags to create hidden divs that are displayed/hidden by the onMouseover/onMouseout events?
Full Sample:
Sample Site

You can create a generic function easily. You can add on the #menu1 tag an attribute with the url of your image and a class name like that :
<li class='menu' data-src='img/1.JPG'></li>
And then create the function like that :
$('.menu').mouseover(function(){
$('#swapspace').html('<img src="'+$(this).data('src')+'"></img>');
});
$('.menu').mouseout(function(){
$('#swapspace').html(heroSwap);
});
As for your second question, i would simply swap the src of you img instead of changing the entire HTML.
$('#swapspace').find('img').attr('src', $(this).data('src')); //on hover
$('#swapspace').find('img').attr('src', ''); //on out

It is better that you store the image src in the data-src attribute. So that you need not use multiple variables for each image.
Then you would not need to change the html, just changing the src attribute would do the trick.
Firstly replace your li to use class instead of id's
HTML
<ul class="nav nav-stacked nav-pills">
<li class="menu" data-src="img/1.JPG"> Web Development </li>
<li class="menu" data-src="img/2.JPG"> Software Development</li>
<li class="menu" data-src="img/3.JPG"> System Support</li>
<li class="menu" data-src="img/4.JPG"> SEO</li>
<li class="menu" data-src="img/5.JPG"> Social Media Marketing </li>
<li class="menu" data-src="img/6.JPG"> Project Management</li>
</ul>
Javascript
$(document).ready(function () {
var $swapImg = $('img', '#swapspace'),
defaultImage = 'default.jpg';
$('.menu').on({
mouseover: function () {
$swapImg.attr('src', $(this).data('src'));
},
mouseout: function () {
$swapImg.attr('src', defaultImage);
}
})
});
This way you would have only one event handler for all the li's , instead of a separate handler for each menu item.

It's actually better to use css for this. It's easier too.
The background can be anything in css, url, color etc.
<div id="menu1" class="menu-item"><div class="img"></div></div>
<div id="menu2" class="menu-item"><div class="img"></div></div>
cont'd.
Simple js hover uses mouseenter and mouseleave http://api.jquery.com/hover/
$(function() {
$(".menu-item").hover(function() {
$(this).addClass("hover");
}, function() {
$(this).removeClass("hover");
});
});
Then markup your images with css:
.menu-item {
margin: 0 0 5px 0;
}
.img {
display: block;
width: 200px;
height: 30px;
background: #ddd;
}
.menu-item.hover .img {
background: #000;
}
#menu2.hover .img {
background: url("http://placehold.it/200x30") no-repeat;
}
#menu4.hover .img {
background: url("http://placehold.it/200x30") no-repeat;
}
You can preload the images as well by using sprite sheets instead of javascript loading images in the background.
http://jsfiddle.net/E6xtq/1/

Related

jQuery on click, add class but also remove if the class is already present

I have a nav menu that needs to trigger with clicks rather than hovers. When the links are clicked, an .open class would be added to the parent li. If that parent already has the .open class, then it would get removed. It would also be removed if another link is clicked on. So far I can get the class added when clicked and removed when a sibling is clicked, but not removed when it's already .open.
I tried adding a hasClass conditional, but that didn't work either. Seemed like it reruns the function every time it's clicked and therefore ignores the hasClass conditional.
Can anyone provide help? I tried toggleClass, but that didn't work.
$('li a').on('click', function() {
$('li a').parent().removeClass('open');
$(this).parent().addClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 1
</li>
</ul>
</nav>
To do what you require you can use toggleClass() on the parent li when the element is clicked. To remove the class from all other li elements you can use removeClass() along with not() to exclude the current li. Try this:
$('li a').on('click', function() {
let $li = $(this).parent().toggleClass('open');
$('li').not($li).removeClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 1
</li>
</ul>
</nav>
You can use
jquery toggleClass() to toggle yellow highlight (.open css class) on click/unclicking the same link.
jquery siblings() to remove .open class on all the other li items.
Below is the link for the demo
https://jsfiddle.net/so1u8hq6/
$('li a').on('click', function() {
$(this).parent().siblings().removeClass('open');
$(this).parent().toggleClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 2
</li>
<li>
Item 3
</li>
</ul>
</nav>
Late to the party, but, after seeing the provided answers and some of the CSS you use I had to urge with my suggestions:
UX. Avoid styling LI tags in general, or at least set the desired display and move on. Style directly the a tag (with the necessary paddings etc.). You'll not only get less CSS to take care of, but also a larger touch interaction area. Makes no sense to style something yellow if it's not a UI part of something interactable. Also in JS, you don't need to take care about the LI wrappers any more - but only about the actual A Elements.
Don't use common selectors like $('li a') - those might target any LI→A elements in your app. Instead be more specific and use a Class like i.e: .tabs for the parent UL. Both in CSS and JS.
Try to use Event Delegation (in jQuey using the .on() method). Not only it will help you to catch the Event.delegateTarget parent UL where needed, but also the this (the clicked element), but mainly reference all the "group" of a elements enclosed in the common parent. That way you can have as many .tabs in a single page as you like. And yes, thanks to Event delegation you can even add dynamically LI Elements - and your JS will still work as expected.
Since you're using <a href="#"> Anchor elements, instead of (more properly) <button type="button>" Elements, you need to also use Event.preventDefault() in order to prevent the browser its default behavior and that's to follow anchors (scroll the page, navigate, etc...)
Use the selector "a.open" when you want to target and remove the "open" class. By just using "a" (or in other answers on this page - "li") you're uselessly touching elements trying to remove a class that's not there in the first place.
Finally, here's the CSS retouch and the proper jQuery needed for your task:
$(".tabs").on("click", "a", function(ev) {
ev.preventDefault();
$("a.open", ev.delegateTarget).not(this).removeClass("open");
$(this).toggleClass("open");
});
.tabs {
display: flex;
list-style: none;
padding: 0;
}
/* Style your Anchors, not the dummy LI wrappers */
.tabs a { padding: 10px; }
.tabs a.open { background-color: yellow; }
<ul class="tabs">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
To explain the only complicated line:
$(
"a.open", // Target just the ones (if any) of class "open"
ev.delegateTarget // inside the common ".tabs" ancestor
)
.not(this) // ... not the clicked element (since later we'll use .toggleClass on it)
.removeClass("open"); // ... remove that class "open"
the rest is pretty self explanatory.
Further read:
jQuery Event Delegation
jQuery event.delegateTarget
Event.preventDefault
So you only want the yellow background to appear as a signifier of user interaction rather than for the background color to be displayed? Have you tried using the mousedown/mouseup functions instead of .on('click', function(){...}?
I was able to simulate the click event where the color showcases via this method:
$('li a').mousedown(function() {
$('li a').parent().removeClass('open');
$(this).parent().addClass('open');
});
$('li a').mouseup(function() {
$('li a').parent().removeClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 1
</li>
</ul>
</nav>

jQuery change z-index with data-*

I have divs that all occupy the same space, and I want to set up jQuery that has one div come on top of the other as different tabs are clicked. I assume this has to be done by changing the z-index attribute using a data-* attribute that connects the tab to the div.
/*The tabs to be clicked*/
<ul class="tabs">
<li class="tab" data-tabcontainer-id="websites" style="background-color:#1aa3ff;">Websites</li>
<li class="tab" data-tabcontainer-id="sitemaps">Sitemaps</li>
<li class="tab" data-tabcontainer-id="pages">Pages</li>
</ul>
/*The divs that need to come on top of each other*/
<div id="websites" class="tabcontainer">Websites</div>
<div id="sitemaps" class="tabcontainer">Sitemaps</div>
<div id="pages" class="tabcontainer">Pages</div>
DEMO
http://plnkr.co/edit/aNomjINfbYYrRUhMj63A?p=preview
This is how you can change the z-index property using the data attribute.
JS:
jQuery(document).ready(function(){
$('.tab').click(function(){
var target = $(this).data('tabcontainer-id');
$('.tabcontainer').css('z-index', '0'); //resets z-index to 0 for all other
$('.tabcontainer#'+target).css('z-index', '1'); //sets z-index for current target to 1
})
});
I wrote the answer just to meet what you were asking. But reading your question I think you should have a look at the tabs feature by jQuery UI. May be it will help.
https://jqueryui.com/tabs/
madalin ivascu's answer is quite right according to me.
May be bit off the topic, but you can use Jquery UI for the tabs. Easy to implement and work with.
You don't need to worry about managing the z-index in this case. But it might not be appropriate for your case.
<div id="tabs">
<ul >
<li>Websites</li>
<li>Sitemaps</li>
<li>Pages</li>
</ul>
<div id="websites" class="tabcontainer">Websites</div>
<div id="sitemaps" class="tabcontainer">Sitemaps</div>
<div id="pages" class="tabcontainer">Pages</div>
</div>
Fiddle : https://jsfiddle.net/uxwyj4d4/
better go with toggle display:block/none
$('.tabcontainer').not('.tabcontainer:first').hide();
$('.tab').click(function(){
//toggle active class on tabs
$('.tab').removeClass('active');
$(this).addClass('active');
//show corresponding tab container
var id = '#'+$(this).attr('data-tabcontainer-id');
$('.tabcontainer').hide();//here you can go with another class like above that will toggle between block and none
$(id).show();
});
demo:http://plnkr.co/edit/gPIwv80vUIUTQ46Bderj?p=preview
Example for showing tabs using vanilla js, no jQuery is required.
This example use only display instead of z-index.
// get tabs
var targets = {
websites: document.getElementById('websites'),
sitemaps: document.getElementById('sitemaps'),
pages: document.getElementById('pages')
},
show = function(target) {
hideAll();
targets[target.dataset.tabcontainerId].style.display = '';
},
hideAll = function() {
// hide all tabs
Object.keys(targets).forEach(function(key) {
targets[key].style.display = 'none';
});
};
// when click on link show tab
document.getElementById('w').addEventListener('click', function(event) {
show(event.target);
});
document.getElementById('s').addEventListener('click', function(event) {
show(event.target);
});
document.getElementById('p').addEventListener('click', function(event) {
show(event.target);
});
#websites,
#sitemaps,
#pages {
position: absolute;
top: 150px;
width: 100px;
height: 100px;
}
#websites {
background-color: red;
}
#sitemaps {
background-color: blue;
}
#pages {
background-color: green;
}
<ul class="tabs">
<li id="w" class="tab" data-tabcontainer-id="websites" style="background-color:#1aa3ff;">Websites</li>
<li id="s" class="tab" data-tabcontainer-id="sitemaps">Sitemaps</li>
<li id="p" class="tab" data-tabcontainer-id="pages">Pages</li>
</ul>
<div id="websites" class="tabcontainer">Websites</div>
<div id="sitemaps" class="tabcontainer">Sitemaps</div>
<div id="pages" class="tabcontainer">Pages</div>

addClass and removeClass is not working correctly

Sorry if this is an extremely simple question, but for some reason, I cant get this working.
What I'm trying to do is to add the activeButton class to each list item you click and remove the activeButton class to the list-item that had the activeButton class before the list-item was clicked.
Here is a code snippet of my problem
$(document).ready(function () {
$('.buttons').click(function () {
$('.activeButton').removeClass('.activeButton');
$(this).addClass('.activeButton');
});
});
.buttons {
/*This is for decorative and visual purposes.
So you can ignore the CSS for now.*/
display: inline-block;
margin: 10px;
}
.activeButton {
border-bottom: 1px solid black;/*I use border-bottom to provide underlines for my text. This allows the underline to be transitioned or animated*/
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="buttons activeButton">Link1</li>
<li class="buttons">Link2</li>
<li class="buttons">Link3</li>
<li class="buttons">Link4</li>
</ul>
For the sake of clarification, I will explain my goal and the current problem.
GOAL: Once a list item is clicked, the class .activeButton will be added to the list item that was clicked and the JS will remove .activeButton from the list item that originally had the activeButton class.
PROBLEM: The attempted solution that I have coded does not work.
Like this you mean?
$(document).ready(function () {
$('.buttons').click(function () {
$('.buttons').removeClass('activeButton'); // <-- remove from all .buttons class
$(this).addClass('activeButton'); // <-- add to clicked link only
});
});
.buttons {
/*This is for decorative and visual purposes.
So you can ignore the CSS for now.*/
display: inline-block;
margin: 10px;
}
.activeButton {
border-bottom: 1px solid black;/*I use border-bottom to provide underlines for my text. This allows the underline to be transitioned or animated*/
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="buttons activeButton">Link1</li>
<li class="buttons">Link2</li>
<li class="buttons">Link3</li>
<li class="buttons">Link4</li>
</ul>
You don't need the class selector in the strings you pass to addClass() and removeClass().
Update as follows:
$(function () {
$('.postalProvider').click(function () {
$('.activeButton').removeClass('activeButton');
$(this).addClass('activeButton');
});
});
Update :
$(document).ready(function () {
var $buttons = $('.buttons');
$buttons.click(function () {
$buttons.removeClass('.activeButton');
$(this).addClass('.activeButton');
});
});
I think this is what you were after.

Simplify this javascript for Show one, Hide Rest

I am using a script for a gallery in which clicking on an element in the navigation shows only one div, but hides the others.
Currently my script is very specific, as I need to add a new function for every possible instance. See below... You can imagine this grows out of control easily the more images are added.
Can someone help me make this code more generic and elegant? I'm not very experienced with Javascript/JQuery but this is getting a bit embarrassing lol
So in case it's not clear from the code: the #li1, #li2, #li3 etc are the navigational thumbnails which are always visible. The #img1, #img2, #img3 etc. are the variable displayed divs. When one is visible, the rest should be hidden.
Additional questions:
for every #img1 displayed, I'd like to also show a title in a separate div, let's say #title1, #title2, etc. How do I do this? So eg clicking #li1 would show #img1 and #title1 but hide all other #img.. and #title..
all #'s contain images. I've noticed that when one of the images is broken, the whole script stops working properly (all #img.. divs show at once). Why is that?
this script doesn't actually hide all the images until everything is loaded, which you don't notice when running the HTML locally, but you do when you're waiting for the images to download. I'm suspecting because the $("#li1").load(function() refers to a div that is further down in the document. How can I counter this?
I hope I'm not asking too much, I've tried to understand this myself but I can't figure it out.
$("#li1").load(function() {
$("#img2, #img3, #img4, #img5, #img6, #img7, #img8, #img9, #img10, #img0, #intro").hide();
$("#img1").show();
});
$("#li1").on('click', function() {
$("#img2, #img3, #img4, #img5, #img6, #img7, #img8, #img9, #img10, #img0").hide();
$("#img1").show();
});
$("#li2").on('click', function() {
$("#img1, #img3, #img4, #img5, #img6, #img7, #img8, #img9, #img10, #img0").hide();
$("#img2").show();
});
$("#li3").on('click', function() {
$("#img2, #img1, #img4, #img5, #img6, #img7, #img8, #img9, #img10, #img0").hide();
$("#img3").show();
});
etc.
I would probably try something like this:
Thumbnails like:
<li class="thumbnail" data-imageId="0">
...thumbnail...
</li>
<li class="thumbnail" data-imageId="1">
...thumbnail...
</li>
<li class="thumbnail" data-imageId="2">
...thumbnail...
</li>
Images like:
<div class="image" data-imageId="0">
...image...
</div>
<div class="image" data-imageId="1" style="display: none;">
...image...
</div>
<div class="image" data-imageId="2" style="display: none;">
...image...
</div>
<!-- The style attribute in these element hides the element by default,
while still allowing jQuery to show them using show(). -->
And then the JS:
$(".thumbnail").click(function() {
// Hides all images.
$(".image").hide();
// Shows appropriate one.
var imageId = $(this).data("imageId"); // Fetches the value of the data-imageId attribute.
$(".image[data-imageId="+imageId+"]").show();
});
I see that your li's have ids of 'li1', 'li2', etc. Assign them all a specific class, like 'liLinks'.
Then, add an event handler for that class like this:
$(".liLinks").click(function(){
var ImageToShow = $(this).prop("id").replace("li", ""); // This gets the number of the li
for (i=0; i<= 10; i++){ //or however many images you have
if (i != ImageToShow)
$("#img" + i).hide();
else
$("#img" + i).show();
}
});
Oh, and you can show and hide any other elements with the same method used above. Just make sure their naming convention is the same, and you should be all set!
So, I have two solutions for you:
First option: Edit the HTML code to fix this logic:
<li class="nav" data-image="0">0</li>
<li class="nav" data-image="1">2</li>
<li class="nav" data-image="2">3</li>
...
...and so on.
Now the JavaScript code will be pretty short and easy, here it is:
function showOne(e) {
var max = 5, // assuming that there are 5 images, from #img0 to #img4
toShow = e.target.dataset.image;
for (var i=0; i < max; i++) {
if (i == toShow) $('#img'+i).hide();
else $('#img'+i).show();
}
}
$('.nav').bind('click', showOne);
If your logic isn't this one then i suggest you to edit the HTML to fix this logic, which is the easiest way to do what you want.
Second option: I am assuming that you use a logic like this:
#li0 shows #img0
#li1 shows #img1
#li2 shows #img2
...
#liN shows the Nth img of the array
Here's the code then:
function showOne() {
var max = 4, // assuming that there are 5 images, from #img0 to #img4
toShow = this.id.substr(2);
$('#img'+toShow).show();
for (var i=0; i < max; i++) {
if (i != toShow) $('#img'+i).hide();
}
}
$('#li0, #li1, #li2, #li3, #li4').bind('click', showOne);
In this snippet I only used 5 images, but you can add more images changing the max value and adding the relative li elements in the $('#li0, #li1, ...) selector.
Just hide all of them with CSS, then override the one you care about to show.
<!doctype html>
<html>
<head>
<style type="text/css">
#showbox img { display: none; width: 300px; }
#showbox.show1 img#img1,
#showbox.show2 img#img2,
#showbox.show3 img#img3,
#showbox.show4 img#img4 { display: block; }
</style>
</head>
<body>
<div id="showbox" class="3">
<img id="img1" src="http://upload.wikimedia.org/wikipedia/commons/6/6f/ChessSet.jpg">
<img id="img2" src="http://upload.wikimedia.org/wikipedia/commons/c/c3/Chess_board_opening_staunton.jpg">
<img id="img3" src="http://www.umbc.edu/studentlife/orgs/chess/images/News%20and%20Events/chess_sets.jpg">
<img id="img4" src="http://upload.wikimedia.org/wikipedia/commons/thumb/9/97/Russisches_festungsschach.PNG/350px-Russisches_festungsschach.PNG">
</div>
<input onchange="document.getElementById('showbox').className = 'show' + this.value;">
</body>
</html>
Your images is not hidden while the images is loading because you didn't use
$(function () {
$("imgs").hide ();
});
This function is excuted when the DOM (HTML) is loaded not the images.
The code will be "HTML":
link1
link2
link3
...
jQuery:
$(function () {
$(".img").hide ();
$(".nav").click (function (e) {
$(".img").show ();
});
});
As you might expect you need to change this code to be more progressive but you now get the idea of making them hidden when the page finish liading not when the images finish downloading. And good luck ;) .
var $img = $('#images img'); /* Cache your selector */
$('#nav li').click(function(){
$img.fadeOut().eq( $(this).index() ).stop().fadeIn();
});
#images{ position:relative; }
#images img{ position:absolute; left:0; }
#images img + img {display:none; } /* hide all but first */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id=nav>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<div id=images>
<img src="//placehold.it/50x50/cf5" alt="">
<img src="//placehold.it/50x50/f0f" alt="">
<img src="//placehold.it/50x50/444" alt="">
</div>
Following is an approach:
Add special classes to identify images.
Use classes to show/hide image like: .showing{display:block;}
Use data attribute to store title like: data-title="title"
Add class to identify li and mark selected li with another class like active
$(function() {
$("li.switch").click(function() {
var liActive = $("li.active");
var imgActive = liActive.data("image");
$(imgActive).removeClass("showing").addClass("hidden");
$(liActive).removeClass("active");
//currently clicked li
var $this = $(this);
$this.addClass("active");
var d = $this.data("image");
$(d).removeClass("hidden").addClass("showing");
$("#imgTitle").text($(d).data("title"));
});
});
.gallery {
width: 250px;
height: 250px;
padding: 10px;
}
img {
height: 200px;
width: 200px;
margin: auto auto;
}
.hidden {
display: none;
}
.showing {
display: inline-block;
}
ul {
list-style: none none outside;
display: inline;
}
li {
list-style: none none outside;
display: inline-block;
padding: 3px 6px;
border: 1px solid grey;
color: #0f0;
cursor: pointer;
}
li.active {
border: 2px solid red;
background-color: #c0c0c0;
color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="gallery">
<img src='https://c2.staticflickr.com/4/3862/15320672416_65b28179b4_c.jpg' class='gimage showing' id='img1' data-title="This is image 1" />
<img src='https://c2.staticflickr.com/4/3893/15156335390_16e16aa1c9_c.jpg' class='gimage hidden' id='img2' data-title="This is image 2" />
<img src='https://c1.staticflickr.com/3/2942/15341799225_09d0f05098_c.jpg' class='gimage hidden' id='img3' data-title="This is image 3" />
<img src='https://c2.staticflickr.com/4/3907/15339877992_695dd1daae_c.jpg' class='gimage hidden' id='img4' data-title="This is image 4" />
<img src='https://farm3.staticflickr.com/2942/15333547162_325fefd6d1.jpg' class='gimage hidden' id='img5' data-title="This is image 5" />
</div>
<div id="imgTitle"></div>
<ul>
<li class="switch active" id="li1" data-image="#img1">1</li>
<li class="switch" id="li1" data-image="#img2">2</li>
<li class="switch" id="li1" data-image="#img3">3</li>
<li class="switch" id="li1" data-image="#img4">4</li>
<li class="switch" id="li1" data-image="#img5">5</li>
</ul>
Try it in this fiddle
Fix from Ricardo van den Broek's code, because
var imageId = $(this).data("imageId");
is seem doesn't work. It's returns "Undefined". So we need to change it to
var imageId = $(this).attr("data-imageId");
Here is all the code,
HTML (Thumbnail section)
<ul>
<li class="thumbnail" data-imageId="0">
Thumbnail 0
</li>
<li class="thumbnail" data-imageId="1">
Thumbnail 1
</li>
<li class="thumbnail" data-imageId="2">
Thumbnail 2
</li>
</ul>
HTML (Image section)
<div class="image" data-imageId="0">
Image 0
</div>
<div class="image" data-imageId="1" style="display: none;">
Image 1
</div>
<div class="image" data-imageId="2" style="display: none;">
Image 2
</div>
JavaScript (jQuery)
$(".thumbnail").click(function() {
$(".image").hide();
// Shows the appropriate one.
var imageId = $(this).attr("data-imageId");
$(".image[data-imageId="+imageId+"]").show();
});

Change Active Menu Item on Page Scroll?

I want to activate the menu item when I get to it's corresponding section. I got inspired by this previous SO question: Change Active Menu Item on Page Scroll? .
but the difference is that in my menu I have a little image over each menu item, that shows only if I hover the menu item, and hides when don't.
HTML
<nav>
<ul id="pics">
<li id="text-what"><img src="images/what.png" id="pic-what" class="vishid"><p>item1</p></li>
<li id="text-training"><img src="images/training.png" id="pic-training" class="vishid"><p>item2</p></li>
<li id="text-testi"><img src="images/trait.png" id="pic-testi" class="vishid"><p>item3</p></li>
<li id="text-contact"><img src="images/contact.gif" id="pic-contact" class="vishid"><p>item4</p></li>
</ul>
</nav>
CSS
.vishid{
visibility: hidden;
}
.visvis{
visibility:visible;
}
JAVASCRIPT (to show and hide images when hovering items)
$(document).ready(function(){
$("#text-what").hover(function(){
$("#pic-what").addClass('visvis');
},function(){
$("#pic-what").removeClass('visvis');
});
$("#text-training").hover(function(){
$("#pic-training").addClass('visvis');
},function(){
$("#pic-training").removeClass('visvis');
});
$("#text-testi").hover(function(){
$("#pic-testi").addClass('visvis');
},function(){
$("#pic-testi").removeClass('visvis');
});
$("#text-contact").hover(function(){
$("#pic-contact").addClass('visvis');
},function(){
$("#pic-contact").removeClass('visvis');
});
});
I want to show the image when I am at it's corresponding section. How can I do that with javascript?
There is a lot going on here. Your HTML should technically be corrected. href's should not encapsulte LI's. Instead your href should be set to block - width and height 100% - within the LI. Let's also move the class of .vishid to the parent LI. That way if you want it to effect anything else - besides just the images - in the future, it would be easy to add. So that would look like:
<nav>
<ul id="pics">
<li id="text-what" class="vishid"><img src="images/what.png" id="pic-what"><p>item1</p></li>
<li id="text-training" class="vishid"><img src="images/training.png" id="pic-training"><p>item2</p></li>
<li id="text-testi" class="vishid"><img src="images/trait.png" id="pic-testi"><p>item3</p></li>
<li id="text-contact" class="vishid"><img src="images/contact.gif" id="pic-contact"><p>item4</p></li><
</ul>
</nav>
Then you need to adjust your CSS to correct for the "non-block" level href.
#pics li a {
display: block;
width: 100%;
height: 100%;
}
.vishid img {
visibility: hidden;
}
.visvis img {
visibility: visible;
}
Finally, I am going to assume that you are using "articles" in your HTML for the sections. Doesn't have to be, but that is what my example will assume.
var clickScroll = false,
triggerHighlight = 80; // distance from the top to trigger action
$(window).scroll(function () {
var y = $(this).scrollTop(),
yCatch = y + triggerHighlight;
// Let's wrap in a variable check. Set this to tru is clicking on navigation
// false if simply scrolling
if (!clickScroll) {
$('article').each(function (i) {
var whichArticle = $(this).attr('id');
if ($(this).position().top < yCatch) {
var currentArticle = "#" + whichArticle;
adjustSubNav(currentArticle);
}
});
}
});
function adjustSubNav(l) {
$('#pics a').each(function (i) {
if ($(this).attr('href') == l) { // Add active class to the corresponding menu item
$(this).parent('li').removeClass('vishid').addClass('visvis');
} else {
$(this).parent('li').removeClass('visvis').addClass('vishid');
}
});
}

Categories

Resources