3

So, on my example I have 2 div-buttons (named btn1 and btn2) and 2 div elements (named content1 and content2).

What I would want, is that when you click the btn1, content1 shows. If you click btn2, content2 should show.

Content1 and content2 elements are currently placed in the same position, and by default, none of the content elements shouldn't be open before you have clicked anything. I would like to achieve this with pure javaSript.

Here is the example code:

var btn1 = document.getElementById("btn1");
var content1 = document.getElementById("content1");
content1.style.opacity = "0";

btn1.addEventListener("mouseover", showContent1);

function showContent1(){
  if(content1.style.opacity === "0") {
    content1.style.opacity = "1";
  } else {content1.style.opacity = "0";}
}

var btn2 = document.getElementById("btn2");
var content2 = document.getElementById("content2");
content2.style.opacity = "0";

btn2.addEventListener("mouseover", showContent2);

function showContent2(){
  if(content2.style.opacity === "0") {
    content2.style.opacity = "1";
  } else {content2.style.opacity = "0";}
}
#btn1, #btn2 {
width:100px;height:20px;text-align:center;background:grey;cursor:pointer;margin:10px 0px;
}
#contents {
width: 200px;height:200px;border: 2px solid black;
}
#content1, #content2 {
width: 200px;height:200px;position:absolute;background:lightblue;
}
<div id="btn1">show1</div>
<div id="btn2">show2</div>
<div id="contents">
  <div id="content1">content 1</div>
  <div id="content2">content 2</div>
</div>

5
  • 4
    Please upload what you have tried, i do not see any javascript Commented Nov 11, 2019 at 10:17
  • Hey, uploaded the answer. I am not very experienced with javaScript, this was the best solution I could come up with, but it doesn't work well. Commented Nov 11, 2019 at 10:22
  • Plunker For the same: plnkr.co/edit/brxoF2ClW2TeJOVMxn8d?p=preview Commented Nov 11, 2019 at 10:27
  • 1
    Strange you put in question that you expect it to show on click, but inside the script you're listening to mouseover event? Commented Nov 11, 2019 at 10:32
  • Yes that was my bad. Commented Nov 11, 2019 at 10:33

12 Answers 12

3

You can add click event to the buttons and based on the button clicked you can show or hide the respective div.

<!DOCTYPE html>
    <html>

      <head>
    <link rel="stylesheet" href="style.css">
    <script src="script.js"></script>

    <style>
      #btn1, #btn2 {
width:100px;height:20px;text-align:center;background:grey;cursor:pointer;margin:10px 0px;
}
#contents {
width: 200px;
height:200px;
border: 2px solid black;
}
#content1, #content2 {
width: 200px;
height:200px;
position:absolute;
background:lightblue;
display:none;
}
    </style>
  </head>

  <body>

    <script>
      function showDiv(div){

        if(div == 'btn1'){
          document.getElementById('content1').style.display = 'block';
          document.getElementById('content2').style.display = 'none';
        }else{
          document.getElementById('content1').style.display = 'none';
          document.getElementById('content2').style.display = 'block';
        }
      }
    </script>
    <div id="btn1" onclick="showDiv('btn1')">show1</div>
<div id="btn2" onclick="showDiv('btn2')">show2</div>


<div id="contents">
  <div id="content1">content 1</div>
  <div id="content2">content 2</div>
</div>
  </body>

Plunker For the same: https://plnkr.co/edit/brxoF2ClW2TeJOVMxn8d?p=preview

Sign up to request clarification or add additional context in comments.

Comments

2

Check this, i've made it dynamic so you can create unlimited buttons and contents.

function toogleContent(id){
  var toogleContent = document.getElementsByClassName('toogleContent');
  var i = toogleContent.length;
  while (i--) toogleContent[i].style.display = "none";
  document.getElementById(id).style.display = "block";
}
#btn1, #btn2 {
  width:100px;
  height:20px;
  text-align:center;
  background:grey;
  cursor:pointer;
  margin:10px 0px;
}
#contents {
  width: 200px;
  height:200px;
  border: 2px solid black;
}
#content1, #content2 {
  width: 200px;
  height:200px;
  position:absolute;
  background:lightblue;
  display:none;
}
<div id="btn1" class="toogleBtn" onclick="toogleContent('content1')">show1</div>
<div id="btn2" class="toogleBtn" onclick="toogleContent('content2')">show2</div>
<div id="contents">
  <div id="content1" class="toogleContent">content 1</div>
  <div id="content2" class="toogleContent">content 2</div>
