reducing the javascript with multiple hide/show divs - javascript

I'm hoping that someone would be kind enough to help me.
I have patched together a script to create a set of thumbnails that when hovered over display a link that will show further information in a slide up div.
I need multiple instances of this which I have managed to create but whenever I would like to add a new project (which is what these thumbnails will be) I have to add to the javascript every time I add an instance. I need this to work with a CMS so adding to the javascript is out of the question.
My understanding of javascript is not good enough to work out how to reduce the JS and not have to add $("#projectX").slideDown(500); even time I add a new project. The code I have so far is below. I basically don't want to have to write a piece of javascript every time I input another thumbnail and slide up div pairing.
HTML:
<div class="row">
<div class="col-xs-12">
<div class="hidden-work">
<div id="project1" class="hidden">
<div class="callbacks_container">
<button class="hide">X</button>
<ul class="rslides" id="slider2">
<li>
<div class="row">
<div class="col-md-8 col-xs-12">
<img src="img/eejits/fleur.jpg" alt="">
</div>
<div class="col-md-4 col-xs-12">
<div class="caption">
<h3>Slide 1</h3>
<p>Lorem ipsum</p>
</div><!--caption-->
</div><!--col-->
</div><!--row-->
</li>
</ul>
</div><!--callbacks_container-->
</div><!--eejits-->
<div id="project2" class="hidden">
<div class="callbacks_container">
<button class="hide">X</button>
<ul class="rslides" id="slider1">
<li>
<div class="row">
<div class="col-md-8 col-xs-12">
<img src="img/eejits/fleur.jpg" alt="">
</div>
<div class="col-md-4 col-xs-12">
<div class="caption">
<h3>Slide 2</h3>
<p>Lorem ipsum</p>
</div><!--caption-->
</div><!--col-->
</div><!--row-->
</li>
</ul>
</div>
</div><!--project2 (reach)-->
<div id="project3" class="hidden">
<div class="callbacks_container">
<button class="hide">X</button>
<ul class="rslides" id="slider3">
<li>
<div class="row">
<div class="col-md-8 col-xs-12">
<img src="img/eejits/fleur.jpg" alt="">
</div>
<div class="col-md-4 col-xs-12">
<div class="caption">
<h3>Slide 3</h3>
<p>Lorem ipsum</p>
</div><!--caption-->
</div><!--col-->
</div><!--row-->
</li>
</ul>
</div>
</div><!--project3-->
</div><!--work-->
</div>
</div><!--row-->
<div class="row">
<div class="col-sm-4 col-xs-12">
<div class="thumb-bg">
<div class="thumb no1">
<div class="content">
<h3>Thumb 1</h3>
<p>Lorem ipsum.</p>
<button class="project1 link">VIEW MORE</button>
</div>
</div>
</div>
</div><!--col-->
<div class="col-sm-4 col-xs-12">
<div class="thumb-bg">
<div class="thumb no2">
<div class="content">
<h3>Thumb 2</h3>
<p>Lorem ipsum.</p>
<button class="project2 link">VIEW MORE</button>
</div>
</div>
</div>
</div><!--col-->
<div class="col-sm-4 col-xs-12">
<div class="thumb-bg">
<div class="thumb no3">
<div class="content">
<h3>Thumb 3</h3>
<p>Lorem ipsum.</p>
<button class="project3 link">VIEW MORE</button>
</div>
</div>
</div>
</div><!--col-->
</div><!--row-->
JS:
$(function () {
$("#slider1").responsiveSlides({
auto: false,
pager: false,
nav: true,
speed: 500,
namespace: "callbacks",
before: function () {
$('.events').append("<li>before event fired.</li>");
},
after: function () {
$('.events').append("<li>after event fired.</li>");
}
});
});
$(function () {
$("#slider2").responsiveSlides({
auto: false,
pager: false,
nav: true,
speed: 500,
namespace: "callbacks",
before: function () {
$('.events').append("<li>before event fired.</li>");
},
after: function () {
$('.events').append("<li>after event fired.</li>");
}
});
});
$(function () {
$("#slider3").responsiveSlides({
auto: false,
pager: false,
nav: true,
speed: 500,
namespace: "callbacks",
before: function () {
$('.events').append("<li>before event fired.</li>");
},
after: function () {
$('.events').append("<li>after event fired.</li>");
}
});
});
$(document).ready(function(){
$(".project2").click(function(){
$("#project2").slideDown(500);
$("#project1").slideUp(500);
$("#project3").slideUp(500);
});
$(".project1").click(function(){
$("#project1").slideDown(500);
$("#project2").slideUp(500);
$("#project3").slideUp(500);
});
$(".project3").click(function(){
$("#project3").slideDown(500);
$("#project1").slideUp(500);
$("#project2").slideUp(500);
});
$(".hide").click(function(){
$("#project1").slideUp(500);
$("#project2").slideUp(500);
$("#project3").slideUp(500);
});
});
I really hope that makes sense and any help with this would be brilliant.
Thanks

