存档2019-01-29

敢不敢试试——一个简单小例子立马测出你的JS学的扎不扎实

这是个很经典的例子,也是一个常见的笔试题。大家先不要看答案,试试看。页面的JS代码如下:

(function(){

var m =n = 6;

})();

console.log(“m defined? ” + (typeof a !== ‘undefined’));

console.log(“n defined? ” + (typeof b !== ‘undefined’));

下面来挖挖这个例子背后的知识点。

知识点1:()()是什么?

其实是(function (){/*代码语句*/})();,这是个自执行匿名函数,首先第一个括号里是一个匿名函数(没有函数名),第二个括号表示立即执行,合起来就表示自执行匿名函数(页面加载解析JS的时候就直接执行了),而一般情况下,函数是在调用的时候才执行。

为什么要用这种方式呢?

自执行函数除了立即执行之外,主要是为了划分作用域,或者说创建命名空间,如果不显示的声明为全局变量,匿名函数的代码是封闭在匿名函数内的,外部无法访问。

知识点2:表达式的写法

var m = n = 6;

其实是以下两个语句的

n = 6; //

var m = n; //

而不是 var两个变量

var n = 6;

var m = n;

不同之处在 n=6 he var n=6,这又涉及到JS中变量的创建,

JS是弱类型语言,所以可以随便挖(var), 但是关键字 var 创建的变量是 局部变量,只存在所在作用域,如果前面没有关键字 var 声明的变量是全局变量——变成全局对象window的属性。所以这涉及到变量的声明问题。

知识点3:作用域

见到问题的关键部分。一开始我们以为 在函数内变量m,都是函数内声明的,而两个函数在匿名函数外无法调用匿名函数内的两个变量,所以都应该是undefined。

正确答案是 m是undefined,n 是

m defined? false

n defined? true

原因在知识点2已经说过,m 是匿名函数内局部变量,n是全局变量,所以在函数外部,可以访问n,不能访问m。

这一延伸一个很复杂的知识点——作用域。

    1. 变量作用域

      变量作用域前面已经说过,需要特别说明的是函数的参数也是函数内的局部变量,和函数内显示声明的局部变量一样,他们的作用域仅仅在函数体内,函数外是访问不到的。而且全局变量和局部变量同名的情况下,局部变量的优先级要高于全局变量。

      var num = 111; //声明一个全局变量

      function show() {

      var num = 222; //声明一个局部变量

      return num;

      }

      console.log(show()); //输出:222

      var num = 111; //声明一个全局变量

      function show() {

      return num;

      }

      console.log(show()); //输出:111 ,函数内找不到变量num,就一直往上级的作用域找,直到全局作用域。

    2. 函数作用域

      不像C和Java是块级作用域,JS是函数作用域。意思是在JS中,函数体内声明的变量在其函数体内始终是可见的,包括函数体内的嵌套的函数。

    3. 作用域链

上一篇JS引用类型中讲过,函数也是对象。实际上,在JS中里一切都是对象。函数对象和其它对象一样,拥有可以访问的属性和一些仅供JavaScript引擎访问的内部属性。[[Scope]]就是其中一个内部属性,该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。对象在创建后,其作用域就可以通过这个一层层往上翻,形成一个类似链条的结构:

作用域是一个很复杂的问题,也是一个难点。本片文章整体上进行了介绍,具体技术细节,下次再聊。所以,JS也没有想象中的那么容易,加油吧!

前端响应式页面的布局原理、快速构建和适用范围

响应式页面相信大家都不陌生了,在当今的互联网世界几乎随处可见。今天从响应式分布的原理、基础知识、和页面创建以及注意事项等方面探讨,希望大家对响应式页面有个较为全面的把握。

原理

随着显示终端设备的多样化,出现了各种尺寸的屏幕。而传统的网页主要针对桌面电脑而设计和制作的,电脑显示器屏幕虽然也有多个规格,但相对固定,页面内容区的版块宽度一般也设置为980px。而移动互联网的发展,各种屏幕的手机、pad等出现后,情况变得复杂,但是毕竟移动是趋势,为了给移动端查看网页更好的体验,必须做适合于移动端设备的页面。

那么问题了,怎么盘?

