WP DEVELOP

EP104. “Like JS 模块与点击分发逻辑”

首页 WordPress 开发课程 LIKE / HEART 功能 · EP104
约 8 分钟· #EP104#LIKE / HEART 功能
🔒 登录后可标记已读

新建 Like JS 模块,先只把「点击心形图标该走创建还是删除」这个分发逻辑写出来(用测试弹窗代替真实请求,下一讲才接 API)。判断依据就是上一讲写进 HTML 的 data-exists 属性:已经点过赞(yes)就该删除,没点过就该创建。这一讲也顺手把点击目标的定位逻辑写得比较「通用」——不管用户点在外层灰色盒子上、心形图标上还是数字上,都能正确定位到对应的 .like-box 元素,为将来可能一页多个赞按钮的场景做准备。


涉及文件

  • wp-content/themes/fictional-university-theme/src/modules/Like.js (新建)
  • wp-content/themes/fictional-university-theme/src/index.js (修改)

代码实现

src/modules/Like.js(新建)

// wp-content/themes/fictional-university-theme/src/modules/Like.js
import $ from "jquery"

class Like {
  constructor() {
    this.events()
  }

  events() {
    $(".like-box").on("click", this.ourClickDispatcher.bind(this))
  }

  ourClickDispatcher(e) {
    var currentLikeBox = $(e.target).closest(".like-box")

    if (currentLikeBox.data("exists") == "yes") {
      this.deleteLike()
    } else {
      this.createLike()
    }
  }

  createLike() {
    alert("create test message")
  }

  deleteLike() {
    alert("delete test message")
  }
}

export default Like

src/index.js:导入并实例化新模块

// wp-content/themes/fictional-university-theme/src/index.js
import Like from "./modules/Like"
// ...
const like = new Like()

关键改动点:

  • .on("click", this.ourClickDispatcher.bind(this)) 一开始就加了 .bind(this)——因为 ourClickDispatcher 内部要调用 this.createLike()/this.deleteLike(),如果不绑定,this 会指向被点击的 DOM 元素而不是 Like 实例(这正是 Section 19 里踩过的坑,这次一开始就避免了)
  • $(e.target).closest(".like-box") 而不是直接写死 $(".like-box"):用户实际点击的元素可能是外层灰色容器,也可能是里面的心形 <i> 图标或赞数 <span>,这些内层元素本身没有 data-exists 属性;.closest() 会从「实际被点击的元素」开始,沿着 DOM 树往上找最近的、匹配 .like-box 的祖先元素(包括它自身),从而保证不管点在盒子里哪个部分,都能拿到正确的目标
  • 这个「不管点在哪个子元素上都能正确定位」的写法,也是在为将来一个页面可能出现多个赞按钮(比如列表页每个教授卡片都有一个)做铺垫——即便这门课实际场景里一个页面永远只有一个赞按钮,作者依然按更通用、更能复用的方式来写
  • ourClickDispatcher(e) 本身只负责「判断该创建还是删除」这一件事,具体动作各自拆到 createLike() / deleteLike() 方法里——沿用了 My Notes 模块里「判断逻辑」和「具体操作」分离的代码组织习惯

[截图:前台点击心形图标后浏览器弹出的 "create test message"/"delete test message" 提示框]


Hook / Function 速查

名称类型用途
.closest(selector)jQuery 方法从当前元素自身开始(包含自身),向上查找最近的匹配选择器的祖先元素

常见坑

  • $(".like-box") 写死选择器而不是基于 e.target 动态定位——点击事件的目标可能是内层的图标或数字元素,这些元素本身没有 data-exists 属性,直接判断会永远读到 undefined
  • .parents().closest() 混淆——.parents() 不包含元素自身,只从父级开始找;.closest() 包含元素自身,如果自身就匹配选择器会直接返回自身。这一讲场景里点击目标一般是内层的图标/数字,不会是 .like-box 自身,但了解两者的差异有助于以后按需选择

延伸 / 后续讲座会用到

下一讲(part 2)开始写自定义 REST API 端点,把 createLike() / deleteLike() 里的测试弹窗换成真正的 AJAX 请求。


Sources

Udemy:

  • Become a WordPress Developer: Unlocking Power With Code — Section 20, EP104