Issue with tabbed content in HTML and JavaScript - javascript

I am very much a beginner & having trouble surfacing tabbed content with HTML and JavaScript (I don't believe the issue is due to my CSS).
Essentially, when I review the HTML file on my local browser, I only see the content in the first tab, but then when I click on tabs 2, 3 or 4, nothing happens. I want to work out how to display content in the correct tab. Can you help?
My HTML:
function openMe(inside) {
var i, content;
content = document.getElementByClassName("content");
for (i = 0; i < content.length; i++) {
content[i].style.display = "none";
}
document.getElementById(inside).style.display = "block";
}
<div class="wrapper">
<div class="tabs">
<button onclick="openMe('first')" class="tab">FREELANCERS</button>
<button onclick="openMe('second')" class="tab">GET VERIFIED</button>
<button onclick="openMe('third')" class="tab">SECURITY</button>
<button onclick="openMe('forth')" class="tab">SETTINGS</button>
</div>
<div id="first" class="content">
<h2>FREELANCERS</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec malesuada turpis non sodales aliquam. Proin vel pretium nunc, eu mattis nibh.</p>
</div>
<div id="second" class="content">
<h2>GET VERIFIED</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec malesuada turpis non sodales aliquam. Proin vel pretium nunc, eu mattis nibh.</p>
</div>
<div id="third" class="content">
<h2>SECURITY</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec malesuada turpis non sodales aliquam. Proin vel pretium nunc, eu mattis nibh.</p>
</div>
<div id="forth" class="content">
<h2>SETTINGS</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec malesuada turpis non sodales aliquam. Proin vel pretium nunc, eu mattis nibh.</p>
</div>
</div>
Thank you,
Liam

The correct method is document.getElementsByClassName (with an extra s after Element). Otherwise you'll get an error in your console telling you that the method doesn't exist.
Here it is working nicely with just that simple correction (although you may want to consider whether you actually want all of them displayed at the start, or should some be hidden by default?
function openMe(inside) {
var i, content;
content = document.getElementsByClassName("content");
for (i = 0; i < content.length; i++) {
content[i].style.display = "none";
}
document.getElementById(inside).style.display = "block";
}
<div class="wrapper">
<div class="tabs">
<button onclick="openMe('first')" class="tab">FREELANCERS</button>
<button onclick="openMe('second')" class="tab">GET VERIFIED</button>
<button onclick="openMe('third')" class="tab">SECURITY</button>
<button onclick="openMe('forth')" class="tab">SETTINGS</button>
</div>
<div id="first" class="content">
<h2>FREELANCERS</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec malesuada turpis non sodales aliquam. Proin vel pretium nunc, eu mattis nibh.</p>
</div>
<div id="second" class="content">
<h2>GET VERIFIED</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec malesuada turpis non sodales aliquam. Proin vel pretium nunc, eu mattis nibh.</p>
</div>
<div id="third" class="content">
<h2>SECURITY</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec malesuada turpis non sodales aliquam. Proin vel pretium nunc, eu mattis nibh.</p>
</div>
<div id="forth" class="content">
<h2>SETTINGS</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec malesuada turpis non sodales aliquam. Proin vel pretium nunc, eu mattis nibh.</p>
</div>
</div>

you have a typo in your javasript function with document.getElementsByClassName();
function openMe(inside) {
var i, content;
content = document.getElementsByClassName("content");
for (i = 0; i < content.length; i++) {
content[i].style.display = "none";
}
document.getElementById(inside).style.display = "block";
}

Related

Change div on each click using vanilla js

I have 2 divs div1 and div2. My goal is to make them change on each button click
<div>
<button onclick="changeText();" id="changeText" data-text="Enjoy!">Hello!</button>
<div id="div1" style="display:block">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam ipsum leo,
scelerisque at dapibus ac, consectetur vel ipsum.
</div>
<div id="div2" style="display:none">Cras suscipit ullamcorper elit vitae sodales. Sed euismod felis molestie lorem
gravida a venenatis risus sollicitudin. Proin accumsan lorem in est adipiscing faucibus.
</div>
</div>
My js-code that right now works but i can see that it is completely wrong written.
var button = document.getElementById("changeText");
button.addEventListener(
"click",
function () {
if (document.getElementById("div1").style.display == "block") {
document.getElementById("div1").style.display = "none";
document.getElementById("div2").style.display = "block";
} else {
document.getElementById("div2").style.display = "none";
document.getElementById("div1").style.display = "block"
}
},
false
);
What can I do to make this code look and work better?
It will at least look a little better if you create variables of the two divs;
const div1 = document.getElementById("div1");
const div2 = document.getElementById("div2");
If I understand your question correctly, you can achieve this by toggling between style.display: none and style.display: block on your elements with each click of the button. For example, something like:
function toggleDisplay(el) {
el.style.display = el.style.display === 'none' ? 'block' : 'none';
}
const divEl1 = document.querySelector('#div1');
const divEl2 = document.querySelector('#div2');
document.querySelector('div').addEventListener('click', event => {
if (event.target.tagName === 'BUTTON') {
toggleDisplay(divEl1);
toggleDisplay(divEl2);
}
});
<div>
<button id="changeText" data-text="Enjoy!">Hello!</button>
<div id="div1" style="display:block">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam ipsum leo, scelerisque at dapibus ac, consectetur vel ipsum.
</div>
<div id="div2" style="display:none">Cras suscipit ullamcorper elit vitae sodales. Sed euismod felis molestie lorem gravida a venenatis risus sollicitudin. Proin accumsan lorem in est adipiscing faucibus.
</div>
</div>
My suggestion:
var divs = document.querySelectorAll('.text');
changeText.onclick = () => divs.forEach(div => div.classList.toggle('hidden'));
.hidden {
display: none;
}
<div>
<button id="changeText" data-text="Enjoy!">Hello!</button>
<div class="text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam ipsum leo, scelerisque at dapibus ac, consectetur vel ipsum.
</div>
<div class="text hidden">
Cras suscipit ullamcorper elit vitae sodales. Sed euismod felis molestie lorem gravida a venenatis risus sollicitudin. Proin accumsan lorem in est adipiscing faucibus.
</div>
</div>
Alternatively:
div_2.style.display = "none";
changeText.onclick = () => {
div_2.style.display == "none" ? (div_1.style.display = "none", div_2.style.display = "block") : (div_1.style.display = "block", div_2.style.display = "none")
};
<div>
<button id="changeText" data-text="Enjoy!">Hello!</button>
<div id="div_1">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam ipsum leo, scelerisque at dapibus ac, consectetur vel ipsum.
</div>
<div id="div_2">
Cras suscipit ullamcorper elit vitae sodales. Sed euismod felis molestie lorem gravida a venenatis risus sollicitudin. Proin accumsan lorem in est adipiscing faucibus.
</div>
</div>
Create a CSS class that hides content, and toggle that class:
let divs = document.querySelectorAll(".text");
document.getElementById("changeText").addEventListener("click", () => {
for (let div of divs) div.classList.toggle("hidden");
});
.hidden { display: none }
<div>
<button id="changeText">Hello!</button>
<div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam ipsum leo,
scelerisque at dapibus ac, consectetur vel ipsum.
</div>
<div class="text hidden">Cras suscipit ullamcorper elit vitae sodales. Sed euismod felis molestie lorem
gravida a venenatis risus sollicitudin. Proin accumsan lorem in est adipiscing faucibus.
</div>
</div>
Some comments on your code:
It defines two click handlers: one with addEventListener, but another one with the HTML attribute onclick. The latter references a function you did not provide.
data-text="Enjoy!" is not used
id="div1": don't create a sort of enumerated id attributes. This is almost always a wrong choice. Instead give such a group of elements a common CSS class, and then use a DOM method to get all of them in a node list.
I recommend saving the elements in variables and using classes to hide the element using the classList.toggle () method.
CSS
.hidden{display:none;}
HTML
<div>
<button onclick="changeText();" id="changeText" data-text="Enjoy!">Hello!</button>
<div id="div1">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam ipsum leo, scelerisque at dapibus ac, consectetur vel ipsum.
</div>
<div id="div2" class="hidden">
Cras suscipit ullamcorper elit vitae sodales. Sed euismod felis molestie lorem gravida a venenatis risus sollicitudin. Proin accumsan lorem in est adipiscing faucibus.
</div>
</div>
JS
var button = document.getElementById("changeText");
var div1 = document.getElementById("div1");
var div2 = document.getElementById("div2");
button.addEventListener("click",function () {
div1.classList.toggle('hidden');
div2.classList.toggle('hidden');
});

Select all tags within divs with certain class [duplicate]

This question already has answers here:
document.getElementsByClassName doesn't work
(2 answers)
Closed 7 years ago.
I've been trying to find a solution to my problem for days now without any luck, I found this: getElementsByClassName doesn't work but it's not a solution to my problem since I want to access all tags and change them, so here we go:
I want to be able to change the style of tags that are within divs with a certain class. I started out by trying this with an ID on a div and that works exactly the way I want it, but since the page where I will use this will have the same div's appear several times I have to use class instead and I can't get it to work. I have to use javascript and not jQuery.
Example of how it worked with ID:
var images = document.getElementById("test").getElementsByTagName("img");
for (var i = 0; i < images.length; i++) {
images[i].align = "right";
}
<div id="test">
<img src="http://galerie32.de/images-designer/thumbs/dummy-user.jpg" width="100">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam lobortis turpis justo, eu egestas elit aliquet sit amet. Vivamus convallis, dolor a euismod scelerisque, nisi lorem placerat nisi, sed euismod ligula eros in lorem. Pellentesque vel ante semper,
convallis ante in, mollis odio.
</p>
<img src="http://galerie32.de/images-designer/thumbs/dummy-user.jpg" width="100">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam lobortis turpis justo, eu egestas elit aliquet sit amet. Vivamus convallis, dolor a euismod scelerisque, nisi lorem placerat nisi, sed euismod ligula eros in lorem. Pellentesque vel ante semper,
convallis ante in, mollis odio.
</p>
</div>
Example of how I want it to work:
var images = document.getElementsByClassName("test").getElementsByTagName("img");
for (var i = 0; i < images.length; i++) {
images[i].align = "right";
}
<div class="test">
<img src="http://galerie32.de/images-designer/thumbs/dummy-user.jpg" width="100">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam lobortis turpis justo, eu egestas elit aliquet sit amet.
</p>
<img src="http://galerie32.de/images-designer/thumbs/dummy-user.jpg" width="100">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam lobortis turpis justo, eu egestas elit aliquet sit amet.
</p>
</div>
<div class="test">
<img src="http://galerie32.de/images-designer/thumbs/dummy-user.jpg" width="100">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam lobortis turpis justo, eu egestas elit aliquet sit amet.
</p>
<img src="http://galerie32.de/images-designer/thumbs/dummy-user.jpg" width="100">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam lobortis turpis justo, eu egestas elit aliquet sit amet.
</p>
</div>
I understand that there should be a completely different way of writing the statement when I want to access the classes, but I can't figure out how.
Anyone who knows and can give me some pointers?
The code document.getElementsByClassName("test") gives you a list of elements, not one element. Do a loop (for) on these elements. In this loop, call getElementsByTagName("img").

How to prevent overlapping slides and ensure dynamic container resizing in jquery cycle2 nested slideshows?

I am using cycle2 (http://jquery.malsup.com/cycle2/) to produce a main slideshow containing a number of other slideshows (which contain images and text of variable heights). I want the height of the parent and current slideshow (and container) to resize to the current slide height. This nearly works but I am having a few problems that I can't for the life of me see why and would be massively grateful if someone could point me in the right direction.
You can see a live fiddle at http://jsfiddle.net/deshg/x8xaxx39/
My questions are:
1) Why on first load does it show the 2nd nested slideshow through the first one (when i click on the main pager it fixes it)?
2) Why on first load does cycle-slideshow height not match the current slide height as i'm using the wait command to wait for the images to load and have auto-height set to container (when i click on the main pager it fixes this as well)?
3) Is it a bug that when you manually drag to resize the viewport width sometimes the cycle-slideshow height value is not updated which means the parent height doesn't update or is there a way to solve this?
4) When you click to view gallery 2 and then click back to view gallery 1 the gallery 1 pager (the thumbnails at the bottom) don't work as gallery 2 has a higher z-index despite not being part of the active slide? How do I ensure the active slide has the highest z-index?
Thanks so much for any advice you can give, it doesn't seem to be playing nice for me!
Dave
FYI the related code is:
<div class="module">
<div class="inner">
<h2>GALLERIES</h2>
<!-- empty element for pager links -->
<div id="custom-pager-galleries" class="custom-pager"></div>
<p>Ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
<div class="cycle-slideshow gallery"
data-cycle-fx="fade"
data-cycle-timeout=0
data-cycle-slides="> div"
data-cycle-pager="#custom-pager-galleries"
data-cycle-pager-template="<a href=#> {{name}} </a>"
data-cycle-loader="wait"
data-cycle-auto-height="container"
data-cycle-hide-non-active="true"
>
<div data-name="Gallery 1">
<div class="cycle-slideshow"
data-cycle-fx="fade"
data-cycle-timeout=0
data-cycle-slides="> div"
data-cycle-pager="#custom-pager-gallery"
data-cycle-pager-template="<a href='#'><img src='{{imgsrc}}' class='gallerythumbnail gt{{index}}'></a>"
data-cycle-loader="wait"
data-cycle-auto-height="container"
>
<div data-imgsrc="http://malsup.github.io/images/beach2.jpg">
<img src="http://malsup.github.io/images/beach2.jpg" alt="">
<p class="green"><strong>IMAGE TITLE 1</strong></p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
</div>
<div data-imgsrc="http://malsup.github.io/images/beach3.jpg">
<img src="http://malsup.github.io/images/beach3.jpg" alt="">
<p class="green"><strong>IMAGE TITLE 2</strong></p>
<p>xfsdaLorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
<p>xfsdaLorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
<p>xfsdaLorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
</div>
<div data-imgsrc="http://malsup.github.io/images/beach1.jpg">
<img src="http://malsup.github.io/images/beach1.jpg" alt="">
<p class="green"><strong>IMAGE TITLE 3</strong></p>
<p>xfsdaLorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
</div>
<div data-imgsrc="http://malsup.github.io/images/beach2.jpg">
<img src="http://malsup.github.io/images/beach2.jpg" alt="">
<p class="green"><strong>IMAGE TITLE 4</strong></p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
</div>
<div data-imgsrc="http://malsup.github.io/images/beach3.jpg">
<img src="http://malsup.github.io/images/beach3.jpg" alt="">
<p class="green"><strong>IMAGE TITLE 5</strong></p>
<p>xfsdaLorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
</div>
</div>
<div class="pager">
<div id="custom-pager-gallery" class="custom-pager gallerythumbnails"></div>
</div>
</div>
<div data-name="Gallery 2">
<div class="cycle-slideshow"
data-cycle-fx="fade"
data-cycle-timeout=0
data-cycle-slides="> div"
data-cycle-pager="#custom-pager-gallery2"
data-cycle-pager-template="<a href='#'><img src='{{imgsrc}}' class='gallerythumbnail gt{{index}}'></a>"
data-cycle-loader="wait"
data-cycle-auto-height="container"
>
<div data-imgsrc="http://malsup.github.io/images/beach2.jpg">
<img src="http://malsup.github.io/images/beach2.jpg" alt="">
<p class="green"><strong>IMAGE TITLE 2</strong></p>
<p>xfsdaLorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
<p>xfsdaLorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
<p>xfsdaLorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
<p>xfsdaLorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
<p>xfsdaLorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
<p>xfsdaLorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
<p>xfsdaLorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
<p>xfsdaLorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
<p>xfsdaLorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
</div>
<div data-imgsrc="http://malsup.github.io/images/beach1.jpg">
<img src="http://malsup.github.io/images/beach1.jpg" alt="">
<p class="green"><strong>IMAGE TITLE 1</strong></p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
</div>
<div data-imgsrc="http://malsup.github.io/images/beach2.jpg">
<img src="http://malsup.github.io/images/beach2.jpg" alt="">
<p class="green"><strong>IMAGE TITLE 3</strong></p>
<p>xfsdaLorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
</div>
<div data-imgsrc="http://malsup.github.io/images/beach3.jpg">
<img src="http://malsup.github.io/images/beach3.jpg" alt="">
<p class="green"><strong>IMAGE TITLE 4</strong></p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
</div>
<div data-imgsrc="http://malsup.github.io/images/beach2.jpg">
<img src="http://malsup.github.io/images/beach2.jpg" alt="">
<p class="green"><strong>IMAGE TITLE 5</strong></p>
<p>xfsdaLorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sagittis laoreet nunc, at malesuada ipsum eleifend non. Donec mattis, neque at venenatis tincidunt, risus velit.</p>
</div>
</div>
<div class="pager">
<div id="custom-pager-gallery2" class="custom-pager gallerythumbnails"></div>
</div>
</div>
</div>
</div>
</div>
What you're trying to do is not easy, or provided for "out of the box".
First,
data-cycle-auto-height="container"
is not an allowed option. Check the API. It needs to be an integer, a ratio, or the string "calc".
Second, autoheight can be tricky. You're on the right track with using the wait option on the loader. The problem is that the parent slideshow will still initialize before the children slideshows initialize, simply because it occurs earlier in markup. What you probably want to do is initialize the child slideshows, then initialize the parent slideshow as a callback once both of the child slideshows are fully loaded. Only then will they have layout height that the parent slideshow can use for autoheight calculations. You will need to move off of the declarative syntax, and instead to call cycle slideshow imperatively. I would suggest using jQ deferred objects, and when() syntax to simplify the callback structure.
In semi-pseudo-code:
var childSs1 = new $.Deferred();
var childSs2 = new $.Deferred();
$('.child-slideshow1).on("cycle-post-initialize", function() {
childSs1.resolve();
});
$('.child-slideshow2).on("cycle-post-initialize", function() {
childSs2.resolve();
});
// The following will be called asynchronously
$.when( childSs1, childSs2 ).done(function () {
$(.parent-slideshow).cycle({options});
});
Third, you are most likely running into issues with event bubbling. If an event fires on a child slideshow, that synthetic event will bubble to all parent elements in the DOM, including your parent slideshow(s). That is going to confuse the heck out of the parent slideshow, because it's going to interpret those events as applying to it. Cycle2 wasn't really written with this use case in mind. That isn't to say it can't be done. But you probably will need to do lock down bubbling on all cycle events with something drastic like:
$( ".all-slideshows" ).on("cycle-after cycle-before cycle-bootstrap
cycle-destroyed cycle-finished cycle-initialized cycle-next
cycle-pager-activated cycle-paused cycle-post-initialize
cycle-pre-initialize cycle-prev cycle-resumed
cycle-slide-added cycle-slide-removed cycle-stopped
cycle-transition-stopped cycle-update-view", function( event ) {
event.stopPropagation();
});
Also, it would make it easier for people to help out if you reduced your fiddle as much as possible. Hope this helps.