一个方法是为不同的设备专门制作对应的网站:当用户访问的时候,还是访问PC的域名,然后识别用户的设备,跳转到对应的专门移动端页面,这也就是很多网站m.域名的由来。另一个方法是,和PC同样的页面,当用户访问的时候,不根据用户的设备类型,而是根据用户的设备的屏幕大小,然后对页面应用与PC端不同的样式,使这个页面在这个设备上看起来像是为移动端专门做的页面,这就是现在流行的响应式页面设计——Responsive Design。

两种方法的优劣显而易见。第一种方法开发、运营、推广各种成本几乎就double了,但可以提供更为专业的移动端体验,所以说,除非这个网站盈利够大,要求很高,而且主要是有钱,可以这么干。第二种方法就是两个字——省事,就是编写一个页面,适应所有设备。

下面开始介绍这种省事又酷炫的方法。

从基础开始修炼

基础

meta标签设置视口(viewport)

首先说说viewport,也就是移动开发中经常提及的viewport,当然移动设备的viewport还涉及到物理像素和逻辑像素的问题,在此不做更深的讨论。总之,这个viewport是指网页浏览器(不管是PC还是移动端)中呈现网页的区域,站在用户的角度来说,就是用户能看到的地方。正常来说,这个视口的宽度和设备宽度(屏幕宽度)是一样的,但也有例外,比如当你缩放拖拽浏览器的时候,视口也会随之变化(这也是个检查页面是响应式效果的小窍门)。

视口的宽度获取是响应式设计的基础,响应式页面的响应也就是响应视口宽度的变化。那该如何准确获取视口宽度呢?

两种思路。

一种是用JS获取并且修改CSS。但这种方法除了有js无法使用的风险,更主要的是结果并不是我们想要的。通过document.documentElement.clientWidth获得的设备宽度是厂家设置的宽度(也就是竖屏时候的宽度),也就是当横屏的时候,js获取的还是原来的宽度,这就是实际情况不符了。

另外一种方式是通过设置HTML meta标签来约束视口,其实是控制浏览器如何来渲染网页。代码为:

<meta name=”viewport” content=”width=device-width, initial-scale=1.0,maximum-scale=1.0,user-scalable=no” />

其中“width=device-width”设置视口为设备宽度,“initial-scale=1.0”设置初始化的视口大小是1.0倍

“maximum-scale=1.0”规定允许放大的最大倍数是1倍,“user-scalable=no ”不允许缩放视口,这样保证了与设备显示宽度一致。

CSS媒体查询(Media Query)

CSS媒体查询是响应式页面的核心所在,主要功能是对不同的宽度做出不同的CSS动作(响应),并将这种动作告知浏览器。媒体查询的语法是@Media 和 and操作符,分别查询设备类型和设备属性。比如

@media screen and (min-width:900px){

body{background-color:blue}

}

意思是对所有的屏幕,当宽度大于等于(最小宽度)为900px的时候,应有此样式。比如设备宽度为980px的时候,body的背景颜色设置为蓝色。

同样,可以用and连接多个条件,做地更细化。

@media screen and (min-width:600px) and (max-width:900px){

p{ color:red}

}

意思是对所有的屏幕,当宽度大于在600和900像素之间(包含),将P标签内容的颜色设置为红色。

需要注意的是,IE一些低版本的浏览器如IE6、7、8是不支持媒体查询的,尽管已经很古老,但还是要避免,所以需要先写一个基础的CSS,一些特殊的需要变化的CSS代码则可以在媒体查询里。

创建

有了以上的基础,我们结合流式布局和栅栏布局概念,就可以自己开着手开发响应式页面,当然也可以利用其它现有的工具来提高开发速度。

目前主流前端UI框架都是响应式的,比如Bootstrap、jquery UI、dojo等。下面以Bootstrap为例,师范如何快速创建一个响应式页面。

先到bootstrap官网下载响应的文件,或者你可以用线上的,不过还是建议下载到本地。

注意可以把css和js文件路劲换成本地路径(相对路径),其中bootstrap.min.css和bootstrap.min.js是Bootstrap的核心文件,而bootstrap.min.js是依赖于JQ的,所以,JQ必须在bootstrap.min.js之前加载。这样,你就结合Bootstrap的栅格系统和各种组件搭建自己的响应式页面了,另外,入股你觉得Bootstrap的样式不好看,你可以可以借助媒体查询,在bootstrap.min.js之后引入自己的自定义css覆盖默认的样式。

小技巧

