Javascript 二次点击后才码字

Javascript Code Words Only After Second Click

我正在尝试在我的网页中使用手风琴菜单。它应该在单击时一次只显示一个面板,并且必须使用 onclick 函数调用 js 代码。当我在 html 中的脚本标签之间添加 js 代码时一切正常,但我需要使用 onclick 并改为从外部 .js 文件调用脚本。但是,当我这样做时,代码星标仅在第二次单击后才起作用。如何解决? (没有jquery)

注意: 必须在 html.

<head> 部分调用 JS 文件

HTML:

<button class="course-accordion" onclick="openaccordion()">Title 1</button>
<div class="course-panel">Text 1</div>
<button class="course-accordion" onclick="openaccordion()">Title 2</button>
<div class="course-panel">Text 2</div>
<button class="course-accordion" onclick="openaccordion()">Title 3</button>
<div class="course-panel">Text 3</div>

CSS:

button.course-accordion {
    background-color: transparent;
    color: white;
    cursor: pointer;
    padding: 8px;
    width: 100%;
    border: none;
    text-align: left;
    outline: none;
    font-size: 22px;
    font-weight: 600;
    transition: 0.4s;
    font-family: "Raleway";
    line-height: 1.5em;
    text-transform: none;
    letter-spacing: 0px;
    font-weight: 600;
    font-style: normal;
}
/*When the button is active or mouse hovers*/
button.course-accordion.active, button.course-accordion:hover {
    background-color: rgba(166,166,166,0.6);
}
/*button not active*/
button.course-accordion:after {
    content: '[=12=]2B';
    color: white;
    font-weight: bold;
    float: right;
    margin-left: 5px;
}
/* minus button */
button.course-accordion.active:after {
    content: "12";
}
div.course-panel {
    padding: 0 18px;
    background-color: transparent;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.2s ease-out;
    width: 96%;
    font-family: "Raleway";
    font-size: 15px;
    line-height: 1.6em;
    letter-spacing: .4px;
    font-weight: 400;
    font-style: normal;
    color: rgba(0,0,0,.88);
}

JAVASCRIPT:

    function openaccordion() {
        //this is the button
        var acc = document.getElementsByClassName("course-accordion");
        var i;
        for (i = 0; i < acc.length; i++) {
            //when one of the buttons are clicked run this function
          acc[i].onclick = function() {
            //variables
            var panel = this.nextElementSibling;
            var coursePanel = document.getElementsByClassName("course-panel");
            var courseAccordion = document.getElementsByClassName("course-accordion");
            var courseAccordionActive = document.getElementsByClassName("course-accordion active");

            /*if pannel is already open - minimize*/
            if (panel.style.maxHeight){
                //minifies current pannel if already open
                panel.style.maxHeight = null;
                //removes the 'active' class as toggle didnt work on browsers minus chrome
                this.classList.remove("active");
            } else { //pannel isnt open...
                //goes through the buttons and removes the 'active' css (+ and -)
                for (var ii = 0; ii < courseAccordionActive.length; ii++) {
                    courseAccordionActive[ii].classList.remove("active");
                }
                //Goes through and removes 'activ' from the css, also minifies any 'panels' that might be open
                for (var iii = 0; iii < coursePanel.length; iii++) {
                  this.classList.remove("active");
                  coursePanel[iii].style.maxHeight = null;
                }
              //opens the specified pannel
              panel.style.maxHeight = panel.scrollHeight + "px";
              //adds the 'active' addition to the css.
              this.classList.add("active");
            } 
          }//closing to the acc onclick function
        }//closing to the for loop.
    }

删除 onclick 事件,在加载时调用函数本身。

您在单击每个按钮时调用 openaccordion 函数。 openaccordion 正在注册每个按钮的 onclick 事件。第一次单击按钮时,您将遍历按钮并为所有三个按钮注册 onclick 事件。现在所需的操作已注册,但仅在第一次单击按钮后才注册。从下一次开始,按钮将按预期运行,这是因为在 openaccordion 函数中编写了 onclick 侦听器。但是当您再次单击其中一个按钮时,每个按钮的单击事件将再次注册。这不是必需的。

实际上您的 openaccordion 函数正在注册三个按钮的点击事件。这不需要在每次单击按钮时调用,仅在加载文档时调用一次。

工作 fiddle:我已将函数名称 openaccordion 更新为 registeraccordionEvents,因为这是功能的更通用名称。

function registeraccordionEvents() {
  //this is the button
  var acc = document.getElementsByClassName("course-accordion");
  var i;
  for (i = 0; i < acc.length; i++) {
    //when one of the buttons are clicked run this function
    acc[i].onclick = function () {
      //variables
      var panel = this.nextElementSibling;
      var coursePanel = document.getElementsByClassName("course-panel");
      var courseAccordion = document.getElementsByClassName("course-accordion");
      var courseAccordionActive = document.getElementsByClassName("course-accordion active");

      /*if pannel is already open - minimize*/
      if (panel.style.maxHeight) {
        //minifies current pannel if already open
        panel.style.maxHeight = null;
        //removes the 'active' class as toggle didnt work on browsers minus chrome
        this.classList.remove("active");
      } else { //pannel isnt open...
        //goes through the buttons and removes the 'active' css (+ and -)
        for (var ii = 0; ii < courseAccordionActive.length; ii++) {
          courseAccordionActive[ii].classList.remove("active");
        }
        //Goes through and removes 'activ' from the css, also minifies any 'panels' that might be open
        for (var iii = 0; iii < coursePanel.length; iii++) {
          this.classList.remove("active");
          coursePanel[iii].style.maxHeight = null;
        }
        //opens the specified pannel
        panel.style.maxHeight = panel.scrollHeight + "px";
        //adds the 'active' addition to the css.
        this.classList.add("active");
      }
    }//closing to the acc onclick function
  }//closing to the for loop.
}
registeraccordionEvents();
button.course-accordion {
  background-color: transparent;
  color: white;
  cursor: pointer;
  padding: 8px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 22px;
  font-weight: 600;
  transition: 0.4s;
  font-family: "Raleway";
  line-height: 1.5em;
  text-transform: none;
  letter-spacing: 0px;
  font-weight: 600;
  font-style: normal;
}

