
.dropdown的內容都透過 css 隱藏起來了。.dropdown {
  /* 透明度0 */
  opacity: 0;
  position: absolute;
  overflow: hidden;
  padding: 20px;
  top: -20px;
  border-radius: 2px;
  transition: all 0.5s;
  transform: translateY(100px);
  will-change: opacity;
  /* 排版:隱藏 */
  display: none;
}
而下方又有這兩組 css,代表的是當外層容器有trigger-enter、trigger-enter-active時選單要變更排版及透明度設定。
.trigger-enter .dropdown {
  display: block;
}
.trigger-enter-active .dropdown {
  opacity: 1;
}
負責下拉選單背景的.dropdownBackground容器也有設定透明度隱藏,及若有.openclass 時解除隱藏
.dropdownBackground {
  /*  .               */
  /*  .  其餘css設定   */
  /*  .              */
  opacity: 0;
}
.dropdownBackground.open {
  opacity: 1;
}
因此我們要做的是即是在適當的位置添加事件監聽器,當滑鼠滑入時加入 class 當滑鼠移出時移除 class,看一下結構我們選擇使用<ul class="cool">清單下的每個<li>
//  選取每個nav li 節點
const li = document.querySelectorAll(".cool>li");
//  選取白框背景容器
const background = document.querySelector(".dropdownBackground");
// 每個都增加滑鼠滑入監聽器及滑鼠移出監聽器
li.forEach((node) => {
  node.addEventListener("mouseenter", handleMouseenter);
});
li.forEach((node) => {
  node.addEventListener("mouseleave", handleMouseleave);
});
function handleMouseenter(e) {
  this.classList.add("trigger-enter", "trigger-enter-active");
  background.classList.add("open");
}
function handleMouseleave(e) {
  this.classList.remove("trigger-enter", "trigger-enter-active");
  background.classList.remove("open");
}

handleMouseenter函式將背景容器的寬高變成觸發事件的下拉式選單寬高,以及位移背景容器到觸發事件的下拉式選單位置,即可以達到題目要求效果。//  全域新增兩個變數,因為nav上有設定position:relative;
//  所以會造成位置偏移要扣掉nav.getBoundingClientRect的top及left
const nav = document.querySelector(".top");
const navCoords = nav.getBoundingClientRect();
//  改寫`handleMouseenter`函式
function handleMouseenter(e) {
  this.classList.add("trigger-enter");
  //  因為dropdownBackgroundb容器css有設定transition,所以opacity恢復透明度需要延遲一下
  setTimeout(() => {
    this.classList.add("trigger-enter-active");
  }, 150);
  background.classList.add("open");
  //  選取觸發事件容器內的下拉式選單
  const dropdown = this.querySelector(".dropdown");
  //  display取消隱藏後,才能取得邊界矩形
  const dropdownCoords = dropdown.getBoundingClientRect();
  const coords = {
    height: dropdownCoords.height,
    width: dropdownCoords.width,
    //  因為nav上有設定position:relative;
    //  所以會造成位置偏移要扣掉nav.getBoundingClientRect的top及left
    top: dropdownCoords.top - navCoords.top,
    left: dropdownCoords.left - navCoords.left,
  };
  //  將背景容器寬高,及位置依序設定
  background.style.setProperty("width", `${coords.width}px`);
  background.style.setProperty("height", `${coords.height}px`);
  background.style.setProperty(
    "transform",
    `translate(${coords.left}px, ${coords.top}px)`
  );
}