当我们在做响应式页面的调试和测试的时候,不需要真的拿所有的真机来测试,如果有是最好。可以采用各种仿真模拟器来检测,准确度还是挺高的。浏览器就有各种常用设备的模拟,以谷歌为例。F12打开调试版,然后点那个手机图标就可以选择对应的设备来模拟了。

注意事项

响应式尽管酷炫省事,也并不是完美无缺。一方面响应式页面可以适应多种设备,但只是页面一样,为了提高移动设备,不可避免需要通过舍弃一些内容来减负。减负其实是迫不得已的做法,用户体验不好,更很难和APP的体验,这对于那种展示型网站或许是一个好的选择,但并不适合所有的网站。即使最终的呈现效果看内容减少了,但是这是在完全加载页面内容之后处理后的结果,也就是对移动端而言,前期浪费了很多时间和流量加载了一些没用的内容。另外一个方面是虽然兼容不同的设备,但是还是同一个有页面,这就会给搜索引擎蜘蛛造成困扰,不利于SEO的推广。

总之,响应式设计有好有坏,关键看什么时候怎么使用。

PK掉Java、Python,Javascript成年度最受欢迎编程语言,现在盘它还来得及吗?

没有看错,2018年最受欢迎的编程语言不是Java,也不是火得一塌糊涂的Python,而是Javascript。2018年国外著名开发者社区Stack Overflow 最新调查显示,超过71.5% 的专业开发者将 JavaScript 评为最受欢迎的编程语言。

除了Stack Overflow,Javascript也经常活跃于各大榜单,而且经常名列前茅。

Github 2017年度回顾提供了“Pull Requests”排行,其中Javascript超越Java和Python,排名第一。这也说明Javascript设计的项目在GitHub上占有非常大的比例。

Indeed网站的数据显示了需求最高的编程职位,Java排名第一,Javascript排名第二。

Javascript从当初被人忽略的小厮,到如今活跃各大排行,并且超越多位老牌大哥,发展势头迅猛,可以说是程序语言世界的DS逆袭的典范。但每一条逆袭之路,都是一部血泪史。下面看看javascript的前世今生。

出生卑微

Javascript的诞生是为网页增加交互功能而设计的,当时主要是想主要运行在网景开发的浏览器上,定位只是是一种网页脚本语言,性质上来说JS是一门基于原型的、动态的、弱类型脚本语言。

Brendan Eich是当时是一位就职于网景的年轻工程师,现在被认为是Javascript语言之父。由于公司领导层的干涉和影响,Javascript是在Brendan Eich比较不情愿和随意的情况下,仅用了10天就创造出来的。Javascript日后的流行,可能Brendan Eich自己都没有想到。

正因如此,Javascript甚至遭到了“亲生父亲”的嫌弃。Brendan Eich曾坦言:与其说我爱Javascript,不如说我恨它。它是C语言和Self语言一叶青的产物。他还引用了十八世纪的英国文学家约翰一段名言表达自己对JS的看法:the part that is good is not original, and the part that is original is not good(它的优秀之处并非原创,它的原创之处并不优秀)。

在当时Java ,C横行天下的时候,JS只是运行在当时并不是流行的浏览器上的一种脚本,可以说低到尘埃里。

备受Diss

JS从一开命名就饱受非议,知道的人都了解Javascript和Java是两种截然不同的语言。这个截然不同不仅仅指内涵,还还有截然不同的地位:一个出生正统,如日中天,一个庶出旁门,名不经传。不知道的知道以后,就直接Diss说Javascript是在蹭Java的热度。

除了江湖名分被非议,JS自身也确实诸多不足,导致备受质疑。由于设计JS的过程时间太短,其中细节考虑得并不严谨,导致后来很长一段时间,Javascript写出来的程序混乱不堪。

由于天生的缺陷和尴尬的地位,javascript一度不被承认是一种编程语言,js开发者也经常遭到嘲讽和调侃。

发展混乱

JS是运行在浏览器上的,但是浏览器江湖四分五裂,大家各自为战,让JS的发展更加异彩纷呈(混乱不堪)。微软还创建自己的IE浏览器的脚本语言——Jscript。

JavaScript是按ECMAScript规范实现的一种脚本语言,类似的还有JScript、ActionScript。JS基于此开发并且还提供了ECMA规范外的额外功能。

