WP DEVELOP

EP061. “搜索 Overlay 的开关逻辑”

首页 WordPress 开发课程 LIVE SEARCH AJAX · EP061
约 12 分钟· #EP061#LIVE SEARCH AJAX
🔒 登录后可标记已读

📌 并入 EP060(Quick Note About The Next Lesson): 这一讲开始会用 jQuery。作者原话:jQuery 不是他 2021 年会优先选的方案,但为了这一小段功能重新拍全部 JavaScript 章节不划算,所以建议跟着视频用 jQuery。他补充说,每个 JS 功能做完后,章节末尾都会有一条额外录制的视频(2020 年 6 月补拍),讲怎么用「不依赖 jQuery」的写法实现同样功能,并附带可下载的纯 JS 源码文件可以直接替换。就 Search 这个功能来说,本章节末尾会有一条对应的「jQuery-free」版本讲座。

overlay 的显示/隐藏逻辑正式开工。先在 footer.php 里手写 overlay 的 HTML 骨架(外层容器 + 顶部区域 + 搜索输入框 + 关闭按钮图标),再回到 Search.js 用 jQuery 选取「搜索图标」「关闭图标」「overlay 容器」这三个元素,点击搜索图标时给 overlay 加上 search-overlay--active 这个 class 使其可见,点击关闭图标时把这个 class 移除。同时讲了一遍作者写面向对象 JS 的固定套路:constructor(描述/创建对象)→ events(把事件和方法接起来)→ methods(具体动作)

涉及文件

  • wp-content/themes/fictional-university-theme/footer.php (修改,新增 overlay HTML)
  • wp-content/themes/fictional-university-theme/src/modules/Search.js (修改,重写 constructor,加入 jQuery 开关逻辑)

代码实现

footer.php 里,</footer><?php wp_footer(); ?> 之间新增 overlay 的 HTML 骨架:

<!-- wp-content/themes/fictional-university-theme/footer.php -->
<!-- 新增:加在 </footer> 和 <?php wp_footer(); ?> 之间 -->
<div class="search-overlay">
  <div class="search-overlay__top">
    <div class="container">
      <i class="fa fa-search search-overlay__icon" aria-hidden="true"></i>
      <input type="text" class="search-term" placeholder="What are you looking for?" id="search-term">
      <i class="fa fa-window-close search-overlay__close" aria-hidden="true"></i>
    </div>
  </div>
</div>

Search.js 整份重写(这一讲把 EP059 那个纯测试用的 constructor 换成真正的开关逻辑,代码量不大,直接整份贴):

// wp-content/themes/fictional-university-theme/src/modules/Search.js

import $ from "jquery"

class Search {
  // 1. describe and create/initiate our object
  constructor() {
    this.openButton = $(".js-search-trigger")
    this.closeButton = $(".search-overlay__close")
    this.searchOverlay = $(".search-overlay")
    this.events()
  }

  // 2. events
  events() {
    this.openButton.on("click", this.openOverlay.bind(this))
    this.closeButton.on("click", this.closeOverlay.bind(this))
  }

  // 3. methods (function, action...)
  openOverlay() {
    this.searchOverlay.addClass("search-overlay--active")
  }

  closeOverlay() {
    this.searchOverlay.removeClass("search-overlay--active")
  }
}

export default Search

要点:

  • search-overlay 这个 div 默认是隐藏的(CSS 里 opacity: 0; visibility: hidden;),只有加上 search-overlay--active 这个 class 才会显示出来(这份 CSS 在更早的讲座里就已经写好了,这一讲没有改 scss)。
  • 作者写面向对象 JS 固定分三块:
    1. constructor:描述并创建对象本身(这里是「选取需要用到的三个 DOM 元素」)。
    2. events:把「发生了什么事件」和「该调用哪个方法」接起来(这里是两行 .on("click", ...))。
    3. methods:真正执行动作的函数(这里是 openOverlay / closeOverlay,只负责加/减一个 class)。
  • .on("click", this.openOverlay.bind(this)) 一定要 .bind(this)jQuery 的 .on() 默认会把回调函数里的 this 改成「触发事件的那个 DOM 元素」,不 bind 的话在 openOverlay 方法里写 this.searchOverlay 就会读取不到,因为 this 已经不是指向 Search 对象了。
  • constructor 里要记得调用 this.events(),这样浏览器页面一加载就会去监听这些点击事件,不然按钮点了也没反应。

[截图:前台点击头部搜索图标后,全屏半透明 search-overlay 弹出的画面]

Hook / Function 速查

名称类型用途
import $ from "jquery"JS 写法引入 jQuery,$ 是它的别名
$(selector)jQuery用 CSS 选择器语法选取 DOM 元素
.on(event, handler)jQuery 方法给元素绑定事件监听(如 click
.addClass() / .removeClass()jQuery 方法给元素加上/移除某个 CSS class
.bind(this)JS 内建方法强制把函数内部的 this 锁定成调用时传入的对象,防止被事件处理器覆盖

常见坑

  • 忘记 .bind(this) 会导致 openOverlay / closeOverlay 方法内部的 this 变成被点击的那个图标元素,而不是 Search 对象,this.searchOverlay 就会是 undefined,功能失效
  • overlay 的 HTML 一开始如果直接带上 search-overlay--active 这个 class 去测试(transcript 里作者是先手动加这个 class 确认样式对不对),记得测试完要把这个 class 删掉,不然页面一加载 overlay 就是打开状态。

延伸 / 后续讲座会用到

这个 openOverlay / closeOverlay 方法会在 EP063 继续扩充(加上「打开时禁止背景滚动」、键盘快捷键触发),footer.php 里的这个 overlay 容器也会在 EP065 继续加一个显示搜索结果用的 div

Sources

Udemy:

  • Become a WordPress Developer: Unlocking Power With Code — Section 13, EP060, EP061