Reputation: 857
I have written some jQuery code that does the job I am looking for it do but being fairly new to jQuery I was just curious to know if there was a simpler way to go about it. All its basically doing is hiding and showing divs on click events.
I have tried playing around with a few different ideas but this seems to be the only way I can get what I want to happen on the click events.
Markup below.
$('#facebook-icon').click(function() {
$('#facebook-callout, .hero-callout').fadeToggle();
$('#twitter-icon, #linked-icon').toggleClass('z-index-neg');
});
$('#twitter-icon').click(function() {
$('#twitter-callout, .hero-callout').fadeToggle();
$('#facebook-icon, #linked-icon').toggleClass('z-index-neg');
});
$('#linked-icon').click(function() {
$('#linked-callout, .hero-callout').fadeToggle();
$('#facebook-icon, #twitter-icon').toggleClass('z-index-neg');
});
$('.close').click(function() {
$(this).closest('div').fadeOut('slow');
$('.hero-callout').fadeIn('slow');
$('.social-icon').removeClass('z-index-neg');
});
a {
text-decoration: none;
}
.hero-wrapper {
position: relative;
}
.hero-callout {
position: relative;
height: 300px;
text-align: center;
margin-top: 150px;
}
.close {
font-size: 25px;
color: #151515;
position: absolute;
right: 0;
top: -30px;
cursor: pointer;
}
.social-callout {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
display: none;
}
.social-heading {
color: #151515;
font-size: 45px;
text-transform: none;
position: relative;
}
.z-index-neg {
z-index: -1;
opacity: 0 !important;
-webkit-transition: .5s;
transition: .5s;
}
.social-heading:after {
content: "";
background: #151515;
height: 3px;
width: 0;
display: block;
margin: 0 auto;
-webkit-transition: width .5s;
transition: width .5s;
}
.social-heading:hover:after {
width: 100%;
-webkit-transition: width .5s;
transition: width .5s;
}
#social-icons {
position: absolute;
bottom: 0;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
text-align: center;
}
.social-icon {
position: relative;
color: #151515;
font-size: 18px;
opacity: 1;
-webkit-transition: .5s;
transition: .5s;
cursor: pointer;
display: inline-block;
padding: 0 10px;
}
.icons:hover {
opacity: 0.5;
-webkit-transition: .3s;
transition: .3s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="hero-wrapper">
<div class="hero-callout">
<h2>
Hello World
</h2>
</div>
<div class="social-callout" id="facebook-callout">
<a href="#">
<h2 class="social-heading">Facebook.</h2>
</a>
<span class="close">X</span>
</div>
<div class="social-callout" id="twitter-callout">
<a href="#">
<h2 class="social-heading">Twitter.</h2>
</a>
<span class="close">X</span>
</div>
<div class="social-callout" id="linked-callout">
<a href="#">
<h2 class="social-heading">Linked In.</h2>
</a>
<span class="close">X</span>
</div>
<div id="social-icons">
<span class="social-icon" id="facebook-icon">Facebook</span>
<span class="social-icon" id="twitter-icon">Twitter</span>
<span class="social-icon" id="linked-icon">Linked In</span>
</div>
</div>
Thanks guys
Upvotes: 1
Views: 45
Reputation: 337743
The technique you're looking for is called Don't Repeat Yourself, or DRY. The goal is to genericise the logic so that it can be applied to any relevant element in the DOM, so long as it follows the expected structure.
In this case you can add a data
attribute to the .social-icon
elements which specifies the id
of the .social-callout
element relates to them and should be used when clicked.
Following this pattern means you can now have an infinite number of .social-icon
elements with associated .social-callouts
without ever needing to amend your JS code:
$('.social-icon').click(function() {
var $target = $($(this).data('target'));
$target.add('.hero-callout').fadeToggle();
$('.social-icon').not(this).toggleClass('z-index-neg');
})
$('.close').click(function() {
$(this).closest('div').fadeOut('slow');
$('.hero-callout').fadeIn('slow');
$('.social-icon').removeClass('z-index-neg');
});
a {
text-decoration: none;
}
.hero-wrapper {
position: relative;
}
.hero-callout {
position: relative;
height: 300px;
text-align: center;
margin-top: 150px;
}
.close {
font-size: 25px;
color: #151515;
position: absolute;
right: 0;
top: -30px;
cursor: pointer;
}
.social-callout {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
display: none;
}
.social-heading {
color: #151515;
font-size: 45px;
text-transform: none;
position: relative;
}
.z-index-neg {
z-index: -1;
opacity: 0 !important;
-webkit-transition: .5s;
transition: .5s;
}
.social-heading:after {
content: "";
background: #151515;
height: 3px;
width: 0;
display: block;
margin: 0 auto;
-webkit-transition: width .5s;
transition: width .5s;
}
.social-heading:hover:after {
width: 100%;
-webkit-transition: width .5s;
transition: width .5s;
}
#social-icons {
position: absolute;
bottom: 0;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
text-align: center;
}
.social-icon {
position: relative;
color: #151515;
font-size: 18px;
opacity: 1;
-webkit-transition: .5s;
transition: .5s;
cursor: pointer;
display: inline-block;
padding: 0 10px;
}
.icons:hover {
opacity: 0.5;
-webkit-transition: .3s;
transition: .3s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="hero-wrapper">
<div class="hero-callout">
<h2>
Hello World
</h2>
</div>
<div class="social-callout" id="facebook-callout">
<a href="#">
<h2 class="social-heading">Facebook.</h2>
</a>
<span class="close">X</span>
</div>
<div class="social-callout" id="twitter-callout">
<a href="#">
<h2 class="social-heading">Twitter.</h2>
</a>
<span class="close">X</span>
</div>
<div class="social-callout" id="linked-callout">
<a href="#">
<h2 class="social-heading">Linked In.</h2>
</a>
<span class="close">X</span>
</div>
<div id="social-icons">
<span class="social-icon" id="facebook-icon" data-target="#facebook-callout">Facebook</span>
<span class="social-icon" id="twitter-icon" data-target="#twitter-callout">Twitter</span>
<span class="social-icon" id="linked-icon" data-target="#linked-callout">Linked In</span>
</div>
</div>
Upvotes: 1
Reputation: 318372
You could combine the event handlers, and handle each case based on the clicked icons ID
var icons = $('.social-icon').on('click', function() {
var id = this.id.replace('icon', 'callout');
var el = $('#' + id);
$('.hero-callout').add(el).fadeToggle();
icons.not(this).toggleClass('z-index-neg')
});
$('.close').on('click', function() {
$(this).closest('div').fadeOut('slow');
$('.hero-callout').fadeIn('slow');
$('.social-icon').removeClass('z-index-neg');
});
a {
text-decoration: none;
}
.hero-wrapper {
position: relative;
}
.hero-callout {
position: relative;
height: 300px;
text-align: center;
margin-top: 150px;
}
.close {
font-size: 25px;
color: #151515;
position: absolute;
right: 0;
top: -30px;
cursor: pointer;
}
.social-callout {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
display: none;
}
.social-heading {
color: #151515;
font-size: 45px;
text-transform: none;
position: relative;
}
.z-index-neg {
z-index: -1;
opacity: 0 !important;
-webkit-transition: .5s;
transition: .5s;
}
.social-heading:after {
content: "";
background: #151515;
height: 3px;
width: 0;
display: block;
margin: 0 auto;
-webkit-transition: width .5s;
transition: width .5s;
}
.social-heading:hover:after {
width: 100%;
-webkit-transition: width .5s;
transition: width .5s;
}
#social-icons {
position: absolute;
bottom: 0;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
text-align: center;
}
.social-icon {
position: relative;
color: #151515;
font-size: 18px;
opacity: 1;
-webkit-transition: .5s;
transition: .5s;
cursor: pointer;
display: inline-block;
padding: 0 10px;
}
.icons:hover {
opacity: 0.5;
-webkit-transition: .3s;
transition: .3s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="hero-wrapper">
<div class="hero-callout">
<h2>
Hello World
</h2>
</div>
<div class="social-callout" id="facebook-callout">
<a href="#">
<h2 class="social-heading">Facebook.</h2>
</a>
<span class="close">X</span>
</div>
<div class="social-callout" id="twitter-callout">
<a href="#">
<h2 class="social-heading">Twitter.</h2>
</a>
<span class="close">X</span>
</div>
<div class="social-callout" id="linked-callout">
<a href="#">
<h2 class="social-heading">Linked In.</h2>
</a>
<span class="close">X</span>
</div>
<div id="social-icons">
<span class="social-icon" id="facebook-icon">Facebook</span>
<span class="social-icon" id="twitter-icon">Twitter</span>
<span class="social-icon" id="linked-icon">Linked In</span>
</div>
</div>
Upvotes: 1
Reputation: 1823
Yes it is possible. You can attach the same class to all of your elements with IDs ('#twitter-icon', '#facebook-icon'
, etc). and then bind an event to that class. Lets say you want to put class .icon
. Then simply do this:
$("body").on("click", ".icon", function(){
$(this).fadeToggle();
$(this).toggleClass('z-index-neg');
});
Where $(this)
targets the currently clicked element.
Hope this helps.
Upvotes: 1