Condense Repetitive jQuery statements - javascript

I am pretty green when it comes to javascript, and programming in general. Can someone give me some direction on how to shorten the below code block. I built the front end with consistent naming so I know it can be done, but I'm unsure how.
$('#fd_button').on('click', function(){
$('#fd_content').fadeToggle("slow", "linear");
});
$('#fd_content #close_btn').on('click', function(){
$('#fd_content').fadeToggle("slow", "linear");
});
$('#fl_button').on('click', function(){
$('#fl_content').fadeToggle("slow", "linear");
});
$('#fl_content #close_btn').on('click', function(){
$('#fl_content').fadeToggle("slow", "linear");
});
$('#el_button').on('click', function(){
$('#el_content').fadeToggle("slow", "linear");
});
$('#el_content #close_btn').on('click', function(){
$('#el_content').fadeToggle("slow", "linear");
});
$('#fm_button').on('click', function(){
$('#fm_content').fadeToggle("slow", "linear");
});
$('#fm_content #close_btn').on('click', function(){
$('#fm_content').fadeToggle("slow", "linear");
});
$('#gf_button').on('click', function(){
$('#gf_content').fadeToggle("slow", "linear");
});
$('#gf_content #close_btn').on('click', function(){
$('#gf_content').fadeToggle("slow", "linear");
});
$('#fg_button').on('click', function(){
$('#fg_content').fadeToggle("slow", "linear");
});
$('#fg_content #close_btn').on('click', function(){
$('#fg_content').fadeToggle("slow", "linear");
});
$('#en_button').on('click', function(){
$('#en_content').fadeToggle("slow", "linear");
});
$('#en_content #close_btn').on('click', function(){
$('#en_content').fadeToggle("slow", "linear");
});
$('#fmn_button').on('click', function(){
$('#fmn_content').fadeToggle("slow", "linear");
});
$('#fmn_content #close_btn').on('click', function(){
$('#fmn_content').fadeToggle("slow", "linear");
});
$('#gfn_button').on('click', function(){
$('#gfn_content').fadeToggle("slow", "linear");
});
$('#gfn_content #close_btn').on('click', function(){
$('#gfn_content').fadeToggle("slow", "linear");
});

Add a data-toggle attribute to all elements that should toggle some other element when clicked. This attribute's value should be a reference to the element you want to fadeToggle():
Markup:
<div data-toggle="#fd_content">Some content</div>
<div data-toggle="#fm_content">Some more content</div>
<div data-toggle="#gfn_content">Even more content</div>
JS:
$("[data-toggle]").on("click", function() {
var elementToToggle = $(this).data("toggle");
$(elementToToggle).fadeToggle("slow", "linear");
});
See DEMO.

The answer is going to depend on your markup - if the markup for all these elements is similar, you might only need a single event handler. But taking the case where all of these things have radically different markup, you could do:
var selectors = [
['#fd_button', '#fd_content'],
['#fd_content #close_btn', '#fd_content'],
// ... etc
];
selectors.forEach(function(trigger, target) {
$(trigger).on('click', function(){
$(target).fadeToggle("slow", "linear");
});
});

Related

Following jQuery isn't working. Take a look

Code:
<div>
Back
<div class="outer"></div>
Next
</div>
<div>
Back
<div class="outer"></div>
Next
</div>
jQuery code:
$('.next').click(function() {
$('.next').prev().animate({
scrollLeft: '+=150'
}, 200);
});
$('.back').click(function() {
$('.back').next().animate({
scrollLeft: '-=150'
}, 200);
});
Error:
Basically I have more codes with the same classes as above and I want to scroll the code which is clicked. But the code written above scroll all the ".outer" on the page. Each set of the code is in different div. The inside material of the "outer" isn't provided which is scroll able.
You need to execute the code using current element context i.e. this. Also animate the siblings of parent element so traverse up using $(this).closest('div') then use .prev() or next()
$(function() {
$('.next').click(function() {
$(this).closest('div').prev().animate({
scrollLeft: '+=150'
}, 200);
});
$('.back').click(function() {
$(this).closest('div').next().animate({
scrollLeft: '-=150'
}, 200);
});
});
Simple Use $(this) for get current Object
$('.next').click(function () {
$(this).prev().animate({ scrollLeft: '+=150'}, 200);
});
$('.back').click(function () {
$(this).next().animate({ scrollLeft: '-=150'}, 200);
});
Don't forget to wrap your code in a document ready function.
<script>
$(document).ready(function() {
$('.next').click(function () {
$(this).prev().animate({ scrollLeft: '+=150'}, 200);
});
$('.back').click(function () {
$(this).next().animate({ scrollLeft: '-=150'}, 200);
});
});
</script>
Also using the on method is better for event binding, e.g.
<script>
$(document).ready(function() {
$('.next').on('click', function () {
$(this).prev().animate({ scrollLeft: '+=150'}, 200);
});
$('.back').on('click', function () {
$(this).next().animate({ scrollLeft: '-=150'}, 200);
});
});
</script>
Edit:
As #GuruprasadRao pointed out, I'm assuming you are already but make sure you're using a HTML5 doctype otherwise you'll need to add type="text/javascript" to your script tag.

