Reputation: 105
Im new to javascript because I skipped it and jumped to jquery and now Im writing a javascript code but I'm having trouble. I have multiple elements with the same class name and below each element is an a-tag. i want to hide/show the element upon clicking the button below it. How can i do this in javascript? (no jquery please).
HTML
<div>
<div class="content">content 1</div>
<a class="show-more" onclick="toggleText();" href="javascript:void(0);">Show more</a>
</div>
<div>
<div class="content">content 2</div>
<a class="show-more" onclick="toggleText();" href="javascript:void(0);">Show more</a>
</div>
<div>
<div class="content">content 3</div>
<a class="show-more" onclick="toggleText();" href="javascript:void(0);">Show more</a>
</div>
CSS
.content {
display: none;
}
Javascript
var status = "less";
function toggleText1() {
if (status == "less") {
document.getElementsByClassName("content")[0].style.display = 'block';
document.getElementsByClassName("show-more")[0].innerText = "See Less";
status1 = "more";
} else if (status1 == "more") {
document.getElementsByClassName("content")[0].style.display = 'none';
document.getElementsByClassName("show-more")[0].innerText = "See More";
status1 = "less";
}
}
in my original code i named my content as content1,content2 and my a-tag as show-more1,show-more2 then my functions as toggleText1,toggleText2 and so on. It works but i find it inefficient. Can you guys guide me to the right path?
Upvotes: 2
Views: 15498
Reputation: 19772
Crazy, CSS Only Answer - for fun and educational purposes only
This does have some practical application, you could pre-open one of your content areas by adding a hash to the url. E.g http://yourdomain/page#Content2
.content .show-less {
display: block;
}
.content {
display: none;
}
#content-container .content:target {
display: block;
}
#content-container .content:target~.show-more {
display: none;
}
<div id="content-container">
<div>
<div class="content" id="Content1">content 1 <a href="#content-container" class="show-less">Show Less</a></div>
<a class="show-more" href="#Content1">Show more</a>
</div>
<div>
<div class="content" id="Content2">content 2 <a href="#content-container" class="show-less">Show Less</a></div>
<a class="show-more" href="#Content2">Show more</a>
</div>
<div>
<div class="content" id="Content3">content 3 <a href="#content-container" class="show-less">Show Less</a></div>
<a class="show-more" href="#Content3">Show more</a>
</div>
</div>
More Reading:
Upvotes: 0
Reputation: 41893
Here's one of methods how to solve it. Catch all the links, then use Array#forEach
to iterate over them and bind click
event to every element. Then find the div
element in the parent node and toggle it's class from hidden to visible.
ES6 solution.
var elems = document.getElementsByClassName("show-more");
Array.from(elems).forEach(v => v.addEventListener('click', function() {
this.parentElement.getElementsByClassName('content')[0].classList.toggle('hidden');
}));
.hidden {
display: none;
}
<div>
<div class="content">content 1</div>
<a class="show-more" href="javascript:void(0);">Show more</a>
</div>
<div>
<div class="content">content 2</div>
<a class="show-more" href="javascript:void(0);">Show more</a>
</div>
<div>
<div class="content">content 3</div>
<a class="show-more" href="javascript:void(0);">Show more</a>
</div>
ES5 solution.
var elems = document.getElementsByClassName("show-more");
for (var i = 0; i < elems.length; i++){
elems[i].addEventListener('click', function(){
this.parentElement.getElementsByClassName('content')[0].classList.toggle('hidden');
})
}
.hidden {
display: none;
}
<div>
<div class="content">content 1</div>
<a class="show-more" href="javascript:void(0);">Show more</a>
</div>
<div>
<div class="content">content 2</div>
<a class="show-more" href="javascript:void(0);">Show more</a>
</div>
<div>
<div class="content">content 3</div>
<a class="show-more" href="javascript:void(0);">Show more</a>
</div>
Upvotes: 3
Reputation:
You can also use a delegated event listener, which is an event listener assigned to a common ancestor element.
Check to see if the element is the type of element we are looking for (this check will probably change based on the actual content of the page), then select the previous element sibling and change the display property and text based on the current values.
This example uses a fat arrow function (introduced in the ECMAScript 2015 language specification), but a normal function expression would suffice if supporting old browsers is required.
document.addEventListener('click', event => {
const element = event.target
if(event.target.classList.contains("toggle")) {
const previous = event.target.previousElementSibling
const text = element.textContent
element.textContent = element.dataset.toggleText || "Show less"
element.dataset.toggleText = text
previous.classList.toggle('hidden')
}
})
.hidden {
display: none;
}
<div>
<div class="content hidden">content 1</div>
<a class="toggle" href="#">Show more</a>
</div>
<div>
<div class="content hidden">content 2</div>
<a class="toggle" href="#">Show more</a>
</div>
<div>
<div class="content hidden">content 3</div>
<a class="toggle" href="#">Show more</a>
</div>
Upvotes: 0
Reputation: 1
var hidePrev = function(event){
element = event.target;
element.previousSibling.previousSibling.classList.toggle('hidden');
};
.hidden {
display: none;
}
<div>
<div class="content">content 1</div>
<a class="show-more" onclick='hidePrev(event);'
href="javascript:void(0);">Show more</a>
</div>
<div>
<div class="content">content 2</div>
<a class="show-more" onclick='hidePrev(event);'
href="javascript:void(0);">Show more</a>
</div>
<div>
<div class="content">content 3</div>
<a class="show-more" onclick='hidePrev(event);'
href="javascript:void(0);">Show more</a>
</div>
Upvotes: 0
Reputation: 401
First, you can pass the element in the onclick by using the this as the argument/parameter to know the source of the on click. Then you get the parent and get the correct content div and use the style element and to do some logic on what to display or hide.
And according to your post, you should also make your content divs hidden by default.
function toggleText(aTag) {
var content = aTag.parentNode.getElementsByClassName("content")[0];
if(content.style.display == null || content.style.display == "none")
{
content.style.display = 'block';
aTag.innerText = "See Less";
}
else
{
content.style.display = 'none';
aTag.innerText = "See More";
}
}
<div>
<div class="content" style="display:none;">content 1</div>
<a class="show-more" onclick="toggleText(this);" href="javascript:void(0)">Show more</a>
</div>
<div>
<div class="content" style="display:none;">content 2</div>
<a class="show-more" onclick="toggleText(this);" href="javascript:void(0)">Show more</a>
</div>
<div>
<div class="content" style="display:none;">content 3</div>
<a class="show-more" onclick="toggleText(this)" href="javascript:void(0)">Show more</a>
</div>
also is it just me, or that just smells like a homework?
Upvotes: 0