摘要:前端工程化重构时最大的区别就是工程化了。这次重构,想起了这个,分析了一下,其实很简单网站采用了技术,进入首页后,插件注入的就被触发,寻找被隐藏的下载地址,然而这时并没有这个。
事件的起因源于我大三时写过的一个chrome插件:老司机的工具箱,当时因为某XX御所开启了老司机模式,导致资源下载链接被隐藏,再加上那时无意间看了一篇教程Chrome扩展及应用开发,于是性致勃勃的花了几天时间,写出了这个插件:用来显示被隐藏的下载地址和自动填写百度网盘密码。之后插件也陆陆续续迭代了几个版本,不过最后不了了之。
插件发布到如今,两年时间里,也有几千用户了,这点倒是让我挺意外的,看来世上还是绅士多吧。。。
前几天在家无事,于是就review了代码(项目地址): 两年前的代码看懂是不可能看懂的,这辈子都不能看懂,只能重构下代码这样子。 不过在重构的过程中,也不禁感叹两年的时间,前端还真的是风云变幻,当年的自己的确菜的抠脚。
前端工程化重构时最大的区别就是工程化了。
两年前的代码,我还是停留在html页面直接引入js,css,写代码就是jQuery一把梭子的层面。
而如今,在真正写代码前,我可能需要花些时间,来配置一些诸如webpack,babel的构建、编译工具。配置的繁琐带来的是开发时的便捷,2年前没有模块化的js和css是我现在不敢想象的。
代码风格两年前的代码到处充斥着各种全局变量和函数,随意的DOM操作和callback调用,使得面条代码让人看得更加凌乱。
而如今,我更加倾向于面向对象和函数式编程。
两年前我应该会毫不犹豫写出这样的代码:
window.addEventListener("DOMContentLoaded", function() { function renderContainer(data) { // 对数据进行一些加工 return newData; } ajax({ url: api, type: "GET", dataType: "json", success: function(data) { const container = document.querySelector("#container"); container.innerHTML = renderContainer(data); } }) const btn = document.querySelector("#btn"); btn.addEventListener("click", function() { // 处理事件 }) })
现在我会这样写:
class Demo { constructor() { this.container = document.querySelector("#container"); this.btn = document.querySelector("#btn"); this.init(); } renderTemplate(data) { // 对数据进行一些加工 return newData; } init() { this.renderContainer(); this.bindHandler(); } async renderContainer() { const data = await ajax({ url: api, type: "GET", dataType: "json" }); this.container.innerHTML = this.renderTemplate(data); } bindHandler() { this.btn.addEventListener("click", function() { // 处理事件 }) } } window.addEventListener("DOMContentLoaded", function() { const demo = new Demo(); })
其实这种写法已经类似于React和Vue了。MVVM框架除了带来数据驱动的理念,其实也在一定程度上推动了面向对象和函数式编程的思想。
解决问题两年前我写这个插件的时候,遇到了一个很费解的bug:就是进入网站首页,点击文章标题进入详情页面后,并不能显示隐藏的下载地址,每次都需要我手动刷新一遍页面才能成功。
当时水平有限,想了半天也不明白为啥会这样,拖着拖着就忘了。这次重构,想起了这个bug,分析了一下,其实很简单:网站采用了pjax技术,进入首页后,插件注入的js就被触发,寻找被隐藏的下载地址dom,然而这时并没有这个dom。点击标题进入详情页,这时我们需要的dom被插入了,但是由于使用了pjax,整个页面其实并没有重新加载,插件注入的js已经被执行过一次了,所以这时就无法把dom展示出来,而需要我们手动刷新,重新执行一遍注入的js。
解决方法是,利用MutationObserver监听pjax更新的dom元素,如果发现更新了dom,就再次执行js方法
还遇到了一个问题:
`【磁力链接】 magnet:?xt=urn:btih:404d1cf190660dfd301e289411cfc3185fcb2c92 【百度云】 传送门 提取码:lmys `
如何在把lmys提取出来?
当时很拙劣的使用了字符串截取:
function getPwd(str) { var index1 = str.indexOf("提取码"); var index2 = str.indexOf(" ", index1); if (index1 !== -1 && index2 !== -1) { return str.slice(index1 + 4, index2).trim(); } return ""; }
现在看来,一行正则就搞定的事情:
const regPassword = /提取码.*([a-zA-Z0-9]{4})/;总结
废话了那么多,其实就是想说,每个人在每个阶段都会受限于当时的技术水平和眼界格局,而写出在当时自认为是最好的代码。
如果你最近觉得自己水平一直上不去,技术遇到了瓶颈,这时不妨---
拔掉网线,关上电脑,读几页《Angular从入门到放弃》,出门去漫展走走,要么去女装,天黑了约几个好久不见的肥宅找个地方喝点快乐水、聊聊纸片老婆,随便做些什么。一天下来,你就会发现,还是jQuery写的爽!
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/97582.html
摘要:二叉树二叉树是一种树形结构,它的特点是每个节点最多只有两个分支节点,一棵二叉树通常由根节点,分支节点,叶子节点组成。 二叉树 二叉树(Binary Tree)是一种树形结构,它的特点是每个节点最多只有两个分支节点,一棵二叉树通常由根节点,分支节点,叶子节点组成。而每个分支节点也常常被称作为一棵子树。 showImg(https://segmentfault.com/img/bVbmEd...
摘要:建模语言建模语言是可用于表达信息或知识或系统的任何人造语言,该结构由一组一致的规则定义,目标是可视化,推理,验证和传达系统设计。将这些文件安排到不同的地方称为源代码树。源代码树的结构通常反映了软件的体系结构。 大纲 软件构建的一般过程: 编程/重构 审查和静态代码分析 调试(倾倒和记录)和测试 动态代码分析/分析 软件构建的狭义过程(Build): 构建系统:组件和过程 构建变体...
摘要:最近在维护一个三年前的旧代码,用的是框架。单元测试和语言并发控制实际上是个蛋疼的问题,夸张一点说,当时的并不能特别轻松地实现并发,甚至不能实现并发。语言的功能之一就是自带单元测试。用语言之前,我的习惯是不写单元测试。 最近在维护一个三年前的旧代码,用的是laravel框架。 从某些方面来讲,这个代码算是比较标准为了实现在规定的时间内完成相关功能,同时程序员水平不高、经过大量优化之后,变...
摘要:同时,在方法命名上也投入一精力,尽可能地使方法名保持简单,它将帮助你在重构代码时,更好的达到单一职责。 这是理解SOLID原则中,关于单一职责原则如何帮助我们编写低耦合和高内聚的第二篇文章。 单一职责原则是什么 之前的第一篇文章阐述了依赖倒置原则(DIP)能够使我们编写的代码变得低耦合,同时具有很好的可测试性,接下来我们来简单了解下单一职责原则的基本概念: Every module o...
阅读 2199·2021-11-16 11:44
阅读 618·2019-08-30 15:55
阅读 3251·2019-08-30 15:52
阅读 3550·2019-08-30 15:43
阅读 2176·2019-08-30 11:21
阅读 394·2019-08-29 12:18
阅读 1927·2019-08-26 18:15
阅读 431·2019-08-26 10:32