到目前为止,ECMAScript一共发布了8个版本:

      1. 1997年06月,发布第一版ECMAScript 1;
      2. 1997年06月,修改规范完全符合ISO/IEC 16262国际标准,大修之后发布为ECMAScript 2;
      3. 1999年12月:增加正则、更好的文字处理、新的控制语句、try/catch异常处理、更加明确的错误定义,数字输出格式等等,发布为ECMAScript 3;
      4. 大改的ECMAScript 4,放弃发布,该版本被直接跳过;
      5. 2009年12月:完善了ECMAScript 3版本、增加”strict mode,”(严格模式)、以及getter和setter、JSON库支持和更完整的对象属性,发布为ECMAScript 5 ;

        2011年06月:使规范更符合ISO/IEC 16262:2011第三版,发布为ECMAScript 5.1;

      6. 2015年06月:本增加了非常重要的东西,改动比较大,比如箭头函数,引入面向对象等,为ECMAScript 6(ES6),亦称为ECMAScript 2016;
      7. 2016年06月:完善ES6规范,新增:求幂运算符(*)和array.prototype.includes方法也被称,为ECMAScript 6(ES6),亦称为ECMAScript 2016;
      8. 2017年06月:增加新的功能,如并发、原子操作、Object.values/Object.entries、字符串填充、promises、await/asyn等等,为ECMAScript 8。

从JS核心ECMAScript充满波折和近乎让人咋舌的版本更新就可以知道JS的发展并不顺利。而且各大浏览器对JS的也不是由JS说了算,这也严重影响了JS开发和发展的进程。比如ES6中的箭头函数,各家浏览器的支持层度千差万别:

改革自强

尽管困难重重,但是JS改革的脚步从未停止。从其版本发布过程中,可以看出,JS一直跟随市场不断调整自己,不断改正自己的不足,纳入新的特点,有时候甚至是颠覆式的改革,其痛楚不小于刮骨疗毒,生儿长出新的肌肉。经过不断的修改、迭代,js已经是一门成熟的开发语言了,可以做的事情越来越多。

迎风而起

JavaScript可运行在所有主要平台的所有主流浏览器上,也可运行在每一个主流操作系统的服务器端。随着互联网的爆发,作为各大浏览器唯一默认的语言,JavaScript 几乎无处不在——JS终于迎来了发展的春天。在传统的前端, 各种框架层出不穷,你可以用Angular、React 或 Vue 等快速构建基于浏览器的 Web 应用程序。在服务器端,Node.js 能够让开发者使用与前端一样的编程语言来开发后端程序。甚至基于Node,开发者可以编写物联网(IoT)项目,以及进行机器学习方面的程序。而且,随着JS的日渐完善,整个互联网行业对JS的支持也在加强,谷歌、微软、Facebook以及亚马逊等科技巨头都在大力使用 JavaScript。

到目前为止,JS它已经从当初仅运行在浏览器的脚本语言,变成了现代的多功能语言,而且这一过程还在继续意欲一统江湖。

以上是JS发展的历程,现在作为一个web开发者,你所要做的就是:盘它!

下一篇接着上一篇,2019年Web开发趋势分析和学习指南——高级篇,关注跟我一起来 盘 吧!

Web开发提升手册:2019年前端趋势与能力提高方法——进阶篇

进阶篇的提升是全方位的提升,包括知识掌握深度、技术应用能力、问题转化能力、团队协作能力、利用工具能力等。如果说新手阶段是在演习,熟悉兵器,进阶就是要上战场了。战场上就是真刀真枪,每一个举动都关系到身家性命——钱。这个战场就是项目,成果就是互联网产品。总之,就是文武兼备,进阶的开发者要有与团队快速完成项目并投入商业的能力。

要学的真多

武——过硬的技术

武指的是技术能力——进前端知识掌握的深度与应用。进阶的开发者已经是个成熟的开发者了,要快速要对HTML、CSS和JavaScript知识有全面的掌握,并将之融会贯通,揉成一个东西,快速转换成具有价值(满足某些需要的功能或者创造商业价值)的产品。

推荐使用原生的代码去实现,但由于商业环境的激烈竞争,我们仍然可以借助一些辅助工具来加速这个过程,比如学习和使用前端UI框架,Bootstrap、Bulma、Materialize等,他们都是非常优秀的响应式框架,有助于我们快速构建自己的应用,当然在利用之于,如果你研究挖掘框架本身,无疑你将会收获更多。

