0

Have a problem and can't get to solve it. Tried to use QuerySelectorAll and comma separating with GetElementsByClassName, but that didn't work, so I am wondering how to solve this problem.

I have this HTML:

<div class="area">Test title
  <div class="some content" style="display: none">blablbala
    <input></input>
  </div>
  <div class="two">This should be clickable too</div>
</div>

<div class="area">
  Test title
  <div class="some content">
    blablbala
    <input></input>
  </div>
  <div class="two">This should be clickable too</div>
</div>

JS:

function areaCollapse() {
  var next = this.querySelector(".content");

  if (this.classList.contains("open")) {
    next.style.display = "none";
    this.classList.remove("open");
  } else {
    next.style.display = "block";
    this.classList.add("open");
  }
}

var classname = document.getElementsByClassName("area");

for (var i = 0; i < classname.length; i++) {
  classname[i].addEventListener('click', areaCollapse, true);
}

http://jsfiddle.net/1BJK903/nb1ao39k/6/

CSS:

.two {
position: absolute;
top: 0;
}

So now, the div with classname "area" is clickable. I positioned the div with class "two" absolute and now the whole div is clickable, except where this other div is. If you click on the div with classname "two", it doesn't work (it does not collapse or open the contents). How can I make this work, without changing the structure?

4
  • Your fiddle doesn't match the question. Also, use a snippet, not a jsfiddle. Commented Oct 9, 2015 at 6:25
  • @Siyah which div you want to clickable.? Commented Oct 9, 2015 at 6:50
  • Updated my answer though I have a question: Should the div some content as well hide itself or is it only the area and the two div's that should do that? Commented Oct 9, 2015 at 7:22
  • @Siyah be clear with your expectation Commented Oct 9, 2015 at 8:36

3 Answers 3

1

One way is using a global handler, where you can handle more than one item by checking its id or class or some other property or attribute.

Below snippet finds the "area" div and pass it as a param to the areaCollapse function. It also check so it is only the two or the area div (colored lime/yellow) that was clicked before calling the areaCollapse.

Also the original code didn't have the "open" class already added to it (the second div group), which mean one need to click twice, so I change the areaCollapse function to check for the display property instead.

function areaCollapse(elem) {
  
  var next = elem.querySelector(".content");
  
  if (next.style.display != "none") {
    next.style.display = "none";
  } else {
    next.style.display = "block";
  }

}  

window.addEventListener('click', function(e) {
  
    //temp alert to check which element were clicked
    //alert(e.target.className);
            
        if (hasClass(e.target,"area")) {
          
            areaCollapse(e.target);

        } else {
          
          //delete next line if all children are clickable
          if (hasClass(e.target,"two")) {
            
            var el = e.target;
          
            while ((el = el.parentElement) && !hasClass(el,"area"));
          
            if (targetInParent(e.target,el)) {
            
              areaCollapse(el);
            
            }
                      
          //delete next line if all children are clickable
          }
            
        }
  
    });


function hasClass(elm,cln) {
     return (" " + elm.className + " " ).indexOf( " "+cln+" " ) > -1;
}

function targetInParent(trg,pnt) {
  return (trg === pnt) ? false : pnt.contains(trg);
}
.area {
  background-color: lime;
}
.two {
  background-color: yellow;
}

.area:hover, .two:hover {
  background-color: green;
}

.some {
  background-color: white;
}
.some:hover {
  background-color: white;
}
<div class="area">Test title clickable 1
           <div class="some content" style="display: none">blablbala NOT clickable 1
           </div>
<div class="two">This should be clickable too 1</div>
        </div>

    <div class="area">Test title clickable 2
           <div class="some content">blablbala NOT clickable 2
           </div>
<div class="two">This should be clickable too 2</div>
        </div>

<div class="other">This should NOT be clickable</div>

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

1 Comment

Just updated my answer with some colors to show which is clickable and which is not, so we talk about the same clickable div's ... tried this on the newest version of Chrome/IE/Edge/FF with success
0

You need to find your two elements while you're binding classname, and bind that as well.

var classname = document.getElementsByClassName("area");
for(var i=0; i < classname.length; i++){
    classname[i].addEventListener('click', areaCollapse, true);
    var twoEl = classname[i].getElementsByClassName("two")[0];
    twoEl.addEventListener('click', function(e) { console.log('two clicked'); });
}

2 Comments

This is a nice one, but it just logs the click. It doesn't actually open the contents... so it does not open or collapse.
Your question was how to make a div clickable. I answered.
0

If you want to use jQuery:

 $('.two').click(function(){
       //action here
    });

2 Comments

He doesn't use jQuery
Don't want to use jQuery.

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.