</div>

Comments

2

Whilst the above answers are all correct insofar as they will get you from A to B (based on the code you have provided), there are also a few 'best practice' changes you should use in your code, to avoid common pitfalls (and allow better maintainability and code reuse).

Firstly, you should avoid using IDs for styling. Whilst using an ID to apply styles is perfectly valid to do (and won't break anything) it is discouraged. An ID for a page must always be unique within a document, so using it to style potentially multiple similar elements means that you will very quickly have either broken HTML (by reusing an ID) or unwieldy and non-maintainable stylesheets (by having multiple identical selectors). You should prefer using classes to add styles to elements, as you can reuse classes, and even extend or use multiple classes per element.

In my snippet, I have also used a dataset with a number in it to help identify which element is being 'selected'. Datasets are intended to store custom data, and are extremely useful for storing and retrieving data in JavaScript. By using a dataset to store an ID that is independent of the ID or class of an element, you can infinitely add/remove tabs without having to change your CSS or JavaScript to fit. After all, I can add in a dataset for an ID of 3 (e.g. <div class="button" data-id="3">) and the button styling won't be affected.

Other good practices include using separate class names or selectors for JavaScript compared to those used to style an element (again so that you can change the name of a JavaScript selector without affecting the look of an element - you can also prepend a JavaScript selector with js- as I have done, so that it is more obvious that the selector is used by JavaScript, and not used to style an element).

I have also used a BEM styleguide to name my classes (though this is a preference thing - in short though, it is good practice to pick and then use some sort of naming convention or style guide for naming/styling elements).

A final recommendation (not shown) <button> element instead of a <div> for buttons. This will improve your disability access for a website, as screen reader technology can then distinguish between what is a button and what is merely a block of content (after all, a screen reader might not pick up that the <div> has a click event handler added, and so a disabled user might not be aware they can click on the 'button' to switch tabs).

// Select all buttons using querySelectorAll
let buttons = document.querySelectorAll('.js-toggle');

// Loop through each button and add an event listener
Array.from(buttons).forEach(button => {
  // Click event listener
  button.addEventListener('click', function() {
     // Select all elements to hide/show
     let tab_contents = document.querySelectorAll('.js-content');
      
     // Hide all elements
     hideElems(tab_contents);
     
     // Get ID of button
     let id = this.dataset.id;
     
     // Select relevant tab using the ID above
     document.querySelector(`.js-content-${id}`).style.display = 'block';
  });
});

// Function for hiding all elements
let hideElems = (elems) => {
  Array.from(elems).forEach(elem => elem.style.display = 'none');
}
.button {
  width: 100px;
  height: 20px;
  text-align: center;
  background: grey;
  cursor: pointer;
  margin: 10px 0;
}

.tabs {
  width: 200px;
  height: 200px;
  border: 2px solid black;
}

.tabs__content {
  width: 200px;
  height: 200px;
  background: lightblue;
  display: none;
}
<div class="button js-toggle" data-id="1">show1</div>
<div class="button js-toggle" data-id="2">show2</div>

<div class="tabs">
  <div class="tabs__content js-content js-content-1">content 1</div>
  <div class="tabs__content js-content js-content-2">content 2</div>
</div>

Comments

1

document.getElementById('btn1').addEventListener('click', ()=>{
                document.getElementById('content2').style.display = "none";
                document.getElementById('content1').style.display = "block";
            });
    document.getElementById('btn2').addEventListener('click', ()=>{
                document.getElementById('content1').style.display = "none";
                document.getElementById('content2').style.display = "block";
            });
#btn1, #btn2 {
    width:100px;height:20px;text-align:center;background:grey;cursor:pointer;margin:10px 0px;
    }
    #contents {
    width: 200px;height:200px;border: 2px solid black;
    }
    #content1, #content2 {
    width: 200px;height:200px;position:absolute;background:lightblue;display:none;
    }