/*When the button is active or mouse hovers*/
button.course-accordion.active,
button.course-accordion:hover {
  background-color: rgba(166, 166, 166, 0.6);
}

/*button not active*/
button.course-accordion:after {
  content: '[=11=]2B';
  color: white;
  font-weight: bold;
  float: right;
  margin-left: 5px;
}

/* minus button */
button.course-accordion.active:after {
  content: "12";
}

div.course-panel {
  padding: 0 18px;
  background-color: transparent;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.2s ease-out;
  width: 96%;
  font-family: "Raleway";
  font-size: 15px;
  line-height: 1.6em;
  letter-spacing: .4px;
  font-weight: 400;
  font-style: normal;
  color: rgba(0, 0, 0, .88);
}
<button class="course-accordion">Title 1</button>
<div class="course-panel">Text 1</div>
<button class="course-accordion">Title 2</button>
<div class="course-panel">Text 2</div>
<button class="course-accordion">Title 3</button>
<div class="course-panel">Text 3</div>

包括 head 部分中的 script

在上面的示例中,Whosebug fiddle 在正文部分下方添加了脚本。但是,如果您在正文上方的头部部分添加相同的脚本,该应用程序将无法运行。 为什么? 因为在函数内部,我们正在使用 document.getElementsByClassName("course-accordion") 访问您的 course-accordionhead 部分在主体加载之前被调用。这使得 return 的选择器成为一个长度为 0 的列表。因为在脚本执行时,DOM 中不会没有这样的元素,因为主体将在脚本之后加载,当我们在正文顶部添加脚本。为避免这种情况,可以将函数调用 registeraccordionEvents 移至 body 的 body onload 事件。此时 DOM 个元素将可用。

工作Fiddle

button.course-accordion {
  background-color: transparent;
  color: white;
  cursor: pointer;
  padding: 8px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 22px;
  font-weight: 600;
  transition: 0.4s;
  font-family: "Raleway";
  line-height: 1.5em;
  text-transform: none;
  letter-spacing: 0px;
  font-weight: 600;
  font-style: normal;
}

/*When the button is active or mouse hovers*/
button.course-accordion.active,
button.course-accordion:hover {
  background-color: rgba(166, 166, 166, 0.6);
}

/*button not active*/
button.course-accordion:after {
  content: '[=11=]2B';
  color: white;
  font-weight: bold;
  float: right;
  margin-left: 5px;
}

/* minus button */
button.course-accordion.active:after {
  content: "12";
}

div.course-panel {
  padding: 0 18px;
  background-color: transparent;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.2s ease-out;
  width: 96%;
  font-family: "Raleway";
  font-size: 15px;
  line-height: 1.6em;
  letter-spacing: .4px;
  font-weight: 400;
  font-style: normal;
  color: rgba(0, 0, 0, .88);
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script>
    function registeraccordionEvents() {
      //this is the button
      var acc = document.getElementsByClassName("course-accordion");
      var i;
      for (i = 0; i < acc.length; i++) {
        //when one of the buttons are clicked run this function
        acc[i].onclick = function () {
          //variables
          var panel = this.nextElementSibling;
          var coursePanel = document.getElementsByClassName("course-panel");
          var courseAccordion = document.getElementsByClassName("course-accordion");
          var courseAccordionActive = document.getElementsByClassName("course-accordion active");

          /*if pannel is already open - minimize*/
          if (panel.style.maxHeight) {
            //minifies current pannel if already open
            panel.style.maxHeight = null;
            //removes the 'active' class as toggle didnt work on browsers minus chrome
            this.classList.remove("active");
          } else { //pannel isnt open...
            //goes through the buttons and removes the 'active' css (+ and -)
            for (var ii = 0; ii < courseAccordionActive.length; ii++) {
              courseAccordionActive[ii].classList.remove("active");
            }
            //Goes through and removes 'activ' from the css, also minifies any 'panels' that might be open
            for (var iii = 0; iii < coursePanel.length; iii++) {
              this.classList.remove("active");
              coursePanel[iii].style.maxHeight = null;
            }
            //opens the specified pannel
            panel.style.maxHeight = panel.scrollHeight + "px";
            //adds the 'active' addition to the css.
            this.classList.add("active");
          }
        }//closing to the acc onclick function
      }//closing to the for loop.
    }
    // registeraccordionEvents();
  </script>
</head>
<body onload="registeraccordionEvents()">
  <button class="course-accordion">Title 1</button>
  <div class="course-panel">Text 1</div>
  <button class="course-accordion">Title 2</button>
  <div class="course-panel">Text 2</div>
  <button class="course-accordion">Title 3</button>
  <div class="course-panel">Text 3</div>
</body>
</html>

此脚本也可以移动到外部文件。请确保函数 registeraccordionEventsbody onload 期间被调用。这次您的选择器 document.getElementsByClassName("course-accordion") 将 return 3 个节点。