I have 3 divs + 3 hidden divs. I want to click on "service1" and edit "display:block" in "toggle1".
The HTML:
<div id="service1" onclick="changeService('toggle1')></div>
<div id="service2"></div>
<div id="service3"></div>
<br><br>
<div id="toggle1"></div>
<div id="toggle2"></div>
<div id="toggle3"></div>
The CSS:
#toggle1, #toggle2, #toggle3 {display:none}
The Javascript:
function changeService(this) {
this.style.display = "block";
}
Hope I explained myself well enough so you guys can understand. What am I doing wrong?
Thanks in advance :)
You are passing a string into function, not an object. You can use document.getElementById method to get corresponding div element:
function changeService(id) {
document.getElementById(id).style.display = "block";
}
I think it would be best to use CSS classes.
So go:
#toggle1, #toggle2, #toggle3 {display:none}
#toggle1.active, #toggle2.active, #toggle3.active{display: block}
And then:
function changeService(id) {
document.getElementById(id).setAttribute("class", "active");
}
Then you can keep view and logic separated and easily add more style if necessary. Try never to change your CSS in Javascript. Better add classes like this to keep things clear.
https://jsfiddle.net/t74tmu7r/2/
first of all place your script file before the closing body tag to make sure all DOM elements are loaded then use this code:
function changeService(id){
var elem = document.getElementById(id);
elem.style.display = "block";
}
then in the div tag with a class name 'service1' do this:
<div id="service1" onClick="changeService('toggle1');"></div>
that should do the job.
Related
I've seen a few articles about this dotted around but I cant seem to get their solutions to work for me.
What I have are two buttons which control the show() and hide() states of different div's. On page load both of the div's are set to .hide() as the user doesn't need to see them until clicked.
So, I have two buttons a and b which currently work perfectly however you can show() both div's at the same time which I don't want to happen. The current code resembles
$('#a-div).hide();
$('#b-div).hide();
$('#a').click(function(){
$('#a-div).toggle(500);
});
$('#b').click(function(){
$('#b-div).toggle(500);
});
So how can I re-write this so that if #a-div is visible (already tried the .is(':visible') method) and #b is clicked nothing happens until #a-div is hidden again and vis versa?
Try this
$('#a-div').hide();
$('#b-div').hide();
$('#a').click(function(){
$('#a-div').toggle(500);
if($('#b-div').is(":visible"))
$('#b-div').hide();
});
$('#b').click(function(){
$('#b-div').toggle(500);
if($('#a-div').is(":visible"))
$('#a-div').hide();
});
probably you need to apply concept like this
$('#a-div).hide();
$('#b-div).hide();
$('#a').click(function(){
if ($('#b').isVisible)[you can check via css property as well]
{
$('#b-div).toggle(500); [or set css property visiblity:hidden]
$('#a-div).toggle(500);
}
else {$('#a-div).toggle(500);}
});
$('#b').click(function(){
if ($('#a').isVisible)[you can check via css property as well]
{
$('#a-div).toggle(500); [or set css property visiblity:hidden]
$('#b-div).toggle(500);
}
else {$('#b-div).toggle(500);}
});
What I ended up doing is this
$('#a-div').hide();
$('#b-div').hide();
$('#a').click(function(){
$('#a-div').toggle();
$('#b-div').hide();
});
$('#b').click(function(){
$('#b-div').toggle();
$('#a-div').hide();
});
For anyone who is interested. Prior to this I was making this much more complex than it needed to be.
Another solution is to create a universal function and pass the parameters of the shown and hidden objects. This way you can use the same method for future elements:
function toggleDivs($show, $hide) {
$show.toggle();
$hide.hide();
}
$("#b").on("click", function() { toggleDivs($("#b-div"), $("#a-div")); });
$("#a").on("click", function() { toggleDivs($("#a-div"), $("#b-div")); });
The only item missing is to initially hide the div objects, but I would add a css class to the objects to hide them.
HTML
<button id="a">Show A</button>
<button id="b">Show B</button>
<div id="a-div" class="hideDiv">A</div>
<div id="b-div" class="hideDiv">B</div>
CSS
.hideDiv { display:none; }
var $aDiv = $('#a-div');
var $bDiv = $('#b-div');
var $aBtn = $('#a');
var $bBtn = $('#b');
$aDiv.hide();
$bDiv.hide();
$aBtn.click(function(){
$aDiv.toggle(500, function(){
if($aDiv.is(":visible"))
$bBtn.prop("disabled",true);
else
$bBtn.prop("disabled",false);
});
});
$bBtn.click(function(){
$bDiv.toggle(500, function(){
if($bDiv.is(":visible"))
$aBtn.prop("disabled",true);
else
$aBtn.prop("disabled",false);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="a-div">div a</div>
<div id="b-div">div b</div>
<button id="a">btn a</button>
<button id="b">btn b</button>
In css I have set all the <hr> elements in my html to "display:none;" which works.
I have an onclick event listener set up to change the "display" to "block".
I use:
document.getElementsByTagName("hr").innerHTML.style.display = "block";
I get an error "Cannot read property 'style' of undefined".
Do it the following way:
var hrItems = document.getElementsByTagName("hr");
for(var i = 0; i < hrItems.length; i++) {
hrItems[i].style.display = 'block';
}
This is incorrect in two ways
getElementsByTagName gives you a list on elements and there is no method to operate on all elements, so you'll have to loop through all of them and add the required style individually.
innerHTML returns a string containing the mark up in an element but <hr> doesn't have any thing in it and the style property is on the <hr> itself.
var hrs = document.getElementsByTagName("hr");
for(var i = 0; i < hrs.length; i++) {
hrs[i].style.display = 'block';
}
Simple (and very effective) solution:
tag your body with a class-element
<body class="no_hr"> <article><hr/> TEXT Foo</article> <hr/> </body>
in css don't hide hr directly, but do
.no_hr hr {
display:none;
}
now define a second style in your css
.block_hr hr{
display:block;
}
in your buttons onClick, change the one and only body class from no_hr to block_hr
onclick() {
if ( document.body.className == "no_hr" ) {
document.body.className = "block_hr";
} else {
document.body.className = "no_hr";
}
}
This is a very charming solution, because you don't have to iterate over elements yourself, but let your browsers optimized procedures do their job.
For people who want a solution that doesn't require JavaScript.
Create an invisible checkbox at the top of the document and make sure that people can click on it.
<input type="checkbox" id="ruler"/>
<label for="ruler">Click to show or hide the rules</label>
Then tell the stylesheet that the <hr>s should be hidden by default, but should be visible if the checkbox is checked.
#ruler, hr {display:none}
#ruler:checked ~ hr {display:block}
Done. See fiddle.
getElementsByTagName() returns a node list, and therefore you must iterate through all the results. Additionally, there is no innerHTML property of an <hr> tag, and the style must be set directly on the tag.
I like writing these types of iterations using Array.forEach() and call:
[].forEach.call(document.getElementsByTagName("hr"), function(item) {
item.style.display = "block";
});
Or, make it even easier on yourself and use jQuery:
$("hr").show();
I have the following working Javascript function:
function collapsible(zap) {
if (document.getElementById) {
var abra = document.getElementById(zap).style;
if (abra.display == "block") {
abra.display = "none";
} else {
abra.display = "block";
}
return false;
} else {
return true;
}
}
When I use the following in html code it displays or hides the "element" div:
<li>Element</li>
Thats working fine. But the problem is, that I want to use the function for multiple links, and then the other elements, that were clicked before, stay, open.
How can I reprogram the code, so that only one div stays open and the other gets closed if i click on another link?
Thanks beforehand!
If you could use jQuery and more importantly jQueryUI accordion I think it would accomplish exactly what you're looking for.
However, without using those two, here is how I would structure it. Like mentioned above, I would use classes to modify the styles of the divs you want shown or hidden. Then the js code can just toggle those classes on each of your elements. The slightly more difficult part (without jquery) is modifying class values since in your final application you may have lots of classes on each div. This is just a very crude example to get you going.
Working JSFiddle Example
Sample DOM
<div >
<li>Element1</li>
<div id='elem1' class='myelem visible'>
Element 1 contents
</div>
</div>
<div >
<li>Element2</li>
<div id='elem2' class='myelem'>
Element 2 contents
</div>
</div>
<div >
<li>Element3</li>
<div id='elem3' class='myelem'>
Element 3 contents
</div>
</div>
Sample JS
window['collapsible'] = function(zap) {
if (document.getElementById)
{
var visDivs = document.getElementsByClassName('visible');
for(var i = 0; i < visDivs.length; i++)
{
visDivs[i].className = visDivs[i].className.replace('visible','');
}
document.getElementById(zap).className += " visible";
return false;
}
else
return true;
}
Sample CSS:
.myelem {
display: none;
}
.visible {
display: block;
}
The way to go is to create a class(or maybe two), like collapsible and active or open that has this style(display: block or none) and then you working adding or removing the class.
The logic would be:
Links that has the class collapsible when clicked would add the active or open class which would give the behavior that remains opens(or active) by css.
If you want to hide others elements you would look for the elements with the class collapsible and then remove the active(or open) class if has any.
Here is my solution: http://jsfiddle.net/g5oc0uoq/
$('.content').hide();
$('.listelement').on('click', function(){
if(!($(this).children('.content').is(':visible'))){
$('.content').slideUp();
$(this).children('.content').slideDown();
} else {
$('.content').slideUp();
}
});
show() and hide() can be used instead of slideUp() and slideDown() if you have performance issues.
I have a redundant process for making div's visible / hidden and I believe the way to make it more efficient is to use a loop.
Currently I have numerous div's through the document but there are 6 in particular that I want to deal with. I have a series of buttons that correspond to the six div's. When person clicks button A I want to show (make visible) div A and hide Div's B,C,D,E,F. My javascript is something like this:
<a href="#" onclick="ShowMe('A'); return false" />
<a href="#" onclick="ShowMe('B'); return false" />
<a href......etc />
<div id="A">blah...blah</div>
<div id="B">blah...blah</div>
<script type="java....">
function ShowHideDiv(DivName)
{
if(DivName == 'A')
{
var diva = document.getElementById('A');
div.style.visibility = 'visible';
var divb = document.getElementById('B');
div.style.visibility = 'hidden';
etc....
}
else if (DivName == 'B')
{
var diva = document.getElementById('A');
div.style.visibility = 'hidden';
var divb = document.getElementById('B');
div.style.visibility = 'visible';
etc...............
}
}
</script>
So as mentioned a prime candidate for loop but my question is how to contain the loop. For example if my loop went through the entire document object then I would have divs that I want visible being hidden so how do I avoid this?
I had two thought but was if others had additional thoughts, ideas, techniques etc.
Give my divs a really oddball prefix to their name like ShowHide_A then my loop can go through all the divs in the document object, parse it's name, if it doesn't have the prefix then move to the next one. This of course would be very inefficient if we had a large document and the script was getting every object and parsing then checking the name.
Wrap the div's in question in a parent container such as:
Then my javascript could be contained to looping through just the DivParent tree. But what if my div's are at different places in the document model? Do I keep them in the ParentDiv and position then where they belong with with css position properties?
Any other ideas would be greatly appreciated
JB
Let me suggest a better approach.
If you can use jQuery, you can do the following:
Assign a class (e.g. box) to all of your divs. Then your button needs to call this function:
function toggleDiv (divID) {
$(".box").hide();
$("#"+divID).show();
}
What you can also do is assign e.g. data-div attribute to your button which contains the ID of the div to hide/show, and then you can transform the above to the following (assuming your buttons have the button class):
$(".button").click(function () {
var divID = $(this).attr("data-div");
$(".box").hide();
$("#"+divID).show();
});
The above covers everything, assigning events to the buttons and hiding/showing divs.
see suppose you have markup like this
<div id="A" class="marked" >A</div>
<div id="B" class="marked" >B</div>
<div id="C" class="marked" >C</div>
<div id="D" class="marked" >D</div>
<div id="E" class="marked" >E</div>
<input type="button" value="Show A" data-target-div="A" />
<input type="button" value="Show B" data-target-div="B" />
then add a script like this:
$('input[type=button]').click(function(){
$('.marked').hide(200);
$('#'+$(this).data('target-div')).show();
});
it should work.
see this fiddle
so, you are not iterating through all the dom elements, you are picking exactly the ones you need to deal with. upon click, you hide all of them, and show the one which is target i.e. data-target-div
jQuery based solution:
Add a class to your div's that allow hiding/showing and then do
function ShowHideDiv(DivName)
{
$(".ShowHide").not("#" + DivName).hide();
$("#" + DivName).show();
}
Add class='switchable' (or whatever) to each such DIV then using prototype.js you could do something like this
function showMe( elem ) {
$$( '.switchable' ).each( function( switchable ) {
if ( switchable.id == $(elem).id )
switchable.show();
else
switchable.hide();
} );
}
Please refer to the following codes :
<div id="message-1" onclick="javascript:showresponddiv(this.id)>
</div>
<div id="respond-1" style="display:none;">
</div>
<div id="message-2" onclick="javascript:showresponddiv(this.id)>
</div>
<div id="respond-2" style="display:none;">
</div>
<script type="text/javascript">
function showresponddiv(messagedivid){
var responddivid = messagedivid.replace("message-", "respond-");
if (document.getElementById(responddivid).style.display=="none"){
document.getElementById(responddivid).style.display="inline";
} else {
document.getElementById(responddivid).style.display="none";
}
}
</script>
The codes above already success make the respond div appear when user click on message div. The respond div will disappear when user click on message div again. Now my question is how to make the respond div of 1st message disappear when user click on 2nd message to display the respond div of 2nd message?
You should give the "respond" divs a common class:
<div id="respond-1" class="response' style="display:none;"></div>
Then you can get all divs by using getElementsByTagName, compare the class and hide them on a match:
function hideAllResponses() {
var divs = document.getElementsByTagName('div');
for(var i = divs.length; i-- ;) {
var div = divs[i];
if(div.className === 'response') {
div.style.display = 'none';
}
}
}
We cannot use getElementsByClassName, because this method is not supported by IE8 and below. But of course this method can be extended to make use of it if it is supported (same for querySelectorAll). This is left as an exercise for the reader.
Further notes:
Adding javascript: to the click handler is syntactically not wrong but totally unnecessary. Just do:
onclick="showresponddiv(this.id)"
If you have to do a lot of DOM manipulation of this kind, you should have a look at a library such as jQuery which greatly simplify such tasks.
Update: If always only one response is shown and you are worried about speed, then store a reference to opened one:
var current = null;
function showresponddiv(messagedivid){
var id = messagedivid.replace("message-", "respond-"),
div = document.getElementById(id);
// hide previous one
if(current && current !== div) {
current.style.display = 'none';
}
if (div.style.display=="none"){
div.style.display="inline";
current = div;
}
else {
div.style.display="none";
}
}
Edit: Fixed logic. See a DEMO.
You can add some class to all divs with id="respond-"
e.g
<div id="respond-1" class="classname" style="display:none;"></div>
<div id="respond-2" class="classname" style="display:none;"></div>
Now at first row of your function "showresponddiv()" you should find all divs with class "classname" and hide them.
With jQuery it is simple code:
$(".classname").hide();
jQuery - is a Javascript Library that helps you to easy manipulate with DOM and provides cross-browser compatibility.
Also you can look to Sizzle - it is a JavaScript CSS selector engine used by jQuery for selecting DOM elements