如果在外部单击,如何自行关闭手风琴

时间:2019-10-02 17:43:39

标签: javascript

我构造了一种手风琴,它可以正常工作,但是如果有人在JavaScript中的元素之外单击,我想关闭它

我试图添加一个点击侦听器,该点击侦听器捕获div外部的点击并关闭其显示,但是它不起作用,因为它将链接本身视为div链接的外部,因此停止打开div

function toggleaccordition() {
  var link = document.getElementById('acrd_link');
  var accrdion = document.getElementById("acc");
  link.classList.toggle('active');
  accrdion.classList.toggle('active');
}
nav ul {
  display: flex;
}

nav ul li {
  display: block;
  margin-right: 20px;
  margin-left: 2px;
  list-style: none;
  text-decoration: none;
}

nav ul li a {
  text-decoration: none;
}

#acrd_link.active {
  text-decoration: underline;
  color: deepskyblue;
}

.accrd {
  display: block;
  height: 0px;
  width: 450px;
  color: blue;
  opacity: 0.0;
  transition: opacity 0.5s;
  transition: height 0.5s;
  padding-top: 30px;
  position: relative;
  z-index: 4;
  background: #ff0036;
}

.internal {
  background: gray;
}

.internal span {
  color: yellow;
}

.accrd>* {
  display: none;
}

.accrd.active {
  display: block height: 500px;
  opacity: 1.0;
  transition: height 1s;
  transition: opacity 1s;
}

.accrd.active>* {
  display: block;
}
<nav>
  <ul>
    <li><a href="#">xxxxxxx</a></li>
    <li><a href="#" id="acrd_link" onclick="toggleaccordition()">Click two open/close accordion</a></li>
    <li><a href="#">yyyyyyyy</a></li>
  </ul>
</nav>
<div class="accrd" id="acc">
  <div class="internal">
    This is my accordion that works fine.<span>I just want this to be closed when i click outside this accrdion<span></div>
</div>

1 个答案:

答案 0 :(得分:3)

只需在确认不是您单击的手风琴之后,在document上添加一个事件侦听器即可关闭手风琴。

此外,在单击超链接时不要使用超链接将不会导致导航-从语义上讲这是不正确的,并且会干扰屏幕阅读器。只需将click事件应用于您喜欢的任何其他元素。

最后,请勿使用HTML内联处理事件处理(onclick)。 Here's why.用JavaScript进行所有事件绑定。

// Set up DOM element references outside of callbacks so you only
// go get the references one time, not every time the callback runs.
var link = document.getElementById('acrd_link');
var accordion = document.getElementById("acc");
var internal = document.querySelector(".internal");

link.addEventListener("click", toggleaccordition);

function toggleaccordition() {
  link.classList.toggle('active');
  accordion.classList.toggle('active');
}


// Set up handler for clicks that occur outside of the accordion
document.addEventListener("click", closeaccordition);

function closeaccordition(event) {
  // Since accordion is part of the document, we need to make
  // sure this click didn't originate with the accordion.
  if(event.target !== link && event.target !== accordion && event.target !== internal){
    link.classList.remove('active');
    accordion.classList.remove('active');
  }
}
nav ul {
  display: flex;
}

nav ul li {
  display: block;
  margin-right: 20px;
  margin-left: 2px;
  list-style: none;
  text-decoration: none;
  cursor:pointer;
}

#acrd_link.active {
  text-decoration: underline;
  color: deepskyblue;
}

.accrd {
  display: block;
  height: 0px;
  width: 450px;
  color: blue;
  opacity: 0.0;
  transition: opacity 0.5s;
  transition: height 0.5s;
  padding-top: 30px;
  position: relative;
  z-index: 4;
  background: #ff0036;
}

.internal {
  background: gray;
}

.internal span {
  color: yellow;
}

.accrd>* {
  display: none;
}

.accrd.active {
  display: block height: 500px;
  opacity: 1.0;
  transition: height 1s;
  transition: opacity 1s;
}

.accrd.active>* {
  display: block;
}
<nav>
  <ul>
    <li>xxxxxxx</li>
    <li id="acrd_link">Click two open/close accordion</li>
    <li>yyyyyyyy</li>
  </ul>
</nav>
<div class="accrd" id="acc">
  <div class="internal">
    This is my accordion that works fine.<span>I just want this to be closed when i click outside this accrdion</span>
   </div>
</div>