You need to look into the different selector type. http://api.jquery.com/category/selectors/ Anything prefaced with a # is referencing an element by id (which should be unique and thus only return 1 element) anything prefaced with a . refers to elements by class
EDIT:
Just realised you need to manipulate a separate element to the one that is clicked. OK so to make sure this works universally, you need to make sure the order is the same for the "buttons" and the "slides". We're going to find the index of the button clicked and then use that same logic to slide the appropriate divs.
You can give your buttons a class of "project-button" and your projects a class of "project"
So to make your code universally applicable with one listener you could give all your projects a class of project and then do something like this:
// Attach the same click listener to all elements which have class `project-button`
$('.project-button').on('click', function () {
// Get the index of this clicked button
var myIndex = $(this).index();
// Now get the corresponding `slide`
var mySlide = $('.project').get(myIndex);
// Get all `.project`'s then exclude `mySlide`and slide up
$('.project').not(mySlide).slideUp(500);
// Now slide down just `mySlide`
$(mySlide).slideDown(500);
});
Demo: http://jsfiddle.net/robschmuecker/jPyk6/

You can try below code.
$(".hidden").click(function(){;
$(this).slideDown(500);
($(this).siblings()).each(function( index ) {
$( this ).slideUp(500);
});
});

I saw that you use class="link" for every buttons, you can use class instead of id. Then add id to the button for selecting the right div, like this:
HTML
<button id="project1" class="project1 link">VIEW MORE</button>
jQuery
$('.link').click(function(){
//slideUp all div with class hidden
$('div.hidden').slideUp(500);
//slideDown div with id equals the clicked button
$('div#'+$(this).attr('id')).slideDown(500);
});
I think the same goes for your slider, use the class instead of the id, like this:
$(function () {
$(".rslides").responsiveSlides({
auto: false,
pager: false,
nav: true,
speed: 500,
namespace: "callbacks",
before: function () {
$('.events').append("<li>before event fired.</li>");
},
after: function () {
$('.events').append("<li>after event fired.</li>");
}
});
});
Note: I don't see any element with class events, so I assume its a global element..

Related

jQuery $(this) selector accidentally selects more than 1 element

I'm using the .each() jQuery function together with the $(this) selector to effect a hovered div, but because the given divs are close to one another, the $(this) selector selects more than one element if I move the mouse too fast.
Is there any way to make sure to force $(this) not to select more than one element?
Here is my HTML:
<div class="row">
<div class="col-md-4 donation 180">
<div class="box">
<div class="cover">
<h2>Freedom<br>Package</h2>
</div>
<form class="form"></form>
</div>
</div>
<div class="col-md-4 donation 200">
<div class="box">
<div class="cover">
<h2>Sovereignty<br>Package</h2>
</div>
<form class="form"></form>
</div>
</div>
<div class="col-md-4 donation 400">
<div class="box">
<div class="cover">
<h2>Royalty<br>Package</h2>
</div>
<form class="form"></form>
</div>
</div>
</div>
And here is my jQuery:
if($(window).width() < 800 ) {
$(".form").show();
$(".cover").hide();
} else {
$(".donation").each(function() {
$(this).hover(function() {
$(this).children($(".box")).addClass("animated flipInY");
$(this).children($(".box")).children($(".cover")).fadeOut("", function() {
$(this).siblings($(".form")).show();
});
}, function() {
$(this).children($(".box")).removeClass("animated flipInY");
$(this).children($(".box")).children($(".form")).fadeOut("", function() {
$(this).siblings($(".cover")).show();
});
});
});
}
I would appreciate your help, Thank You!
You don't need to use $(this). You can use the value from each.
$(".donation").each(function(i, val) {
alert($(val).attr('class'));
});

How can I write variables so I don't have to repeat myself?

