0

I limited click event to :after pseudo-element using click-event:auto and created a span to bind an event inside the parent element. Why the span does not work?

function toggle(){
  var button=document.querySelector('.toggle');
  var bar=document.querySelector('.slide');
  if(bar.className==='slide up'){
    bar.className='slide down';
  }else{
    bar.className='slide up';
   }
}

function click(){
  document.body.innerHTML+='<div>Hello</div>';
}
span{
  position:relative;
  top:90px;
  background:green;
  cursor:pointer;
  pointer-event:auto;
}
*{
  margin:0px;
  padding:0px;
  height:100%;
  width:100%;
}
.box{
  overflow:hidden;
  background-image: url('http://tombricker.smugmug.com/Travel/San-Francisco-California/i-jk2Z7D7/0/L/san-francisco-golden-gate-bridge-morning-sun-bricker-L.jpg');
  background-size: cover;
  background-position:center;
}
.slide{
  position: relative;
  left:39vw;
  
  width: 55vw;
  height: 77vh;
  background: red;
  pointer-events:none;
  
}
.slide:before {
  pointer-events:auto;
  cursor:pointer;
  content: '';
  position:absolute;
  top:-3vh;
  width: 0px;
  height: 0px;
  
  border-left:27.5vw solid transparent;
  border-right:27.5vw solid transparent;
  
  border-bottom:3vh solid white;  
}
.slide.down{
 transform:translateY(100vh);
}
.slide.up{
  transform:translateY(23vh);
}
.slide.up:before{
  transform:translateY(3vh) rotateX(180deg);
}
.slide{
  transition:transform 0.4s ease-out;
}
<div class='box'>
  <div class='slide up' onclick='toggle()'><span onclick='click()'>Hello</span></div>
</div>

The white triangle is .slide:before. I use click-event:auto; on it. I am NOT sure if I should use AUTO or ALL. Then I use click-event: none; on .slide class, which is the red rectangle below it. So now, I cannot click on the red rectangle just the white triangle to make it slide up and down. But I do still want to click on part of the red rectangle to do other things(not sliding necessarily).So I added a span(green Hello) inside the div that is the rectangle+the triangle. I then write the JS code so that if the green Hello is clicked, a div will Hello will be added to the body of the HTML. But it does NOT work.

I learned this span method here, but I dont quite understand it.

Randy Hall
  • 7,716
  • 16
  • 73
  • 151

1 Answers1

1

A few things:

  • Avoid events on pseudo-elements
  • Don't add elements by reassigning the entire body innerHtml - you lose all event bindings on all elements
  • Try to avoid putting JavaScript in your HTML

//listen for click event on toggle element
document.querySelector(".toggler").addEventListener("click", function(){
  this.parentElement.classList.toggle("up");
});

//listen for click event on hello
document.querySelector(".clicker").addEventListener("click", function(){
  var div = document.createElement("div");
  var text = document.createTextNode("Hello");
  div.appendChild(text);
  document.body.appendChild(div);
});
html, body{
  height:100%;
}
*{
  margin:0px;
  padding:0px;
}
.clicker{
  position:relative;
  top:90px;
  background:green;
  cursor:pointer;
}
.box{
  overflow:hidden;
  background-image: url('http://tombricker.smugmug.com/Travel/San-Francisco-California/i-jk2Z7D7/0/L/san-francisco-golden-gate-bridge-morning-sun-bricker-L.jpg');
  background-size: cover;
  background-position:center;
  height:100%;
  width:100%;
}
.slide{
  position: relative;
  left:39vw;
  width: 55vw;
  height: 77vh;
  background: red;
  transform:translateY(100vh);
  transition:transform 0.4s ease-out;
}
.slide.up{
  transform:translateY(23vh);
}
.toggler {
  cursor:pointer;
  content: '';
  position:absolute;
  top:-3vh;
  width: 0px;
  height: 0px;
  border-left:27.5vw solid transparent;
  border-right:27.5vw solid transparent;
  border-bottom:3vh solid white;
}
.slide.up .toggler{
  transform:translateY(3vh) rotateX(180deg);
}
<div class='box'>
  <div class='slide up'>
    <span class='toggler'></span>
    <span class='clicker'>Hello</span>
  </div>
</div>

Even better:

This effect can be done completely without JavaScript. Use sibling selectors, a label, and a checkbox instead. See working demo here

Randy Hall
  • 7,716
  • 16
  • 73
  • 151
  • Oh. I revised it. But still now I can see the cursor changing to pointer but no div added anywhere – most venerable sir Jul 10 '17 at 18:51
  • @user132522 Working on it... this seems a strange way to implement. I'm going to give you a better work around. – Randy Hall Jul 10 '17 at 18:54
  • @user132522 updated. I think this is what you're trying to do. – Randy Hall Jul 10 '17 at 19:21
  • @user132522 Also added a workaround that doesn't require javascript for your slider – Randy Hall Jul 10 '17 at 19:31
  • I noticed a problem. I even had it in my original code is whenever you add a div to the HTML the red rectangle would get pushed down. I dont know how I relatively position everything. – most venerable sir Jul 10 '17 at 23:23
  • 1
    @user132522 You should accept this answer as it fixes your original issue. As for the positioning, open a new question and link it here, I'll look and try to answer it. Try to stick to one issue per question if you can – Randy Hall Jul 11 '17 at 15:06
  • Is it irresponsible of me to post 60 lines of code on SO? Nobody will look through them. I will try to rebuild it to see if the problem goes away – most venerable sir Jul 11 '17 at 19:54
  • @user132522 So long as your snippet is well-formed and demonstrates what you're asking, it's irresponsible NOT to post it. It's far easier for people to debug your example then to try and guess what's going on – Randy Hall Jul 11 '17 at 19:55
  • Why do you add the 'event' parameter for the function inside the first event listener but not the second? – most venerable sir Jul 14 '17 at 14:36
  • 1
    @user132522 Habit. You don't need either one since you're not using it in your callback – Randy Hall Jul 14 '17 at 16:47