除了UI框架,随着前端工程化和大型化的趋势,JS框架如雨后春笋般发展。这些框架带来了新的交互和体验,以及模块化的开发模式,有助于团队协作完成大型项目,所以掌握这些框架,非常有利于你在战场上速战速决。目前比较火的有React、Angular和Vue。

其次,实际项目中很重要一方面就是数据交互。基本的网络协议,通信方法,get、post、Ajax要学起来,如果略懂后台知识是最好的。

最后,良好的编程习惯和规范也是一个程序员素养最好体现。

文——理解沟通执行能力

文就是你的软实力或者说是你的情商方面体现出来的。比如理解能力,团队协作能力,抗压能力、沟通表达能力。进阶的开发者必须完成项目,而且大多数项目都是以团队形式完成的,所以出了过硬的技术,以上能力能降低沟通成本,缩短开发周期,提高效率,提高产品的质量。

工作态度和自我管理也是在工作中非常重要的方面。

器——开发工具和协作工具

  1. 编辑器及其插件

    前端开发常用的编辑器由轻到重分别为notepad++、Sublime Text、Atom、Brackets、HBuilder、VS Code、WebStorm等,当然据说有高人用记事本写代码的,只能跪拜,DW就不推荐使用了。

    另外,插件才是编辑器最迷人的地方,好的插件可以减轻编码带来的痛苦,让原本乏味的工作看起来更加酷炫。

  2. 版本管理工具以及模块化

    Git是每一个程序员都知道也都必须会用的版本管理工具,前端开发亦如此。一些基础的命令行,如touch, cd, mkdir什么的必须会, 这些在工具使用过程中非常有用。其他使用到的工具有:

    包管理工具:NPM 或 Yarn

    打包工具:Webpack 或者 Parcel

    任务管理和构建工具:Gulp 或者 Grunt

  3. 状态管理工具

    状态管理是指管理你的应用级的状态,对于使用框架的大型前端项目, 可能需要经常用到。常见的工具有

Redux(Context API)

Apollo(GraphQL Client)

Vuex

NgRx

总结:进阶的开发者掌握技术知识,能够利用工具,和他人协作,将知识转化产品,变投入商业用途,实现价值。毕竟产品挣钱,老板才能挣钱,老板挣钱了,你才可能有钱分啊!

加油!

不疯魔 不成活

大牛指路:2019年Web开发趋势分析与学习指南——新手篇

大牛指路:2019年Web开发趋势分析与学习指南——新手篇

2018已经过去,2019年马不停蹄而来,时间匆匆从未停下脚步,你为新的一年做好规划了吗?或许你还没有进入web的精彩世界,或许你已经是被html,css,js代码虐过的前端小白,亦或者你是各种框架应用地得心应手的前端高手,甚至你已经野心勃勃的开始向后端延伸,涉足大数据,人工智能等新兴领域。无论你处于什么阶段,这篇外国开发者的分享一定会对你有启发,助你开启新年的前端之路。

基础阶段——新手

一、HTML、CSS和Javascript基本方面

  1. HTML的各种语义化标签;
  2. 基本CSS知识,包括定位(possition)、盒模型(box)等;
  3. 布局:Flexbox & Grid
  4. 在CSS中使用变量;
  5. 了解浏览器并学会使用浏览器开发者工具帮助开发

三大基石 三座大山

二、响应式页面

为适应不同尺寸的设备并控制开发和维护成本,响应式页面已经越来越平常。响应式页面的基础知识包括meta标签设置视口(viewport)、使用媒体查询(@media screen and(条件)等)、移动优先,柱状显示等、宽度不固定,使用百分比、响应式图片等

千人千面

三、CSS预处理

CSS预处理可以使CSS代码更具可读性,更方便维护,尤其在团队开发中,将公共样式独立成一个单独的文件,每个人只需要在自己编写的sass文件顶部采用@import就能直接引用,提高了代码的复用性,和开发效率。常见的预处理器有Sass、LESS和Stylus,他们都具有具有变量、作用域、混合、嵌套、继承、运算符、颜色函数、导入和注释等基本特性。

四、踏实学好原生JS