style switcher when clicked jumps to the top of the page

I have style switcher, used php, and jquery to implement it. Now when i click on its button to open, the page jumps to the top of the page. and also when i click the same button to close the style box. the same happens it jumps to the top of the page. how to change the code to make it open without jumping.
jQuery.fn.styleSwitcher = function(){
$(this).click(function(){
// We're passing this element object through to the
// loadStyleSheet function.
loadStyleSheet(this);
// And then we're returning false.
return false;
});
function loadStyleSheet(obj) {
$.get( obj.href+'&js',function(data){
// Select link element in HEAD of document (#stylesheet) and change href attribute:
$('#stylesheet').attr('href','css/' + data + '.css');
// Check if new CSS StyleSheet has loaded:
});
}
}
$(document).ready(function () {
$(".toggleDiv .expand-arrow").show();
$(".toggleDiv .shrink-arrow").hide();
$(".toggleDiv .expand-arrow").click(function(){
$("#style-switcher").animate(
{"left": "0"}, "slow");
$("#swatchesDiv").animate(
{"opacity": "1"}, "slow");
$(".toggleDiv .expand-arrow").hide();
$(".toggleDiv .shrink-arrow").show();
});
$(".toggleDiv .shrink-arrow").click(function(){
$("#style-switcher").animate(
{"left": "-200px"}, "slow");
$("#swatchesDiv").animate(
{"opacity": "0"}, "slow");
$(".toggleDiv .expand-arrow").show();
$(".toggleDiv .shrink-arrow").hide();
});
});
You should disable the behaviour of your links, with preventDefault or return false:
$(document).ready(function () {
$(".toggleDiv .expand-arrow").show();
$(".toggleDiv .shrink-arrow").hide();
$(".toggleDiv .expand-arrow").click(function(e){
e.preventDefault(); // disable the link
$("#style-switcher").animate(
{"left": "0"}, "slow");
$("#swatchesDiv").animate(
{"opacity": "1"}, "slow");
$(".toggleDiv .expand-arrow").hide();
$(".toggleDiv .shrink-arrow").show();
});
$(".toggleDiv .shrink-arrow").click(function(e){
e.preventDefault(); // disable the link
$("#style-switcher").animate(
{"left": "-200px"}, "slow");
$("#swatchesDiv").animate(
{"opacity": "0"}, "slow");
$(".toggleDiv .expand-arrow").show();
$(".toggleDiv .shrink-arrow").hide();
});
});

Two jQuery popup close functions

I am trying to make a jQuery popup close function. But I have two different popup lightbox area. Problem is first popup close function not working but second popup close function is working.
First jQuery click close link is not working:
$('.kapat').click(function(){
close_box();
});
$('.degistiralani').click(function(){
close_box();
});
Second jQuery click close link is working:
$('.pclose').click(function(){
close_box();
});
$('.cover_change_wrap').click(function(){
close_box();
});
All of my jQuery code is here:
$(document).ready(function() {
$('.d_button').click(function(){
$('.degistiralani, .box').animate({'opacity':'.50'}, 300, 'linear');
$('.alan').animate({'opacity':'1.00'}, 300, 'linear');
$('.degistiralani, .alan').css('display', 'block');
});
$('.kapat').click(function(){
close_box();
});
$('.degistiralani').click(function(){
close_box();
});
});
function close_box()
{
$('.degistiralani, .alan').animate({'opacity':'0'}, 300, 'linear', function(){
$('.degistiralani, .alan').css('display', 'none');
});
}
$(function(){
$('.b_c_d_button').click(function(){
$('.cover_change_wrap, .box').animate({'opacity':'.50'}, 300, 'linear');
$('.kapak_degistirme_alani').animate({'opacity':'1.00'}, 300, 'linear');
$('.cover_change_wrap, .kapak_degistirme_alani').css('display', 'block');
});
$('.pclose').click(function(){
close_box();
});
$('.cover_change_wrap').click(function(){
close_box();
});
});
function close_box()
{
$('.cover_change_wrap, .kapak_degistirme_alani').animate({'opacity':'0'}, 300, 'linear', function(){
$('.cover_change_wrap, .kapak_degistirme_alani').css('display', 'none');
});
}
You have close_box() defined twice. You're overwriting the first definition. Give them different names and it should work. I changed your first one to close_box1()
$('.kapat').click(function(){
close_box1();
});
$('.degistiralani').click(function(){
close_box1();
});
function close_box1()
{
$('.degistiralani, .alan').animate({'opacity':'0'}, 300, 'linear', function(){
$('.degistiralani, .alan').css('display', 'none');
});
}

Re-targeting jQuery "this"

