你可能不需要一个 JavaScript 框架(二)

 解决方案 Solution

你需要的,还是 JavaScript 和 Web API。我希望阁下可以看看 Web API (detailed),快速浏览一下然后回到本文。

What you need is vanilla JavaScript and the Web API. I want you to take a look at the Web API (detailed). Scimm through it for a couple of minutes and come back.

看完了?不错。我第一次细读之后,大为惊叹。去掉很多东西变得很简单。好比说 MutationObserver,通过它你观察 DOM 变化,那么做起数据绑定和 DOM 交互就非常简单。

Done? Awesome. I was pretty impressed when I first looked at it in detail. A lot has changed and it's much simpler to work with. Take MutationObserver for example - it allows you to watch parts of the DOM for mutations. This feature alone would allow you to setup simple databinding and react to potential changes.

举个例子,观察 h1 可编辑标签。

Here's an example of observing a contenteditable h1 tag:

let elementToWatch = document.querySelector('h1')
elementToWatch.contentEditable = true

let observer = new MutationObserver(mutations => {
  mutations.forEach(mutation => {
    console.log(mutation.target.textContent)
  })
})

observer.observe(elementToWatch, {
  subtree: true,
  characterData: true
})

这算是没有的例子,你宁愿观察 DOM 结构是怎么变化的,

This is a fairly useless example, and you would rather want to observe DOM structure mutations with it, but you get the idea.

另外一个例子是 Fetch API,比 XHR 更强大、简单。

Another example is the Fetch API. It's like XHR, but much more straight-forward and powerful.

更新 UPDATE (30/4 17:30 CET):

我回想起我六年前那时候开始搞 Web 开发,彼时的 Web API 和 DOM API 确实令人头疼。时光荏苒,ECMAScript 已经变化很多。首先是语法部分改进了很多,其次是 Web API 的实用性也增强了。开始的时候之所以你会使用这些框架是因为你觉得有许多新玩意,其实大多数都通过 polyfill 实现的。

When I first started web development 6 years back, the Web API & DOM API were indeed a pain to work with, but times have changed and the ECMAScript updates alone has turned the tables quite a bit. Syntatical changes has been made to the language that plays much nicer with some parts of the Web API that were previously non-trivial to work with. New features are constantly being rolled out that accounts for many of the reasons you are working with a framework in the first place, most of which can be polyfilled where not available.

新语言特性 Proxy 可以实现 A 到 Z 的交互。

The new Proxy language feature allows you to implement reactivity from A to Z, among other things.

Decorators 可以部分地添加你代码的功能。

Decorators allows you to add additional functionality to parts of your code.

类继承可让你的程序像演化那样,从基础一直发展下去。

Class inheritance allows you to start from a base and extend additional features to your app as it evolves.

还是那句话,这是你程序需要不需要的问题。其实这可以不要的,甚至不需要装饰的,但是这没意义,浏览器本身提供好的功能你调用就是了,不需要再你程序多此一举引入其他库。

This again, is a question of what your application needs. It might not even need reactivity, it might not even need to decorate functionality - but nontheless it is there, in the browser and available to you whenever you need it without any additional overhead to your application (unless polyfilled).

这篇文章几乎变成围绕“如何将你框架替换成为普通 JS”,但我想说的这并不是我的原意。我原意是反思下使用框架的原因。问问自己是否真的那么复杂。

This post has blown up to becoming "how you replace your framework with vanilla JavaScript", and that was not the intention. The idea is that you should take a moment and reflect on your reason for using a framework. You have to ask yourself if your application really is all that complex that you absolutely require solutions to the vast amount of problems a framework tries to solve.

 实际上一开始没那么的问题,只不过你想了才会有。

You most definitely don't have many of those problems in the first place if you think about it:

  • 把状态反射到 UI 没有问题的,只不过你想了才会有。You don't have problems reflecting state onto the UI if you think about it.
  • 数据保存和缓存没有问题的,只不过你想了才会有。You don't have problems with data storage or caching if you think about it.
  • 我写的可复用组件和代码没有问题的,只不过你想了才会有。You don't have problems with writing reusable code/components if you think about it.
  • 程序实际没那么庞大,UI 没那么复杂,只不过你想了才会有。You don't have problems with large, complex UIs if you think about it.
  • 实际没那么多性能的问题,只不过你想了才会有。 You don't have problems with performance if you think about it.

公司之所以这样并不表示他们很高级,而且其中的程序员就是那么平庸,觉得使用框架就是对的。实际要不要框架还是取决于他们实际的需求。

Just because most companies are using frameworks doesn't mean they have to either. Companies aren't some higher form of being, they consist of developers and normal people that has made a choice of using a framework because they think it is the right to do. If it is a good choice or not depends on their application(s).

