惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
Microsoft Azure Blog
Microsoft Azure Blog
aimingoo的专栏
aimingoo的专栏
Vercel News
Vercel News
U
Unit 42
L
LangChain Blog
J
Java Code Geeks
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Cloudflare Blog
F
Fortinet All Blogs
小众软件
小众软件
I
InfoQ
P
Proofpoint News Feed
D
DataBreaches.Net
Martin Fowler
Martin Fowler
H
Help Net Security
T
Tailwind CSS Blog
N
Netflix TechBlog - Medium
有赞技术团队
有赞技术团队
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
B
Blog RSS Feed
酷 壳 – CoolShell
酷 壳 – CoolShell
B
Blog

热爱生活与梦想

迁移LeanCloud的Waline评论数据到TiDB/Neon 25年江浙地区暑假自驾游之感慨 使用阿里云灵码继续完成构建 SSL 证书管理器 亲手给儿子做的棒棒糖摩天轮六一礼物 使用腾讯云 CodeBuddy 构建 SSL 证书管理器 修复代码块默认高度相关缺陷 HugoNexT4.7.2 新功能和升级提示 改善代码块折叠和选中功能 支持Github风格的警告样式 新增音乐短代码功能支持 给文章添加摘要和过期提示功能 回顾24年的过去总结 修复Mathjax行内显示公式的问题 给Hugo文章增加阅读更多跳转的锚点定位功能 Win10隐匿的VPN设置和L2TP连接常见错误 Go语言中“糟糕”的日期时间格式化设计 DaoCloud道客提供的免费Docker镜像代理服务 感谢万能淘宝让自己吃到喜欢的美食 WSL运行时遇到未知异常错误无法使用 隐藏的换行符导致Base64加密解密失败 MySQL自带客户端直接免密登录操作 Linux系统中删除目录软链接的注意项 Java程序调用外网API时CA问题 如何不关机重启WSL2恢复虚拟服务 在Windows上安装Podman容器平台做虚拟化 记一次无法弹出移动硬盘的记录 为友情链接添加自动检测脚本 重新激活Github的2FA认证 Linux中使用tar压缩命令排除文件 继续小米手环的健康生活之旅
在JS中使用强大的CSS选择器来定位页面元素
凡梦星尘 · 2022-10-23 · via 热爱生活与梦想

近期由于受到谷歌退出中国市场的影响,就连之前可以正常使用的翻译 API 也无法使用了。 无奈之下为不影响本站的加载速率,决定暂时关闭谷歌的在线翻译功能。🙃

接着就发生了奇怪的现象,重新生成站代码发布完成后,自测是没有问题的,但是有网友反馈说站点访问加载不出来内容。听完自己也甚是一惊,难道是服务器出问题啦?

连忙打开手机访问验证了下一切都是正常的,切换到电脑访问(用的是Edge浏览器)也是正常,难道真的是个别现象吗?然后又切换到火狐浏览器进行测试,结果还真是加载不出来内容,通过 F12 也快速定位到了的问题,是因为关闭了谷歌在线翻译功能后,按钮的注册事件失败,影响到了后续 JS 脚本的执行。

看来发版的时候要多测试几款浏览器才行啦

hugo-theme-next 主题最新版本中加入了右侧工具按钮的小功能,那自然是避免不了给按钮添加点击事件,来看下之前写的代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
registerToolButtons: function() {
  document.getElementById('goto-comments').addEventListener('click', () => {
      window.anime({
      targets  : document.scrollingElement,
      duration : 500,
      easing   : 'linear',
      scrollTop: document.getElementById('comments').getBoundingClientRect().top + window.scrollY
    });
  });
  
  /* 发生问题的代码 */
  document.getElementById('goto-gt').addEventListener('click', () => {
      window.anime({
      targets  : document.scrollingElement,
      duration : 500,
      easing   : 'linear',
      scrollTop: document.getElementById('google_translate_element').getBoundingClientRect().top + window.scrollY
    });
  });
}

起初只是快速添加功能的实现,没有管控住代码的质量,现看看写的也太挫啦,真是失败!

熟悉 JS 代码的小伙伴应该都清楚这里发生了啥,最简单的修复方式就是在注册点击事件前,加个 if 条件判断,当元素不存在时不进行事件注册。只是这样做代码就更挫啦,可清晰的看到此处代码冗余的有点多,另外考虑到后续如果还要再添加按钮的话,难道也是说按 CTRL+CCTRL+V 再来重复写一遍代码!那是坚决不能接受的。😜

于是便想到了使用 CSS 的选择器语法来支持,首先定位到这些按钮的父元素上,然后再逐一对子元素(即按钮本身)进行事件注册,这样当某个按钮被删除后也就无须 if 条件判断,同样也不用调整 JS 代码。顺着这个思路往下走的时候,发现并不是所有按钮的事件都是相同的,得排除掉其它非同类项的按钮。

结合之前编写 SCSS 代码时的经验,是否可以使用 :first-child 这样的选择器进行排除呢?直接在浏览器终端窗口中使用 JS 语法进行了快速验证,得到的答案是可行的。那么接下来就是对原代码进行改造,最终的成果参考如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
registerToolButtons: function () {  
  const scrollbar_buttons = buttons.querySelectorAll('.tool-buttons div:not(:first-chlid)');
  scrollbar_buttons.forEach(button => {
    let target_id = button.id;
    if (target_id != '') {
      target_id = target_id.substring(5);
    }
    button.addEventListener('click', () => {
      this.slidScrollBarAnime(target_id);
    });
  });
}

此时的代码看起来就清爽多啦,同时也兼顾到了后续工具按钮增加的可扩展性。相比于 JS 中使用 ID 或名称来定位页面元素的方式,这种使用 CSS 选择器的模式,操作起来会更的加简便和灵活。好啦,问题也是得到了圆满的解决,此次“事故”也是给自己提了个醒,不仅要注重代码的规范,而且在架构设计上面也要多下点功夫。🤔

看来对于 hugo-theme-next 主题的代码架构评审的工作得加紧啦,毕竟使用的用户也在逐步增长中,得对大家的信赖“负责”才是。😁