javascirpt是一门典型的入门容易精通难的语言,市场上层出不穷的js框架和库为大家使用js提供了方便,降低了门槛,但同时也降低了热热门操纵JS的能力,原生js的威力远没有发挥出来,而随着ES6的普及,js的成熟,应用前景广阔,对原生js的要求也越来越高。学习原生js一定要耐得住寂寞,不能偷懒,js有点像内功,周期长,起效慢,但是一旦练成,威力无穷。

强大的ES6

五、使用服务器展示静态网站

网页的价值体现在用户的访问,曝光量越大,影响力就越大。想要人们通过网络就能访问到你辛辛苦苦制作的页面,就必须把你的页面发布到服务器上。简单来说就是要注册或者购买一个域名,购买服务器(个人学习购买虚拟主机足矣),进行域名解析和绑定,通过FTP工具将静态页面上传在服务器,这样别人就能通过网络访问到你的静态页面了。

在开发过程中,也可以使用Netlify, Github Pages等进行静态页面托管,进行团队协作。

以上五点式基本的知识点介绍和学习建议,经过反复的练习,就具备基本的根据设计图制作html,添加动态效果,发布到服务器,更新网站页面的能力,顺利成为新手了。

如何元素垂直居中?6招请收藏

在写页面的时候,很多前端程序员都面临一个简单又复杂的问题——垂直居中。其实垂直居中一直都是个顽疾,曾经难倒无数英雄汉,但无数程序员的脑细胞的牺牲为我们探索了几招,攻克了垂直居中这一世界性难题。

水平居中很简单

有点基础的同学都知道,要实现水平居中非常简单。如果要居中的元素本身是行内元素(inline),直接设置父级标签style样式:text-align:center。如果元素本身是块级标签,那么直接设置margin:o auto就行,同样适用于行内块级元素,当然把行内元素通过改变display属性值变成行内块级或者块级元素后同样适用,so easy.

如何垂直居中

有同学说把屏幕横过来,就居中了。脑洞太大但是没有人用用处。作为一个踏实勤奋又善于思考的前端攻城狮,要学会分析问题然后解决问题,正所谓看病抓药,就是这个道理,根据不同的情况选择最合适的方法,一击而中。开始吧!

1 对于最最基础的单行文本,要想实现垂直方向居中,很简单的方法就是让文本的行高等于父级元素的高度。这个仅适用于让当行文本垂直居中的情况,多行文本就不适用了。

2 如果是图片的话,直接设置img的属性vertical-align: middle;前提是需要设置父级元素为块级元素并且设置高度。

3 用absolute绝对定位,分别父级元素和子元素的position为

HTML:

节点内容节点内容

.out

.in {

position: absolute;

top: 50%;

left: 50%;

height: 30%;

width: 50%;

margin: -15% 0 0 -25%;

}

这个只适玉元素本身有规定的高度和宽度,但是实际应用中是要根据内容才能确定高度,所以就有了升级版

4 用absolute定位,并且可不限制高度。很简单,借助强大的CSS3中的translate() 变形函数。具体原理是translate() 属性值的百分比是元素本身的宽高为基准进行计算的,直接把margin的移动换成translate() 实现,让元素相对自身往左往上移动自己宽和高的一半,正好剧中。代码如下:

.in {

position: absolute;

top: 50%;

left: 50%;

transform: translate(-50%, -50%);

}

 

我在宇宙中心

 

 

5 利用Flexbox布局

Flexbox 好像是专门为这类需求而生的一样。我们只需写两行代码轻松搞定:

第一是先给这个待居中元素的父元素设置 display:flex,第二是再给这个元素自身设置 margin:auto

这个方法的缺陷是并不是所有浏览器都支持,好消息是越来越多的浏览器已经支持了。

6 依靠科技进步

一行代码搞定,就和水平居中一样:align-self: center。不过这个仅仅是未来CSS的规划,还没有现实支持。

但是有这么好用的特性,我们肯定要第一时间去点赞的。

一定要会的前端基础——浏览器的工作原理

浏览器大家都不陌生了,可以说没有浏览器,网络就是个迷宫,而不是个你接触到的精彩的网络世界。我们都知道,当我们需要访问网络上的一个站点的时候,需要打开浏览器,在浏览器上输入域名,然后点击回车,网站的内容就会呈现在你的眼前。正常情况下,这个过程很快,尤其现在网络提速的情况下,但是你却不知道就这短短几秒钟内,发生了什么?

浏览器背后