编写函数和类 Write functions and classes

在代码很常见的一件事情就是写函数和类。例如在服务端和 DOM 交互的时候,写一个观察者是有必要的;另外一个例子就是你要写组件的时候很自然地会写一个类。你完全可以利用 HTML5 History API 构建你自己的一个小型的路由器。

Things that you often use in your application should of course be placed in their own functions or classes, depending on if you need instances of something or not.This could for example be setting up observers, walking the DOM or talking with a server-side resource.A great example of using classes is if you want a lightweight implementation of components. An instance of a specific class can represent a component and be its view-model.You could also build a tiny router and utilize HTML5 History API.

也许有人认为这是在重复制作轮子。不过这还真不是,因为只有你一个在写,你当然拥有决定权怎么去写代码,只要你自己觉得舒服就好。你想怎么弄就怎么弄。

Some may argue that this is like reinventing the wheel, but it really isn't because you are the one in control. You are the author of your code, and you get to work with code you feel comfortable with. You can build it however you want and support whatever browser versions you want.

看看 router.js,README 如此说:

Take a look at router.js, this is what their README says:

router.js 是个轻量级的 JS 库,以 route-recognizer 和  rsvp 的 为基础,提供路由处理的 API。

router.js is a lightweight JavaScript library that builds on route-recognizer and rsvp to provide an API for handling routes.

库文件压缩后 24.4KB,转译后 2,175 行代码。

The library is 24.4KB minified, and 2,175 lines of code after transpilation.

你在你程序中你写一个路由器会写多少行代码?100?200?1000?20 行呢?

How many lines of code do YOU think that YOU can write a router for your application in? 100? 200? 1000? How about 20?

我不是说你不应该使用库,只是我希望你在选择库的时候要谨慎一些。看看源码,如果不需要的东西就要减少文件大小,或者试试提交一个 pull 请求。

I'm not saying that you shouldn't use libraries, because you should. But I want you to be critical when choosing what libraries to use. Check through the source, maybe submit a pull request and try to help reduce the size a bit if you find something that's unnecessary.

要知道何时适合用 js,何时适合 css Know when to use JS and when to use CSS

CSS 也很强大啦。很多动画和效果都不需要 JS 参与完成。建议不要用 height / width 而是 transform/opacity 做动画。另外可以参考这里。伪类 :hover/:active/:focus 在做下拉菜单时候很好用,可通过这些伪类触发事件,精确到每个子元素。

CSS is powerful too. It can handle almost every animation/transition that you can imagine without the need of any JavaScript involved.

Only animate the transform and opacity attributes, and never things like height or width. A bit more about this here.

Use :hover, :active and :focus for simple triggers for something like a dropdown menu. You can also trigger child elements via these methods.

浏览器特性支持够吗?What about browser support?

前端项目的一个问题就是解决浏览器是否支持某项特性的问题。如果遇到不支持的做法就是采取 polyfill 方案(它是用来描述复制缺少的 API 和API 功能的行为。你可以使用它编写单独应用的代码而不用担心其他浏览器原生是不是支持)。然而有些像 Service Worker  的功能却是无法做到兼容,——这种情形,搞不定就是搞不定,换上框架也是爱莫能助。

Browser support is usually something you have decide upon a project-basis, but if there's a feature that isn't available for a browser you want to support, just polyfill it. Granted, there are some features like Service Worker that can't be polyfilled, but if a feature can't be polyfilled, a framework can't have support for it either.

关于 polyfill 还有个问题就是会增大程序尺寸。确实如此,不过好消息是,如果浏览器支持的就无须加载 polyfill 那部分代码。你可能又会说,这样会增加请求服务器的往返次数。不过还好,现代的 web 不存在这个问题了,下文再解释。

An argument that often comes up when talking about polyfilling is that it increases the size of your application. That is true, however you can dynamically polyfill based on what the client browser already has support for. And the follow-up argument is that dynamic polyfilling adds additional round-trips to the server, and that is however NOT true in modern web, explained below.

时间: 2024-10-15 10:54:51

你可能不需要一个 JavaScript 框架(二)的相关文章

你可能不需要一个 JavaScript 框架(一)

你可能不需要一个 JavaScript 框架 You (probably) don't need a JavaScript framework 我并不打算写一篇类似于<为何 JavaScript 社区如此不堪>的文章那是因为我觉得真没必要.只是我认为事情本来就很简单,而且以"就地取材"的方式去做事情也确实十分有趣.下面我就为您一一娓娓道来,介绍到底 Web API 和原生 DOM 有多么强大和多么简单. I'm not going to post yet another r