<div id="btn1">show1</div>
    <div id="btn2">show2</div>
    <div id="contents">
      <div id="content1">content 1</div>
      <div id="content2">content 2</div>
    </div>

Comments

1

You need onClick event and 2 conditions. Please check this,

function showContent(content_id) {

  if (content_id == 'content1') {
    document.getElementById('content1').style.display = 'block';
    document.getElementById('content2').style.display = 'none';
  } else if (content_id == 'content2') {
    document.getElementById('content1').style.display = 'none';
    document.getElementById('content2').style.display = 'block';
  }
  

}
#btn1, #btn2 {
width:100px;height:20px;text-align:center;background:grey;cursor:pointer;margin:10px 0px;
}
#contents {
width: 200px;height:200px;border: 2px solid black;
}
#content1, #content2 {
width: 200px;height:200px;position:absolute;background:lightblue; display:none;
}
<div id="btn1" onClick='showContent("content1")'>show1</div>
<div id="btn2" onClick='showContent("content2")'>show2</div>
<div id="contents">
  <div id="content1">content 1</div>
  <div id="content2">content 2</div>
</div>

Comments

1

This is a simple way to do it with vanilla javascript, just add a method that hides/shows the element based on which button you click

function toogle(showelem, hideelem) {
      document.getElementById(showelem).style.display = "block";
      document.getElementById(hideelem).style.display = "none";
    }
#btn1, #btn2 {
width:100px;height:20px;text-align:center;background:grey;cursor:pointer;margin:10px 0px;
}
#contents {
width: 200px;height:200px;border: 2px solid black;
}
#content1, #content2 {
width: 200px;height:200px;position:absolute;background:lightblue;
}
<div id="btn1" onClick="toogle('content1','content2');">show1</div>
<div id="btn2" onClick="toogle('content2','content1');">show2</div>
<div id="contents">
  <div id="content1">content 1</div>
  <div id="content2">content 2</div>
</div>

Comments

1

function myFunction() {
  var element = document.getElementById("myDIV");
  element.classList.remove("displayblock");
}
function myFunctionShow(){
  var element = document.getElementById("myDIV");
  element.classList.add("displayblock");
}
.mystyle {
  width: 100%;
  padding: 25px;
  background-color: coral;
  color: white;
  display:none;
}
.displayblock{
  display:block;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>

<p>Click the "Try it" button to remove the "mystyle" class from the DIV element:</p>

<button onclick="myFunction()">Hide</button>

<button onclick="myFunctionShow()">Show</button>

<div id="myDIV" class="mystyle displayblock">
This is a DIV element.
</div>



</body>
</html>

Comments

1

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        #btn1,
        #btn2 {
            width: 100px;
            height: 20px;
            text-align: center;
            background: grey;
            cursor: pointer;
            margin: 10px 0px;
        }

        #contents {
            width: 200px;
            height: 200px;
            border: 2px solid black;
        }

        #content1,
        #content2 {
            width: 200px;
            height: 200px;
            position: absolute;
            background: lightblue;
        }
    </style>
</head>

<body>

    <div id="btn1" onclick="showdiv1()">show1</div>
    <div id="btn2" onclick="showdiv2()">show2</div>
    <div id="contents">
        <div id="content1">content 1</div>
        <div id="content2">content 2</div>
    </div>
</body>

<script>
   function showdiv1(){
       console.log( document.getElementById('content1'))
        document.getElementById('content1').style.display='block';
        document.getElementById('content2').style.display='none';
    }

    function showdiv2(){
        document.getElementById('content1').style.display='none';
        document.getElementById('content2').style.display='block';
    }
</script>

</html>

Here We Go

You can you this for any element to hide and show

element.style.display = 'none';           // Hide
element.style.display = 'block';          // Show
element.style.display = 'inline';         // Show
element.style.display = 'inline-block';   // Show

Comments

0

If I understand you right, you should set "display: none" by default and then handle click on button to toggle "open" class. See example below.

const btn1 = document.getElementById("btn1"),
	  btn2 = document.getElementById("btn2"),
	  content1 = document.getElementById("content1"),
	  content2 = document.getElementById("content2");