How do I count number of div's with a class inside a selection of other div's with jQuery

I need to count the number of div's with the event class inside each div named event_month.
I have this at the moment:
$('#events #event_listings .event_month').each(function(i, obj) {
var Count = $(this +'> .event').size();
console.log(Count);
});
This is the HTML I am trying to apply the Javascript to:
<div class="header"><span>October 2012</span></div>
<div class="event">
<h3>Telematics Munich 2012 (29th to 30th)</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer commodo ante iaculis purus placerat sed consectetur odio venenatis. Ut erat nisi, laoreet at tempor vel, sollicitudin sed dui.</p>
</div>
</div>
<div id="september2012" class="event_month">
<div class="header"><span>September 2012</span></div>
</div>
<div id="august2012" class="event_month">
<div class="header"><span>August 2012</span></div>
</div>
<div id="july2012" class="event_month">
<div class="header"><span>July 2012</span></div>
</div>
<div id="june2012" class="event_month">
<div class="header"><span>June 2012</span></div>
<div class="event">
<h3>Telematics Detroit 2012 (6th to 7th)</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer commodo ante iaculis purus placerat sed consectetur odio venenatis. Ut erat nisi, laoreet at tempor vel, sollicitudin sed dui.</p>
</div>
</div>
<div id="may2012" class="event_month">
<div class="header"><span>May 2012</span></div>
<div class="event">
<h3>Insurance Telematics Europe 2012 (9th to 10th)</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer commodo ante iaculis purus placerat sed consectetur odio venenatis. Ut erat nisi, laoreet at tempor vel, sollicitudin sed dui.</p>
</div>
</div>
Needless to say, it's not working. Any ideas?
Try the following:
$('#event_listings .event_month').each(function(i, obj) {
var count = $(this).find('.event').length;
console.log(count);
});
this is an object, so you can't concatenate it with a string. Wrap it in jQuery then filter its children afterwards.
var Count = $(this).children('.event').length;
try this
$(function(){
$('div.event_month').each(function(){
alert($(this).children('.event').length);
});​
}
);​
here is a functional example: http://jsfiddle.net/Ug7SF/

