Javascript touchevent 上的菜单下拉菜单(点击)

Javascript menu dropdown on touchevent (tap)

我正在尝试创建我的网站的响应版本,对于移动版本,我正在尝试添加一个事件,其中用户点击菜单项,列表下拉,当他们再次点击它时, 它关闭备份。我正在使用香草 javascript touchstart 和 touchend 事件,我开始认为这不是执行此操作的最佳方式,一旦我将手指从菜单项上移开,菜单就会崩溃。

请指导我实现此目标的最佳方法!

HTML

<ul class="mainnav">
  <li class="productstouch">
    <a href="#"><p>Products</p></a>

    <ul class="navlvl2">
      <li class="item">
        <a href="#"><p>Sensors</p></a>

        <ul class="navlvl3">
          <li>
            <a href="#"><p>Proximity Sesnors</p></a>
          </li>
          <li>
            <a href="#"><p>Magnetic Sensors</p></a>
          </li>
          <li>
            <a href="#"><p>Photoelectric Sensors</p></a>
          </li>
        </ul>
      </li>
      <li class="item">
        <a href="#"><p>Controllers</p></a>
      </li>
      <li class="item">
        <a href="#"><p>Motion Devices</p></a>
      </li>
    </ul>
  </li>
  <li>
    <a href="#"><p>Home</p></a>
  </li>
  <li>
    <a href="#"><p>Manufacturers</p></a>
  </li>
</ul>

JS

function watchForHover() {
  let lastTouchTime = 0

  let it = document.getElementsByClassName("mainnav")
  let her = document.getElementsByClassName("navlvl2")
  let him = document.getElementsByClassName("navlvl3")

  function enableHover() {
    if (new Date() - lastTouchTime < 500) return

    for (let i = 0; i < it.length; i++) {
      it[i].classList.add("hasHover")
    }

    for (let c = 0; c < her.length; c++) {
      her[c].classList.add("hasHover")
    }

    for (let d = 0; d < him.length; d++) {
      him[d].classList.add("hasHover")
    }
  }

  function disableHover() {
    for (var i = 0; i < it.length; i++) {
      it[i].classList.remove("hasHover")
    }
    for (let c = 0; c < her.length; c++) {
      her[c].classList.remove("hasHover")
    }

    for (let d = 0; d < him.length; d++) {
      him[d].classList.remove("hasHover")
    }
  }

  function updateLastTouchTime() {
    lastTouchTime = new Date()
  }

  document.addEventListener("touchstart", updateLastTouchTime, true)
  document.addEventListener("touchstart", disableHover, true)
  document.addEventListener("mousemove", enableHover, true)

  enableHover()
}

watchForHover()

//--------------------End of Watch for Hover------------------------------//

function registerTouch() {
  let mobileLevelZeroItems = document.getElementsByClassName("mainnav")

  for (let i = 0; i < mobileLevelZeroItems.length; i++) {
    let Zerochild = mobileLevelZeroItems[i]

    //mobileLevelZeroItems.onclick = mobileLevelZeroItems.classList.add('onTouch')  ;

    Zerochild.addEventListener("touchstart", function () {
      mobileLevelZeroItems[i].classList.add("onTouch")
    })

    Zerochild.addEventListener("touchend", function () {
      mobileLevelZeroItems[i].classList.remove("onTouch")
    })
  }
}

registerTouch()

CSS

.mainnav {
  display: block;
  list-style: none;
  text-align: center;
  width: 100vw;
  margin: 0;
  padding: 0;
}

.mainnav > li {
  background-color: #1a6baa;
}

.mainnav > li > a {
  text-decoration: none;
  color: white;
}

.navlvl3 {
  display: none;
}

.mainnav > li > ul {
  display: none;
}

.mainnav.onTouch > li > ul {
  display: grid;
}

/*----------------------Beginning of .hasHover classes-------------------------------*/

.mainnav.hasHover {
  display: flex;
  list-style: none;
  background-color: lightblue;
  margin: 0;
  padding: 0;
  position: relative;
}

.mainnav.hasHover > li {
  background-color: lightblue;
  padding: 10px 30px 10px 30px;
  margin: 0;
}

.mainnav.hasHover > li > a > p:hover {
  color: green;
}

.mainnav.hasHover > li > a {
  text-decoration: none;
  margin: 0;
  padding: 0;
  color: black;
}

.mainnav.hasHover > li:hover .navlvl2.hasHover {
  visibility: visible;
  display: block;
  top: 100%;
  left: 0;
  margin: 0;
  padding: 0;
}

.mainnav.hasHover > li > a > p {
  margin: 0;
  font-size: 20px;
}

.navlvl2.hasHover {
  visibility: hidden;
  display: flex;
  position: absolute;
  background-color: lightgray;
  margin: 0;
}

.navlvl2.hasHover > li {
  margin: 0;
  padding: 15px;
  list-style: none;
}

.mainnav.hasHover > li:hover {
  background-color: pink;
}

.navlvl2.hasHover > li > a > p {
  margin: 0;
  padding: 0;
}

.navlvl2.hasHover > li:hover {
  background-color: lightgreen;
  color: white;
}

.navlvl3.hasHover {
  display: none;
  position: absolute;
  background-color: teal;
}

.navlvl3.hasHover > li {
  list-style: none;
}

.navlvl2.hasHover > li:hover .navlvl3.hasHover {
  display: block;
  top: 0;
  left: 100%;
}

我认为你把事情复杂化了。对于触摸屏设备上的 'swipe'、'drag' 等事件,您应该使用 'touch' 事件。 'tap' 之类的简单事情已经为您处理好了。例如,您可以使用隐藏 CSS

中的下拉菜单
.dropdown {
   display: none;
}

当用户点击菜单项时,简单地显示这个下拉菜单

menuItem.addEventListener("click", function(){
   dropdown.style.display = "block";
})

显然,这可以通过添加 'transitions' 和更多样式来进一步改进。但这是一般的想法。 'click'、'onmousedown' 等事件适用于触摸屏设备。