简单来说,你在浏览器看到的是自己电脑(本地的),但是这个东西在你没访问之前是网站的,浏览器的工作就是找到你要看的网站,然后把它的内容拿到你电脑的浏览器,然后你的浏览器整理打扮一下,然后在浏览器窗口展示给你。概括来说,浏览器就是“找”、“拿”、“整理打扮”。其中“找”和“拿”涉及到DNS寻址以及网络方面的知识,这里就不敞开介绍,这里主要介绍最后一个过程,就是浏览器将获取的资源进行“整理打扮”并展示给用户的过程。需要说明的是,网络请求的网站资源一般都是二进制流传过来的HTML、CSS、JS文件,以及图片、PDF以及其他类型的文件。

渲染(Rending)主流程: 将获取的HTML文档解析生成DOM树,然后生成渲染树,布局渲染树,最后是绘制渲染树,绘制的结果就是将内容(HTML文字字符)、样式(CSS)、动作(JS)和其他资源(图片、PDF文件等)作为浏览器窗口看到的页面。

渲染过程的主要步骤

而不同的浏览器内核,在这个主流程下的具体步骤,实现方法略微有区别,但主要步骤基本一致。

解析(Parsing)与生成DOM树

解析文档是将获取的文档按照一定的规则转化成符合规范的结构,也就是浏览器能够识别和处理的结构,解析的输入是HTML,CSS,JS文档等,输出通常是代表了文档结构的DOM节点树,也称语法树。具体来说,解析包括两个子过程,词法解析和语法解析。词法解析器将文档中的内容分解成有效标记,并处理一些无关的字符,解析器再根据一定的语法规则,生成解析树(DOM树)。

解析过程

HTML 解析器的工作就是是将 HTML 标记解析成解析树。

生成渲染树

在生成解析树的同时,还会构建渲染树。渲染树由可视化元素(标记)按照一定的顺序组成。渲染树的工作是规定顺序以保证正确的将页面绘制出来。不同的浏览器内核生成渲染书的方法不一样,Webkit内核将解析样式和创建渲染树的过程称为“附加”,每隔DOM节点都有一个“attach”方法。Gecko内核(火狐)则将渲染树中的元素称为”框架“(Frame)。处理html和body标记就会变为生成渲染树的根节点。这个根节点呈现对象类似于 CSS 规范中所说的容器 block,这是外层的 block,包含了其他所有 block。它的尺寸就是视口(viewport),即浏览器窗口显示区域的尺寸。

<html>

<head>

</head>

<body>

<div><img src=”img.png” /></div>

<p>渲染树</p>

</body>

</html>

需要注意的是,DOM中的节点和渲染对象并不是一一对应的关系,比如一些不可见的元素如样式中display值为none的元素,不是给用户阅读的节点<head>等就不会被生成到渲染树中。

布局渲染树

当生成了DOM树和渲染树,树的节点并没有位置和大小的信息,完全是杂乱无章的摆在那里。而计算节点位置和大小的过程就是布局的过程,称为layout 或者reflow.HTML文档是基于流的布局模型,也称文档流,其布局顺序为自然顺序,自上而下,从左向右。再进行样式的计算时,使用规则树计算样式,确定有限顺序和最终结果。重点需要了解的是盒模型

绘制渲染树

在增量的绘制过程中,一些渲染对象以不影响整棵树的方式改变,改变的渲染对象使其在屏幕上的矩形区域失效,这将导致操作系统将其看作dirty区域,并产生一个paint事件,操作系统很巧妙的处理这个过程,并将多个区域合并为一个。Chrome中,这个过程更复杂些,因为渲染对象在不同的进程中,而不是在主进程中。Chrome在一定程度上模拟操作系统的行为,表现为监听事件并派发消息给渲染根,在树中查找到相关的渲染对象,重绘这个对象(往往还包括它的children)。css2定义了绘制过程的顺序

这个就是元素压入堆栈的顺序,这个顺序影响着绘制,堆栈从后向前进行绘制。一个块渲染对象的堆栈顺序是:

1. 背景色-》2. 背景图-》3. border-》4. children-》5. outline

所有的渲染对象都有一个layout或reflow方法,每个渲染对象调用需要布局的children的layout方法。

以上四个流程是浏览器工作的主要原理,每个过程又包含非常复杂的子流程。上述一个完整的流程走完,只是表示页面完成一次加载,但是现实情况是,页面并不是一次可以加载完,而是不同的变化之中。基于性能和效率的考虑,还设计到浏览器重绘,线程,事件等一些列知识点。总之,两三秒打开页面的背后,远没有你看见的这么简单。复杂的背后交给前端,简单的结果呈现给用户,这也是产品的要义。