I'm using an animated modal called animatedModal.js
In order to have a modal fire on click, I have to register a new ID and class every time I need a new Modal. I'm writing this as static HTML, CSS, and JavaScript.
I don't want to register 49 classes and IDs when I know there's a more DRY way of doing so. How can I write this code so it finds classes and IDs and passes them into a function?
<div class="item box student-life">
<a class="demo2" href="#animatedModal-2">
<img class="responsive-img" src="img/design-3-cards-buttons-icon-update-final-design-TILES3_07.jpg">
<div class="content-card">
<h3 class="title">This is an example of a long headline. They Happen sometimes but, I won't let them destroy my layout. Not this time.</h3>
<h5 class="title">Service Learning</h5>
<div class="icon"><img src="img/icons/student-life.png" class="responsive-img" alt=""/></div>
<button class="btn pull-right">Read More</button>
</div>
</a>
</div>
<!--DEMO02 Window-->
<div id="animatedModal-2">
<!--THIS IS IMPORTANT! to close the modal, the class name has to match the name given on the ID class="close-animatedModal" -->
<div class="close-animatedModal-2">CLOSE MODAL</div>
<div class="modal-content"> <img class="responsive-img" src="img/ART-01024.jpeg">
<h1>Content for this block</h1>
</div>
</div>
JavaScript:
$("#demo01").animatedModal({
animatedIn:'zoomIn',
animatedOut:'bounceOut',
color:'#39BEB9',
beforeOpen: function() {
var children = $(".thumb");
var index = 0;
function addClassNextChild() {
if (index == children.length) return;
children.eq(index++).show().velocity("transition.expandIn", { opacity:1, stagger: 250 });
window.setTimeout(addClassNextChild, 200);
}
addClassNextChild();
},
afterClose: function() {
$(".thumb").hide();
}
});

Use of the :not selector

I have a website with different sections. I have jQuery to slide between these sections.
But now I have a link in a section which points to another section.
HTML:
<div class="section" id="one">
<div class="row">
<p>This is some text</p>
</div>
<div class="row">
<img src="button"/>
</div>
</div>
<div class="section" id="tow">
<div class="row">
<p>This is some text</p>
</div>
<div class="row">
<img src="button"/>
</div>
</div>
<div class="section" id="ordernow">
<div class="row">
<p>This is some text</p>
</div>
<div class="row">
<img src="button"/>
</div>
</div>
<div class="section" id="four">
<div class="row">
<p>This is some text</p>
</div>
<div class="row">
<img src="button"/>
</div>
</div>
jQuery:
// onclick on an object with class "section" scroll to this object
$('div.section').click(function() {
$.scrollTo($(this), 800);
});
function scrollOrderNow(){
$('html,body').animate({
scrollTop: $("#ordernow").offset().top
}, 1000);
}
The problem is that if I click on the link scrollOrderNow() the page slides to the order page and than back to the section because the link is in that section.
Could you please help me figure this out?
Thank You!
You can use a single click handler and determine what to do based on which element was clicked inside the section. For this, it's best to distinguish the clickable element by giving it a class:
<div class="section" id="four">
<div class="row">
<p>This is some text</p>
</div>
<div class="row">
<img src="button" class="scroll-to-order"/>
</div>
</div>
The the click handler code:
$('div.section').on('click', function(evt) {
var $target = $(evt.target);
if ($target.is('.scroll-to-order')) {
// the image itself was clicked, so scroll to ordernow
$('html,body').animate({
scrollTop: $("#ordernow").offset().top
}, 1000);
} else {
// something else inside the section was clicked, scroll to section
$.scrollTo($(this), 800);
}
});
You'll need to put return false to your scrollOrderNow() function.
function scrollOrderNow(){
$('html,body').animate({
scrollTop: $("#ordernow").offset().top
}, 1000);
return false;
}
This way, your links will not react and the hash will not be appended to the URL, leaving the page where it is.

Show specific content for each div using Fancybox,

I am trying to load a specific sibling for each div using fancybox.
E.g:
<div id ="content">
<div class="item1">
<div class="pop-ups"><span>click</span></div>
<div class="hidden"><span>content for item 1</span></div>
</div>
<div class="item2">
<div class="pop-ups"><span>click</span></div>
<div class="hidden"><span>content for item 2</span></div>
</div>
<div class="item3">
<div class="pop-ups"><span>click</span></div>
<div class="hidden"><span>content for item 3</span></div>
</div>
<div class="item4">
<div class="pop-ups"><span>click</span></div>
<div class="hidden"><span>content for item 4</span></div>
</div>
</div>
I tried to do the config using the property Content, but not got it, is it possible to get each hidden for each specific item ?
You can use below code:
$(function(){
$("div.pop-ups span").click(function(){
$.fancybox({ content: $(this).parent().next().html() });
});
});
This will show the content of relevant div in fancybox.
You can call this function to open some specific div content in a fancybox.
function OpenDiv(divIDtoopen) //eg. divIDtoopen= #divID //# is must to be prepended to divID for selection
{
$(document).ready(function ()
{
$.fancybox.open(
{
href: divtoopen
}
);
}
);
}

