
原文地址: https://github.com/hugojing/web-lessons/blob/master/lesson4/README.md
创建 lesson4 项目,引入 Modernizr CLI 。
使用 Modernizr CLI 生成自己需要的 Modernizr 包。
使用 Modernizr 进行功能特性检测,在浏览器不支持某一特性时应用相应样式和逻辑。
当在浏览器中访问 http://localhost:8080 时,输出页面。
在进行前端开发时,想用一些浏览器的新特性,却不确定用户的浏览器是否支持。
这时便需要进行手工检测来判断,进而给出不同的处理。
使用 Modernizr ,可以方便地进行特性检测。从这些手工检测中解放出来,腾出力气来做好优雅降级。
而且 Modernizr 可订制化,列出一个 JSON 格式的特性清单,便可以打出一个你所需要的最小的包。
上节课有用到 Webpack 的插件: extract-text-webpack-plugin ,这次首先介绍一个新的小插件: html-webpack-plugin. 主要功能是自动生成 HTML 文件。
使用 Yarn (新的 npm CLI client )初始化项目:
$ yarn init #替代原 npm init 沿用上一节课的项目结构,创建需要用到的文件目录。
添加 html-webpack-plugin 到项目:
$ yarn add --dev html-webpack-plugin #替代原 npm i --save-dev html-webpack-plugin 添加 Webpack config 如下:
const HtmlWebpackPlugin = require('html-webpack-plugin') // ... plugins: [ // ... new HtmlWebpackPlugin({ title: 'Modernizr 实战', template: path.resolve(SRC_PATH, 'index.html') }), // ... ] 这段配置是说以 src/index.html 为模板,创建一个 title 为 Modernizr 实战 的 html 文件,并输出到 output 输出目录。如果一同输出的有 JS 和 CSS 文件,它会自己写好 script src 和 link 到所输出的 html 文件中。
新增 src/index.html 文件,编写如下:
<!DOCTYPE html> <html class="no-audio"> <head> <title>Modernizr 实战</title> </head> <body> <div id="music"> <p>The End Of The World</p> </div> </body> </html> 这样一来,打包时就会自动生成符合需要的 dist/index.html 文件。
添加 Modernizr CLI 到项目中:
$ yarn add modernizr #替代原 npm i modernizr --save 新增 modernizr CLI 的 generate 命令到 package.json ,可根据指定的 config json 文件生成自订制的 modernizr.js 文件。
"scripts": { "modernizr": "modernizr -c node_modules/modernizr/lib/config-all.json" } 执行 modernizr CLI 的 generate 命令,生成 modernizr.js 文件:
$ yarn run modernizr #替代原 npm run modernizr # Modernizr build saved to xxxxx/lesson4/modernizr.js 为了代码中方便使用,可在 webpack.config.js 的 config.resolve.alias 中配置别名:
alias: { 'modernizr': path.resolve(ROOT_PATH, 'modernizr.js') } 在 src/main.js 文件中编写代码,引入需要加载的一些前端模块( CSS 、 MP3 ):
import 'normalize.css' // 不是合法的 ES2015 Modules 写法,由 babel 转为 `require('normalize.css')`,再由 Webpack 实现 CSS 加载 import './main.css' // 同上,会转为 `require('normalize.css') import musicUrl from './The_End_Of_The_World.mp3' // 同上,会转为 `const musicUrl = require('./The_End_Of_The_World.mp3')` 代码中的 import(require) 都是 Webpack 接管的,所以 The_End_Of_The_World.mp3 这个音频文件得让 Webpack 来加载它。这就要用到两个新的 loader: url-loader 和 file-loader .
添加到项目中:
$ yarn add --dev url-loader file-loader 然后添加 Webpack config:
module: { loaders: [ // ... { test: /\.mp3$/, loader: 'url?limit=1024&name=[hash].[ext]' } ] },
url?limit=1024&name=[hash].[ext]意思是使用 url-loader 来加载,小于 1024k 的打成 Base64 ,大于的复制文件到 output 输出目录、并命名为 [hash].[ext] 的格式。
这样, JS 中 import(require) 一些 mp3 文件的时候, Webpack 就可以按照配置策略进行加载,其返回值为 Base64 值或者 文件的 url.
可以验证一下,console.log(musicUrl) 会得到类似 /205cc6e697917a94362ed6ed99febe71.mp3 的结果,即为加载成功。
继续编辑 src/main.js , 应该引入我们生成的自订制 modernizr 文件了。
查看 modernizr.js 文件,可以发现这个模块既不是 AMD 、 CMD 、 CommonJS 模块,也不是 ES2015 模块,更不是 UMD 模块,而是传统的 globals 库,将 modernizr 挂载在 window 上。(了解不同的模块类别,推荐阅读:关于 AMD,CMD,CommonJS 及 UMD 规范、识别库的类型)
由于 modernizr.js 文件是传统的 globals 库,所以执行所加载的 modernizr.js 即可,写法如下:
import 'modernizr' // modernizr 即为 ./modernizr.js 注意,这虽是合法的 ES2015 Modules 写法,但实现上依然是由 babel 转为
require('modernizr'),再由 Webpack 实现 JS 加载的。
这样, window.Modernizr 就可用了。
打包一下:
$ yarn run build #替代原 npm run build 然后启动服务:
$ yarn run serve #替代原 npm run serve 打开浏览器查看开发者工具,查看 Elements :

可见,直接加载执行 Modernizr ,它不仅挂载了 window.Modernizr, 还依照检测结果给 <html> 标签写入了对应的 CSS class 名,例如 cookies cors crypto cssall no-backdropfilter audio 等。这样,开发者就可以写两种 CSS 样式(比如 .audio body 与 .no-audio body),以应对两种可能的情况(某一功能的有或无)。
于是,这样编写 src/main.css :
html, body { width: 100%; height: 100%; } body { display: flex; justify-content: center; align-items: center; font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; } .no-audio body { color: #fff; background-color: #000; } .audio body { color: #000; background-color: whitesmoke; } .no-audio #music { width: 600px; text-align: left; } .audio #music { width: 300px; text-align: center; } JS 中也可以获取检测结果,例如:
Modernizr.audio // turn or false 于是,这样编写 src/main.js :
//... const cOntainer= document.getElementById('music') if (Modernizr.audio) { // Modernizr 即是 window.Modernizr const music = new Audio(musicUrl) music.cOntrols= 'controls' container.appendChild(music) } else { const musicIntro = document.createElement('p') musicIntro.textCOntent= '史琪特戴维丝 1963 年演唱的《 The End Of The World 》(世界末日)被评为当年最受欢迎的歌曲,被无数人翻唱过,但无人能及她原唱的魅力,这首歌也是她唯一的传世之作。' container.appendChild(musicIntro) } 别忘了打包和启动服务。
在支持 HTML5 Audio 的浏览器中:

在不支持 HTML5 Audio 的浏览器中:

感谢 Modernizr ,给了我们一个更优雅的检测浏览器新特性的方式。
1 neoblackcap 2016-10-29 23:28:32 +08:00 不是我吹毛求疵。都多少年了,用 Modernizr 来进行特性检测以便编写兼容性更好的网页这不是前端开发的常识吗?我记得当 Chrome 刚出来那几年间,还得兼容 IE6,7,8 的时候,就已经推崇用 Modernizr 编写现代化的网页。 |
2 toloric OP @neoblackcap 对呀 |