继续加油!

坚持努力,我们终将胜利!

Web前端开发必须懂——浏览器及其内核

对于用户来说,浏览器是用户的万花筒,从这里可以浏览网络世界的任何一个角落;对于前端开发工程师来说,浏览器就是前端知识最大的舞台。当然,现在的前端的舞台不仅限于浏览器,也有其他应用,如手机端的APP,但其基本原理和浏览器类似,正所谓入乡随俗,在别人的地盘耍事,就必须认识浏览器,了解其工作机理,知道其中规矩。下面我们开始一步一步探讨浏览器。

浏览器有哪些?

根据最新的统计显示,全球浏览器市场份额最大的几家厂商及其排名分别是:Google Chrome、Mozilla Firefox、Internet Explorer、Microsoft Edge、Opera及Safari,国内的主要浏览器UC、QQ浏览器、搜狗、360,百度等。

主流浏览器市场份额

前端工程师敲的代码就是在这些浏览器解读和执行的,他们的差别也就是在代码的解读和执行上。同样一行代码,不同的浏览器会有不同的解读和呈现,而且速度也不一样,给人的体验也不一样。而决定如何解释和执行代码的核心就是浏览器的内核。

浏览器组成

如果把浏览器做个拆分,其组成部分主要有:用户界面、浏览器引擎、渲染引擎、 网络 、JS解释器、UI后端、数据存储7个部分。

1 用户界面 - 包括地址栏、后退/前进按钮、书签目录等,也就是所看到的除了用来显示所请求页面的主窗口之外的其他部分。

2 浏览器引擎 - 用来查询及操作渲染引擎的接口

3 渲染引擎 - 用来显示请求的内容,例如,如果请求内容为html,它负责解析html及css,并将解析后的结果显示出来。

4 网络 - 用来完成网络调用,例如http请求,它具有平台无关的接口,可以在不同平台上工作。

5 UI后端 - 用来绘制类似组合选择框及对话框等基本组件,具有不特定于某个平台的通用接口,底层使用操作系统的用户接口。

6 JS解释器 - 用来解释执行JS代码。

7 数据存储 - 属于持久层,浏览器需要在硬盘中保存类似cookie的各种数据,HTML5定义了web database技术,这是一种轻量级完整的客户端存储技术。

浏览器内核

做过设计尤其是3D动画的人对渲染这个词应该不陌生。浏览器内核,其实就是浏览器的渲染引擎,英文叫“Rendering Engine”,它是浏览器的核心。渲染引擎负责对网页代码的解释并按照规则渲染出显示器上的网页。网页怎么显示,完全由它说了算。

四个内核以及已它为基础的浏览器:

(1)Trident内核,由于被微软采用,并得益于微软操作系统的普及,以前几乎一统天下,所以又称为“IE内核”,主要浏览器有IE系列浏览器;

(2)Gecko内核,因为被Mozilla FireFox浏览器采用并得到开发者的进一步丰富,又被称为“Firefox内核”;

(3)WebKit内核,是Safari浏览器使用的内核,由Apple研发。 Google Chrome、Opera及各种国产浏览器高速模式也使用Webkit作为内核。

(4)Blink内核,由Google和Opera Software共同开发的浏览器内核,现在Chrome(28及往后版本)、Opera(15及往后版本)都将Webkit内核换成了Blink内核。

一般来说,一个浏览器采用一个内核。但是国内的开发者脑洞比较大,开创性发明了双核浏览器。360浏览器、猎豹浏览器都是采用IE+Chrome双内核,搜狗、遨游、QQ浏览器也是双内核:Trident(兼容模式)+Webkit(高速模式); UC浏览器电脑版采用Blink内核和Trident内核,百度浏览器、世界之窗内核都是单核(IE内核)。

另外,浏览器内核另外一个很重要的部分就是JS引擎,之前JS引擎也被集成在内核中,但是随着JS引擎越来越独立,慢慢浏览器内核就是只渲染引擎了。

以上介绍了目前我们熟悉的浏览器产品,以及浏览器内核简介,下一次探讨真正核心的部分,也是和前端开发最相关的部分——浏览器的工作原理。