const map = new Map()
	.set(btn1, content1)
        .set(btn2, content2);

const closeMapContent = _ => 
  map.forEach((value, key) => value.classList.remove("open"));

map.forEach((value, key) => {
	key.addEventListener("click", event => {
  	closeMapContent();
  	value.classList.add("open");
  })
});
#btn1, #btn2 {
  width: 100px;
  height: 20px;
  text-align: center;
  background: grey;
  cursor: pointer;
  margin: 10px 0px;
}
#contents {
  width: 200px;
  height: 200px;
  border: 2px solid black;
}
#content1, #content2 {
  width: 200px;
  height: 200px;
  position: absolute;
  background: lightblue;
  display: none;
}

.open {
  display: block !important;
}
<div id="btn1">show1</div>
<div id="btn2">show2</div>
<div id="contents">
  <div id="content1">content 1</div>
  <div id="content2">content 2</div>
</div>

Comments

0

function show() {
          const h = document.getElementById('hidden1');
          h.style.display = 'block' ;
          const s =document.getElementById('showed');
          s.style.display = 'none';
        }
        function hide() {
            const h = document.getElementById('hidden1');
            h.style.display = 'none' ;
            const s =document.getElementById('showed');
            s.style.display = 'block';
        }
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
<div >
      <button id="showed"  onclick="show()" >click to show</button>
      <div id="hidden1" style="display: none">
          <button  onclick="hide()" >click to close</button>
          <h1 >Content1</h1>
      </div>

  </div>
</body>
</html>

see with snippet

Comments

0

Another way to approach this is to use data-* attribute with little bit of styling. You can change the attribute of the parent div then the changes are reflected on children using CSS.

Also, you don't need to loops through elements if know the number of children elements.

See this example:

function toogleContent(target) {
  document.querySelector("#contents").setAttribute("data-show", target);
}
#btn1,
#btn2 {
  width: 100px;
  height: 20px;
  text-align: center;
  background: grey;
  cursor: pointer;
  margin: 10px 0px;
}

#contents {
  width: 200px;
  height: 200px;
  border: 2px solid black;
}

#content1,
#content2 {
  width: 200px;
  height: 200px;
  position: absolute;
  background: lightblue;
  opacity: 0;
}

#contents[data-show='1']>#content1 {
  opacity: 1;
}

#contents[data-show='2']>#content2 {
  opacity: 1;
}
<div id="btn1" onclick="toogleContent(1)">show1</div>
<div id="btn2" onclick="toogleContent(2)">show2</div>
<div id="contents" data-show=''>
  <div id="content1">content 1</div>
  <div id="content2">content 2</div>
</div>

Comments

0

https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes

(function() {
  const buttons = document.querySelectorAll('.button');
  const content = document.querySelector('.content__wrapper');

  hideAll();
  setUpClickHandlers();

  function hide(element) {
    element.classList.add('hide');
  }

  function show(element) {
    element.classList.remove('hide')
  }

  function hideAll() {
    Array.from(content.children).forEach(hide);
  }

  function toggle(element) {
    hideAll();
    show(element)
  }

  function onClick(content) {
    return () => toggle(content)
  }

  function setUpClickHandlers() {
    const handler = element => {
      const show = content.querySelector(`.${element.dataset.for}`);
      element.addEventListener('click', onClick(show));
    };

    Array.from(buttons).forEach(handler);
  }
})()
.hide {
  display: none
}

.button {
  height: 30px;
  line-height: 30px;
  border-radius: 5px;
  border: 1px solid grey;
  padding: 0 10px;
  display: inline-block;
  margin: 10px 0;
  cursor: pointer;
}

.content__wrapper {
  background-color: aqua;
  padding: 16px;
}
<button class="button" data-for="content_1">content 1</button>
<button class="button" data-for="content_2">content 2</button>
<button class="button" data-for="content_3">content 3</button>
<button class="button" data-for="content_4">content 4</button>


<div class="content__wrapper">
  <div class="content content_1">Content 1</div>
  <div class="content content_2">Content 2</div>
  <div class="content content_3">Content 3</div>
  <div class="content content_4">Content 4</div>
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.