写一个JavaScript框架:比setTimeout更棒的定时执行

这是 JavaScript 框架系列的第二章.在这一章里,我打算讲一下在浏览器里的异步代码不同执行方式.你将了解定时器和事件循环之间的不同差异,比如 setTimeout 和 Promises. 这个系列是关于一个开源的客户端框架,叫做 NX.在这个系列里,我主要解释一下写该框架不得不克服的主要困难.如果你对 NX 感兴趣可以参观我们的 主页. 这个系列包含以下几个章节: 项目结构 定时执行 (当前章节) 沙箱代码评估 数据绑定介绍 数据绑定与 ES6 代理 自定义元素 客户端路由 异步代码执行

写一个 JavaScript 框架:比 setTimeout 更棒的定时执行

这个系列是关于一个开源的客户端框架,叫做 NX.在这个系列里,我主要解释一下写该框架不得不克服的主要困难.如果你对 NX 感兴趣可以参观我们的 主页. 这个系列包含以下几个章节: 项目结构 定时执行 (当前章节) 沙箱代码评估 数据绑定介绍 数据绑定与 ES6 代理 自定义元素 客户端路由 异步代码执行 你可能比较熟悉 Promise.process.nextTick().setTimeout(),或许还有requestAnimationFrame() 这些异步执行代码的方式.它们内部都使用了事

什么是JavaScript框架

摘要:现代网站和web应用程序趋向于依赖客户端的大量的javascript来提供丰富的交互.特别是通过不刷新页面的异步请求来返回数据或从服务器端的脚本(或数据系统)中得到响应.在这篇文章中,你将会了解到javascript框架如何更快.更方便的创建互动性强.响应快得网站和web应用程序. 导言:JavaScript是一种面向对象的脚本语言,一直以来用作Web浏览器应用程序客户端脚本接口的选择.JavaScript允许Web开发人员编程与网页上的对象的工作,为凭空操作这些对象提供了一个平台.当Ja

JavaScript框架的选择函数:DOM遍历

DOM遍历 基于ID.元素类型.类名查找元素非常有用,但是如果你想基于它在DOM树中的位置来查找元素该怎么办?换句话说,你有一个给定的元素,你想查找它的父元素.子元素中的一个.它的上一个或下一个节点兄弟节点.例如,采用下面这段零碎的HTML代码: 清单1:HTML碎片(一个table) <table>    <thead>        <tr>            <th>Name</th>            <th>Emai

5个JAVASCRIPT框架详细的比较

框架比较 表1对本文中讨论的五个框架提供详细的比较   Prototype jQuery YUI ExtJS MooTools Latest Version 1.6.1 1.4.1 3.00 3.1 1.2.4 License MIT MIT & GPL BSD Commercial & GPL v3 MIT       Browser Compatibility     IE Support 6.0+ 6.0+ 6.0+ 6.0+ 6.0+ Firefox Support 1.5+ 2.

九个用于移动APP开发的顶级JavaScript框架

从技术上讲,iOS.Android和Windows Phone上的移动app使用了不同的编程语言进行编码.iOS app使用Objective-C,Android app使用Java,而Windows Phone app使用.NET.但是,掌握一定量的JavaScript.CSS和HTML知识,你就可以构建超棒的移动app.因此,在本博客中,我们将讨论用于开发移动app的顶级JavaScript框架. 对于Web开发而言,JavaScript是一个有前途的编程语言,并且在不久的将来它将依然在这个

2016年非常热门的七大顶级JavaScript框架

当涉及到Web开发时,JavaScript框架往往是一些开发人员和企业最受欢迎的平台.可能,你有机会尝试过一两个顶级的JavaScript框架,但你仍然有点不确定哪个才是最佳的最值得掌握的,或者哪个值得你建议你的开发人员选择用于下一个web开发项目. JavaScript正在以惊人的速度前进,并且添加新的技能到你的存储库变得有不断的压力.为了做到这一点,知道和了解更多的顶级JavaScript框架在现在看来是必要的.在ValueCoders进行了彻底的研究后,我们入围了其中七个顶级框架,它们是:

怎样在不使用框架的基础上开发一个 Javascript 组件

本文讲的是怎样在不使用框架的基础上开发一个 Javascript 组件, 许多开发者(包括我)犯的一个错误是当遇到问题时他们总是自上而下地考虑问题.他们想问题的时候,总是从考虑框架(Framework),插件(Plugin),预处理器(Pre-processors),后处理器(Post-processors),面向对象模式(objected-oriented patterns)等等这些方面出发,他们也可能会从他们以前看过的一篇文章来考虑.而这时如果有一个生成器(Generator)的话,他们当然