Is there a better way to write this jQuery script?

So the script works, but it seems pretty long. I think there may be some shortcuts I could take, maybe use an array? But I'm new at JS, and really new at jQuery.
What it does:
I have a list of ten questions, and I want to take a graphic (plus sign) and toggle it when clicked to a minus sign. It will also reveal the answer by using a slide toggle.
Here's the code:
<script type="text/javascript" src="jquery-1.3.2.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$(".divOne").hide();
$(".divTwo").hide();
$(".divThree").hide();
$(".divFour").hide();
$(".divFive").hide();
$(".divSix").hide();
$(".divSeven").hide();
$(".divEight").hide();
$(".divNine").hide();
$(".divTen").hide();
$(".bbone").click(function(){
$(".divOne").slideToggle("slow");
$("#button1").toggleClass("down");
});
$(".bbtwo").click(function(){
$(".divTwo").slideToggle("slow");
$("#button2").toggleClass("down");
});
$(".bbthree").click(function(){
$(".divThree").slideToggle("slow");
$("#button3").toggleClass("down");
});
$(".bbfour").click(function(){
$(".divFour").slideToggle("slow");
$("#button4").toggleClass("down");
});
$(".bbfive").click(function(){
$(".divFive").slideToggle("slow");
$("#button5").toggleClass("down");
});
$(".bbsix").click(function(){
$(".divSix").slideToggle("slow");
$("#button6").toggleClass("down");
});
$(".bbseven").click(function(){
$(".divSeven").slideToggle("slow");
$("#button7").toggleClass("down");
});
$(".bbeight").click(function(){
$(".divEight").slideToggle("slow");
$("#button8").toggleClass("down");
});
$(".bbnine").click(function(){
$(".divNine").slideToggle("slow");
$("#button9").toggleClass("down");
});
$(".bbten").click(function(){
$(".divTen").slideToggle("slow");
$("#button10").toggleClass("down");
});
});
</script>
Here's the CSS:
<style type="text/css">
body
{
font-family:Verdana, Arial, Helvetica, sans-serif;
}
.divOne, .divTwo, .divThree, .divFour, .divFive, .divSix, .divSeven, .divEight, .divNine, .divTen
{
border:1px solid #CC0000;
background-color:#efefef;
width:580px;
margin-top:5px;
font-size:10px;
padding:5px;
clear:left;
}
.one, .two, .three, .four, .five, .six, .seven, .eight, .nine, .ten
{
padding-left:10px;
text-decoration:none;
color:#CC0000;
font-variant:small-caps;
font-size:14px;
}
.bbone, .bbtwo, .bbthree, .bbfour, .bbfive, .bbsix,.bbseven,.bbeight,.bbnine,.bbten
{
vertical-align:middle;
}
.question
{
height:auto;
background-color:#fff;
margin-bottom:10px;
width:800px;
}
p {
margin:0;
padding:0;
float:left;
width:16px;
height:16px;
background-image:url(images/add.png);
background-repeat:no-repeat;
}
p.down {
float:left;
width:16px;
height:16px;
background-image:url(images/delete.png);
background-repeat:no-repeat;
}
.wwwLink
{
padding-left:20px;
background: transparent url(images/world_go.png) no-repeat center left;
}
</style>
Here's the HTML:
<body>
<div class="question">
<p id="button1" class="bbone"> </p>Myth No. 1: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam egestas. . <br/>
<div class="divOne">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum purus porta urna aliquet consectetur. Maecenas tempus tellus sed augue tincidunt molestie fermentum lorem porttitor. Nam tincidunt elit vitae quam.
Lorem ipsum dolor sit amet, consectetur adipiscing.
</div>
</div>
<div class="question">
<p id="button2" class="bbtwo"> </p>Myth No. 2: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam egestas. <br/>
<div class="divTwo">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum purus porta urna aliquet consectetur. Maecenas tempus tellus sed augue tincidunt molestie fermentum lorem porttitor. Nam tincidunt elit vitae quam. <br/><br/>
Lorem ipsum dolor sit amet, consectetur adipiscing.
</div>
</div>
<div class="question">
<p id="button3" class="bbthree"> </p>Myth No. 3: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam egestas. <br/>
<div class="divThree">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum purus porta urna aliquet consectetur. Maecenas tempus tellus sed augue tincidunt molestie fermentum lorem porttitor. Nam tincidunt elit vitae quam. <br/><br/>
Lorem ipsum dolor sit amet, consectetur adipiscing.
</div>
</div>
<div class="question">
<p id="button4" class="bbfour"> </p>Myth No. 4: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam egestas. <br/>
<div class="divFour">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum purus porta urna aliquet consectetur. Maecenas tempus tellus sed augue tincidunt molestie fermentum lorem porttitor. Nam tincidunt elit vitae quam. <br/><br/>
Lorem ipsum dolor sit amet, consectetur adipiscing.
</div>
</div>
<div class="question">
<p id="button5" class="bbfive"> </p>Myth No. 5: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam egestas. <br/>
<div class="divFive">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum purus porta urna aliquet consectetur. Maecenas tempus tellus sed augue tincidunt molestie fermentum lorem porttitor. Nam tincidunt elit vitae quam. <br/><br/>
Lorem ipsum dolor sit amet, consectetur adipiscing.
</div>
</div>
<div class="question">
<p id="button6" class="bbsix"> </p>Myth No. 6: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam egestas. <br/>
<div class="divSix">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum purus porta urna aliquet consectetur. Maecenas tempus tellus sed augue tincidunt molestie fermentum lorem porttitor. Nam tincidunt elit vitae quam. <br/><br/>
Lorem ipsum dolor sit amet, consectetur adipiscing.
</div>
</div>
<div class="question">
<p id="button7" class="bbseven"> </p>Myth No. 7: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam egestas. <br/>
<div class="divSeven">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum purus porta urna aliquet consectetur. Maecenas tempus tellus sed augue tincidunt molestie fermentum lorem porttitor. Nam tincidunt elit vitae quam.
</div>
</div>
<div class="question">
<p id="button8" class="bbeight"> </p>Myth No. 8: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam egestas. <br/>
<div class="divEight">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum purus porta urna aliquet consectetur. Maecenas tempus tellus sed augue tincidunt molestie fermentum lorem porttitor. Nam tincidunt elit vitae quam.
</div>
</div>
<div class="question">
<p id="button9" class="bbnine"> </p>Myth No. 9: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam egestas. <br/>
<div class="divNine">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum purus porta urna aliquet consectetur. Maecenas tempus tellus sed augue tincidunt molestie fermentum lorem porttitor. Nam tincidunt elit vitae quam. <br/><br/>
Lorem ipsum dolor sit amet, consectetur adipiscing.
</div>
</div>
<div class="question">
<p id="button10" class="bbten"> </p>Myth No. 10: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam egestas. <br/>
<div class="divTen">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum purus porta urna aliquet consectetur. Maecenas tempus tellus sed augue tincidunt molestie fermentum lorem porttitor. Nam tincidunt elit vitae quam. <br/><br/>
Lorem ipsum dolor sit amet, consectetur adipiscing.
</div>
</div>
<body>
Use this instead of any of the jQuery you posted:
$(document).ready(function() {
$('div.question')
.children('div').hide().end()
.children('p').click(function(){
$(this).toggleClass('down').next().slideToggle("slow");
});
});
Also, you really should consolidate your classes. I would use this updated HTML pattern for all your questions:
<div class="question">
<p class="button"> Myth No. 2: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam egestas. </p>
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum purus porta urna aliquet consectetur. Maecenas tempus tellus sed augue tincidunt molestie fermentum lorem porttitor. Nam tincidunt elit vitae quam. <br/><br/>
Lorem ipsum dolor sit amet, consectetur adipiscing.
</div>
</div>
Your CSS would follow this form:
.question { }
.button { } /* Instead of bbOne, bbTwo, etc*/
.question div { } /* Instead of divOne, divTwo, etc */
.question div a { } /* Instead of wwwLink */
And then I would use this slightly updated jQuery:
$(document).ready(function() {
$('div.question')
.children('div').hide().end()
.find('p > a').click(function(e){
$(this)
.parent().toggleClass('down')
.next().slideToggle("slow");
e.preventDefault();
});
});
something like
$(document).ready(function(){
$('.question div').hide();
$('.question p').click(function(){
$(this).next('div').slideToggle("slow");
$(this).addClass('down');
});
});
you could also modify your markup some and use the jquery ui accordion:
http://docs.jquery.com/UI/Accordion
Give your DIVs a common class and use id's for identification, i.e. instead of all the ids on everything, just have one id on the top-level div, and then generic class names on child Ids. Also avoid using and <br/> tags, but do it with CSS padding/margins instead. Something along these lines:
<div class="question" id="question1">
<div class="questionText">
<p class="questionButton"></span>
Myth No. 1: ...
</div>
<div class="questionAnswer">
...
</div>
</div>
This will also simplify your CSS. Just use the common class names instead of enumerating all the questions.
In general you just need to use jQuery on the class names and it will attach itself to all your elements. Also in a jQuery click handler you rarely need to use the ids of elements, you can use $(this) to get the current element and then use traversing functions to get associated elements. Like this:
$(document).ready(function() {
$(".questionAnswer").hide();
$(".questionButton").click(function(){
$(this).parent().find(".questionAnswer").slideToggle("slow");
$(this).toggleClass("down");
});
});
Fred

Categories

Resources