I have this code:
$('.mainDiv').on('click', function(){
$(this).animate({'width':'70%', 'height':'70%'}, 300, 'swing');
$('p', this).stop().animate({'font-size':'70%', 'color':'#000000', 'opacity':'1'}, 300, 'swing',
function(){
$(?????).animate({'width':'110%', 'height':'110%', 'opacity':'0'}, 300, 'swing');
}
);
});
Question: (?????) how do I re-target ".mainDiv" after targeting it's child "p" ?
You can do this :
$('.mainDiv').on('click', function(){
var $maindiv = $(this); // <= save the external "this"
$maindiv.animate({'width':'70%', 'height':'70%'}, 300, 'swing');
$('p', this).stop().animate({'font-size':'70%', 'color':'#000000', 'opacity':'1'}, 300, 'swing',
function(){
$maindiv.animate({'width':'110%', 'height':'110%', 'opacity':'0'}, 300, 'swing');
}
);
});
You can use:
var $this=$(this);
and then use $this when you need to refer the original element.
I wold rather suggest using:
$('.mainDiv').on('click', function(){
var that = this;
$(this).animate({'width':'70%', 'height':'70%'}, 300, 'swing');
$('p', this).stop().animate({'font-size':'70%', 'color':'#000000', 'opacity':'1'}, 300, 'swing',
function(){
$(that).animate({'width':'110%', 'height':'110%', 'opacity':'0'}, 300, 'swing');
});
});
The main idea is to 'attach' the variable to some other, I personaly like it being called 'that', but there are few possible approaches.

Show/Hide div on click using jQuery

I've got 4 divs and on click of the navigation I want to show one of them and hide the others. I have it working but I feel its not as smooth as I know it could be, its definitely my code that needs to be refactored! Heres what I have.
$('#details-speakers').click(function() {
$('#home').slideUp('slow', function() {});
$('#sessions-content').slideUp('slow', function() {});
$('#cases-content').slideUp('slow', function() {});
$('html,body').animate({scrollTop: $("#details").offset().top - 16}, 200, "swing");
$('#speakers-content').slideDown('slow', function() {
$('#details-speakers').addClass('selected');
//Remove other classes
$('#details-sessions').removeClass('selected');
$('#details-cases').removeClass('selected');
$('#details-workshops').removeClass('selected');
});
});
$('#details-sessions').click(function() {
$('#home').slideUp('slow', function() {});
$('#speakers-content').slideUp('slow', function() {});
$('#cases-content').slideUp('slow', function() {});
$('html,body').animate({scrollTop: $("#details").offset().top - 16}, 200, "swing");
$('#sessions-content').slideDown('slow', function() {
$('#details-sessions').addClass('selected');
//Remove other classes
$('#details-speakers').removeClass('selected');
$('#details-cases').removeClass('selected');
$('#details-workshops').removeClass('selected');
});
});
$('#details-cases').click(function() {
$('#home').slideUp('slow', function() {});
$('#speakers-content').slideUp('slow', function() {});
$('#sessions-content').slideUp('slow', function() {});
$('html,body').animate({scrollTop: $("#details").offset().top - 16}, 200, "swing");
$('#cases-content').slideDown('slow', function() {
$('#details-cases').addClass('selected');
//Remove other classes
$('#details-speakers').removeClass('selected');
$('#details-sessions').removeClass('selected');
$('#details-workshops').removeClass('selected');
});
});
Ctrl+C and Ctrl+V programming leads straight to hell... I think you can do something like that:
var divs = $('#details-speakers, #details-sessions, #details-cases');
divs.click(function () {
divs.not(this).add('#home').slideUp('slow');
// animation with home and body
$(this).slideDown('slow', function () {
$(this).addClass('selected');
divs.not(this).removeClass('selected');
});
}
And performance depends on a lot of thing (firebug is on, divs' content, divs' style, half-transparent backgrounds etc.) -- not just poor javascript.
The smoothness or lackthereof is not the fault of your code. Some browsers are slow. It's just not something that can be fixed from JS.
You can make your code shorter but I don't think there will be any material performance improvements.
$('#details-speakers').click(function() {
$('#home, #sessions-content, #cases-content').slideUp('slow');
$('body').animate({scrollTop: $("#details").offset().top - 16}, 200, "swing");
$('#speakers-content').slideDown('slow', function() {
$('#details-speakers').addClass('selected');
//Remove other classes
$('#details-sessions, #details-cases, #details-workshops').removeClass('selected');
});
});
$('#details-sessions').click(function() {
$('#home, #speakers-content, #cases-content').slideUp('slow');
$('body').animate({scrollTop: $("#details").offset().top - 16}, 200, "swing");
$('#sessions-content').slideDown('slow', function() {
$('#details-sessions').addClass('selected');
//Remove other classes
$('#details-speakers, #details-cases, #details-workshops').removeClass('selected');
});
});
$('#details-cases').click(function() {
$('#home, #speakers-content, #sessions-content').slideUp('slow');
$('body').animate({scrollTop: $("#details").offset().top - 16}, 200, "swing");
$('#cases-content').slideDown('slow', function() {
$('#details-cases').addClass('selected');
//Remove other classes
$('#details-speakers, #details-sessions, #details-workshops').removeClass('selected');
});
});
If it's a cleaner approach you're looking for how about something like this:
$(".my4Divs").click(function() {
var self = this;
$(".my4Divs").each(function() {
if(self == this) {
$(self).addClass("selected");
...
...
return;
}
$(this).removeClass("selected");
...
...
});
});

Categories

Resources