jQuery Multiple Accordions | Only One Tab Expanded

As this is my first post here,
I would like to thank all of you very much for your great support.
Now to the point...
I have 2 accordions in one page.
How can I prevent having 2 accordion tabs expanded?
I mean, if a tab from the first accordion is expanded, I want this tab to be collapsed, when click a tab from the second accordion.
Spent many hours searching over the net and Stack Overflow, but found nothing.
Example Code:
Javascript:
$(function() {
$( ".myAccordion" ).accordion({
collapsible: true,
active: -1
});
});
Html:
<div>Category One</div>
<div class="myAccordion">
<h3>Title1</h3>
<div>Text1</text>
<h3>Title2</h3>
<div>Text2</text>
</div>
<div>Category Two</div>
<div class="myAccordion">
<h3>Title1</h3>
<div>Text1</text>
<h3>Title2</h3>
<div>Text2</text>
</div>
I tried adding a changestart option:
changestart: function(event, ui) {
$('h3.ui-accordion-header').removeClass('ui-state-active ui-corner-top').addClass('ui-state-default ui-corner-all');
$('div.ui-accordion-content').slideUp();
$('div.ui-accordion-content').removeClass('ui-accordion-content-active ui-corner-top').addClass('ui-corner-all');
$('span.ui-icon').removeClass('ui-icon-triangle-1-s').addClass('ui-icon-triangle-1-e');
}
This does the trick, but only for the first time, a tab is clicked.
When you click that tab for a second time, it doesn't change at all. You have to click it for a third time to get it expand again.
Any help will be very appreciated.
Thanks again...
After I played a little and didn't find any solution, I decided to leave ui-accordion and make my own one! I believe that was the best solution to my problem!
As I didn't need fancy styling I used this code to achieve the result I needed:
<body>
<h1>Category 1</h1>
<div class="accTabs">
<a class="accLink" href="#">
<div class="tab-title">Tab Title</div>
<div class="tab-slide" style="display:none;">Tab Content to Slide</div>
</a>
</div>
<div class="accTabs">
<a class="accLink" href="#">
<div class="tab-title">Tab Title</div>
<div class="tab-slide" style="display:none;">Tab Content to Slide</div>
</a>
</div>
<h1>Category 2</h1>
<div class="accTabs">
<a class="accLink" href="#">
<div class="tab-title">Tab Title</div>
<div class="tab-slide" style="display:none;">Tab Content to Slide</div>
</a>
</div>
<div class="accTabs">
<a class="accLink" href="#">
<div class="tab-title">Tab Title</div>
<div class="tab-slide" style="display:none;">Tab Content to Slide</div>
</a>
</div>
<script>
$("a.accLink").click(function () {
var $that = $(this),
$children = $that.children('div.tab-slide');
// If expanded tab was clicked, collapse it.
// >> FIXED LOGIC ERROR >> if ($children.hasClass("slided")) {
if ($that.hasClass("slided")) {
$children.slideUp("slow", function () {
$that.removeClass("slided");
});
} else {
// Collapse all expanded tabs
// FIXED LOGIC ERROR >> $("div.slided").slideUp("slow", function() {
$(".slided").find("div.tab-slide").slideUp("slow", function () {
$(".slided").removeClass("slided");
});
// Expand clicked tab
$children.slideDown("slow", function () {
$that.addClass("slided");
});
}
});
</script>
</body>
UPDATED SCRIPT: FIXED LOGIC ERRORS TO MAKE 100% FUNCTIONAL
You want to attach your accordion() to a container element, not the actual divs.
For example:
<div id='accordion'>
<h3><a href='#'>Category One</a></h3>
<div class="myAccordion">
<h3>Title1</h3>
<div>Text1</text>
<h3>Title2</h3>
<div>Text2</text>
</div>
<h3><a href='#'>Category Two</a></h3>
<div class="myAccordion">
<h3>Title1</h3>
<div>Text1</text>
<h3>Title2</h3>
<div>Text2</text>
</div>
</div>
And then your script:
$(function() {
$( "#accordion" ).accordion({
collapsible: true,
active: false
});
});

Categories