EDIT: Thanks, but those answers are not the best way to do it and are difficult to understand by a beginner.
I have this structure:
<div>Title <a href="#" onclick="a1()">+</a>
<div id="b1">...content...</div></div>
..... n times this structure ....
<div>Title <a href="#" onclick="function aN()">+</a>
<div id="bN">...content...</div></div>
When the user clicks the + sign the content should show or disappear.
function a1(){
$('#b1').toggle();
}
.... too many functions .....
function aN(){
$('#bN').toggle();
}
How can I rewrite all those functions in one single function to write less code?
EDIT: Thanks, but those answers are not the best way to do it and are difficult to understand by a beginner.
I have this structure:
<div>Title <a href="#" onclick="a1()">+</a>
<div id="b1">...content...</div></div>
..... n times this structure ....
<div>Title <a href="#" onclick="function aN()">+</a>
<div id="bN">...content...</div></div>
When the user clicks the + sign the content should show or disappear.
function a1(){
$('#b1').toggle();
}
.... too many functions .....
function aN(){
$('#bN').toggle();
}
How can I rewrite all those functions in one single function to write less code?
Share Improve this question edited Aug 28, 2014 at 23:20 Claudiu Creanga asked Aug 28, 2014 at 22:02 Claudiu CreangaClaudiu Creanga 8,40613 gold badges78 silver badges118 bronze badges 2- stackoverflow./questions/190253/… – Donal Commented Aug 28, 2014 at 22:05
- 2 Whenever you have something like this, the first step you can do is make the thing that's different in each function (in your case the selector), a parameter of the function. – Felix Kling Commented Aug 28, 2014 at 22:24
10 Answers
Reset to default 6You can just make it more descriptive int he markup itself , use a custom attribute data-target
(or use the href itself) and store the id of the target.
<div>Title <a data-target="#b1" class="toggler" href="#">+</a>
<div id="b1">...content...</div></div>
..... n times this structure ....
<div>Title <a data-target="#b2" class="toggler" href="#" >+</a>
<div id="bN">...content...</div></div>
and just register a function:-
$(function(){
$('.toggler').on('click', function(e){
e.preventDefault();
$($(this).data('target')).toggle();
});
});
This way you can put any selector for the target in the attribute, regardless of wherever it appears in your markup (Not just the next element), and move away from the inline click handlers.
You can abstract your code by using a generalized class to hook your javascript to. jsFiddle Example
HTML
<div>
Title <a href="#" class="toggleNext">+</a>
<div id="b1">...content...</div>
</div>
jQuery
$('.toggleNext').click(function(e){
e.preventDefault();
$(this).next().toggle()
});
Have you tried?
<div>Title <a href="#" onclick="a('b1')">+</a>
<div id="b1">...content...</div></div>
..... n times this structure ....
<div>Title <a href="#" onclick="a('bN')">+</a>
<div id="bN">...content...</div></div>
function a(id){
$('#' + id).toggle();
}
<div class="container">Title <a href="#" class="link">+</a>
<div class="content">...content...</div></div>
..... n times this structure ....
<div class="container">Title <a href="#" class="link">+</a>
<div class="content">...content...</div></div>
<script>
$(".container .link").bind('click', function(event) {
event.preventDefault();
$(this).parent().find('.content').toggle();
});
</script>
Add a dummy class to all + anchor. e.g. anc
Then
$('.anc').on('click', function (){
$(this).next('div').toggle();
}
DEMO
HTML: Using a CSS class
<div>Title <a href="#" class="myanchor">+</a>
<div id="b1">...content...</div></div>
<!--..... n times this structure ....-->
<div>Title <a href="#" class="myanchor">+</a>
<div id="bN">...content...</div></div>
JS
$(function() {
$('a.myanchor').on('click', a);
function a(e) {
e.preventDefault();
$(this).next('div').toggle();
}
});
Use jQuery's on
method:
HTML:
<div>Title <a href="#" class="toggle">+</a>
<div class="content">...content...</div></div>
<div>Title <a href="#" class="toggle">+</a>
<div class="content">...content...</div></div>
<div>Title <a href="#" class="toggle">+</a>
<div class="content">...content...</div></div>
JavaScript:
$(document).on('click', '.toggle', function(e) {
$(e.currentTarget).parent().find('.content').toggle();
});
Working jsfiddle: http://jsfiddle/uq1mafs3/
First, using inline event handlers is considered bad form for a variety of reasons.
That said, there are a few ways to do what you like. Personally, I would go for this approach:
<div>Title <a href="#" onclick="toggleThing()" data-thing-to-toggle="b1">+</a>
<div id="b1">...content...</div></div>
function toggleThing() {
var toggleId = this.getAttribute("data-thing-to-toggle");
var $target = $(toggleId);
$target.toggle();
}
A simple solution is passing the id of the element:
function a(id) {
$('#' + id).toggle();
}
Your HTML would look like this:
<div>Title <a href="#" onclick="a('b1');">+</a>
<div id="b1">...content...</div></div>
..... n times this structure ....
<div>Title <a href="#" onclick="a('bN');">+</a>
<div id="bN">...content...</div></div>
You should be able to pass the id of the element to be toggled as a function parameter:
<div>Title <a href="#" onclick="toggle('#b1')">+</a>
<div id="b1">...content...</div></div>
..... n times this structure ....
<div>Title <a href="#" onclick="toggle('#bN')">+</a>
<div id="bN">...content...</div></div>
Then you can implement just one function:
function toggle(id){
$(id).toggle();
}
See JavaScript Function Parameters for more information.