Siyah
Siyah

Reputation: 2897

Make div in div clickable with Javascript

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?

Upvotes: 0

Views: 526

Answers (3)

Asons
Asons

Reputation: 87191

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>

Upvotes: 1

Mr.Nimelo
Mr.Nimelo

Reputation: 332

If you want to use jQuery:

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

Upvotes: 0

Artless
Artless

Reputation: 4568

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'); });
}

Upvotes: 0

Related Questions