This repository has been archived by the owner on Nov 23, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
content.json
1 lines (1 loc) · 191 KB
/
content.json
1
[{"title":"JS堆栈内存","date":"2018-08-23T03:01:53.000Z","path":"/posts/8c41410f/","text":"堆栈内存的作用JS 中的内存堆内存和栈内存,所有堆栈内存的处理,浏览器会自行在内部执行 栈内存: 提供一个供 JS 代码自上而下执行的环境(作用域,代码都是在栈内存中执行的) 由于基本类型比较简单,它们都是直接在栈内存中开辟一个位置,直接把值存储进去的 堆内存:引用值对应的空间存储引用类型的(对象:键值对,函数:代码字符串) 堆内存的释放让所有引用堆内存空间地址的变量赋值为 null 即可,当堆内存没有被任何的变量或者其他东西引用时,就会在浏览器执行垃圾回收的时候,被销毁掉。 堆内存释放后,里面存储的值也就会被释放掉。 栈内存的释放全局作用域会在页面关闭或者刷新的时候释放。(栈内存释放后,存储在栈内存中的值也都会销毁。) 私有作用域:一般情况下,当函数执行完成,所形成的私有作用域(栈内存)都会自动释放掉,但是也有特殊的情况。 函数执行完成,当前形成的栈内存中,某些内容被栈内存意外的变量一直占用,此时栈内存不能释放,栈内存中存储的基本值也不会被释放,一直保存下来。最典型的就是闭包。 var i = 1;function fn(i) { return function(n) { console.log(n + (++i)); }}var f = fn(2); //=> i = 2f(3); //=>7, i = 2 n =3,执行 n + (++i) => 3 + 3 = 6fn(5)(6); //=>12, i = 5 n = 6,执行 n + (++i) => 6 + 6 = 12fn(7)(8); //=>16, i = 7 n = 8,执行 n + (++i) => 8 + 8 = 16f(4); //=>8, i = 3 n = 4,执行 n + (++i) => 4 + 4 = 8 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"JavaScript","slug":"JavaScript","permalink":"http://destinytaoer.cn/tags/JavaScript/"}]},{"title":"JS变量提升","date":"2018-08-20T11:34:53.000Z","path":"/posts/bd208f70/","text":"1. 变量提升的概念变量提升的概念:当栈内存(作用域)形成,JS 代码自上而下执行之前,浏览器首先会把所有带 var / function 关键字开头的进行提前声明或者定义,这种预先处理机制称为“变量提升”。 声明(declare):var a (默认 undefined)定义(defined):a = 12(定义其实就是赋值操作) 在变量提升阶段: 带 var 是只提升声明未定义(给个默认值 undefined) 带 function 是提升声明和定义都完成了 console.log(a); //=> undefined,如果后面都没有声明,那么就会报错var a = 12;b(); //=> 1,可以直接使用,如果后面没有定义,那么会报错function b() { console.log(1);} 因为用 function 关键字声明的函数 ,在变量提升阶段已经赋好值了,所以我们可以在 JS 文件中的任意位置调用这个函数 深入理解变量提升变量提升只发生在当前作用域开始加载页面的时候只对全局作用域下进行变量提升,因为此时函数中存储的都是字符串而已 在全局作用域下声明的函数或者变量是全局变量,同理,在私有作用域下声明的变量是私有变量[带 var/function 的才是声明] 代码执行时,跳过已提升的声明和定义浏览器很懒,做过的事情不会重复执行第二遍,也就是当代码执行遇到创建函数这部分代码后,直接跳过即可。遇到变量声明时,也会直接跳过声明,进行赋值。因为在提升阶段就已经完成变量的声明和函数的赋值操作。 函数执行,形成私有作用域后,也会进行变量提升私有作用域形成后,会先进行形参赋值,然后进行变量提升 ES5 中的作用域在 ES5 语法规范中,只有全局作用域和函数执行的私有作用域,其他大括号不会形成栈内存 2. 带 var 和 不带 var 的区别在全局作用域下声明一个变量,也相当于个 window 全局对象设置了一个属性,变量值就是属性值。而私有作用域中声明的私有变量和 window 没有关系。a; //=> undefinedwindow.a; //=> undefined'a' in window; //=> true 在变量提升阶段,在全局作用域中声明了一个变量 a,此时就已经把 a 当作属性添加到 window 上了,只不过此时还没有给 a 赋值,默认值为 undefinedvar a = 12; a; //=> 全局变量 a 12window.a; //=> window 的属性 a 12//=> 全局变量和 window 中的属性存在映射机制a = 13;window.a; //=> 13window.a = 14;a; //=> 14 全局作用域中:不带 var 时,本质是给 window 添加属性在读取属性时,首先检测其是否是变量,是变量则读取其值,不是变量,则读取 window 中的属性,window 也没有这个属性,则报错。a; //=> 报错window.a; //=> undefined,这里是对象机制,没有这个属性则返回 undefined'a' in window; //=> false,说明 window 中没有 aa = 12; //=> 相当于 window.a = 12,此时的 a 不是变量,而是 window 的属性a;//=> 12window.a; //=> 12 var a = 12, b = 13; //=> 此时 b 是带 var 的,相当于 var a = 12; var b = 13;var a = b = 12;//=> 此时 b 不带 var 的,相当于 var a = 12; b = 12;console.log(a, b); //=> undefined undefinedvar a = 12, b = 12;function fn() { console.log(a,b); //=> undefined 12 var a = b = 13; console.log(a, b); //=> 13, 13}fn();console.log(a,b); //=> 12, 13 私有作用域中: 带 var 的在私有作用域变量提升阶段,都声明为私有变量,和外界没有任何关系 不带 var 的不是私有变量,会向它的上级作用域查找,一直找到 window 为止(我们把这种查找机制叫做作用域链) function fn() { b = 12; 'b' in window; //=> true,在作用域链查找过程中,如果知道找到全局作用域 window 中也没有这个变量,则是相当于给 window 设置了一个属性 b console.log(b); //=> 12}fn();console.log(b); //=> 12,此时读取的也是 window 的属性 具体分析:a(); //=> f 函数体var a = 10;var a = 20;console.log(a) //=> 20a(); //=> 报错,此时 a=20,不是函数function a() { console.log(a);}/* * 变量提升过程: * var a; function a = xxxfff000 * 代码执行 * a() --> a 执行,里面输出 a,也就是地址对应函数 * a = 10; --> 这是的变量 a 从地址变成了数字 10 * a = 20; --> 这时的变量 a 从数字 10 变成数字 20 * console.log(a); --> 输出变量 20 * a() --> a 执行,相当于 20(),不是函数,所以直接报错:a is not a function */ fn();// 15var n = 13;console.log(n); // 13fn(); // 15console.log(n);//15function fn(){ n = 15; console.log(n);}fn(); // 15alert(n);//15// 在变量提升阶段 n :undefined// fn() n : 15// n = 13; n : 13// fn() n : 15 3. 变量提升的特殊情况(1)等号右边的不会进行变量提升fn(); //=> 变量提升,可以执行a(); //=> 变量提升,只提升了声明未定义,报错 a is not a functionf(); //=> 不提升,报错,f is not definedvar a = function f(){}function fn() {} (2)条件语句中的变量提升 对于 var 没有影响的,不管条件是否成立,都会进行变量提升 对于 function 比较特殊: 在老版本浏览器渲染机制下,声明加定义都提升 为了迎合 ES6 中的块级作用域,新版本浏览器对于函数,不管条件是否成立,都只提升声明,没有定义,类似 var console.log(sum2,sum3); //=> undefined undefinedconsole.log(f,g); //=> undefined undefinedif(1 > 2){ var f = 12; function sum2() { console.log(12) }} else { var g = 14; function sum3() { console.log(13); }}console.log(sum2,sum3); //=> undefined f:function sum3(){}console.log(f,g); //=> undefined 14 当条件成立,进入到判断体中(在 ES6 中它是一个块级作用域,不完整的块级作用域),第一件事并不是代码执行,而是类似于变量提升一样先把函数进行定义,也就是判断体中代码执行之前,函数就已经赋值了。console.log(fn); //=> undefinedif (1 === 1) { console.log(fn); //=> 函数本身 function fn() { console.log(1); }} (3)匿名函数、自执行函数、等号右边函数和 return 返回的函数都不会有变量提升,只有开头直接使用 function 声明的才会变量提升//=> 即使加上函数名,也不会变量提升(function(){ })()var a = function() {}obj.onclick = function(){}function a() { //=> e 不会提升 return function e() { }} (4)函数的形参与变量提升var a=12;function fn1(){ console.log(a); var a=13;}fn1(); //=> undefinedvar n=13;function fn2(n){ // 在变量提升之前就有了一个形参赋值的过程,也就是相当于 // n = 13 // var n 这里 n 的值不会改变,仍是 13 // console.log(n); //13 console.log(n); var n=14; console.log(n);}fn2(n);//=> 13 14 4. 重名问题的处理 var 和 function 关键字声明的名字,都是变量,只是存储的值不同。取相同的名字,也是重名 关于重名的处理:如果名字重复了,不会重新声明,但是会重新的定义(赋值),不管是变量提升阶段还是代码执行阶段都是如此。 需要注意的是:在变量提升时,如果变量没有值,才会给它默认的值 undefined,如果已经有值,那么这一步不会执行 /* * 变量提升阶段 * function a 定义,后面的 var a 重名,不会重新声明,所以被忽略 */function a() { console.log(a);}var a = 12; /* * 变量提升阶段 * 会把函数声明和定义全部提升,重名的时候,也是在这个阶段进行重新定义 * * 后面代码执行会忽略全部变量声明、函数声明和定义 * */fn(); //=> 4function fn() {console.log(1);}fn(); //=> 4function fn() {console.log(2);}fn(); //=> 4var fn = 100;fn(); //=> 报错,fn is not a functionfunction fn() {console.log(3);}fn();function fn() {console.log(4);}fn(); 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"JavaScript","slug":"JavaScript","permalink":"http://destinytaoer.cn/tags/JavaScript/"}]},{"title":"DOM的映射机制","date":"2018-08-10T13:15:24.000Z","path":"/posts/c52c9c94/","text":"前言这在我们平常操作 DOM 的时候司空见惯。就比如:我通过获取一个元素来改变其样式,自然而然的反映到 HTML 页面中。 但是,我们操作 JS 对象的时候,本质上操作的是 JS 堆内存,为什么会反映到页面中呢?就是因为浏览器存在这个 DOM 的映射机制。 1. 什么是 DOM 的映射机制?我们使用 JS 从页面获取到的元素对象,或者自己手动创建的已经插入页面的元素对象,与页面中的 HTML 元素是绑定在一起的。也就是说修改其中一个,另一个也会跟着自动修改。这就是 DOM 的映射机制。 2. 形成映射的几种情形改变元素对象的属性这是我们最常用到的一种情形。当我们需要为元素添加自定义属性、或者修改属性等,就可以从页面中获取到元素对象,然后对其进行修改,就能够自动反映到 HTML 页面元素上。//=> 修改从页面中获取的元素样式Div.style.color = 'red';//=> 修改已经插入页面的元素的属性var p = document.createElement('p');box.appendChild(p);p.dataset.index = 1; 这两种方式得到的元素对象,修改其属性,都能够直接反映到页面中,不需要再次插入页面中。 在元素内部继续添加元素//=> 在其内部插入标签或文本var list = Div.getElementsByTagName('li');console.log(list); // 空的元素集合Div.innerHTML('<li></li>');console.log(list); // 有一个元素集合//=> 添加自己创建的元素对象,同样原理Div.appendChild(p); 在容器中的数据绑定前,我们获取容器中元素,得到一个空的元素集合,容器数据绑定后,我们不需要重新获取,DOM 的映射机制会帮我们把新增加的元素映射到之前获取的空集合中,让其变为有元素的集合。 在页面中追加已有元素list = Div.getElementsByTagName('li')[0];Div.appendChild(list); appendChild 在追加元素对象的时候,如果这个元素在容器中已经存在,此时并不是克隆一份新的追加到末尾,而是把原有的元素移动到末尾。 其根本原因在于,同一个元素在页面中,只能够有一个位置。把 JS 元素对象插入页面中某个位置,实际上就是把其绑定的 HTML 元素移动到那个位置上。 这里的元素已经存在有两种情形: 元素是从页面中获取到的 创建的元素已经添加过一次,再次添加时 因此,就无需手动移除原先的元素,再进行添加。直接插入即可。 3. 特殊情况querySelectAll 获取的集合是静态集合(staticNodeList),不存在上述所谓的映射机制,基于这个方法,数据绑定完成后需要重新获取一次才可以。var box = document.querySelectorAll('#box');var box1 = document.getElementById('box');console.log(box); //=> 获取到的是 NodeList 对象console.dir(box1); //=> 而这里获取到的是 HTMLElement 的实例 这个特殊的 NodeList 不存在与 HTML 页面元素的映射,而且没有很多 HTMLElement 实例才拥有的方法。因此,使用这个方法的时候每次操作时,都应该重新获取。 另外,jQuery 中获取的元素同样不存在这些映射,实现映射需要使用其内部的方法,而且要使用原生 HTMLElement 实例的方法,需要通过后面加 [0] 的方法转换为原生元素对象。 另外,由于存在这种映射机制,在使用循环 DOM 中,改变了 DOM 的顺序,那么循环原本的顺序也就改变了。[].forEach.call(children, (item)=> { parent.appendChild(item);});//=> 这样做你会发现,循环完成后 children 改变了,不符合预期 因此,真实项目中,不应该过分依赖于 DOM 的映射机制。 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"JavaScript","slug":"JavaScript","permalink":"http://destinytaoer.cn/tags/JavaScript/"},{"name":"DOM","slug":"DOM","permalink":"http://destinytaoer.cn/tags/DOM/"}]},{"title":"记第一次博客改版更新","date":"2018-08-02T12:45:06.000Z","path":"/posts/ce1c69ab/","text":"前言博客很久没有更新文章了,主要是自身处于就业、学习的双重焦虑状态。 另外一个原因,是我在捣鼓上一个主题 next 的过程中,由于电脑的恢复出厂和一系列失误的原因,丢失了自己更改很久的版本。后来想再去重新做一遍已经失去了耐心。 最近,也是在这一系列的压力之下,却是想通了,有种豁然开朗的感觉。于是又再一次的踏上征程。仅以此次改版纪念这一次重生。 感谢一直以来都在默默支持我的你们。 主题变更没有太多的时间去研究模板引擎这类的东西,又不想花钱购买服务器。于是,还是选择了使用 hexo + GitHub page 帮我实现这个博客。 next 主题是我最喜欢的一个主题之一,比较喜欢它的简约以及功能的齐全和可扩展性。后来一想,其实没有必要,够用就行。花太多的时间捣鼓,还不如多写写文章。 在 hexo 的官网主题页,总共也不是很多,就一个个查看。 最终比较满意的只有三个: Maupassant tomotoes staunch 最终选定的是最花哨的 tomotoes。说实话,我看中的就是他的动画,以及布局。 插件选用 abbrlink:用于生成页面的唯一码,有利于 SEO 优化 valine 评论 jsonContent 搜索 不蒜子访问量统计 leanclound 阅读量统计 wordcount:文章字数统计 记录一些坑valine:主题作者把 appid 和 appkey 的名称,在模板和主题配置中不一致,导致了评论系统出不来。 index:要实现文章的排序,插件 hexo-generator-index 的 JS 文件中,把 order_by 的值写死了,导致无法通过博客配置更改文章顺序。//=>在 node_modules/hexo-generator-index/index.js 进行修改order_by: typeof hexo.config.order_by === 'undefined' ? '-date' : hexo.config.order_by 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"博客前言","slug":"博客前言","permalink":"http://destinytaoer.cn/tags/博客前言/"}]},{"title":"JS变量的创建机制","date":"2018-07-04T02:44:57.000Z","path":"/posts/31a465c1/","text":"前言JS 怎么创建变量?相信大家都会:var a;function b(){} 那么它们具体存储在哪里,又是怎么运行的呢? 这次,就聊一聊 JS 的堆栈内存和变量的创建机制。(这里只介绍 ES5 的机制) 1. 堆栈内存在了解变量创建机制之前,先来了解一下变量的存储空间。 存储空间分为栈内存和堆内存。 栈内存:作用域 提供一个供 JS 代码自上而下执行的环境(代码都是在栈内存中执行的) 存储基本类型值。由于基本类型比较简单,它们都是直接在栈内存中开辟一个位置,直接把值存储进去的 堆内存:引用值对应的空间 对象:键值对 函数:代码字符串 由于引用类型的值可能过于复杂,所以需要另外开辟空间来存储,而变量中存储的只是指向这个空间的地址。 2. 变量的创建(1)创建作用域当浏览器(内核/引擎)渲染和解析 JS 代码的时候,会提供一个供 JS 代码运行的环境,这个环境称为“全局作用域”(global / window scope),是一个栈内存 (2)进行变量提升将在作用域中使用 var / function 声明的变量进行提升。其中 var 声明的变量只提升声明,不定义 function 声明的变量,既提升声明,也提升定义 所以,函数在当前作用域的任何地方都可以使用。 (2)代码自上而下执行基本数据类型的值会存储在当前作用域下,以 var a = 12 为例 首先在当前作用域中声明一个变量 a(这一步会在变量提升阶段完成,执行时会忽略这个声明) 然后开辟一个空间存储值 12 最后让声明的变量与存储的值进行关联(就是赋值操作,也叫做定义) 基本数据类型(也叫做值类型),是按照值来操作的:把原有的值赋值一份放到新的空间或者位置上,和原来的值没有关系 引用数据类型的值,我们需要开辟一个新的空间(理解为仓库),把内容存储到这个空间中 首先声明一个变量(同样,这一步是在变量提升阶段完成,执行时会忽略这个声明) 然后开辟一个新的内存空间,把对象中的键值对依次存储起来(此空间有个 16 进制的地址) 让变量与空间地址关联起来(把空间地址赋值给变量) var obj = { n: 10, m: obj.n * 10 //=> Uncaught TypeError: Cannot read property 'n' of undefined};console.log(obj.m); 原因分析 形成一个全局作用域(栈内存) 代码自上而下执行 首先开辟一个新的堆内存,把键值对存储到对内存中 n: 10, m: obj.n * 10 此时堆内存信息还没有存储完成,空间地址还没有与变量 obj 关联,此时的 obj 是 undefined,obj.n <=> undefined.n,所以报错 var obj = { n: 10};obj.m = obj.n * 10; // 此时的 obj 已经有值了console.log(obj.m); //=> 100 引用类型不是按照值来操作,它操作的是空间的地址:把原有空间地址赋值给新的变量,但是原来的空间没有被克隆,还是同一个空间,这样就会出现多个变量关联的是相同的空间,相互之间就会存在影响。 var arr1 = [3, 4];var arr2 = arr1;arr2[0] = 1;arr2 = [4, 5];arr2[1] = 2;arr1[1] = 0;console.log(arr1, arr2); //=> 1, 0, 4, 2 原因分析: 数组也是对象,属于引用类型,会开辟一个新的堆内存保存 [3,4] 往下,arr2 = arr1,此时两个变量同时保存一个堆内存的地址 改变 arr2 会反映到 arr1,此时 arr1: [1,4] arr2: [1,4] 新开辟一个堆内存,保存 [4,5],然后再把地址赋值给 arr2 此时两个变量关联的内存不再一样,对其的操作不再相互影响,此时 arr1: [1,4] arr2:[4,5] 再次赋值后,arr1: [1,0] arr2: [4,2] 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"JavaScript","slug":"JavaScript","permalink":"http://destinytaoer.cn/tags/JavaScript/"}]},{"title":"Markdown添加Latex数学公式","date":"2017-12-09T13:05:22.000Z","path":"/posts/97ae8199/","text":"前言在编辑文章的时候,经常都会有使用数学公式的需求。我查找到一篇文章,总结的比较好,在这里跟你们分享。 需要注意的是,想要在 Markdown 中使用这些数学公式,需要你的编辑器支持这个功能。这里介绍的就是其中一种:Latex。我的博客对数学公式的支持也不是很好,跟 Markdown 的编译插件有所冲突,大家可以查看我的 CSDN 上的文章:Markdown 添加 Latex 数学公式 Markdown 中添加公式行内公式$行内公式$ 行间公式$$行间公式$$ Latex 数学公式语法角标(上下标)上标^{} 下标_{} 上下标命令用来放在需要插入上下标的地方,花括弧内为上下标的内容,当角标为单个字符时候,可以不使用花括号;如果角标为多字符或者多层次的时候,必须要使用花括号。 比如:x^2, x_1^2, x^{(n)}_{22}, ^{16}O^{2-}_{32}, x^{y^{z^a}}, x^{y_z} $$x^2, x_1^2, x^{(n)}{22}, ^{16}O^{2-}{32}, x^{y^{z^a}}, x^{y_z}$$ 使用文字作为角标 文字模式\\mbox{} 改变文字大小的命令\\tiny 比如:\\partial f_{\\mbox{\\tiny 极大值}} $$\\partial f_{\\mbox{\\tiny 极大值}}$$ 强制改变角标大小或层次命令\\scriptstyle 比如:y_N, y_{_N}, y_{_{\\scriptstyle N}} $$y_N, y_{N}, y{_{\\scriptstyle N}}$$ 第一种输出为正常输出,但输出效果不明显;第二种是将一级角标改为二级角标,字体也自动变为二级角标字体;第三种将一级角标改为二级角标,但是强制字体改为一级角标字体。 分式分式命令\\frac{分子}{分母} 比如:\\frac{x+y}{y+z} 行内分式:$\\frac{x+y}{y+z}$行间分式:$$\\frac{x+y}{y+z}$$ 表明行内分式字体比行间字体小,因为行内分式使用的是角标字体可以人工改变行内分式的字体大小,\\displaystyle\\frac{x+y}{y+z} $\\displaystyle\\frac{x+y}{y+z}$ 连分式x_0+\\frac{1}{x_1+\\frac{1}{x_2+\\frac{1}{x_3+\\frac{1}{x_4}}}} $$x_0+\\frac{1}{x_1+\\frac{1}{x_2+\\frac{1}{x_3+\\frac{1}{x_4}}}}$$ 可以通过强制改变字体大小使得分子分母字体大小一致:\\newcommand{\\FS}[2]{\\displaystyle\\frac{#1}{#2}}x0+\\FS{1}{X_1+\\FS{1}{X_2+\\FS{1}{X_3+\\FS{1}{X_4}}}} 第一行命令定义了一个新的分式命令,规定每个调用该命令的分式都按 \\displaystyle 的格式显示分式 分数线长度值是预设为分子分母的最大长度,如果想要使分数线再长一点,可以在分子或分母两端添加一些间隔\\frac{1}{2},\\frac{\\;1\\;}{\\;2\\;} $$\\frac{1}{2},\\frac{\\;1\\;}{\\;2\\;}$$ 其中第一个显示是正常的显示,第二个显示是分子分母前后都放入一个间隔命令 \\; 中 根式二次根式命令\\sqrt{表达式} 如果表达式是个单个字符,则不需要花括号,但需要在字符和 sqrt 之间加入一个空格 $n$ 次根式命令\\sqrt[n]{表达式} 被开方表达式字符高度不一致时,根号上面的横线可能不是在同一条直线上 为了使横线在同一条直线上,可以在被开方表达式插入一个只有高度没有宽度的数学支柱 \\mathstut\\sqrt{a}+\\sqrt{b}+\\sqrt{c},\\qquad \\sqrt{\\mathstrut a}+\\sqrt{\\mathstrut b}+\\sqrt{\\mathstrut c} $$\\sqrt{a}+\\sqrt{b}+\\sqrt{c},\\qquad \\sqrt{\\mathstrut a}+\\sqrt{\\mathstrut b}+\\sqrt{\\mathstrut c}$$ 当被开方表达式高时,开方次数的位置显得略低,解决方法为:将开方此时改为上标,并拉近与根式的水平距离,即显示将命令中的 [n] 改为 [^n\\!],其中 ^ 表示是上标,\\! 表示缩小间隔\\sqrt{1+\\sqrt[^p\\!]{1+\\sqrt[^q\\!]{1+a}}} 注意比较两个根式开方次数的显示位置 求和与积分求和命令\\sum_{k=1}^n表达式(求和项紧随其后,下同) 积分命令\\int_a^b表达式 比如: 无穷级数 $\\sum_{k=1}^\\infty\\frac{x^n}{n!}$ 可以化为积分 $\\int_0^\\infty e^x$ 也即是:$\\sum_{k=1}^\\infty\\frac{x^n}{n!} = \\int_0^\\infty e^x$ 改变上下限位置的命令:\\limits(强制上下限在上下侧) \\nolimits(强制上下限在左右侧) 比如:\\sum\\limits_{k=1}^n\\sum\\nolimits_{k=1}^n $\\sum\\limits_{k=1}^n$ 和 $\\sum\\nolimits_{k=1}^n$ \\int\\limits_0^\\infty e^x\\int\\nolimits_0^\\infty e^x $\\int\\limits_0^\\infty e^x$ 和 $\\int\\nolimits_0^\\infty e^x$ 上、下划线上划线命令\\overline{公式} 下划线命令\\underline{公式} 比如:\\overline{\\overline{a^2}+\\underline{ab}+\\bar{a}^3} $$\\overline{\\overline{a^2}+\\underline{ab}+\\bar{a}^3}$$ 上、下括弧上花括弧命令\\overbrace{公式}{说明} 下花括弧命令\\underbrace{公式}_{说明} 比如:\\underbrace{a+\\overbrace{b+\\dots+b}^{m\\mbox{\\tiny 个}}}_{20\\mbox{\\scriptsize 个}} $$\\underbrace{a+\\overbrace{b+\\dots+b}^{m\\mbox{\\tiny 个}}}_{20\\mbox{\\scriptsize 个}}$$ 数学重音符号这里以 a 为例,如果是字母 i 或 j 带有重音,应该替换为\\imath、\\jmath \\hat{a}\\check{a}\\breve{a}\\tilde{a}\\bar{a}\\vec{a}\\acute{a}\\grave{a}\\mathring{a}\\dot{a}\\ddot{a} $$\\hat{a}\\check{a}\\breve{a}\\tilde{a}\\bar{a}\\vec{a}\\acute{a}\\grave{a}\\mathring{a}\\dot{a}\\ddot{a}$$ 堆积符号 \\stacrel{上位符号}{基位符号} 基位符号大,上位符号小 {上位公式\\atop 下位公式} 上下符号一样大 {上位公式\\choose 下位公式} 上下符号一样大;上下符号被包括在圆弧内 比如:\\vec{x}\\stackrel{\\mathrm{def}}{=}{x_1,\\dots,x_n}\\\\ {n+1 \\choose k}={n \\choose k}+{n \\choose k-1}\\\\ \\sum_{k_0,k_1,\\ldots>0 \\atop k_0+k_1+\\cdots=n}A_{k_0}A_{k_1}\\cdots $$ \\vec{x}\\stackrel{\\mathrm{def}}{=}{x_1,\\dots,x_n}\\ {n+1 \\choose k}={n \\choose k}+{n \\choose k-1}\\ \\sum_{k_0,k_1,\\ldots>0 \\atop k_0+k_1+\\cdots=n}A_{k_0}A_{k_1}\\cdots$$ 定界符()\\big(\\big) \\Big(\\Big) \\bigg(\\bigg) \\Bigg(\\Bigg)\\big(\\Big) \\bigg(\\Bigg) $$()\\big(\\big) \\Big(\\Big) \\bigg(\\bigg) \\Bigg(\\Bigg)\\big(\\Big) \\bigg(\\Bigg)$$ 自适应放大命令\\left\\right 放在左右定界符前,自动随着公式内容大小调整符号大小 比如:(x)\\left(x^{y^z}\\right) $$(x)\\left(x^{y^z}\\right)$$ 占位宽度 两个 quad 空格 \\qquad, 两个 m 的宽度:$a \\qquad b$ 一个 quad 空格 \\quad, 一个m的宽度:$a \\quad b$ 大空格 \\, 1/3m 宽度:$a\\ b$ 中等空格 \\; 2/7m 宽度:$a\\;b$ 小空格 \\, 1/6m 宽度:$a\\,b$ 没有空格:$ab$ 紧贴 \\! ,缩进1/6m宽度:$a!b$ \\quad 代表当前字体下接近字符‘M’的宽度(approximately the width of an “M” in the current font) 集合相关的运算命令集合的大括号\\{ ...\\} $${ …}$$ 属于\\in $$\\in$$ 不属于\\not\\in $$\\not\\in$$ 包含于A\\subset B $$A\\subset B$$ 真包含于A \\subsetneqq B $$A \\subsetneqq B$$ 包含A \\supset B $$A \\supset B$$ 真包含A \\supsetneqq B $$A \\supsetneqq B$$ A不包含于BA \\not \\subset B $$A \\not \\subset B$$ A交BA \\cap B $$ A \\cap B $$ A并BA \\cup B $$A \\cup B$$ A的闭包\\overline{A} $$\\overline{A}$$ A减去BA\\setminus B $$A\\setminus B$$ 实数集合\\mathbb{R} $$\\mathbb{R}$$ 空集\\emptyset $$\\emptyset$$ 引自 引自:Markdown 添加 Latex 数学公式 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"markdown","slug":"markdown","permalink":"http://destinytaoer.cn/tags/markdown/"}]},{"title":"前端学习历程","date":"2017-12-01T05:31:47.000Z","path":"/posts/711a3dcc/","text":"前言简单介绍自己自 2016 年 11 月起至今,从定下学习前端目标,开始对前端进行学习的历程。 包含: 基础知识 书籍阅读 项目实战 工作经历 一、基础知识2016 HTML、CSS 入门 2017 JavaScript DOM、GitHub 入门 jQuery 入门 HTML5、CSS3 入门 Sass 入门 Bootstrap 了解 AJAX 入门 响应式布局 vue 入门 ElementUI 和 MintUI 了解 学习面向对象程序设计课程(C++) 掌握 HTML、CSS,深入了解 CSS 的部分机制与属性的特性 熟悉 HTML5,掌握 HTML5 的新标签与功能 深入学习 JavaScript 内置对象的属性、方法 了解闭包、原型等概念 学习数据结构课程(C语言描述) 2018 vue 加深学习 ES6 语法入门 小程序的入门 深入了解 JavaScript 内部机制,类型转换、变量提升、堆栈内存、闭包、原型等 面向对象编程思想、设计模式 拓展学习2016 GitHub 和 githubpage 上传项目 2017 gulp 学习 git 了解 npm 了解,下载各种包和运行服务器 hexo 搭建博客 ESLint 了解 学习计算机网络课程,了解 HTTP 协议 2018 GitBook 的入门 => 做参考笔记 学习 webpack 的基础配置 二、书籍阅读2016 Web前端设计与开发:HTML+CSS+JavaScript+HTML 5+jQuery Web前端开发精品课:HTML与CSS进阶教程 2017 javascript DOM 编程艺术 锋利的 JQuery 响应式网页设计、响应式网页设计实战 vue.js 前端开发快速入门与专业应用 HTML5 揭秘 CSS 权威指南 2018 CSS 揭秘 javascript 高级程序设计 ECMAScript 6 入门 数据结构与算法 JavaScript 描述 三、项目实战2017 仿小米官网,静态主页 仿深大内部网,静态主页 理财网站,响应式页面 destiny’Note,个人博客 2018 仿饿了么外卖,vue 项目实战 个人响应式简历 H5 交互简历 四、工作经历 时间 地点 工作 2018.3.8 - 2018.3.26 伟博思 小程序页面开发 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"人生历程","slug":"人生历程","permalink":"http://destinytaoer.cn/tags/人生历程/"}]},{"title":"ESLint (二)配置文件","date":"2017-11-30T14:28:10.000Z","path":"/posts/b0fbee66/","text":"一、配置方式 注释形式:使用 JavaScript 注释将配置信息直接嵌入到文件中 文件形式 .eslintrc.js .eslintrc.yaml 或者 .eslintrc.yml .eslintrc.json package.json 文件中创建 eslintConfig 属性 .eslintrc.js 文件module.exports = { root: true, parser: 'babel-eslint', parserOptions: { sourceType: 'module' }, env: { browser: true, }, extends: 'standard', plugins: [ 'html' ], 'rules': { // allow paren-less arrow functions 'arrow-parens': 0, 'semi': 0, // allow async-await 'generator-star-spacing': 0, // allow debugger during development 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 }}; .eslintrc.json 文件{ "parserOptions": { ... }, "env": { ... }, "globals": { ... } "rules": { ... }} .eslintrc.yml 文件--- parserOptions: ... env: ... globals: ... rules: ... package.json 文件{ "name": "mypackage", "version": "0.0.1", "eslintConfig": { "plugins": ["example"], "env": { "example/custom": true } }} 注意:配置文件如果在主目录下,那么会先使用与文件就近的配置文件,找不到其他的配置文件,最后才使用主目录下的配置文件。 主要配置信息有: 环境(Environments):脚本设计运行的环境。每个环境都带有一组预定义的全局变量。 全局变量(Globals) :脚本在执行期间访问的其他全局变量。 规则(Rules):启用了哪些规则以及错误级别。 二、解析器module.exports = { parser: 'babel-eslint', //解析器 parserOptions: { sourceType: 'module' } //解析器选项} 默认解析器:Espree 三、环境环境有浏览器 bower,Node 环境 node 等等module.exports = { env: { browser: true }} 在官网上查找所有环境 四、全局变量在 JavaScript 文件中使用注释来指定全局变量,请使用以下格式:/* global var1, var2 */ 这定义了两个全局变量,var1 和 var2。如果你想有选择地指定这些全局变量不应该被写入(只读),那么你可以设置每个 false 标志:/* global var1:false, var2:false */ 在配置文件中配置全局变量,请使用 globals 键并指示要使用的全局变量。将每个全局变量名称设置为等于 true (允许覆盖变量)或 false (禁止覆盖)。例如:module.exports = { globals: { \"var1\": true, \"var2\": false }} 注意:启用 no-global-assign 规则禁止修改代码中的只读全局变量。 五、插件ESLint 支持使用第三方插件。在使用插件之前,您必须使用 npm 来安装它。 要在配置文件中配置插件,使用 plugins 包含插件名称,两种写法module.exports = { plugins: [ \"plugin1\", \"eslint-plugin-plugin2\" ]} 注意:由于 Node 的 require 功能,全局安装的 ESLint 实例只能使用全局安装的 ESLint 插件,本地安装的版本只能使用本地安装的插件。不支持混合本地和全局插件。 六、规则要更改规则设置,您必须将规则 ID 设置为以下值之一: off 或者 0: 关闭该规则 warn 或者 1: 将规则打开为警告(不影响退出代码) error 或者 2: 将规则打开为错误(触发时退出代码为 1) module.exports = { rules: { \"eqeqeq\": \"off\", \"curly\": \"error\", \"quotes\": [\"error\", \"double\"] }} 参考 ESLint (一)简介与安装配置ESLint 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"javascript","slug":"javascript","permalink":"http://destinytaoer.cn/tags/javascript/"},{"name":"编码规范","slug":"编码规范","permalink":"http://destinytaoer.cn/tags/编码规范/"}]},{"title":"ESLint (一)简介与安装","date":"2017-11-30T14:25:05.000Z","path":"/posts/4e5d3138/","text":"一、关于ESLint 是一个由 Nicholas C. Zakas 于 2013 年 6 月创建的开源 JavaScript linting 实用程序。codelinting 是一种静态分析,常用于查找不符合某些样式指南的有问题的模式或代码。 JavaScript是一种动态和松散类型的语言,特别容易出现开发人员错误。如果没有编译过程的好处,通常会执行 JavaScript 代码以查找语法或其他错误。像 ESLint 这样的 Linting 工具允许开发人员在不执行 JavaScript 代码的情况下发现问题。 ESLint 创建的主要原因是允许开发人员创建自己的 LINTING 规则。ESLint 旨在使所有规则完全可自定义。默认的规则可以改变。他们都可以遵循相同的模式,无论是规则本身还是测试。虽然 ESLint 将附带一些内置的规则,使其从一开始就非常有用,但您可以随时动态加载规则。 ESLint 是使用 Node.js 编写的,通过 npm 提供了一个快速的运行环境和简单的安装。 关于ESLint 二、安装全局与局部安装npm install eslint --save-devnpm install -g eslint 创建配置文件./node_modules/.bin/eslint --init 对某个文件运行 ESLint./node_modules/.bin/eslint yourfile.js 参考 ESLint(二)配置文件起步 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"javascript","slug":"javascript","permalink":"http://destinytaoer.cn/tags/javascript/"},{"name":"编码规范","slug":"编码规范","permalink":"http://destinytaoer.cn/tags/编码规范/"}]},{"title":"JS类型转换总结","date":"2017-11-10T05:31:47.000Z","path":"/posts/dc5d25aa/","text":"前言JS 令人头疼的一点就是它属于弱类型语言,一个变量存储的值可以是字符串、数值、布尔值或者对象等,可以随时变更。获取一个变量,你不会知道其存储的值是什么类型的,所以很多时候都需要进行类型检测。 除了手动变更类型之外,有些情况下,JS 内部也会自动进行类型转换,以满足部分操作符以及语句等的执行。 下面就是我对 JS 类型转换的一些总结,其中大部分来自《JavaScript 高级程序设计》这本书。 1. Boolean 转换转换情况 调用 Boolean() 在 if 或 while 流程控制中,内部执行相应的 Boolean() 转换 逻辑运算符,主要是 ! 和 !!,内部执行 Boolean() 转换 转换规则 数据类型 转换为 true 的值 转换为 false 的值 String 任何非空字符串 空字符串"" Number 任何非零数字值(包括无穷大) 0 和 NaN Object 任何对象 null Undefined 不适用 undefined 也就是说,只有 0 / NaN / "" / null / undefined 才会转换为 false,其余都是 true 所以在 if 判断中,直接写变量有时候是不够严谨的。if (!a){ //=> 想要在 a 不存在或没定义的时候执行 //=> 实际上存储的值是 0 或者 '' 等也会执行}//=> 应该使用 typeofif (typeof a == 'undefined') { //=> a 不存在或没定义的时候执行}//=> 或者使用全等if (a === undefined) { //=> 使用 == 也不够严谨,因为 null == undefined //=> 需要区分 null 或 undefined 的 情况较少} 在真实的项目中还是会经常用到第一种写法,因为其较为简单,而且能满足需求。因为默认情况下,判断的值只有两种情况:第一种是不存在或者未定义、第二种就是约定的值。很少会出现约定的值是转换为 false 的情况,但是使用的时候也要特别的注意。 2. Number 转换转换情况 调用 Number()、parseInt()、parseFloat() 其他情况都是使用 Number() 的转换机制 isNaN() 一元加或减操作符,注意:这里是一元的,如 s = + s,区别于加法和拼接 递增或递减,以及加法(除了拼接)、减法、乘法、除法、求模等操作符 关系操作符 转换规则Number(): Boolean 值 true => 1 false => 0 null => 0 undefined => NaN String 值 只包含数字(包含正负号),将其转换为十进制数值,忽略前导零 包含有效的浮点格式,将其转换为对应的浮点数值,忽略前导零 包含有效的十六进制格式,将其转换为相同大小的十进制数值 空字符串 "",空格 ' ',换行符'\\n',制表符'\\t' => '0' 包含其他格式的字符串,则将其转换为 NaN Object 值 调用对象的 toString() 方法,然后依照上面的规则转换返回的字符串 // [普通对象]({}).toString() => '[object Object]' => NaN// [数组][12,23].toString() => '12, 23' => NaN[12].toString() => '12' => 12[].toString() => '' => 0// [正则]/^$/.toString() => '/^$/' => NaN// [函数]function a() {}a.toString() => \"function a(){}\" => NaN parseInt(): 第一个参数必须是字符串,如果不是则转换为字符串,使用 toString() 方法转换为字符串 忽略前面的空格,直至找到第一个非空字符 第一个非空字符不是数字字符或者负号,则返回 NaN 空字符串返回 NaN 第一个是数字字符,会继续解析下一个字符,直至遇到非数字字符,返回前面的数字字符 遇到非数字字符后,后面的字符都是无效的了 传入第二个参数:转换时使用的基数,即多少进制,就可以解析二进制、八进制、十六进制的字符串。指定了第二个参数的,字符串中甚至不用带前面的前缀,如 parseInt("AF", 16);//175 为了避免解析错误,任何情况下都应该明确指定基数,十进制也不例外 parseFloat(): 第一个参数必须是字符串,如果不是则转换为字符串,使用 String() 方法 字符串中第一个小数点有效,第二个无效 空字符串返回 NaN 始终忽略前导零 只要遇到非浮点字符或者第二个小数点,后面的字符串都无效 字符串解析为整数,那么返回整数 3. String 转换转换情况 基于 alert / confirm / prompt / document.write 等方法输出内容 调用 toString() 、String() 加号操作符,有一个是字符串时,内部调用 toString() 对象转换成 Number 类型时,内部调用 toString() 转换规则toString() 方法 返回相应值的字符串表现 数值、布尔值、对象和字符串值都有一个 toString() 方法 字符串的 toString() 方法返回字符串的一个副本 null => "null" undefined => "undefined" NaN => 'NaN' true => 'true',false => 'false' 普通对象只能返回 [object Object],不能返回字符串形式 数组 [] => '',[12, 23] => '12,23' 正则、日期等对象都返回其字符串表现 String() 转型函数,你可以认为 String 和 toString 转换机制是一样的。 4. 特殊转换+ 号操作的特殊情况// 虽然没有看到字符串,但是引用类型转换为数字时,会先转换为字符串,这样就变成了字符串拼接[12] + 10 //=> \"1210\"({}) + 10 //=> '[object Object]10'{} + 10 //=> 10//=> 原因是 {} 会被解析为代码块,最后只是操作了 +10 {} + {} //=> '[object Object][object Object]'//=> 非常特殊,不同浏览器解析有差异({})+{} //=> '[object Object][object Object]'{} + ({}) //=> NaN//=> 一行中开头的 {} 才会被解析为代码块,所以用 () 包裹后可以避免被解析为代码块,一行后面的 {} 不会被解析为代码块,而是空对象。 == 进行比较时对象 == 对象:地址相等才相等{} == {} //=> false[] == [] //=>false{name: 'xxx'} == {name: 'xxx'} //=> falsevar obj1 = {};var obj2 = obj1;obj1 == obj2 //=> true 对象 == 数字:把对象转换为数字对象 == 布尔:都转化为数字字符串 == 数字:把字符串转换为数字字符串 == 布尔:都转化为数字布尔 == 数字:把布尔转换为数字对象 == 字符串:把对象转换为字符串之后再比较 1==true //=> true1==false //=> false2==true //=> false,都转化为数字[]==false //=> true,都转换为数字[]==true //=> false,都转换为数字![]==false //=> true,先算 ![] 为 false,再比较![]==true //=> false,先算 ![] 为 false,再比较[]==![] //=> true,先算 ![] 为 false,然后都转换为数字再比较 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"JavaScript","slug":"JavaScript","permalink":"http://destinytaoer.cn/tags/JavaScript/"}]},{"title":"编码规范(二)CSS","date":"2017-10-26T01:34:18.000Z","path":"/posts/cc36fdab/","text":"前言统一的编码规范,有助于编写高质量、可读性强、易于维护的代码。 CSS 代码的编写,应该尽量简洁、高性能、高可维护性,达到三者的一个最佳平衡。不能为了简洁牺牲可维护性。 本文引自:编码规范 by @mdo 黄金定律不管有多少人共同参与同一项目,一定要确保每一行代码都像是同一个人编写的。 一、语法 用两个空格来代替 tab 单独的选择器单独放在一行 左花括号前添加一个空格 声明块的右花括号应当单独成行 : 后插入一个空格 每条声明都应该独占一行 所有声明语句都应当以分号结尾 以逗号分隔的属性值,逗号后面插入一个空格 不要在 rgb()、rgba()、hsl()、hsla() 或 rect() 值的内部的逗号后面插入空格。这样利于从多个属性值(既加逗号也加空格)中区分多个颜色值(只加逗号,不加空格)。 .5 代替 0.5;-.5px 代替 -0.5px 十六进制值应该全部小写 尽量使用简写形式的十六进制值 为选择器中的属性添加双引号 避免为 0 值指定单位 /* Bad CSS */.selector, .selector-secondary, .selector[type=text] { padding:15px; margin:0px 0px 15px; background-color:rgba(0, 0, 0, 0.5); box-shadow:0px 1px 2px #CCC,inset 0 1px 0 #FFFFFF}/* Good CSS */.selector,.selector-secondary,.selector[type=\"text\"] { padding: 15px; margin-bottom: 15px; background-color: rgba(0,0,0,.5); box-shadow: 0 1px 2px #ccc, inset 0 1px 0 #fff;} 二、属性声明2.1 顺序相关的属性声明应当归为一组,并按照下面的顺序排列: 定位 盒模型 版式 视觉 由于定位可以从正常的文档流中移除元素,并且还能覆盖盒模型相关的样式,因此排在首位。盒模型排在第二位,因为它决定了组件的尺寸和位置。 其他属性只是影响组件的内部或者是不影响前两组属性,因此排在后面。 .declaration-order { /* 定位 */ position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: 100; /* 盒模型 */ display: block; float: right; width: 100px; height: 100px; margin: 10px; padding: 10px; box-sizing: border-box; /* 版式 */ font: normal 13px \"Helvetica Neue\", sans-serif; line-height: 1.5; color: #333; text-align: center; /* 视觉 */ background-color: #f5f5f5; border: 1px solid #e5e5e5; border-radius: 3px; box-shadow: 0 0 10px #000; /* 杂项 */ opacity: 1;} 2.2 简写形式的属性声明在需要显示地设置所有值的情况下,应当尽量限制使用简写形式的属性声明。 padding margin font background border border-radius 大部分情况下,我们不需要为简写形式的属性声明指定所有值。例如 header 元素只需要设置上、下边距的值,因此,在必要的时候,只需覆盖这两个值就可以。 过度使用简写形式的属性声明 导致代码混乱 对属性值带来不必要的覆盖从而引起意外的副作用 重新的渲染造成浏览器资源的消耗 /* Bad example */.element { margin: 0 0 10px; background: red; background: url(\"image.jpg\"); border-radius: 3px 3px 0 0;}/* Good example */.element { margin-bottom: 10px; background-color: red; background-image: url(\"image.jpg\"); border-top-left-radius: 3px; border-top-right-radius: 3px;} 2.3 带前缀的属性当使用特定厂商的带有前缀的属性时,通过缩进的方式,让每个属性的值在垂直方向对齐,这样便于多行编辑。/* Prefixed properties */.selector { -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15); box-shadow: 0 1px 2px rgba(0,0,0,.15);} 2.4 单行规则声明对于只包含一条声明的样式,为了易读性和便于快速编辑,建议将语句放在同一行。对于带有多条声明的样式,还是应当将声明分为多行。/* Single declarations on one line */.span1 { width: 60px; }/* Multiple declarations, one per line */.sprite { display: inline-block; width: 16px; height: 15px; background-image: url(../img/sprite.png);} 2.5 媒体查询(Media query)的位置将媒体查询尽可能放在相关规则的附近。不要将他们打包放在一个单一样式文件中或者放在文档底部。如果你把他们分开了,将来只会被大家遗忘。 三、class 命名 class 名称中只能出现小写字符和破折号,破折号应当用于相关 class 的命名 避免过度任意的简写 class 名称应当尽可能短,并且意义明确 使用有意义的名称。使用有组织的或目的明确的名称,不要使用表现形式的名称 基于最近的父 class 或基本 class 作为新 class 的前缀 使用 .js-* class 来标识行为(与样式相对),并且不要将这些 class 包含到 CSS 文件中 四、选择器 对于通用元素使用 class ,这样利于渲染性能的优化。 对于经常出现的组件,避免使用属性选择器 选择器要尽可能短,并且尽量限制组成选择器的元素个数,建议不要超过 3 只有在必要的时候才将 class 限制在最近的父元素内(也就是后代选择器) 五、代码组织 以组件为单位组织代码段 制定一致的注释规范 使用一致的空白符将代码分隔成块,这样利于扫描较大的文档 如果使用了多个 CSS 文件,将其按照组件而非页面的形式分拆,因为页面会被重组,而组件只会被移动 5.1 不要使用原生 @import与 <link> 标签相比,@import 指令要慢很多,不光增加了额外的请求次数,还会导致不可预料的问题。 使用 Sass 或 Less 等 CSS 预处理器的 @import 指令,将多个 CSS 文件编译为一个文件 通过 Rails、Jekyll 或其他系统中提供过 CSS 文件合并功能 六、注释确保你的代码能够自描述、注释良好并且易于他人理解,可以很大程度地提高可维护性。 好的代码注释能够传达上下文关系和代码目的。不要简单地重申组件或 class 名称。 对于较长的注释,务必书写完整的句子;对于一般性注解,可以书写简洁的短语。 八、Less 和 Sass8.1 操作符为了提高可读性,在圆括号中的数学计算表达式的数值、变量和操作符之间均添加一个空格。 8.2 嵌套避免不必要的嵌套。这是因为虽然你可以使用嵌套,但是并不意味着应该使用嵌套。只有在必须将样式限制在父元素内(也就是后代选择器),并且存在多个需要嵌套的元素时才使用嵌套。 九、编辑器配置将你的编辑器按照下面的配置进行设置,以避免常见的代码不一致和差异: 用两个空格代替制表符(soft-tab 即用空格代表 tab 符)。 保存文件时,删除尾部的空白符。 设置文件编码为 UTF-8。 在文件结尾添加一个空白行。 将这些配置信息添加到项目的 .editorconfig 文件中 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"css","slug":"css","permalink":"http://destinytaoer.cn/tags/css/"}]},{"title":"编码规范 (一)HTML","date":"2017-10-25T15:46:05.000Z","path":"/posts/22d73100/","text":"前言统一的编码规范,有助于编写高质量、稳定、可维护的代码。 本文引自:编码规范 by @mdo 黄金定律不管有多少人共同参与同一项目,一定要确保每一行代码都像是同一个人编写的。 实用为王尽量遵循 HTML 标准和语义,但是不要以牺牲实用性为代价。任何时候都要尽量使用最少的标签并保持最小的复杂度。 一、语法 使用两个空格来代替制表符 嵌套元素应当缩进一次(即两个空格) 对于属性的定义,确保全部使用双引号,绝不要使用单引号。 不要在自闭合元素的尾部添加斜线 不要省略可选的结束标签 二、HTML5 doctype为每个 HTML 页面的第一行添加标准模式的声明,这样能够确保在每个浏览器中拥有一致的展现。<!DOCTYPE html><html> <head> </head></html> 三、语言属性强烈建议为 html 根元素指定 lang 属性,从而为文档设置正确的语言。这将有助于语音合成工具确定其所应该采用的发音,有助于翻译工具确定其翻译时所应遵守的规则等等。<html lang=\"en-us\"></html> 四、IE 兼容模式IE 支持通过特定的 <meta> 标签来确定绘制当前页面所应该采用的 IE 版本。除非有强烈的特殊需求,否则最好是设置为 edge mode,从而通知 IE 采用其所支持的最新的模式。<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\"> 五、字符编码通过明确声明字符编码,能够确保浏览器快速并容易的判断页面内容的渲染方式。这样做的好处是,可以避免在 HTML 中使用字符实体标记,从而全部与文档编码一致(一般采用 UTF-8 编码)。<meta charset=\"UTF-8\"> 六、引入 CSS 和 JavaScript 文件根据 HTML5 规范,在引入 CSS 和 JavaScript 文件时一般不需要指定 type 属性,因为 text/css 和 text/javascript 分别是它们的默认值。<!-- link --><link rel=\"stylesheet\" href=\"code-guide.css\"><!-- style --><style></style><!-- script --><script src=\"code-guide.js\"></script> 七、属性顺序HTML 属性应当按照以下给出的顺序依次排列,确保代码的易读性。 class id, name data-* src, for, type, href, value title, alt role, aria-* class 用于标识高度可复用组件,因此应该排在首位。id 用于标识具体组件,应当谨慎使用,因此排在第二位。<a class=\"...\" id=\"...\" data-toggle=\"modal\" href=\"#\"></a><input class=\"form-control\" type=\"text\">![](...) 八、布尔型属性布尔型属性可以在声明时不赋值,直接写属性名认为是 true,不写认为是 false。 <input type=\"text\" disabled required><input type=\"checkbox\" value=\"1\" checked><select> <option value=\"1\" selected>1</option></select> 九、减少标签的数量编写 HTML 代码时,尽量避免多余的父元素。很多时候,这需要迭代和重构来实现。<!-- 一般 --><span class=\"avatar\"> ![](...)</span><!-- 更好 -->![](...) 十、尽量避免使用 JavaScript 生成的标签通过 JavaScript 生成的标签让内容变得不易查找、编辑,对搜索引擎不友好,并且降低性能。能避免时尽量避免。 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"html","slug":"html","permalink":"http://destinytaoer.cn/tags/html/"}]},{"title":"浅谈响应式","date":"2017-10-23T04:53:32.000Z","path":"/posts/80fe0eaf/","text":"前言 由于移动设备的增多,携带便利,人们在移动设备上浏览网页的时间不断增加,甚至要超过PC端。但是PC端的网页放到移动端,就会出现各种问题,如字体太小、图片不清晰等。浏览体验变得很差。于是,就有了响应式网页的诞生。在多种设备的不同尺寸的屏幕上,精巧设计和制作出最佳视觉体验的网页。 下面,就跟大家分享一下如何做一个响应式的网页。 我学习响应式时做的网页:理财网站 一、如何做响应式 网页元素的尺寸和字体大小在不同尺寸的屏幕显示不同大小,以达到最舒适的效果; 网页内容的信息内容在大尺寸屏幕中被全部显示出来,尽可能充实页面,而在小尺寸屏幕里则部分隐藏起来,通过用户的触控再把被隐藏的信息呈现出来; 网页信息在大屏幕中以多列形式展现,小屏幕中逐渐减少列数,直到变为满屏; 网页图片在不同屏幕下不失真,保持比例和清晰度。 二、设置viewport以及各种兼容设置2.1 设置 viewport页面宽度设置为设备宽度,初始缩放比例为100%<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"> 页面宽度设置为设备宽度,初始缩放比例为100%,最大、最小缩放为100%,用户不允许缩放,只能滚动<meta name=\"viewport\" content=\"width=device-width, initial-scale=1,maximum-scale=1, user-scalable=no\"> 一般设置第一种,还有其他情况应该根据需要设置 2.2 对IE浏览器的优化和兼容性告诉IE浏览器以尽可能高的仿真版本显示该网页,建议使用<metahttp-equiv=\"X-UA-Compatible\" content=\"IE=edge\"> 下面两个插件用于在IE8以及以下版本浏览器支持HTML5元素和媒体查询,如果不需要用可以移除<!--[if lt IE9]><scriptsrc=\"https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js\"></script><scriptsrc=\"https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js\"></script><![endif]--> 由于响应式网页面向的更多是移动设备,大多数不会使用低版本IE等浏览器,可以直接忽略这部分需求,不兼容IE低版本。设置一个条件注释,以提醒低版本用户。<!--[if lte IE 8]> <p class=\"browserupgrade\">您的浏览器版本老的可笑,请到<a href=\"http://browsehappy.com/\">这里</a>更新以获取最佳体验<p><![endif]--> 三、使用相对单位3.1 em rem 出现之前,很多人都使用 em 来实现响应式。但是 em 单位是相对父元素的字体大小而改变的,小的改动可能引起其所有子元素的样式改变,需要考虑的因素增多,难易把控。 主要应用于与字体大小有一定关联的样式中,例如 button 按钮的内填充等,这样就可以只通过改变字体大小就得到不失真的按钮,可维护性增强 3.2 remrem 的出现被很多人称为最好的相对单位。 基础设置首先设置html的字体大小为 62.5%,在chrome浏览器下有最小字体限制,1rem = 12px,其他都为 10px。这样就很容易使用 rem 作为单位,不需要考虑太多的父子关系等。 一般情况下,font-size 不使用 rem 单位,还有一些固定大小的元素,适合使用 px 注意:rem 存在兼容性问题,也就是说,使用 rem 作为单位的话,就不再考虑向下兼容了。 通过 js 控制根字体大小一般情况在项目的最前面加载一段 js 来修改 html 的 font-size,针对不同分辨率计算 font-size,监听浏览器更改 html 的 font-size(根据实际情况通过设计稿与当前可视区的大小做一个比例关系,通过这个比例进行缩放处理)。docEl.style.fontSize = 20 * (docEl.clientWidth / 320) + 'px'; 给html设置fontSize大小,其实就是在DOMContentLoaded或者resize变化后调整fontSize的大小,从而调整rem的比值关系。 var docEl = document.documentElement,//当设备的方向变化(设备横向持或纵向持)此事件被触发。绑定此事件时,//注意现在当浏览器不支持orientationChange事件的时候我们绑定了resize 事件。//总的来说就是监听当前窗口的变化,一旦有变化就需要重新设置根字体的值 resizeEvt = 'orientationchange' in window ? 'orientationchange' :'resize', recalc = function() { //设置根字体大小 docEl.style.fontSize = 20 * (docEl.clientWidth / 320) + 'px'; };//绑定浏览器缩放与加载时间window.addEventListener(resizeEvt, recalc,false);document.addEventListener('DOMContentLoaded',recalc, false); 3.3 百分比百分比是响应式布局中最常使用的一个单位之一。因为它是通过比例来控制大小的,能够自适应屏幕宽度,在布局中最常使用,但不适合用于具体元素的大小 总之,这些单位应该灵活的应用,而不是死板的只是用 rem 或者百分比等 四、媒体查询媒体查询是响应式网页的核心。媒体查询是一个将很多响应式概念和工具连接在一起的粘合剂。这些查询语句都是简单但是功能很强大的,它们允许我们检测设备属性,定义规则,并根据规则等的不同加载不同的CSS属性。//宽度大于等于 60em@media only screen and (min-width: 60em) { aside { width: 33%; }}//宽度小于等于 680px@media only screen and (max-width: 60em) { aside { display: none; }}//横屏下@media only screen and (orientation: landscape) { body { background-color: lightblue; }} 使用em或rem为单位都是一样的,但是rem有兼容问题,所以用em最为合适 其主要作用在于改变布局,以及字体大小、元素大小,部分元素的显示隐藏等 注意:即使响应式网页可以轻松的由媒体查询实现,但是我们在应用中,也应该尽可能的实现元素自身的响应式,以减少媒体查询的使用,来减少代码,提高性能。 参考:CSS3 @media 查询为响应式web设计创建媒体查询 五、弹性图片5.1 基本设置img{ max-width:100%;} 当有几张图片并排时,同样设置百分比 当你需要设置px间距时,使用calc()函数计算来合并相对单位和絶対単位以达到响应式 5.2 背景图片背景图片可以响应调整大小或缩放。以下是三个不同的方法: background-size 属性设置为 contain, 背景图片将按比例自适应内容区域。图片保持比例不变 background-size 属性设置为 100% 100% ,背景图片将延展覆盖整个区域 background-size 属性设置为 cover,则会把背景图像扩展至足够大,以使背景图像完全覆盖背景区域。注意该属性保持了图片的比例因此 背景图像的某些部分无法显示在背景定位区域中 设置媒体查询,在不同的屏幕大小使用不同分辨率的图片做背景 5.3 响应式图片 针对不同的分辨率屏幕加载不同分辨率的图片 1. javascript 或者 服务端的处理命令式的实现,通过对屏幕的宽度的判断,来改变图片的地址$(function(){ function makeImageResponsive(){ var width = $(window).width(); var img = $('.content img'); if (width <= 480) { img.attr('src','img/480.png'); } else if (width <= 800) { img.attr('src', 'img/800.png'); } else { img.attr('src', 'img/1600.png'); } } $(window).on('resize load',makeImageResponsive);}); 2. srcset 配合sizes说明式的实现,把几个图片(缩放的图片)的地址声明在img标签中,让浏览器来决定如何加载 srcset属性:格式:srcset = “图片地址 图片宽度,图片地址 图片宽度” 图片地址与图片宽度以空格隔开,图片宽度格式:480w即宽度480。把所有的图片地址都设置在srcset中。 注意: 在dpr为1的设备中,在小屏幕下,逐渐增大屏幕宽度,会加载出不同的图片,但是在加载了大分辨率的图片后,缩小屏幕不会改变图片,仍然使用大分辨率的图片 因为浏览器已经加载了大的图片在缓存中,再加载大的图片不再有网络消耗,浏览器会自行选择最优的处理. 在dpr为2的设备中,按原理应该在设定宽度除以2的地方加载不同的图片,但是浏览器会在比的临界值高一点的地方加载图片,浏览器会综合考虑来选择图片 设置 srcset,在图片容器变小时出现 bug,所以要设置 sizes sizes属性告诉浏览器以什么样的比例来显示图片格式:sizes = “(min-width:800px)800px,100vw” 单位可以是px、vw、vh,vw表示视口宽度,vh表示视口高度,100表示百分比 前面的表示媒体查询,没有添加媒体查询的表示其他情况,空格隔开后的是在这种情况下图片的预估宽度 图片宽度经常使用计算的形式:calc(100vw – 3em),100vw是默认值,需要根据图片容器的宽度进行设置 3. picture标签夺回部分浏览器自行选择图片的控制权。在需要在小屏幕加载裁剪图片,而在大屏幕中加载宽的图片记住要加入picture.js插件填平兼容性<picture><!-- 针对媒体查询设置不同大小的图片 --><source media=\"(max-width:36em)\" srcset=\"img/tiananmen-s.jpg 768w\"><!-- 横屏的设置 --> <source srcset=\"img/tiananmen-s.jpg 768w\" media=\"(orientation:landscape)\"> <source srcset=\"img/tiananmen.jpg 1800w\"> <!-- 针对媒体查询设置多组不同格式的图片 --><source type=\"image/svg+xml\" srcset=\"logo.svg 480w,logo.svg 800w,logo.svg 1600w\"><source type=\"image/webp\" srcset=\"logo.webp 480w,logo-m.webp 800w,logo-l.webp 1600w\"><!--在不兼容 picture 时加载的图片-->![](img/tiananmen.jpg)</picture> 浏览器会遍历 picture 里面的 source,找到满足当前环境的 media,把适合的 source 里面的 srcset 匹配到 img 里面的 src 中 4. svg图片svg是可缩放的矢量图形,基于可扩展标记语言来生成,可以用任何的文本编辑器来创建。Svg图片怎么缩放都不会失真,因为它不是基于像素的,是基于一定的绘制规则 六、网格系统6.1 什么是网格系统?基于网格设计,按列来布局。使用网格视图有助于我们设计网页。这让我们向网页添加元素变的更简单。 响应式网格视图通常是 12 列,宽度为100%,在浏览器窗口大小调整时会自动伸缩。 6.2 创建响应式网格视图首先确保所有的 HTML 元素 box-sizing 设置为 border-box,确保边距和边框包含在元素的宽度和高度间。* { box-sizing: border-box;} 计算每列的百分比: 100% / 12 列 = 8.33%。在每列中指定class="col-" ,用于定义每列所占的比例 :.col-1 {width: 8.33%;}.col-2 {width: 16.66%;}.col-3 {width: 25%;}.col-4 {width: 33.33%;}.col-5 {width: 41.66%;}.col-6 {width: 50%;}.col-7 {width: 58.33%;}.col-8 {width: 66.66%;}.col-9 {width: 75%;}.col-10 {width: 83.33%;}.col-11 {width: 91.66%;}.col-12 {width: 100%;} 所有的列向左浮动,间距(padding) 为 15px:[class*=\"col-\"] { float: left; padding: 15px; border: 1px solid red;} 添加清除浮动:.row:after { content: \"\"; clear: both; display: block;} 添加媒体查询,使其在不同尺寸的屏幕下,响应式安排列数@media only screen and (min-width: 600px) { /* For tablets: */ .col-m-1 {width: 8.33%;} .col-m-2 {width: 16.66%;} .col-m-3 {width: 25%;} .col-m-4 {width: 33.33%;} .col-m-5 {width: 41.66%;} .col-m-6 {width: 50%;} .col-m-7 {width: 58.33%;} .col-m-8 {width: 66.66%;} .col-m-9 {width: 75%;} .col-m-10 {width: 83.33%;} .col-m-11 {width: 91.66%;} .col-m-12 {width: 100%;}} 使用<div class=\"row\"> <div class=\"col-3 col-m-12\">...</div> <div class=\"col-9 col-m-12\">...</div></div> 七、Flex弹性布局Flex布局是W3C在2009年提出的新方案,可以简便、完整、响应式地实现各种页面布局。已经得到所有浏览器的支持。 语法介绍请查看:关于Flex布局使用flex实现的简单网格系统 参考 移动端 h5开发相关内容总结为响应式web设计创建媒体查询自适应网页设计 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"css","slug":"css","permalink":"http://destinytaoer.cn/tags/css/"},{"name":"响应式","slug":"响应式","permalink":"http://destinytaoer.cn/tags/响应式/"}]},{"title":"像素与viewport概念","date":"2017-10-22T15:00:15.000Z","path":"/posts/4af0d4fa/","text":"前言学习移动端、响应式,首先必须明白的就是像素和viewport的概念,才能搞清楚出现各种情况的原因。 本文主要介绍物理像素、逻辑像素的概念以及他们之间的关系,viewport的由来以及设置。下面与大家分享。 一、像素的概念 px :逻辑像素 ,浏览器使用的抽象单位 dp、pt:物理像素 dpr:设备像素缩放比 ppi:屏幕每英寸的像素数量,即单位英寸内的像素密度 ppi 120 160 240 320 dpr 0.75 1.0 1.5 2.0 ppi 越高,像素数越高,图像越清晰。Retina屏即高清屏,dpr 大于等于 2。 二、viewportweb初期,网页渲染在手机上,会只显示页面的其中一部分。用户需要通过滑动屏幕才能查看网页的全貌。由于用户体验太差,于是浏览器商就引入了 viewport 的概念。 2.1 手机浏览器的默认行为 页面默认先渲染在一个980px(ios)或其他的 viewport 里面 通过缩放,让用户能看到网页的全貌 为什么渲染时,要加入 viewport ?直接渲染在小屏幕会导致排版布局等的混乱 2.2 viewport 的概念两个 viewport :视口(visual) viewport 和布局(layout) viewport 视口 viewport 就是用户查看网页的视口(可以理解为屏幕),可以通过缩放来改变其大小 布局 viewport 就是网页渲染的一个底层页面,ios 默认 viewport 为980 px 指的就是布局 viewport 通过调用document.body.clientWidth查看默认布局Viewportwindow.innerWidth查看度量Viewport 2.3 不使用默认布局 viewport 的原因 不同设备的默认值不同,宽度不可控制 缩放后连接可能因为太小不能准确触控,又有滚动,交互差 font-size:40px=PC的12px,不规范 2.4 设置 viewport在 html 中使用元标签meta设置 viewport:<meta name='viewport' content='width=device-width,initial-scale=1,user-scalabel=no'> 相关参数 width:设置布局viewport的值 initial-scale:设置页面的初始缩放 minimum-scale:最少缩放 maximum-scale:最大缩放 user-scalable:用户能否缩放 最佳设置使视口 viewport = 设备宽度 = 布局 viewport width = device-width,让布局 viewport 等于设备宽度,也就是说,设置 320px 的元素会铺满 iphone5 的屏幕宽度。 initial-scale = 1,设置初始缩放比为1,使得缩放比因为网页的大小而改变,让视口 viewport = 布局 viewport user-scalable = no,使得视口 viewport = 布局 viewport 保持不变 参考 慕课网教程:Hello,移动WEB 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"css","slug":"css","permalink":"http://destinytaoer.cn/tags/css/"},{"name":"响应式","slug":"响应式","permalink":"http://destinytaoer.cn/tags/响应式/"},{"name":"移动端","slug":"移动端","permalink":"http://destinytaoer.cn/tags/移动端/"}]},{"title":"sass的使用","date":"2017-10-19T13:07:22.000Z","path":"/posts/1c539f20/","text":"前言在介绍之前,请大家先弄清楚下面的问题: 什么是 sasssass 是 css 的预处理器(css preprocessor) 为什么使用 sass1、 它能够帮我们更快更高效的编写更好维护的 css 。2、 它自带很多原生 css 没有的功能,如变量(现在 css 中已经实现)、条件语句等 如何使用sass1、 安装 sass :ruby环境、sass编译2、 sass的语法 下面要介绍的就是 sass 的基本用法。 一、安装和使用1.1 安装RubySASS是 Ruby 语言写的,但是两者的语法没有关系。不懂Ruby,照样使用。只是必须先安装Ruby 1.2 安装SASS在命令行输入下面的命令(必须先安装Ruby): gem install sass 1.3 文件后缀sass 有两种后缀名文件: 一种后缀名为 sass,不使用大括号和分号; 另一种就是 scss 文件和我们平时写的 css 文件格式差不多,使用大括号和分号。//文件后缀名为sass的语法body background: #eee font-size:12pxp background: #0982c1//文件后缀名为scss的语法 body { background: #eee; font-size:12px;}p{ background: #0982c1;} 在此也建议使用后缀名为 scss 的文件,以避免 sass 后缀名的严格格式要求报错。后面使用的也都是 scss 文件。 1.4 编译在屏幕上显示.scss文件转化的css代码: sass 文件名.scss 编译到 css 文件: sass test.scss test.css SASS提供四个编译风格的选项: nested:嵌套缩进的css代码,它是默认值。 expanded:没有缩进的、扩展的css代码。 compact:简洁格式的css代码。 compressed:压缩后的css代码。 生产环境当中,一般使用最后一个选项。 sass --style compressed test.sass test.css 监听某个文件或目录,一旦源文件有变动,就自动生成编译后的版本。 // watch a file sass --watch input.scss:output.css // watch a directory sass --watch app/sass:public/stylesheets 如果你不喜欢用命令行,可以使用: GUI界面编译工具:koala教程:Less/Sass编译工具,koala使用指南 二、基本语法2.1 嵌套规则 选择器嵌套。 //CSS代码div h1 { color : red;}//SASS代码div { hi { color:red; }} 属性嵌套 p { border: { color: red; }} 注意: border后面必须加上冒号。 使用&引用父元素a { &:hover { color: #ffb3ff; } //常用写法 .class & {color: #fff;} //在前面加上特殊类或父元素的写法} 2.2 变量 以$开头声明变量 $blue : #1875e7; div { color : $blue;//直接使用} 变量写在#{}中以镶嵌入字符串 $side : left;.rounded { border-#{$side}-radius: 5px;} 变量名用中划线分隔sass中变量名的分隔并没有要求,而且使用中划线或下划线,会指向同一个变量。但是,尽量使用中划线来统一规范。 变量作用域sass 中变量声明在某个规则块 { } 中,则只能在那个规则块内使用。定义在规则块外的,即此文件都可以使用。一般将变量声明放在文件最前面或者独立一个文件。 其他 请参考:sass语法 2.3 计算功能在代码中使用算式:body { margin: (14px/2); top: 50px + 100px; right: $var * 10%;} 注意: 除了/之外,其他都应该在符号两边加上空格 2.4 注释SASS共有两种注释风格。 标准的CSS注释 / comment / ,会保留到编译后的文件。 单行注释 // comment,只保留在SASS源文件中,编译后被省略。 在 /* 后面加一个感叹号,表示这是”重要注释”。即使是压缩模式编译,也会保留这行注释,通常可以用于声明版权信息。/*! 重要注释!*/ 2.5 导入文件@import命令,用来插入外部文件。 scss文件,编译后会合并到同一个 css 文件中 @import \"path/filename.scss\"; css 文件,则等同于 css 的 import 命令,编译后依然是导入文件 @import \"foo.css\"; 因为 css 中 import 会导致性能问题,所以一般不使用。 2.6 继承SASS允许一个选择器,继承另一个选择器。使用@extend命令:.class2 { @extend .class1; font-size:120%;} 2.7 mixinmixin 有点像C语言的宏(macro),是可以重用的代码块。 使用@mixin命令,定义一个代码块。 @mixin left { float: left; margin-left: 10px;} 使用@include命令,调用这个mixin。 div { @include left;} mixin的强大之处,在于可以指定参数和缺省值。@mixin left($value: 10px) { float: left; margin-right: $value;} 使用的时候,根据需要加入参数:div { @include left(20px);} mixin 里面不仅可以定义属性,还可以使用 css 规则,包含选择器等 注意:mixin 不能滥用,会导致性能问题。详情请查看Sass中文网 2.8 颜色函数SASS提供了一些内置的颜色函数,以便生成系列颜色。lighten(#cc3, 10%) // #d6d65cdarken(#cc3, 10%) // #a3a329grayscale(#cc3) // #808080complement(#cc3) // #33c 三、高级用法3.1 条件语句@if可以用来判断:p { @if 1 + 1 == 2 { border: 1px solid; } @if 5 < 3 { border: 2px dotted; }} 配套的还有@else命令:@if lightness($color) > 30% { background-color: #000;} @else { background-color: #fff;} 3.2 循环语句SASS支持for循环:@for $i from 1 to 10 { .border-#{$i} { border: #{$i}px solid blue; }} 也支持while循环:$i: 6;@while $i > 0 { .item-#{$i} { width: 2em * $i; } $i: $i - 2;} each命令,作用与for类似:@each $member in a, b, c, d { .#{$member} { background-image: url(\"/image/#{$member}.jpg\"); }} 3.3 自定义函数SASS允许用户编写自己的函数。@function double($n) { @return $n * 2;}#sidebar { width: double(5px);} 参考 Sass中文网Sass用法指南Sass Guide 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"sass","slug":"sass","permalink":"http://destinytaoer.cn/tags/sass/"},{"name":"css预处理器","slug":"css预处理器","permalink":"http://destinytaoer.cn/tags/css预处理器/"}]},{"title":"说说CSS学习中的瓶颈","date":"2017-10-19T02:45:27.000Z","path":"/posts/86591ac9/","text":"前言本文是在自己重新开始学习CSS的过程中看到的,与其说它是讲如何深入学习CSS,更多的是警醒的作用,看了文章之后,才真正认清自己的浮躁,也庆幸自己回头恶补。本文不涉及技术,但是希望大家都能看一看。 0 写在前面虽已数年,但未就学习专门写过文章,这回破处了。苍蝇不叮没有缝隙的鸡蛋,领导不做没有跟拍的表演,同样,想到写CSS学习的文章也是有原因的(虽然我的不少行为没有原因)。 情景再现(尊重隐私,下面故事中人名均为化名,有加工): 如月姑娘(本届D2上微博中奖上台最漂亮的那位)的内部分享会——关于CSS3 background相关内容……一顿巴拉巴拉……如月:假设背景图片500px500px,则应用background-size:50%后,显示的背景图片大小就是250px250px三晶:咔!不对吧!……CSS中的所有百分比都是相对于父级元素的,不会是自身……仁力:是啊,50%应该相对的是容器指定类型的box的尺寸…………又巴拉巴拉百分比值相关东西……如月:哦,教我们网页的那个老师让我们line-height使用百分比形式,说这样更好,行高自适应~~三晶:咔!我信了你老师的邪!百分比行高并不具有自适应性,除非使用该死低效的*通配符…… 上面场景剧情可以总结为:“一个百分号认识所引发的讨论”,然后,引发的后续剧情就是:“一个百分号讨论所引发的写文章的冲动”。 “冲动”在何处?在于我似乎看到了很多人都正面对的,但同时自己并未意识到的学习瓶颈。当然,所谓瓶颈并不是你不能够搞明白line-height:150%和line-height:1.5的区别,而是你没有意识到要搞明白。 这就是我多次提到的:想法、意识远比技术本身更有传授的价值! 1 何为瓶颈?“瓶颈”指瓶子的颈部,相对狭窄。这是很传神的一个词。因为狭窄,因此难以突破; 但是,一旦突破了,就是广阔天空(偌大瓶身)! 小弟不才,凑合画了个瓶颈示意图,如下: 图中,A → B → C → … 表示进阶,即相关技能的提升;①②③④则表示各个阶段要进入的瓶颈!这个适用于各行业,各学派。 杨过的武功学习与瓶颈 我们都看过《神雕侠侣》,为便于理解,我就以“神雕大侠”杨过的武功成长经历解释上图的含义: 各进阶阶段 阶段A武功杂:蛤蟆功,玉女剑,打狗棒,弹指神通 阶段B武功一流:整天蛇胆嗑药,玄武重剑 阶段C武功顶尖:勤学苦练,木剑之术;自创神功,黯然销魂掌 各阶段瓶颈 瓶颈①无压力:天资聪慧+主角光环,因此,一些杂七杂八功夫入门迅速 瓶颈②雕兄:该瓶颈突破全靠雕兄。蛇胆嗑药治伤增内力,武功引导与陪练 瓶颈③自身:海边多年苦练,内功积累。自身观点想法转变(武功都是人创造的,我也可以……),自创掌法 瓶颈④小龙女:野史外传,小龙女一起阴阳之类,神一般的存在…… 您可以对照您目前CSS或JS的学习,您觉得您目前突破的几个学习瓶颈,目前在第几阶段? 2 只缘身在此山中CSS的学习入门很容易。 也可以说CSS学习的第①个瓶颈很大(见上图①处瓶口),以至于不能称为“瓶颈”。可能只要1年甚至半年的时候,我们就能根据设计图迅速成型页面,能熟练使用些CSS hack,这个阶段我们的成长很快,只要有页面写或只要四处转转,我们每天都能汲取新知识。如果用二维曲线表示就是: 满瓶不动半瓶摇,这个阶段实际上是CSS非常初级的阶段,也是广大页面仔们最为浮躁,最自以为是,最觉得CSS不过如此的阶段!所学越多越知所知甚少,那些成天叫嚣的人往往半吊子居多。 所以,我这里有必要提个醒,睡在冻床上不知冷热的“牛人”们,小看CSS的结果就是你丫直接在高速公路上被淹死! 不过,大多数这个阶段的同行们都清楚,自己还有很多东西要学的。但问题在于,每天也努力工作了,也去花时间学习了,只是似乎只是纯粹经验的积累,没有学到多少实质性的东西。这就是学习的瓶颈! 拿“如月”同学举例:工作是很认真的,页面也是能写的,前端书籍也买了很多,技术博客也会逛,前端技术论坛也参加。但是最后的效果呢?在我看来,还是那个层次,没有实质性的提高!为什么呢? 泛泛的经验积累式学习,看不到自己技术的瓶颈所在,总在同一层次添砖加瓦。就跟杨过的A阶段一样,总是不停地学习新功夫,但都不是很深入很牛逼,结果,连对付霍都都吃力。 广度与深度任何一门学科都有其广度以及深度。在CSS的A级阶段,显然所学基本上是扩展自己知识面的广度:各个CSS属性熟悉,各个基本盒模型,各个声明在不同浏览器下的表现熟悉,兼容性问题如何修复熟悉等。 然而,CSS的属性就那么多,如果只从了解每个CSS属性名称、属性值上来看,肯定会有一天达到饱和的。 此时,我们就会觉得似乎没有什么新的东西可学了,CSS的那点东西我都知道了;似乎工作就成了每天的重复。这就是瓶颈期! 看看这张图: 我们很自然想到,要从A到B阶段,只要向下,向深度发展就可以了。所以,如果您觉得现在CSS这块学到的东西不多了,试试向垂直方向学习。 补充:有时候,如果我们CSS的基础足够得扎实与强大,我们会自热而然进入到B阶段,但这种完全经验积累的进阶学习需要很长的时间周期。如果没有一定的CSS基础以及经验做支撑,我们是无法进入B阶段的。深度才是你的核心竞争力。深入的细节掌握,深入的机制理解等,这些都是要下苦功才能掌握的,这是你有别于其他千千万万自认为会写页面的CSSer们的地方! 瓶口间的跳跃CSS3的出现似乎让一些CSSer们的学习有了新的方向:CSS2.1中的那些CSS代码我闭着眼睛都能敲出来,实在太无趣了,终于出来个小三 – CSS3来调剂生活! 然而,从CSS2到CSS3的学习增加的只是一点广度的知识,多点时间,谁都可以达到你这种程度(学习门槛低啊!)。在我看来,无非就是从一个瓶口跳到另外一个稍显时髦的瓶口而已。 视角的局限武侠中,主角们的进阶似乎都离不开所谓的“高人指点”;就算现实生活中,我们的人生也可能因为一句话而发生重大改变。那“指点”的是什么呢? “改变”的又是什么呢?——看待问题的方式以及角度!据说阿里有个倒立文化,换个视角看问题,会得到不同的答案。 我们很多人找不到学习的突破口,可能就是由于视角的问题。 我们往往不是这样子看的: 而是从上往下,只看到瓶口 看不出水有多深,看不到瓶颈在哪里!想起了一部美剧——《迷失》,想起了一句古话——“只缘身在此山中”。 3 瓶颈在哪? 我先问几个问题,看看你是否能够回答上来? dl, dt, dd三个标签浏览器默认margin值多少?是否有标签默认文字粗体? line-height:150%和line-height:1.5的区别是? float为何会让外部容器高度塌陷?这是bug? vertical-align的表现为何在IE7, IE8, IE9下表现不尽相同?其中的渲染机制是? 以上问题可以大致判别你是A阶段还是B阶段。倒不是问题本身,而是问题所指的类别。 问题1, 2表示“深入的细节掌握”;3, 4表示“深入的机制理解”。再往后可能就是“网页大事,为我所控”,“天下页面,听我号令”,这要C阶段了,先不予讨论。 换句话说,您现在的瓶颈可能在于“细节掌握不够”、“机制等理解不够”。 关于细节有人可能会反问:我为什么要知道dl, dd, dt标签默认的margin值大小?我一般都是直接在CSS reset中设置:body,h1,... ,dl,dt,dd,...,th,td { margin:0; padding: 0; } 你看,淘宝网首页就是这么干的(global-min.css)!从实际应用来看,我无需关心! 这样的想法,类似于:我根本不需要知道我的前任、现任、后任女友是否是处女,因为我都直接让她们做处女膜修复!从实际应用来看,我无需关心 很多事情,如果你足够了解之,就能灵活掌控之!即所谓的驾驭能力。CSS细节了解,有助于你更好地驾驭CSS, 而不是被CSS调试,被浏览器劫持。 3~4两的大闸蟹虽然也有人要,但是,多啊,不值几个钱;但是半斤以上的大闸蟹的单价就要翻番。盲从CSS reset的人也有人要,但是,多啊,不值几个钱;但是,知根究底的人这身价就要翻番了。 如果你有自己想法,知根知底,你可能就是这样做reset的:body, h1, ..., dl, dd { margin: 0; } dt标签的reset只是白白浪费,增加页面渲染负荷;padding属性值仅极少标签(ol, ul)有,其他标签无需浪费渲染重新设置。//zxx: 对于淘宝首页的渲染速度我就不说什么了 有不少人曾问我:“你的那个CSS架构我用了,很不错,使用很方便。但是,我经常CSS库的类名有5个甚至更多!而你写的页面很少会这样,为什么呢?”<span class=\"db l h24 lh24 b\">注意:</span>我是…… 如果你对CSS细节足够掌握,可能您的使用就会是这样:<strong class=\"l lh24\">注意:</strong>我是…… 这就是我说过的,如果页面开发工程师对CSS属性理解不够透彻,我的这种架构对其而言反而会略显吃力! 关于理解你是否有这样的调试经历:尼玛IE(x)浏览器下出了个奇怪问题,哥哥我不知道原因啊原因啊原因,然后很苦逼地把觉得有可能的CSS属性一个一个试验——改一个刷一下,看看有没有变好。 唉,可怜的娃,宝贵的青春就这么蹉跎掉了,省下来和前台美女MM调调情也比这强多了~~ 为什么我们需要深入理解CSS的一些表现? 所谓“对症下药”,你要先知道这个症,这个根才可以。同样,当我们对CSS的底层表现有一定的理解与认识的时候,遇到一些看似奇怪的问题,我们可以一针见血,一语中的,分分钟搞定,然后,聊天,喝茶,把妹~~ 所谓“发明创造”,你要先知道其基本原理,工作机制。同样,当我们面对CSS的一些特殊需求的时候,一些看似蛋疼的问题,我们可以发挥我们的创造性思维,创建一个属于你的首创新方法,然后卖萌,邀功,得瑟~~例如,我之前折腾过的inline-block两端对齐等。 理解的对与错每个人的成长经历不同,大脑擅长处理的东西也不同,导致其看待与理解事物的方式也不同。因此,对于同一CSS表现的差异,每个人的理解都不同。 一旦有所差异,就有所谓的“对错”之争。估计不少人会拿《CSS权威指南》上的东西说事:你那种理解是错误的,CSS权威指南上说……或W3C官方文档解释说…… 我大学电路老师最后一节课专门讲了她的科学观:何为科学?能够自圆其说,自成体系即是科学。中医算科学吗?算!因其有一套自己解释畅通的理论体系。 同样,对于CSS的理解,我个人一直认为什么对错的争执等都是没有意义的。如果你的解释可以自圆其说,自成体系,且应用无误,哪怕你的解释与什么规范啊权威啊八竿子都打不着,别人压根理解不了,你都是对的,OK的! 拘泥只会限制自身的创造力以及认知能力。火影的世界算是世界吗?是,自圆其说,自成体系!海贼王的世界算是世界吗?是自圆其说,自成体系。 因此,如果你是设计出身,或文学出身的。什么复杂逻辑,深奥解释理解不了,你大可摒弃之,用你自己的世界去解释其表现,你的感性思维以及艺术情怀只会让这个世界变得更精彩!那些自以为是,抱残守缺的杂碎们就不用鸟他们,让他们随着时间消逝去吧~~ 好比面对“浮动元素会让外部高度塌陷的原因?”这个问题,你可以这样解释: 浮动是敏感词 浮动是海市蜃楼 浮动是个不孝子,会让爸爸颜面无存,显得很矮小 浮动是个魔鬼,和绝对定位是兄弟,本都属于天上人 浮动是中国,讲究面子工程 浮动是中国股市,吸引屁民跟在左右,本身就是个泡沫 …… 只要这类解释能够把其他所有的CSS表现都解释地通,成为体系,都是正确且深入的理解。 4 如何突破?知道问题在哪里,其实已经解决了一大半。 下面的问题如何实践了! 杨过16年前就开始意识到要可以自创武功(类似于我们自创CSS实现),但是,最终实现确实N年以后,不断的感悟以及练习才得以成功。 即使你再天才(杨过够天才吧),机遇够神奇(杨过经历够神奇吧),也也是要会很多功夫和精力才能到达另外一个层次的。只是别人可能30年的,你只要20年而已(黄药师说过,杨过20岁的武功修为其30岁才达到)。 我想了想,关于突破瓶颈的建议我有三个:戒骄戒躁、分享讨论、打破重组。 关于戒骄戒躁如果有人当面说你:“旺财啊,你这个人有时候比较浮躁啊!”你可能心里或嘴上就嘀咕了:“有吗?我不觉得啊。我做事很认真的啊!” 究竟如何呢?人们常说当局者迷旁观者清。 假设你看到了一个用法:vertical-align:-2px; 你的反应以及做法会是?A. 我擦,原来vertical-align还支持数值啊,学习了!B. 哟,vertical-align支持数值?我去查查呀,果然C. 切,大惊小怪,我早就知道vertical-align支持数值,包括负值了,百分比值~~D. 阿拉,我要自己试验下,新建个HTML页面,做个简单demo,看看兼容性什么的~~E. 啊,什么,我刚扫视了,没注意到~~ 对应下表: 实际对比我会发现差异不大,但是我不会认为其没有差异,因为高中大学做实验很基本的一条就是多个条件的实践,于是,我会使用vertical-align:-200px; 与margin-bottom:-200px;再做一次验证(当然,会设置其他用来观察的条件——背景色,边框或其他元素),结果,差异非常明显地出来了(这里先忽略IE6/IE7下margin-bottom负值极限bug):如果是我,我会更近一步,对比思考:vertical-align:-2px;与margin-bottom:-2px;之间有什么差异,我会试验之~~ vertical-align会增加容器的高度,而margin-bottom负值则是减小! 然后,我可能会整理,然后……(接下面) 关于分享讨论分享看似把东西授予他人,自己做了吃力不讨好的事情。而实际上,准备分享内容以及在分享的过程中,你会提炼总结思考你要分享的东西,这对于学习而言是非常重要的,这个阶段好比模具成型,鱼入网袋,妹子推倒。 讨论的作用也很大,别人或中肯或傻逼的批评以及建议都会让你发现你知识上的不完善或不准确之处,群众的眼睛是雪亮的。 还是说我自己,接上面,如果是我,我可能就会把vertical-align负值与margin-bottom负值的差异整理成一篇文章发布出来(实际上是不会的,因为内容太少,质量档次不够,一般只会穿插在其他文章中,比如本文)。在发布书写制作demo的过程中,我肯定会有观点的提炼等,我就会发现一些新的东西,比方说IE6/IE7的margin-bottom负值数值超过一定限度时候的兼容性问题。 在写文章的时候,我可能会使用一些激烈的措辞,激发与他人的互动与讨论,从别人的评论中查漏补缺,获取新的知识。 当然,每个人分享的方式可能不一样。我因为嘴皮子的表达欠佳,因此,大多借助文章这个渠道分享与讨论。传播技术的同时自身也得到提高,如此一举两得的事情,何乐而不为呢!而你呢?如果你擅长交际组织什么的,分享会什么的,都是很赞的方式! 关于打破重组华为貌似做过这样的事情,所有的老员工一律辞职,自己再重新去应聘。而且,好像类此的操作不只做了一次,“始作俑者”为任正非老先生。这种打破重组的效果如何呢? 据说奇效,当年华为业绩可见一斑。 在突破瓶颈的时候,我们也可以,而且建议这么尝试。限制于惯性思维中,是很难突破瓶颈的。我们可以将自己过往的一切全盘否定,然后重新再来,你可能就会看到另外一个自己。举个例子 如果你一直都是固定布局的,自己在心里默念三遍:固定布局就是个屎,我要投奔流体布局!如果你一直都是流体布局的,自己心里也默念三遍:流体布局就是个屎,我要投奔固定布局!如果你固定/流体布局兼修,自己心里也默念三遍:什么固定/流体布局都是屎,我要投奔时髦的响应布局! 放开自己,拥抱未来,拥抱变化。舍弃过往,接受新颖的架构,思想,理念。你就会发现,很短的时候,自己有了质地提升。 其中玄奥我是很难道明,要看你自己能不能体会出来了! 5 最后其实,广大页面屌丝们并不畏惧那些学习能力强的人,畏惧的是那些学习能力强,同时,尼玛学习又拼命的人。 页面仔们,扪心自问下:我每天几点下班?我每天下班后都干嘛了?我有专门花空余时间深入理解学习CSS的一些东西吗?我能够连续坚持数月吗? 最后,我只说一句话: 吃得苦中苦,方为人上人吃得苦中苦,方为人上人吃得苦中苦,方为人上人 引自 本文转载自说说CSS学习中的瓶颈 关于作者张鑫旭,09年华中科技大学毕业,现上海,就职于阅文集团,专注web前端偏前领域,钓鱼爱好者。 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"css","slug":"css","permalink":"http://destinytaoer.cn/tags/css/"}]},{"title":"给不了解前端的同学讲前端","date":"2017-10-17T15:54:28.000Z","path":"/posts/ca85f766/","text":"前言这篇文章,是在前几天逛知乎的时候看到的文章,觉得很棒,正好也有这个需求,想向不了解前端的人介绍何为“前端”。不然,自己所在的群体中好像很少人能明白我一天到晚钻研的东西是什么。下面与大家分享。 ps:本文为 PPT 演讲的形式所作的图文介绍,图片较多。 本文转自知乎:前端 101:给不了解前端的同学讲前端本演讲原作者css魔法,文末有作者简介 简介 本文改编自魔法哥为 “百姓网暑期实习生训练营” 所作的前端入门讲座。此讲座面向在校大学生,内容比较初级,高手请飘过~ 大家好,今天的分享主要分为以下三个部分: 由于目前计算机专业还没有为 Web 前端技术设立专门的课程,每位同学对前端的了解程度也不一样,今天的讲座会以最浅显的方式来为大家介绍 “前端”,帮助大家建立一个基本的概念。 前端是什么? 在回答这个问题之前,我想到了一道面试题: 当我们在浏览器中输入网址并按回车之后,接下来会发生什么? 我们来简单地看一看 “网页展现” 的整个过程。 比如这里有一个用户,它需要访问abc.com这个网址。一般来说,当用户输入一个域名时,是在请求一个 HTML 资源。当他完成域名解析之后,他的浏览器会向abc.com这个域名所指向的 Web 服务器发出请求。 有时候 Web 服务器直接就可以返回用户的请求了;有时候 Web 服务器还需要向数据库查询一些数据,然后才能把处理结果返回给用户。 当用户的浏览器拿到服务器返回的 HTML 资源之后,就开始解析并显示 HTML 的内容了。 一般来说,HTML 页面需要 CSS 资源来描述页面的样式。比如浏览器在解析 HTML 时发现了一个 CSS 外链 abc.com/a.css,它就会去请求这个资源。 HTML 页面往往还需要加载外部的 JS 资源,比如 abc.com/a.js,此时浏览器同样会向服务器请求这个资源。 当所需的资源都加载完成之后,这个页面就可以提供完整的外观和功能了。整个过程差不多就是这个样子了。 我们看一看这张流程图,可以在中间画一道竖线,把它分成左右两个部分。 我们会发现,这道线左侧的事情发生在浏览器端,我们称之为 “前端”;右侧的事情发生在服务器端,称为 “后端”。(“前端” 之所以叫 “前端”,是因为它离用户更近一些。) 大家都学过后端开发的相关课程,对后端这一块应该都比较熟悉了。那问题来了:在上面这个过程中,后端有哪些局限? 服务器一旦把资源提供给浏览器之后,便失去对内容的影响。 服务器无法得知用户在浏览器里做了什么,无法与用户交互。 这意味着,只有当用户下一次向服务器请求资源时,服务器才有机会再次决定用户看到的内容。那么,用户什么时候再向后端请求资源呢? 第一种情况是 “导航动作”。比如用户刷新页面、点击链接、点击浏览器的前进/后退等等。 第二种情况是用户提交表单。表单是最传统的页面交互方式之一,提交表单时浏览器会向服务器发出新请求——这意味着浏览器会跳转到一个新的地址,服务器会在新页面中显示表单的处理结果。 还有一种特殊情况,就是服务器在给浏览器返回 HTML 资源时,在页面中插入一个特殊的标记,浏览器看到这个标记就会在一定的时间后自动刷新当前页面或跳转到其它页面,相当于服务器强制用户再次发出请求。可想而知,这种非用户意愿驱动的页面跳转行为并不讨人喜欢,因此已经不常用了。 在传统网页中,上述几种用户与服务器之间的交互方式也算够用了。不过随着网页形态的不断演进,用户对网页体验提出了更高的要求,很多时候网页不仅仅是一篇静止的文档,而更像是一个应用程序,用户随时可能与之互动。这个时候,前端的价值就体现出来了。 用户从停留在当前页面到发起新请求的这段时间内,前端可以控制页面内容。 当用户停留在当前页面时,前端有能力与用户交互。由于前端的 JS 可以监听用户在浏览器中的各种行为(比如鼠标点击、键盘输入、滚动页面等等),前端就可以针对这些行为作出相应的反馈。 在前端与用户的交互过程中,有些事情光靠前端就可以做出响应。比如我们在网页上做了一个计算器的功能,当用户输入算式之后,JS 就可以直接计算出结果并显示给用户。整个过程不需要服务器的参与就可以完成。 但有些事情,光有前端是无法完成的。此时前端就需要交给后端来处理,拿到处理结果之后再交给用户。在这个过程中,前端可以让用户一直停留在当前页面,交互过程具有良好的连续性。 那么,前端如何把任务交给后端并拿到后端处理的结果呢?主要有两种方式:Ajax和 Socket连接。 Ajax 是最常见的前后端交互方式。它以 “请求→响应” 的方式来完成前后端的信息传递。传统的表单交互需求几乎都可以由 Ajax 改造为 “原地提交并获取反馈” 的交互方式,不需要跳转页面,从而有效提升用户体验。 而对于实时性比较高的场景,Socket 连接就是一个更好的选择。它的工作方式是前后端建立一个持续的连接,信息可以随时由前端发向后端,或由后端推送到前端。如果我们要建立一个实时对话的应用,通常就会用到 Socket 连接了。 前端需要用到哪些技术? 说到前端技术,我们通常都会说到 “三大块”: HTML CSS JS 这是前端最核心的三项技术。 接下来,我们就会说到 “前端的分层架构”。这个架构的原则就是 “让合适的技术去做合适的事情”。一个网页从逻辑上可以视为这三层的有机结合体: 结构层:这一层的作用是表述一个页面中有哪些信息,以及这些信息之间的关系是什么。这一层在技术上是由 HTML 来实现的。 表现层:这一层决定了页面中的信息会以什么样的外观呈现出来。这一层由 CSS 来实现。 行为层:这一层控制了页面如何与用户进行交互。在传统的展示型网页中,可能只需要 “结构层” 和 “表现层” 就足以提供完整的功能;而现代网页承载了越来越多的交互,这就推动 “行为层” 的能力不断增强。这一层由 JS 来实现。我们通过一个实例来理解这个分层架构。 比如我是一个百姓网的用户,我打开了 “用户中心” 中的 “我发布的信息” 这个页面。 这个页面的 HTML 描述了信息以及信息的结构。即使没有 CSS 和 JS 的辅助,这个页面仍然可以呈现出可理解的内容(参见上图)。页面顶部是一些导航元素,接下来的 “显示中的信息” 是一个标题,它又引出了一个列表。这个列表自然就是我在百姓网发布的所有信息了。(除了 “显示中的信息” 以外,页面后半段还有 “已删除的信息”,这里不再赘述。) 接下来,我们会在表现层下功夫,通过 CSS 来为页面中的各个元素设定外观。经过这一层的修饰之后,页面中的内容更加美观了;更重要的是,各元素的功能职责也更加直观易懂了(参见上图)。 这已经是一个挺不错的网页了,但接下来,我们还会通过 JS 来丰富它的功能,提升用户的使用效率。 作为信息的发布者,我可能需要修改某条信息的内容,或对它进行 “刷新” 之类的操作。在传统的交互中,我需要在这个列表中点击需要操作的信息,然后在信息的详情页选择合适的操作。 我们可以把这个流程简化一下:我们在这个列表中为每条信息添加一个操作按钮,当用户点击某条信息的操作按钮时,我们就在页面中弹出一个操作面板,用户可以直接选择想要的操作,减少了中间环节(参见上图)。 由此可见,结构层、表现层、行为层这三者各有所长,共同构造了一个功能完备、体验良好的网页出来。 除了基本的 “三大块” 之外,作为前端工程师,我们还需要掌握以下知识和技能: HTTP 相关:由于前端资源都是浏览器通过网络下载的,因此我们有必要了解相关的网络协议。 浏览器相关:前端代码运行在浏览器中,我们需要了解浏览器的各种特性,以及浏览器向我们提供的各种接口。 前端性能优化:让网页更快,减少用户的等待,这也是前端工程师面临的重要课题。优化网页的前端性能,需要我们具备上面两项知识,并且掌握性能优化相关的工具和方法。 图形图像:网页信息不仅包含文字,还包含图片、视频等多媒体信息。图片作为最常用媒体资源,需要我们掌握与其相关的技能。比如了解各种图片格式适用的场景、基本的图片处理方法等等。 前端的开发方式是怎样的? 前面我们已经介绍了前端技术 “三大块”,然而在如今,当我们在编写这三块的代码时,已经不再 “裸写” 了。这意味着我们在开发阶段编写的代码与实际在浏览器环境中运行的代码已经不一样了,详细来说: 我们通过模板语言来生成 HTML。 通过 CSS 预处理器来生成 CSS 代码。 通过 ES6+ 的语法和特性来编写 JS 代码。 举例来看吧,以下三个例子展示了代码书写方式的演化。 百姓网采用了 Jade 和 Jedi 这两种模板语言。在上图的代码中,我们仅仅使用了模板语言最基本的标记语法,还没有插入使用模板语言的任何逻辑能力。仅此一步,就可以看出模板语言带来的好处。 原先我们在写 HTML 代码时,会花费大量的精力在 <、/、> 这样的语法噪音上;同时,识别标签的嵌套关系也很费眼。幸运的是,Jade 和 Jedi 这样的现代模板语言把前端工程师解放了出来。它们通过缩进来表达嵌套关系,层级关系一目了然;语法更精练,表现力更强。 在 CSS 预处理器方面: 通过更简洁的语法减轻开发者的书写负担 通过内置的逻辑能力增强了代码的表现力。 举个例子,在使用原生 CSS 来写代码时,不同元素采用的相同颜色只能分散在代码各处;而采用了 CSS 预处理器之后,我们可以把相同意义的颜色通过变量的形式抽象出来,然后在代码各处调用即可。这样不仅便于后期维护,在平时读代码时也更容易理解代码意图。 在 JS 方面,我们开始享受 ES6+ 带来的新特征福利。ES(ECMAScript)是定义 JS 这门语言的标准规范,从第六版开始,ES 以每年一版的节奏持续快速地扩展着 JS 语言的能力。 在以往,如果我们要实现 “在数组中找出符合特定条件的成员” 的需求,往往需要借助 Underscore 这样的工具库,调用它的 _.find() 方法。而在 ES6 中,语言本身就扩展了数组的能力,我们只需要直接调用 Array#find() 接口即可。另外,像箭头函数这样的新语法也可以令代码进一步简化。 在 HTML、CSS、JS 这三大块,我们放弃 “裸写”,采用 “更高级” 语言的目的在于: 利用高级语言提供的 “逻辑能力” 来增强代码的表现力。 利用高级语言的 “语法糖” 和 “新特性” 来提升开发效率和舒适度。 当然,采用这些更高级的语言也不是完全没有成本的。我们在开发阶段所用的语言已经不是纯粹的 HTML、CSS、JS 了,浏览器无法直接识别和运行。因此,当我们放弃 “裸写”,也就意味着: 在部署流程中需要设立构建环节,把源码编译到浏览器环境可以运行的目标代码。 在开发阶段,需要有工具来实时监视并编译有变动的源码,以确保页面上呈现的是我们修改过的最新效果。 在百姓网,前端架构组已经搭建好了必要的开发环境,开发者们只需要关注开发本身就可以了。 在企业级的前端开发中,我们还需要了解如下知识点: 模块化:模块化是最常见的编程实践之一,令我们的代码组织更加清晰、易维护。ES6 为 JS 增加了完善的模块化方案,我们的日常开发也已经迁移到了 ES6 模块规范之下。 包管理:如何将开源社区中的优秀组件为我所用?这就不能不提 “npm” 这个最主流的 JS 包管理器。前端界优秀的开源项目几乎都发布到了 npm 的包仓库,我们日常开发中用到的第三方库也都是由 npm 来管理的。打包工具可以把我们写的模块化的源码和第三方包整合到一起,形成页面所需的完整 JS 资源。“包管理器”、“模块化”、“打包工具” 的相互结合,基本上就是日常的 JS 代码组织方式。 组件化:在传统的前端开发中,HTML、CSS、JS 这三块的代码有各自独立的文件,这些文件往往也分散在不同的目录结构中。如果页面功能区块的划分足够清晰,开发者就可以用 “组件” 的概念来把页面拆分,整个页面会被视为多个组件的嵌套和组合;同时,开发者也倾向于把每个组件相关的 HTML、CSS、JS 代码整合到同一个目录(或同一个文件)中,便于管理和维护。这就是 “组件化” 的开发模式。要实现这样的开发模式,通常需要前端框架和构建工具的配合。 单页应用:HTML5 的 History API 为前端提供了控制浏览器导航行为的能力,配合 Ajax 无刷新更新页面内容的特性,我们可以在一个页面内实现应用的多视图切换,避免页面的频繁跳转,提供类似桌面应用的体验。比如 Gmail 等产品就是典型的单页应用模式,百姓网的大多数后台系统也都是单页应用。 其它实用的知识点,就留待大家在工作中慢慢发掘吧。 今天想跟大家分享的主要内容就是这些了,感谢阅读,再见! 作者简介 作者:CSS魔法@前端架构简介:百姓网前端架构 TL,《CSS 揭秘》译者,CSS Conf 讲师,自称 “披着工程师外衣的设计师”。 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"}]},{"title":"CSS实现元素的居中显示","date":"2017-10-17T15:26:12.000Z","path":"/posts/36a501de/","text":"前言元素的水平及垂直居中是在写CSS样式中最常遇到的问题之一。相信会CSS的同学肯定都有自己的解决方法,但是并不一定都能熟练运用,并且知道其中原理。下面,我就将自己总结的实现方法分享给大家。ps:重点是第四,疑惑在第三,第一、第二也较常用 为本文制作的demo:元素居中显示 一、单行文本这里的单行文本不仅是指单行显示的文本以及行内元素(设置了display: inline;的也是行内元素),当然这些元素也只有包含文本才有意义,才能显示出来。 /* 父元素*/div { text-align: center;//水平居中 light-height: heightValue;//垂直居中} 注意: 这里的heightValue指的是height属性值,即行高值 = 高度值,才能实现垂直居中。 另外一种常见的就是不设置高度,直接用行高来撑起高度,这样就不存在行高与高度一致的问题。 具体原因请参考文章:对文字和行高的理解 二、多行文本这里的多行文本,实际上应该说是不定行,这个方法能自适应的居中。 /* 父元素*/div { text-align: center; display: table-cell; vertical-align: middle;} 这里设置table-cell,创建类似表格单元的元素,就可以使用vertical-align设置垂直对齐方式。 注意:在一些文章中,我看到还需要设置其子元素的vertical-align,但是在实践中发现并不需要。与下面使用table-cell的方法有所区别 三、图片这里图片泛指行内块元素 table-cell + vertical-align/* 父元素*/div { display: table-cell; text-align: center; vertical-align: middle;}/* 子元素img*/img{ vertical-align:middle;} 这个方法与上面的有区分,子元素必须加上vertical-align,否则不同大小的图片显示效果不一样 不支持img的父元素浮动,因为这样display会自动变为block,所以当多图片显示时需要再在外面嵌套一层标签,不方便 注意:在一些文章中,在父元素上还添加了font-size的大小控制,在我的实践中,不添加font-size可以实现效果。但是,当font-size达到一定程度的时候,会有影响。 vertical-align + font-size/* 父元素*/div {font-size:128px; vertical-align: middle;}/* 子元素img*/img{ vertical-align: middle;} font-size达到一定大小就会影响行内元素的垂直位置,具体是什么原因不明确,但是感觉是跟vertical-align以及行高有关。 注意:这个方法的原本是在父元素上加display: inline-block;的,实践发现并不需要,只要里面的是行内块元素就可以了。使用这个方法特别注意的是父元素font-size与子元素height的比例关系,因为不可控,所以不推荐使用。 其他方法参照下面的块元素实现 四、盒子盒子主要指块元素和行内块,下面分享的是布局中主要用到的。margin: 0 auto就不做介绍了。 1. position + 负margin/* 父元素 */.demo{ position: relative;}/* 子元素 */.box{ width: 100px; height: 100px; position: absolute; top: 50%; left: 50%; margin-top: -50px; /* img高度的一半*/ margin-left: -50px;/* img宽度的一半*/} 利用position移动父元素宽高的一半,再利用负margin往回移动子元素宽高的一半,刚好居中对齐。适合固定宽高的元素。 2.position + translate/* 父元素 */.demo{ position: relative;}/* 子元素 */.box{ position: absolute; top: 50%; left: 50%; transform:translate3d(-50%,-50%,0);} 同上理,这里利用translate3d往回移动。子元素不固定宽高也适用。 3. table-cell + vertical-align这就是前面图片提到的方法,只不过要设置子元素为display: inline-block; 4. flex这才是真正的布局神器。适用于所有,但也需要灵活应用。.demo { display: flex; align-items: center; justify-content: center;} 简洁、高效,在低版本IE存在兼容问题,但是现在几乎不用考虑了。 详细语法请查看我的博文:关于Flex布局 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"css","slug":"css","permalink":"http://destinytaoer.cn/tags/css/"}]},{"title":"关于Flex布局","date":"2017-10-16T03:42:24.000Z","path":"/posts/4716e729/","text":"前言 讲讲布局,传统的布局,是基于盒子模型,依赖 display + position + float属性。它对于特殊的布局非常不方便,如:垂直居中。 Flex 布局是 W3C 在 2009 年提出的新方案,可以简便、完整、响应式地实现各种页面布局。已经得到所有浏览器的支持。是未来布局的首选方案。下面就跟大家介绍Flex布局。 一、Flex布局是什么Flex是Flexible Box的缩写,意为“弹性布局”,用来给盒子模型提供最大的灵活性。 任何一个容器都可以指定为Flex布局:.box { display: flex;} 行内元素也可以使用Flex布局:.box { display: inline-flex;} Webkit 内核的浏览器,必须加上-webkit前缀:.box { display: -webkit-flex; display: flex; 注意:设为Flex布局以后,其子元素的float、clear、vertical-align属性将失效 二、基本概念 设置flex的元素,称为Flex容器(flex container),它的所有子元素自动成为容器成员,称为Flex项目(flex item) 容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。主轴和交叉轴必定垂直。 项目默认沿主轴排列单个项目所占据的主轴空间叫做mian size,占据的交叉轴空间叫做cross size。 三、容器的属性 flex-direction flex-wrap flex-flow justify-content align-items align-content 1. flex-directionflex-direction属性决定项目的排列方向,即主轴的方向。.box { flex-direction: row | row-reverse | column | column-reverse;} row(默认值):主轴为水平方向,起点在左端。 row-reverse:主轴为水平方向,起点在右端。 column:主轴为垂直方向,起点在上沿。 column-reverse:主轴为垂直方向,起点在下沿。 2. flex-wrap默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap属性定义,如果一条轴线排不下,如何换行。.box{ flex-wrap: nowrap | wrap | wrap-reverse;} nowrap(默认):不换行 wrap:换行,第一行在上方,正常顺序 wrap-reverse:换行:第一行在下方,相反顺序 注意:wrap-reverse会使交叉轴的方向改变 3. flex-flowflex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap.box { flex-flow: <flex-direction> || <flex-wrap>;} 4. justify-contentjustify-content属性定义了项目在主轴上的对齐方式。.box { justify-content: flex-start | flex-end | center | space-between | space-around;} 它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右。 flex-start(默认值):左对齐,与主轴开始位置对齐 flex-end:右对齐,与主轴结束位置对齐 center: 居中,与主轴中心对齐 space-between:两端对齐,项目之间的间隔都相等。 space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。 5. align-itemsalign-items属性定义项目在交叉轴上如何对齐。.box { align-items: flex-start | flex-end | center | baseline | stretch;} 它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下。 flex-start:交叉轴的起点对齐。 flex-end:交叉轴的终点对齐。 center:交叉轴的中点对齐。 baseline: 项目的第一行文字的基线对齐。 stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。 6. align-contentalign-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,就是只有一行,该属性不起作用。.box { align-content: flex-start | flex-end | center | space-between | space-around | stretch;} 该属性可能取6个值。 flex-start:与交叉轴的起点对齐。 flex-end:与交叉轴的终点对齐。 center:与交叉轴的中点对齐。 space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。 space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。 stretch(默认值):轴线占满整个交叉轴。 四、项目的属性 order flex-grow flex-shrink flex-basis flex align-self 1. orderorder属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。.item { order: <integer>;} 2. flex-growflex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。.item { flex-grow: <number>; /* default 0 */} 如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。 3. flex-shrinkflex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。.item { flex-shrink: <number>; /* default 1 */} 如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。负值对该属性无效。 4. flex-basisflex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。.item { flex-basis: <length> | auto; /* default auto */} 它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。 5. flexflex属性是flex-grow, flex-shrink和flex-basis的简写,默认值为0 1 auto。后两个属性可选。.item { flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]} 该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。 6. align-selfalign-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。.item { align-self: auto | flex-start | flex-end | center | baseline | stretch;} 该属性可能取6个值,除了auto,其他都与align-items属性完全一致。 引自 本文引自阮一峰的网络日志:Flex 布局教程:语法篇 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"css","slug":"css","permalink":"http://destinytaoer.cn/tags/css/"}]},{"title":"深入理解层叠上下文和层叠顺序","date":"2017-10-14T15:35:50.000Z","path":"/posts/5ef1e80c/","text":"前言原文是在前面对transform引起的z-index“失效”探究过程中找到的,非常棒,所以转载分享。本文大多摘自原文,进行了压缩,也加入了我自己的理解,希望对大家有帮助。 默认情况下,网页内容是没有偏移角的垂直视觉呈现,当内容发生层叠的时候,一定会有一个前后的层叠顺序产生。 我们大家可能都熟悉CSS中的z-index属性,需要跟大家讲的是,z-index实际上只是CSS层叠上下文和层叠顺序中的一叶小舟。 一、什么是层叠上下文层叠上下文,英文称作“stacking context”。是HTML中的一个三维的概念。如果一个元素含有层叠上下文,我们可以理解为这个元素在z轴上“高人一等”。 z轴表示的是用户与屏幕的这条看不见的垂直线: 具象化拥有层叠上下文的元素相当于是一个容器,容器里装着其他元素。不同容器内的元素的高低由容器决定。容器里面的元素,有高低之分,但不会突破容器。 二、什么是层叠水平“层叠水平”英文称作”stacking level”,决定了同一个层叠上下文中元素在z轴上的显示顺序。 就跟人一样,网页中的元素虽然都是独立个体,但是总有一个类似的排名排序的情况存在。这个就是层叠水平。层叠上下文的层叠水平是优先级更高的层叠水平。 普通元素的层叠水平优先由层叠上下文决定,因此,层叠水平的比较只有在当前层叠上下文元素中才有意义。 注意:千万不要把层叠水平和z-index属性混为一谈。某些情况下z-index确实可以影响层叠水平,但是,只限于定位元素以及flex盒子的子元素,而层叠水平所有的元素都存在。 三、什么是层叠顺序“层叠顺序”英文称作”stacking order”,表示元素发生层叠时的垂直显示顺序。层叠上下文和层叠水平是概念,而这里的层叠顺序是规则。 在CSS2.1的年代,在CSS3还没有出现的时候(注意这里的前提),层叠顺序规则遵循下面这张图: 这样的设计是由元素的重要性出发的,内容优于布局,布局优于装饰 注意: 这是css2的时候 这里的z-index: 0 只是表示一个0级别,对应的是z-index: auto,没有创建层叠上下文的级别 四、层叠准则层叠领域的黄金准则。当元素发生层叠的时候,其覆盖关系遵循下面2个准则: 谁大谁上当具有明显的层叠水平标示的时候,如识别的z-indx值,在同一个层叠上下文领域,层叠水平值大的那一个覆盖小的那一个。 后来居上当元素的层叠水平一致、层叠顺序相同的时候,在DOM流中处于后面的元素会覆盖前面的元素。 五、层叠上下文的特性层叠上下文元素有如下特性: 层叠上下文的层叠水平要比普通元素高; 层叠上下文可以阻断元素的混合模式; 层叠上下文可以嵌套,内部层叠上下文及其所有子元素均受制于外部的层叠上下文; 每个层叠上下文和兄弟元素独立,也就是当进行层叠变化或渲染的时候,只需要考虑后代元素; 每个层叠上下文是自成体系的,当元素发生层叠的时候,整个元素被认为是在父层叠上下文的层叠顺序中。 六、层叠上下文的创建层叠上下文基本是由一些特定的css属性所创建,主要分为三种: 1. 根层叠上下文页面根元素,也就是滚动条的默认的始作俑者元素。这就是为什么,绝对定位元素在left/top等值定位的时候,如果没有其他定位元素限制,会相对浏览器窗口定位的原因。 2. 定位元素与传统层叠上下文 设置position:relative/position:absolute,z-index值不是auto的定位元素 设置position:fixed的定位元素,z-index为任意 3. CSS3与新时代的层叠上下文 设置了z-index,且不为auto的flex元素(父元素display:flex|inline-flex) 设置了opacity,且不为1的元素 设置了transform,且不为none的元素 设置了mix-blend-mode值,且不为normal的元素 **设置了isolation,且为isolate的元素 设置了filter值,且不是none的元素 will-change指定的属性值为上面任意一个 设置了-webkit-overflow-scrolling,且为touch的元素 七、层叠上下文与层叠顺序最终的层叠顺序分两种情况讨论: 层叠上下文不依赖z-index数值,其层叠顺序是z-index: auto,就是z-index: 0的级别,没有创建层叠上下文的元素的级别 层叠上下文依赖z-index数值,则由z-index决定也就是两个层叠准则的详细解释,第一个:后来者居上,第二个:谁大谁上。 引自 引自:张鑫旭的博客本文地址:http://www.zhangxinxu.com/wordpress/?p=5115 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"css","slug":"css","permalink":"http://destinytaoer.cn/tags/css/"}]},{"title":"Transform 引起的 z-index \"失效\"","date":"2017-10-12T10:31:44.000Z","path":"/posts/c1fd4e78/","text":"前言重新学习CSS后的第三天,学习制作阴影的过程中,发现的问题:设置了box-shadow后展现的阴影: 添加transform:rotate(10deg);后的效果: 查看CodePen例子:阴影效果 一脸懵逼!再修改z-index完全没有效果。 百度之后,找到了问题的答案,也自己摸索着找到了这个问题的解决办法。下面与大家分享。 一、原因 给元素设置transform属性会创建一个新的stacking context,译作层叠上下文的一个区域。 原本的层叠规则就会发生变化,导致了设置了transform的元素变成了一个层叠上下文容器,也就相当于最底层。 与其他兄弟元素或者外层元素依然保持原来的层叠规则,影响的只是其子元素。 二、什么是层叠上下文相信大家都知道,css是层叠样式表,层叠上下文就是html文件渲染的时候,各个元素的堆叠规则,是css中非常重要的潜在规则。 详细规则请点击:深入理解CSS中的层叠上下文和层叠顺序 三、什么情况会创建新的区域MDN上有相关的介绍: 根元素(HTML) 设置了position为absolute或relative,且z-index不是auto的元素 设置了z-index,且不为auto的流动元素 设置了opacity,且不为1的元素 设置了transform,且不为none的元素 设置了mix-blend-mode值,且不为normal的元素 设置了isolation 为 isolate的元素on mobile WebKit and Chrome 22+, 设置position为fixed的元素 四、解决办法不使用transform是不可能的了,那么该如何解决呢?我想到的办法是再覆盖,覆盖掉不让看见的东西。 1. 首先在元素里再创建一个标签因为元素的before、after伪类都被占用了,只能再创建标签覆盖。 2. 应用新标签的before伪类.shadow5 p::before { content: \"\"; position: absolute; z-index: -1; background: #fff; box-shadow: 0 0 40px rgba(0, 0, 0, 0.1) inset; top: 0; bottom: 0; right: 0; left: 0;} 设置定位,以原来的元素为基准,top、bottom、right、left为0,以充满整个容器注意:z-index的设置与原来元素的before、after中的z-index有关,必须比它的值大,不然after伪类又会显示在上面。 参考 张鑫旭博文:深入理解css中的层叠上下文和层叠顺序Segmentfault回答:Transform 引起的 z-index “失效”豆瓣文章:小心 CSS3 Transform 引起的 z-index “失效” 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"css","slug":"css","permalink":"http://destinytaoer.cn/tags/css/"}]},{"title":"关于inline-block问题","date":"2017-10-10T11:44:14.000Z","path":"/posts/6b877873/","text":"前言在重新学习css,做自己的学习demo时,设置一堆div在一行显示,呈现对比。 结果如图,设置了display:inline-block之后,出现了部分下沉现象。改为float之后,又恢复正常对齐。 不过,很快就得到了解决。于是,就写了这篇关于inline-block问题的文章,包含了以前分享过的间距问题,在这里与大家分享。 一、下沉问题原因1. 行内元素有一个基线,所有在这一行中的元素都以这条基线为准对齐。如文字: 而行内块元素,如图片等,会以底部为准对齐: 2. 文本在容器中默认是上对齐的,且不能设置其他垂直对齐方式要设置垂直居中之类的,只能用p标签或者其他标签包含之后,设置这些标签的对齐方式 3. 文本是老大,它不迁就别人,只有容器靠下来迁就它。这是个很奇怪的现象,行内块元素的基线原本是底部,在有文本之后,该元素的基线就变成了文本的基线,为了与其他元素对齐,才导致下沉。 解决方案1. 设置vertical-align元素的默认vertical-align为baseline,也就是基线。把它的值设置为其他值,就能实现其他方式的对齐,如top、bottom、text-bottom、text-top、middle等,同高度下,效果相同。display: inline-block;verticla-align: top; CSS vertical-align 属性 2. 使用float等其他方法替换inline-block当然,在这里说到用其他方法还有很多,已经与inline-block无关了,所以也不多说。 二、间距问题原因行内块元素或者设置成inline-block的元素之间,会自动存在间距。 这种表现是符合规范的应该有的表现。但是,在某些情况却会对我们的布局造成影响。 解决方法1. 使用margin负值.space a { display: inline-block; margin-right: -3px;} margin负值的大小与上下文的字体和文字大小相关,其中,间距对应大小值可以参见“基于display:inline-block的列表布局”一文part 6的统计表格: inline-block元素间间隔大小与字体和文字大小之前的关系表截图 例如,对于12像素大小的上下文,Arial字体的margin负值为-3像素,Tahoma和Verdana就是-4像素,而Geneva为-6像素。由于外部环境的不确定性,以及最后一个元素多出的父margin值等问题,这个方法不适合大规模使用。 2. 使用font-size:0类似下面的代码:.space { font-size: 0;}.space a { font-size: 12px;} 这个方法,基本上可以解决大部分浏览器下inline-block元素之间的间距(IE7等浏览器有时候会有1像素的间距)。不过有个浏览器,就是Chrome, 其默认有最小字体大小限制,因为,考虑到兼容性,我们还需要添加:类似下面的代码:.space { font-size: 0; -webkit-text-size-adjust:none;} 点击这里查看示例:font-size:0清除换行符间隙demo 补充:目前Chrome浏览器已经取消了最小字体限制。因此,上面的-webkit-text-size-adjust:none;代码估计时日不多了。 3. 使用letter-spacing类似下面的代码:.space { letter-spacing: -3px;}.space a { letter-spacing: 0;} 该方法可以搞定基本上所有浏览器,不过Opera浏览器下有蛋疼的问题:最小间距1像素,然后,letter-spacing再小就还原了。 4. 使用word-spacing类似下面代码:.space { word-spacing: -6px;}.space a { word-spacing: 0;} 一个是字符间距letter-spacing,一个是单词间距word-spacing,大同小异。据我测试,word-spacing的负值只要大到一定程度,其兼容性上的差异就可以被忽略。因为,貌似,word-spacing即使负值很大,也不会发生重叠。 点击这里查看示例:word-spacing与元素间距去除demo 您使用Chrome浏览器,可能看到的是间距依旧存在。确实是有该问题,原因我是不清楚,不过我知道,可以添加display: table;或display:inline-table;让Chrome浏览器也变得乖巧。.space { display: inline-table; word-spacing: -6px;} 5. 其他成品方法下面展示的是YUI 3 CSS Grids 使用letter-spacing和word-spacing去除格栅单元见间隔方法(注意,其针对的是block水平的元素,因此对IE8-浏览器做了hack处理):.yui3-g { letter-spacing: -0.31em;/* webkit */ *letter-spacing: normal; /* IE < 8 重置 */ word-spacing: -0.43em; /* IE < 8 && gecko */}.yui3-u { display: inline-block; zoom: 1; *display: inline; /* IE < 8: 伪造 inline-block */ letter-spacing: normal; word-spacing: normal; vertical-align: top;} 以下是一个名叫RayM的人提供的方法:li { display:inline-block; background: orange; padding:10px; word-spacing:0;}ul { width:100%; display:table; /* 调教webkit*/ word-spacing:-1em;}.nav li { *display:inline;} 也就是上面一系列CSS方法的组组合合。 感谢 去除inline-block元素间间距的N种方法inline-block之后意外发现块下沉 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"css","slug":"css","permalink":"http://destinytaoer.cn/tags/css/"}]},{"title":"Sublime Text 实用插件介绍","date":"2017-09-23T11:09:24.000Z","path":"/posts/855f23c8/","text":"前言这是一款个人特别喜欢的编辑器,用来写前端代码。特别棒的是最新版本的文件栏中,中文不再出现乱码 本文主要是为自己做笔记以及备份的,介绍自己使用的sublime text插件。希望对大家也有所帮助。 官网地址:Sublime Text 插件官网:packageControl大神文章:详细插件介绍 插件介绍 packageControl最新版本的sublimetext不再需要复制代码到控制台下载packagecontrol了。而是直接打开命令面板,快捷键ctrl+shift+p,输入ipc选中install packagecontrol,就会自行安装。 emmet快速生成HTML代码段的插件,强大到无与伦比,必备。 ConvertToUTF8支持 GBK, BIG5, EUC-KR, EUC-JP, Shift_JIS 等编码的插件,解决编辑中文乱码。 SideBar Enhancements这个插件改进了侧边栏,增加了许多功能 ChineseLocalizations使菜单栏等支持中文 DocBlockr自动生成PHPDoc风格的注释,用于增强注释功能 Bracket Highlighte用于匹配括号,引号和html标签。 Vue Syntax Highlightvue的高亮显示 AutoFileName文件路径自动提示 AdvancedNewFile允许在项目中更快的创建文件 FileDiffs用来比较文件差异 Alignment等号对齐 Ctrl+Alt+A添加冒号对齐在Preferences -> package settings -> Alignment -> Settings User中添加下面代码: { \"align_indent\": false, \"alignment_chars\": [\"=\", \":\"], \"alignment_space_chars\": [\"=\", \":\"]} SublimeTmpl新建文件的模版插件 详情请见:SublimeTmpl markdown previewmarkdown编辑 AllAutocompleteSublimeText默认的Autocomplete功能只考虑当前的文件,而AllAutocomplete插件会搜索所有打开的文件来寻找匹配的提示词。 ColorPicker颜色选择器Ctrl+Shift+C sublimeLint代码错误提示 cssCombcss属性排序 jsformatjs格式化 Ctrl+Alt+F SublimeCodeIntel代码提示插件,支持多种编程语言 css3css3代码提示 sasssass语法编译高亮、代码提示 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"sublimetext","slug":"sublimetext","permalink":"http://destinytaoer.cn/tags/sublimetext/"},{"name":"编辑器","slug":"编辑器","permalink":"http://destinytaoer.cn/tags/编辑器/"}]},{"title":"hexo + next主题高级配置","date":"2017-09-20T10:20:55.000Z","path":"/posts/e1d994bf/","text":"前言配置完yilia后,发现缺少一些东西,百度之下,找到了特别喜欢的主题——next。跟大家分享配置经验。 首先,本文是根据我自己的博客配置而写的,并不全面,其他美化配置在文末提供了相应的参考链接。欢迎浏览我的博客:destiny’Note 其次,本文中有部分自己的改进方案,并非全部摘自他文,所以转载请注明版权 最后,有不懂的或者有其他方案,欢迎联系本人 一、主题下载git clone https://github.com/iissnan/hexo-theme-next.git themes/next 在根目录_config.yml文件中: theme: next 注意:所有配置文件内,每一项配置的冒号后面都要加上空格 二、综合设置1. 语言设置在根目录_config.yml文件中: language: zh-Hans 编辑主题目录下language/zh-Hans.yml中英文的对应关系 2. 修改字体大小、样式在主题目录配置文件下,查找font: font: enable: true # Uri of fonts host. E.g. //fonts.googleapis.com (Default). host: # body元素的字体设置 global: external: true family: Lato size: 18 # 标题的基础字体设置 headings: external: true family: size: 30 # 文章字体设置 posts: external: true family: 18 # logo字体设置 logo: external: true family: size: 30 # 代码块字体设置 codes: external: true family: size: 13 把false改为true,并修改了size的数值,单位是像素。如有需要可自行改变字体。 另外提供一种方法,供会前端的小伙伴参考:打开\\themes\\next\\source\\css\\ _variables\\base.styl文件,修改里面的字体大小 3. 主题选择在主题配置文件中,查找scheme: # 主题中的主题# scheme: Musescheme: Mist# scheme: Pisces# scheme: Gemini 选择你喜欢的,去掉前面的#号,其他加上#号。即注释掉的意思。 4. 背景的设置在主题配置文件中,查找canvas: # Canvas-nestcanvas_nest: false# three_wavesthree_waves: false# canvas_linescanvas_lines: false# canvas_spherecanvas_sphere: false# Only fit scheme Pisces# Canvas-ribboncanvas_ribbon: true 开启相应的背景,只要把对应的false设置为true,记得把其他都改为false 5. 修改内容区域宽度Next 对内容的宽度的设定如下: 700px,当屏幕宽度 < 1600px 900px,当屏幕宽度 >= 1600px 移动设备下,宽度自适应 在主题目录下的 source\\css_variables\\custom.styl 文件,新增变量: // 修改成你期望的宽度$content-desktop = 700px// 当视窗超过 1600px 后的宽度$content-desktop-large = 900px 此方法不适用于 Pisces Scheme, Pisces Scheme 编辑themes\\next\\source\\css\\_schemes\\Picses\\_layout.styl文件,更改以下 css 选项定义值: .header {width: 1150px;}.container .main-inner {width: 1150px;}.content-wrap {width: calc(100% - 260px);} 三、文章模块的美化1. 文章中添加居中模块文章的Markdown文件中写上: <!-- HTML方式: 直接在 Markdown 文件中编写 HTML 来调用 --><blockquote class=\"blockquote-center\">优秀的人,不是不合群,而是他们合群的人里面没有你</blockquote><!-- 标签 方式,要求版本在0.4.5或以上 -->{% fullimage /image-url, alt, title %}<!-- 别名 -->{% fi /image-url, alt, title %} 2. 文章内链接样式美化在主题目录下,将source/css/_custom/custom.styl文件修改如下:// 文章内链接文本样式.post-body a{ color: #0593d3; border-bottom: none; border-bottom: 1px solid #0593d3; &:hover { color: #fc6423; border-bottom: none; border-bottom: 1px solid #fc6423; }} 3. 文章内代码美化 行内代码在主题目录下,将source/css/_custom/custom.styl文件修改如下: //行内代码样式code { color: #c7254e; background: #f9f2f4; border: 1px solid #d6d6d6; padding:1px 4px; word-break: break-all; border-radius:4px;} 区块代码在主题目录下,修改config.yml文件: # 样式可选: normal | night | night eighties | night blue | night brighthighlight_theme: night 4. 文章结束语 添加模板文件 在主题目录下\\layout\\_macro中新建 passage-end-tag.swig文件,并添加以下内容: <div> {% if not is_index %} <div style=\"text-align:center;color: #ccc;font-size:14px;\"> -------------本文结束<i class=\"fa fa-paw\"></i>感谢您的阅读------------- </div> {% endif %}</div> 导入模板文件 在\\layout\\_macro\\post.swig文件中,找到: {#####################}{### END POST BODY ###}{#####################} 在上面代码之前添加: <div> {% if not is_index %} {% include 'passage-end-tag.swig' %} {% endif %}</div> 配置 在主题配置文件中添加:# 文章末尾添加“本文结束”标记passage_end_tag: enabled: true 上述步骤是主题编写的基本步骤,值得参考。 5. 增强文章底部版权信息 增加文章md文件的头部信息中添加copyright: true时,添加版权声明 增加文章标题、发布时间、更新时间等信息 在目录next/layout/_macro/下找到post-copyright.swig,进行部分修改: {% if page.copyright %}<ul class="post-copyright"> <li class="post-copyright-author"> <strong>本文标题:</strong> <a href="{{ url_for(page.path) }}">{{ page.title }}</a> </li> <li class="post-copyright-author"> <strong>{{ __('post.copyright.author') + __('symbol.colon') }}</strong> {{ config.author }} </li> <li class="post-copyright-author"> <strong>发布时间:</strong> {{ page.date.format("YYYY年MM月DD日 - HH:MM") }} </li> <li class="post-copyright-author"> <strong>最后更新:</strong> {{ page.updated.format("YYYY年MM月DD日 - HH:MM") }} </li> <li class="post-copyright-link"> <strong>{{ __('post.copyright.link') + __('symbol.colon') }}</strong> <a href="{{ post.permalink }}" title="{{ post.title }}">{{ post.permalink }}</a> </li> <li class="post-copyright-license"> <strong>{{ __('post.copyright.license_title') + __('symbol.colon') }} </strong> {{ __('post.copyright.license_content', theme.post_copyright.license_url, theme.post_copyright.license) }} </li></ul>{% endif %} 6. 自定义文章的默认头部信息在根目录的/scaffolds/post.md文件中添加: ---title: {{ title }}date: {{ date }}tags: #标签categories: #分类copyright: true #版权声明permalink: 01 #文章链接,有默认值top: 0 #置顶优先级password: #密码保护--- 7. 文章加密访问(没有太大意义)打开主题目录下layout/_partials/head.swig文件,在meta标签后面插入这样一段代码: <script> (function(){ if('{{ page.password }}'){ if (prompt('请输入文章密码') !== '{{ page.password }}'){ alert('密码错误!'); history.back(); } } })();</script> 然后文章头部信息中添加password: password: 你设置的密码 如果password后面为空,则表示不用密码。 8. 博文置顶 安装hexo-generator-index插件 npm install hexo-generator-index --save 替换代码 把node_modules/hexo-generator-index/lib/generator.js内的代码替换为: 'use strict';var pagination = require('hexo-pagination');module.exports = function(locals){ var config = this.config; var posts = locals.posts; posts.data = posts.data.sort(function(a, b) { if(a.top && b.top) { // 两篇文章top都有定义 if(a.top == b.top) return b.date - a.date; // 若top值一样则按照文章日期降序排 else return b.top - a.top; // 否则按照top值降序排 } else if(a.top && !b.top) { // 以下是只有一篇文章top有定义,那么将有top的排在前面(这里用异或操作居然不行233) return -1; } else if(!a.top && b.top) { return 1; } else return b.date - a.date; // 都没定义按照文章日期降序排 }); var paginationDir = config.pagination_dir || 'page'; return pagination('', posts, { perPage: config.index_generator.per_page, layout: ['index', 'archive'], format: paginationDir + '/%d/', data: { __index: true } });}; 设置top值 在文章头部信息中添加top 值,数值越大文章越靠前: ---top: 100--- 9. 增强文章底部标签修改模板/themes/next/layout/_macro/post.swig,搜索 rel=”tag”>#,将 #换成 <i class=\"fa fa-tag\"></i> 10. 修改打赏 修改文字与图片 # 打赏设置reward_comment: 坚持原创技术分享,您的支持将鼓励我继续创作!wechatpay: /assets/img/weixin.jpgalipay: /assets/img/alipay.jpg# bitcoin: /images/bitcoin.png 文字、图片位置可自行修改 字体不闪动设置 修改文件next/source/css/_common/components/post/post-reward.styl,然后注释其中的函数wechat:hover和alipay:hover,如下: /* 注释文字闪动函数#wechat:hover p{animation: roll 0.1s infinite linear;-webkit-animation: roll 0.1s infinite linear;-moz-animation: roll 0.1s infinite linear;}#alipay:hover p{animation: roll 0.1s infinite linear;-webkit-animation: roll 0.1s infinite linear;-moz-animation: roll 0.1s infinite linear;}*/ 四、区块美化1. 添加顶部加载条在主题配置文件_config.yml中,找到pace并修改: pace: truepace_theme: pace-theme-minimal 加载条样式有许多,在你找到的位置中可自行更换 2. 主页文章添加阴影效果打开/themes/next/source/css/_custom/custom.styl,添加: .post { margin-top: 60px; margin-bottom: 60px; padding: 25px; -webkit-box-shadow: 0 0 5px rgba(202, 203, 203, .5); -moz-box-shadow: 0 0 5px rgba(202, 203, 204, .5); } 3. 鼠标点击小红心的设置将 love.js文件添加到主题目录的\\source\\js\\src 下。找到 \\layout\\_layout.swing文件, 在文件的后面, body标签之前 添加以下代码: <!-- 页面点击小红心 --><script type=\"text/javascript\" src=\"/js/src/love.js\"></script> 4. 搜索功能 安装 npm install hexo-generator-searchdb --save 配置 在主题配置文件下,查找local_search: local_search: enable: false trigger: auto top_n_per_article: 1 enable修改为true 在根目录配置文件中,添加以下代码: search: path: search.xml field: post format: html limit: 10000 5. 页脚美化 隐藏网页底部powered By Hexo / 强力驱动 在主题配置文件_config.yml中修改:copyright: false 添加文字或者链接 在主题目录下的layout/_partials/footer,查找powered-by: {% if theme.copyright %} <div class="powered-by">{# #}{{ __('footer.powered', '<a class="theme-link" href="https://hexo.io">Hexo</a>') }}{##}</div> 在上面代码之前添加你的文字,或者增加链接: <p>best for best!</p> <!--文字--><a href=\"www.baidu.com\">百度</a> <!--链接--> 至于样式,这里不多介绍。需要了解html、css知识。还可以设置访问量等信息,在文末参考文章中有介绍。 6. 侧边栏添加访问量等信息 获取不蒜子代码 在不蒜子上获取代码: <script async src=\"//dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js\"></script> 添加js文件 在主题目录下,找到\\layout\\_layout.swing文件, 在文件的后面, </body>标签之前,添加上面代码。 安装wordcount npm install hexo-wordcount --save 修改布局 在主题目录下,找到\\layout\\_macro\\sidebar.swing文件,查找/nav,在</nav>标签之前,添加下面代码: <br><br><div class=\"site-state-item site-state-posts\" style=\"border-left:none;\"> <span class=\"site-state-item-count\" id=\"busuanzi_value_site_pv\"></span> <span class=\"site-state-item-name\">浏览量</span></div><div class=\"site-state-item site-state-posts\"> <span class=\"site-state-item-count\" id=\"busuanzi_value_site_uv\"></span> <span class=\"site-state-item-name\">访客量</span></div><div class=\"site-state-item site-state-posts\"> <span class=\"site-state-item-count\">{{totalcount(site)}}</span> <span class=\"site-state-item-name\">总字数</span></div> 7. 文章标签显示设置在主题配置文件中,查找post_meta:# 文章标签显示设置post_meta: item_text: true created_at: true # 发表时间 updated_at: false # 更新时间 categories: true # 分类# 文章字数显示设置(需要wordcount,前面已经下载)post_wordcount: item_text: true wordcount: true # 显示字数 min2read: false # 所需时间 totalcount: false # 总字数 separated_meta: true # 分割符 文章阅读量 注册leancloud统计账号,按照next官方推荐文档 为NexT主题添加文章阅读量统计功能,获取AppID以及AppKey并在主题的_config.yml文件中填写: leancloud_visitors: enable: true app_id: joaeuuc4hsqudUUwx4gIvGF6-gzGzoHsz app_key: E9UJsJpw1omCHuS22PdSpKoh 8. 添加友言评论在友言评论中注册,并进入管理来获取你的id。修改主题配置文件的友言id:# youyan 评论youyan_uid: \"2144889\" 9. 添加jiathis分享按钮将你的友言Id添加进去:# jiathis分享按钮jiathis: uid: '2144889' 参考 next官网:第三方服务集成hexo的next主题个性化教程:打造炫酷网站Hexo-NexT搭建个人博客 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"hexo","slug":"hexo","permalink":"http://destinytaoer.cn/tags/hexo/"},{"name":"github","slug":"github","permalink":"http://destinytaoer.cn/tags/github/"},{"name":"next","slug":"next","permalink":"http://destinytaoer.cn/tags/next/"}]},{"title":"Hexo + yilia主题 + githubpages博客添加友言评论功能","date":"2017-09-19T04:48:41.000Z","path":"/posts/d04b2bbb/","text":"前言Hexo博客的Yilia主题中评论系统只提供了畅言、网易云跟帖、多说和Disqus。由于多说评论、网易云跟帖已经关闭系统,畅言需要域名备案,而github是国外的,没有备案,所以尝试了其他第三方评论系统————友言。 友言使用极其简单,本地成功实现,但是上传上github后发现无法出现评论。 在多次查找与尝试下,终于成功,下面与大家分享我的方法。 注意:本文是在前面都配置好的情况下进行的,如果最初并没有配置好,请查看:hexo+gitHubPages 快速搭建个人博客 一、注册友言id1. 注册在友言官网上直接使用qq登录,注册成功直接出来代码 2. 获取你的id进入后台管理,你会看到: 获取到你的id 二、博客文件配置1. 创建uyan.ejs文件在hexo\\themes\\yilia\\layout_partial\\post\\下新建一个uyan.ejs的文件将上述代码copy到该文件中。 2. 修改article.ejs文件修改hexo\\themes\\yilia\\layout\\_partial\\article.ejs,找到<% if (!index && post.comments){ %> 在此下方添加下列代码:<% if (theme.uyan){ %> <%- partial('post/uyan', { key: post.slug, title: post.title, url: config.url+url_for(post.path) }) %> <% } %> 3. 修改yilia主题配置文件_config.yml修改hexo\\themes\\yilia下的_config.yml,在空白处,添加如下配置:uyan: '你的友言id' 注意:要用引号包含你的iduyan: 后面必须添加一个空格,这是Hexo博客的配置要求 这样友言已经配置好了,重新编译,运行:hexo cleanhexo ghexo s访问: http://localhost:4000本地实现评论系统成功! 三、解决Github发生错误上传到github上后,打开你的github页面,发现评论并没有出现。按F12,发现报错:The page at 'https...' was loaded over HTTPS, but requested an insecure stylesheet 'http://..../css/1_6/background.css'. This request has been blocked; the content must be served over HTTPS. 原因:https下的http加载会被阻塞,也就是无法加载友言的那个js文件 查明之后,发现友言并不支持https,但是仍然有人实现了,并没有详细的解说。而我注意到域名的更改,如果改了域名,那么就不是https下了。实践证明,是可行的。 1. 域名注册这里不详细说明,没有域名可自行百度:腾讯云、阿里云、万网等注册。域名不贵,基本就几块、十几块一年,毫无问题 2. Github绑定域名添加CNAME文件 注意,CNAME文件必须放进博客目录source文件夹下,不然会被hexo clean命令清除 在文件内写入你的域名,不加www 3. 域名解析 按下图添加记录: 现在基本已经成功,你可以访问你的域名来查看你的博客 四、修改配置文件查看你的博客后,你会发现,头像无法显示,链接发生错误的情况。 原因:根链接发生错误,在不添加域名的时候,你的root会添加/仓库名/,各种链接都会自动添加这个根,而在添加域名后,域名直接指向你的仓库,此时链接仍然会自行添加根而发生链接错误。 博客目录下的_config.yml文件修改根为’/‘root: / 主题目录下的_config.yml文件修改根同上,并去掉头像等链接的仓库名 此时就大功告成了! 参考 为next添加友言评论支持hexo yilia 添加友言评论支持使用GitHub页面的自定义域github怎么绑定自己的域名? 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"hexo","slug":"hexo","permalink":"http://destinytaoer.cn/tags/hexo/"},{"name":"github","slug":"github","permalink":"http://destinytaoer.cn/tags/github/"},{"name":"yilia","slug":"yilia","permalink":"http://destinytaoer.cn/tags/yilia/"}]},{"title":"githubpages + hexo 搭建个人博客","date":"2017-09-18T13:15:58.000Z","path":"/posts/ff1c724b/","text":"前言本文仅仅是使用hexo以及gitHubPages 快速搭建个人博客,后续还会分享详细的内容 官方中文文档:https://hexo.io/zh-cn/docs/index.html 一、准备Node.js作用:node.js用来创建hexo博客框架Git客户端作用:把本地的hexo内容提交到github上去 二、Hexo打开下载好的Git Bash或者Git Shell,作用相当于命令行。 过程中使用的是cnpm,下载node会自带npm,下面使用的是淘宝镜像cnpm 1. 安装Hexocnpm install -g hexo -g为全局安装 2. 创建博客根文件夹进入要创建博客的文件夹下(如E:\\Hexo),执行以下指令,Hexo 即会自动在目标文件夹建立网站所需要的所有文件。 hexo init "文件夹名" 文件夹名称可以不写,那样就会把所有文件放在你先前进入的文件夹 3. 安装依赖包进入到你的博客文件夹下:cnpm install 把package.json文件所定义的所有依赖项全部安装 4. 运行常用命令 hexo g #完整命令为hexo generate,用于生成静态文件hexo s #完整命令为hexo server,用于启动服务器,主要用来本地预览hexo d #完整命令为hexo deploy,用于将本地文件发布到github上hexo n #完整命令为hexo new,用于新建一篇文章hexo g -d #两个命令的合成,一般在修改或者添加博文后直接使用这个命令 运行下面代码: hexo ghexo s 访问http://localhost:4000, 此时,你就能看到了一个漂亮的博客。默认主题为:landscape 三、注册Github帐号已经有Github帐号跳过此步 首先进入Github进行注册 然后,创建repository repository相当于一个仓库,用来放置你的代码文件。首先,登陆进入Github,并进入个人页面然后New一个repository ] 点进仓库,点击settings设置 下拉到GitHub Pages设置 source选中 master bransh ,然后save,就会出现一个网址。 四、部署本地文件到github1. 安装依赖cnpm install hexo-deployer-git --save 2. 编辑配置文件编辑博客文件夹下的_config.yml文件。 在_config.yml最下方,添加如下配置:deploy: type: git repo: https://github.com/用户名/仓库名/ branch: master 3. 配置SSH输入一下命令: ssh -T git@github.com 你应该会看到有警告,但是会有选项(yes/no),输入“yes”就好 4. 运行在命令行中运行hexo g -d 完成后,打开原先的仓库网址,就能看到你的博客。 五、写博文1. 新建博文hexo new "my new post" 2. 编辑博文 博文使用的是markdown语言,如果有不会使用的,请参考我的博文:mardown学习总结 在博客目录下\\source_post中打开my-new-post.md,进行编辑 3. Front-matter 博文的头部,官方文档介绍:Front-matter Front-matter 是文件最上方以 —分隔的区域,用于指定个别文件的变量,如:---title: Hello World #博文标题名date: 2013/7/13 20:46:25 #发布时间update: #更新时间categories: blog #文章文类tags: [life,travel] #文章标签 只有一个标签时:tags: travelcomments: true #是否能够评论---#这里是正文,用markdown写#你可以选择写一段显示在首页的简介后,加上<!--more-->#在<!--more-->之前的内容会显示在首页,之后的内容会被隐藏,当游客点击Read more才能看到。 写完文章后,你可以直接运行hexo g -d 上传到github。 六、创建页面使用命令:hexo new page "pagename" 1. 归档页面hexo new page "archives" 进入博客目录的source/archives/index.md,添加type值:---type: archives--- 2. 分类页面hexo new page "categories" 进入博客目录的source/categories/index.md,添加type值:---type: categories--- 3. 标签页面hexo new page "tags" 进入博客目录的source/tags/index.md,添加type值:---type: tags--- 注意:上述页面都有对应插件生成,只需更改type值 4. 自定义页面以上述同样的方法创建页面 需要模板,自行修改对应的index.md文件内容 不需要模板,完全自定义 首先,在博客目录下的_config.yml文件中,在skip_render后面添加页面路径 修改index.md文件,或者将index.md修改成index.html文件,自行添加样式等 参考 胖逆的嘟嘟的博文:hexo 的八篇干货 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"hexo","slug":"hexo","permalink":"http://destinytaoer.cn/tags/hexo/"},{"name":"github","slug":"github","permalink":"http://destinytaoer.cn/tags/github/"}]},{"title":"Hello World!","date":"2017-09-18T03:05:15.000Z","path":"/posts/481/","text":"前言 老师告诉我,让我写下第一个程序:Hello World!当时很疑惑,问老师,为什么是“Hello World”?老师说,因为这意味着你写的程序被赋予了生命,新生命的诞生总该向世界问好。 很喜欢这样一句话,同样,今天,我赋予我的博客以生命。这是它对世界打的第一声招呼。 博客介绍 博客名:destiny’Note 博主:destiny 博客描述:分享前端技术学习过程中的笔记、一些优质资源以及个人随笔 博客目录: 博客建站 前端技术 资源分享 个人随笔 前端视角 博客配置 githubpage hexo 主题next——Mist 百度统计分析 不蒜子访问量统计 友言评论 leanclound 阅读量统计 jiathis 分享 localsearch 搜索 wordcount 字数统计 hello,大家好。创建之初,希望大家能够从我这里学到知识,获得需要的资源,也希望大家可以给点意见或者建议,我将不胜荣幸。 第一次博客改版(2018.08) 主题:tomotoes abbrlink:用于生成页面的唯一码,有利于 SEO 优化 valine 评论 jsonContent 搜索 不蒜子访问量统计 leanclound 阅读量统计 wordcount 字数统计 站点地图 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"博文前言","slug":"博文前言","permalink":"http://destinytaoer.cn/tags/博文前言/"}]},{"title":"javascript 面向对象编程","date":"2017-09-14T10:53:43.000Z","path":"/posts/3af08ee9/","text":"引自:阮一峰的博客Javascript面向对象编程(一):封装Javascript面向对象编程(二):构造函数的继承Javascript面向对象编程(三):非构造函数的继承 本篇博文是摘自上面的博客,进行了一定的精简,直接呈现最理想的实现方法。 JavaScript 对象封装一、构造函数function Cat(name,color){ this.name = name; this.color = color;} 每个实例特有的属性与方法放在构造函数内,在创建实例时同时创建 1. constructor属性指向它们的构造函数。 alert(cat1.constructor == Cat); //true alert(cat2.constructor == Cat); //true 2. instanceof运算符验证原型对象与实例对象之间的关系。 alert(cat1 instanceof Cat); //true alert(cat2 instanceof Cat); //true 二、prototype实例所共有的属性和方法都指向同一内存地址:prototype对象,节省内存,提高效率 Cat.prototype.type = \" 猫科\";Cat.prototype.eat = function(){alert('吃老鼠'); Prototype模式的验证方法 1. isPrototypeOf()用来判断,某个proptotype对象和某个实例之间的关系。 alert(Cat.prototype.isPrototypeOf(cat1)); //true alert(Cat.prototype.isPrototypeOf(cat2)); //true 2. hasOwnProperty()用来判断某一个属性到底是本地属性,还是继承自prototype对象的属性。 alert(cat1.hasOwnProperty(\"name\")); // true alert(cat1.hasOwnProperty(\"type\")); // false 3. in运算符可以用来判断,某个实例是否含有某个属性,不管是不是本地属性。 alert(\"name\" in cat1); // true alert(\"type\" in cat1); // true 还可以用来遍历某个对象的所有属性。 for(var prop in cat1) { alert(\"cat1[\"+prop+\"]=\"+cat1[prop]); } 三、创建实例var cat1 = new Cat(\"小白\",\"黄色\"); javascript 对象构造函数的继承一、 构造函数绑定第一种方法也是最简单的方法,使用call或apply方法,将父对象的构造函数绑定在子对象上,即在子对象构造函数中加一行: function Cat(name,color){ Animal.apply(this, arguments); this.name = name; this.color = color; } var cat1 = new Cat(\"大毛\",\"黄色\"); alert(cat1.species); // 动物 二、 prototype模式 直接继承父类的prototype对象,但是,直接将子类prototype指向父类的prototype对象,会导致父类prototype对象的constructor属性被改掉,所以利用空对象作为中介 由于Animal对象中,不变的属性都可以直接写入Animal.prototype。所以,我们也可以让Cat()跳过 Animal(),直接继承Animal.prototype。现在,我们先将Animal对象改写: function Animal(){ } Animal.prototype.species = \"动物\"; var F = function(){}; F.prototype = Animal.prototype; Cat.prototype = new F(); Cat.prototype.constructor = Cat; F是空对象,所以几乎不占内存。 封装成一个函数,便于使用。 function extend(Child, Parent) { var F = function(){}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; Child.uber = Parent.prototype; } 使用的时候,方法如下 extend(Cat,Animal); var cat1 = new Cat(\"大毛\",\"黄色\"); alert(cat1.species); // 动物 函数体最后一行 Child.uber = Parent.prototype; 意思是为子对象设一个uber属性,这个属性直接指向父对象的prototype属性。这等于在子对象上打开一条通道,可以直接调用父对象的方法。这一行放在这里,只是为了实现继承的完备性,纯属备用性质。 三、 拷贝继承应当分为浅拷贝和深拷贝 纯粹采用”拷贝”方法实现继承。把父对象的所有属性和方法,拷贝进子对象 function extend2(Child, Parent) { var p = Parent.prototype; var c = Child.prototype; for (var i in p) { c[i] = p[i]; } c.uber = p; } 使用的时候,这样写: extend2(Cat, Animal); var cat1 = new Cat(\"大毛\",\"黄色\"); alert(cat1.species); // 动物 javascript 对象非构造函数的继承一、object()方法json格式的发明人Douglas Crockford,提出了一个object()函数,可以做到这一点。 function object(o) { function F() {} F.prototype = o; return new F(); } 把子对象的prototype属性,指向父对象,从而使得子对象与父对象连在一起。 使用的时候,第一步先在父对象的基础上,生成子对象: var Doctor = object(Chinese); 然后,再加上子对象本身的属性: Doctor.career = '医生'; 这时,子对象已经继承了父对象的属性了。 二、浅拷贝把父对象的属性,全部拷贝给子对象,也能实现继承。下面这个函数,就是在做拷贝: function extendCopy(p) { var c = {}; for (var i in p) { c[i] = p[i]; } c.uber = p; return c; } 使用的时候,这样写: var Doctor = extendCopy(Chinese); Doctor.career = '医生'; alert(Doctor.nation); // 中国 但是,这样的拷贝有一个问题。那就是,如果父对象的属性等于数组或另一个对象,那么实际上,子对象获得的只是一个内存地址,而不是真正拷贝,因此存在父对象被篡改的可能。 所以,extendCopy()只是拷贝基本类型的数据,我们把这种拷贝叫做”浅拷贝”。 三、深拷贝所谓”深拷贝”,就是能够实现真正意义上的数组和对象的拷贝。它的实现并不难,只要递归调用“浅拷贝”就行了。 function deepCopy(p, c) { var c = c || {}; for (var i in p) { if (typeof p[i] === 'object') { c[i] = (p[i].constructor === Array) ? [] : {}; deepCopy(p[i], c[i]); } else { c[i] = p[i]; } } return c; } 使用的时候这样写: var Doctor = deepCopy(Chinese); 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"javascript","slug":"javascript","permalink":"http://destinytaoer.cn/tags/javascript/"}]},{"title":"浏览器设置不保存缓存","date":"2017-08-09T15:59:00.000Z","path":"/posts/55cc9bd8/","text":"前言浏览器是有默认缓存的,当你在 http 服务下调试代码时,会出现改变 js 或者 css 文件,页面没有更改。因为浏览器会保存这些文件,并在下次打开页面需要这些文件时,仍然调用本地最开始缓存的文件,所以不会更新。导致了调试的困难。 解决办法谷歌浏览器的设置: F12打开控制台,点进Network,将下面菜单栏的Disable cache复选框选中 那么在页面打开控制台的时候,不会使用缓存的文件,大大方便了开发者的调试 opera浏览器同样有这个按钮,选中即可 火狐浏览器和IE浏览器,在我并没有任何改动的情况下,已经能过出效果,并不需要刻意设置 开发环境下的做法在开发环境下,都会使用自动化构建工具,将源码文件打包,除了index.html,更改了的文件会自动添加版本号,并且在文件中修改引用。这样就很好的避免了更新后在用户界面没有呈现效果的情况 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"浏览器","slug":"浏览器","permalink":"http://destinytaoer.cn/tags/浏览器/"}]},{"title":"去除inline-block元素间间距的N种方法","date":"2017-08-09T07:54:38.000Z","path":"/posts/4f4e1d8e/","text":"一、现象描述真正意义上的 inline-block 水平呈现的元素间,换行显示或空格分隔的情况下会有间距,很简单的个例子:<input /> <input type=\"submit\" /> 间距就来了~我们使用CSS更改非inline-block水平元素为inline-block水平,也会有该问题:.space a { display: inline-block; padding: .5em 1em; background-color: #cad5eb;} <div class=\"space\"> <a href=\"##\">惆怅</a> <a href=\"##\">淡定</a> <a href=\"##\">热血</a></div> 点击这里看示例:inline-block元素间间距demo 这种表现是符合规范的应该有的表现。不过,这类间距有时会对我们布局,或是兼容性处理产生影响,需要去掉它,该怎么办呢?以下展示N种方法(欢迎补充)! 二、方法之移除空格元素间留白间距出现的原因就是标签段之间的空格,因此,去掉HTML中的空格,自然间距就木有了。考虑到代码可读性,显然连成一行的写法是不可取的,我们可以:<div class=\"space\"> <a href=\"##\"> 惆怅</a><a href=\"##\"> 淡定</a><a href=\"##\"> 热血</a></div> 或者是:<div class=\"space\"> <a href=\"##\">惆怅</a ><a href=\"##\">淡定</a ><a href=\"##\">热血</a></div> 或者是借助HTML注释:<div class=\"space\"> <a href=\"##\">惆怅</a><!-- --><a href=\"##\">淡定</a><!-- --><a href=\"##\">热血</a></div> 等。 三、使用margin负值.space a { display: inline-block; margin-right: -3px;} margin负值的大小与上下文的字体和文字大小相关,其中,间距对应大小值可以参见“基于display:inline-block的列表布局”一文part 6的统计表格: inline-block元素间间隔大小与字体和文字大小之前的关系表截图 例如,对于12像素大小的上下文,Arial字体的margin负值为-3像素,Tahoma和Verdana就是-4像素,而Geneva为-6像素。由于外部环境的不确定性,以及最后一个元素多出的父margin值等问题,这个方法不适合大规模使用。 四、让闭合标签吃胶囊如下处理:<div class=\"space\"> <a href=\"##\">惆怅 <a href=\"##\">淡定 <a href=\"##\">热血</a></div> 注意,为了向下兼容IE6/IE7等喝蒙牛长大的浏览器,最后一个列表的标签的结束(闭合)标签不能丢。 在HTML5中,我们直接:<div class=\"space\"> <a href=\"##\">惆怅 <a href=\"##\">淡定 <a href=\"##\">热血</div> 好吧,虽然感觉上有点怪怪的,但是,这是OK的。 点击这里查看示例:无闭合标签去除inline-block元素间距demo 无闭合标签与inline-block水平元素间距的去除 五、使用font-size:0类似下面的代码:.space { font-size: 0;}.space a { font-size: 12px;} 这个方法,基本上可以解决大部分浏览器下inline-block元素之间的间距(IE7等浏览器有时候会有1像素的间距)。不过有个浏览器,就是Chrome, 其默认有最小字体大小限制,因为,考虑到兼容性,我们还需要添加:类似下面的代码:.space { font-size: 0; -webkit-text-size-adjust:none;} 点击这里查看示例:font-size:0清除换行符间隙demo 补充:根据小杜在评论中中的说法,目前Chrome浏览器已经取消了最小字体限制。因此,上面的-webkit-text-size-adjust:none;代码估计时日不多了。 六、使用letter-spacing类似下面的代码:.space { letter-spacing: -3px;}.space a { letter-spacing: 0;} 根据我去年的测试,该方法可以搞定基本上所有浏览器,包括吃“东鞋”、“西毒(胶囊)”、“南地(沟油)”、“北钙(三鹿)”的IE6/IE7浏览器,不过Opera浏览器下有蛋疼的问题:最小间距1像素,然后,letter-spacing再小就还原了。 七、使用word-spacing类似下面代码:.space { word-spacing: -6px;}.space a { word-spacing: 0;} 一个是字符间距letter-spacing,一个是单词间距word-spacing,大同小异。据我测试,word-spacing的负值只要大到一定程度,其兼容性上的差异就可以被忽略。因为,貌似,word-spacing即使负值很大,也不会发生重叠。 点击这里查看示例:word-spacing与元素间距去除demo 您使用Chrome浏览器,可能看到的是间距依旧存在。确实是有该问题,原因我是不清楚,不过我知道,可以添加display: table;或display:inline-table;让Chrome浏览器也变得乖巧。.space { display: inline-table; word-spacing: -6px;} 八、其他成品方法下面展示的是YUI 3 CSS Grids 使用letter-spacing和word-spacing去除格栅单元见间隔方法(注意,其针对的是block水平的元素,因此对IE8-浏览器做了hack处理):.yui3-g { letter-spacing: -0.31em;/* webkit */ *letter-spacing: normal; /* IE < 8 重置 */ word-spacing: -0.43em; /* IE < 8 && gecko */}.yui3-u { display: inline-block; zoom: 1; *display: inline; /* IE < 8: 伪造 inline-block */ letter-spacing: normal; word-spacing: normal; vertical-align: top;} 以下是一个名叫RayM的人提供的方法:li { display:inline-block; background: orange; padding:10px; word-spacing:0;}ul { width:100%; display:table; /* 调教webkit*/ word-spacing:-1em;}.nav li { *display:inline;} 也就是上面一系列CSS方法的组组合合。 引自 原文转自:张鑫旭-鑫空间-鑫生活 本文地址:去除inline-block元素间间距的N种方法 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"css","slug":"css","permalink":"http://destinytaoer.cn/tags/css/"}]},{"title":"初学者资源推荐","date":"2017-08-08T13:39:24.000Z","path":"/posts/eacfc1ff/","text":"前言本文是在现阶段自学过程用到过的优秀资源的总结,并与大家分享。希望可以对大家,尤其是像我一样的初学者有所帮助,少走弯路。 主要包括:视频网站、文本网站和书籍 一、视频学习网站就自学而言,我感觉还是看视频教学来得轻松些,也容易理解。 慕课网——程序员的梦工厂 我个人极力推荐的一个学习网站,前端的启蒙网站,主要针对互联网的开发。课程有前端开发、后端开发、移动开发、数据库、大数据、运维、UI等,非常适合前端人员。有很多的前端课程,也根据难易程度分为初、中、高三级。还有许多的职业路径、实战教程(大部分实战课程是要付费的)。课程非常的全面。课程里还能查看源码资源、课后小题以及在线的编辑器。总之,这是一个非常棒的国内学习网站。 二、文本类学习网站 w3chool在线教程 菜鸟教程涵盖比较全面,且包含用法和示例,容易上手,新手看的话,比较容易入门。 但是,这两个网站讲解的并不详细,而且没有深度,后期应该放弃 三、书籍《css权威指南》《javascript DOM 编程艺术》《javascript高级程序设计》(这本书较有深度) 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"}]},{"title":"Markdown学习总结","date":"2017-07-28T10:10:24.000Z","path":"/posts/64f3d682/","text":"一、 markdown简介Markdown 是一种用来写作的轻量级标记语言,创始人为约翰·格鲁伯(John Gruber) 优点 纯文本,所以兼容性极强,可以用所有文本编辑器打开 它用简洁的语法代替排版,使我们专心于码字 格式转换方便,Markdown 的文本你可以轻松转换为 html、PDF等 Markdown 的标记语法有极好的可读性 对于从事写作、文字编辑以及想写博客的人来说,非常有学习的必要。 编辑器 sublime text(本人从事前端开发最喜欢用的一个编辑器,轻量级,但是非常强大)、Mac的mou、Markdownpad等 很多网站也支持了 Markdown 的文字录入,如简书 在线编辑器,推荐StackEdit 二、 markdown语法这里只是简单介绍markdown经常用到的语法标记,也只是个人觉得最简单实用、能够快速入门,如果您想深入学习、了解更多的markdown功能,请点击下面的文档: Markdown 语法说明 (简体中文版) 标题在行首插入 1 到 6 个 # ,对应到标题 1 到 6 : # 这是 H1## 这是 H2###### 这是 H6 列表1.无序列表加号“+”或减号“-”都可以作为列表标记,注意后面要跟一个空格。 - Red- Green- Blue 或者+ Red+ Green+ Blue 或者* Red* Green* Blue 效果都是一样的: Red Green Blue 2.有序列表使用数字、一个英文句号和一个空格即可。 1. Red2. Green3. Blue 链接在方括号写下链接文字,圆括号写下网址即可。也可以在右边加上空格,再用引号加上title属性。(这个title属性可能有些人不知道,就是鼠标移动到链接上会显示的文本) [好中文的样子](http://www.jianshu.com/p/d409bb2b5d6c "http://www.jianshu.com/p/d409bb2b5d6c") 效果: 好中文的样子 还有一种在文章最后参考式的链接,在链接文字的括号后面再接上另一个方括号,而在第二个方括号里面要填入用以辨识链接的标记:This is [an example][id] reference-style link. 你也可以选择性地在两个方括号中间加上一个空格:This is [an example] [] reference-style link. 接着,在文件的任意处,你可以把这个标记的链接内容定义出来:[id]: http://example.com/ "Optional Title Here" 当第二个方括号里面为空格时,定义时应当取第一个方括号同样,可以在定义时,写上title属性 图片Markdown 中可以插入图片,比链接的语法多了一个感叹号。 ![Alt text](/path/to/img.jpg "Alt text") Alt 有些 Markdown 编辑器也支持拖拽插入图片,这就简单多了。例如简书 或者 Ulysses 就有这种功能。不过,在不同的环境下显示效果可能会有差异。 引用可以使用”>” 标记来引用其他人的言论、书籍或报纸的内容。只需要在段落的第一行最前面加上 > 即可:> We believe that writing is about content, about what you want to say – not about fancy formatting. 我们坚信写作写的是内容,所思所想,而不是花样格式。— Ulysses for Mac We believe that writing is about content, about what you want to say – not about fancy formatting.我们坚信写作写的是内容,所思所想,而不是花样格式。— Ulysses for Mac 引用可以嵌套,只要根据层次的不同,加上不同数量的 > 即可:> 这是第一级引用。>> 这是第二级引用。> 现在回到第一级引用。 这是第一级引用。 这是第二级引用。 现在回到第一级引用。 在引用的区域内,也可以使用其他的 Markdown 语法,包括标题、列表等 代码标记一小段行内代码,用反引号`左右把它包起来Use the `printf()` function. 效果:Use the printf() function. 如果要标记代码区段,你可以用多于三个反引号来开启和结束代码区段,注意开始和结束的反引号数量必须一致。\\There is a literal backtick (`) here.\\ 强调在Markdown中,可以使用 * 和 _ 来表示斜体和加粗。需要注意的是,“_”是下划线 在需要斜体的文本左右各加一个“*”或“_” 在需要加粗的文本左右各加两个“*”或“_” 在需要加粗并且斜体的文本左右各加三个“*”或“_” 表格| Tables | Are | Cool || ---------- |:-------:| --------:|| col 3 is | right-aligned | $1600 || col 2 is | centered | $12 || zebra stripes | are neat | $1 | 显示效果 Tables Are Cool col 3 is right-aligned $1600 col 2 is centered $12 zebra stripes are neat $1 分割线在一行中用三个以上的星号、减号、底线来建立一个分隔线,行内不能有其他东西。你也可以在星号或是减号中间插入空格。 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"markdown","slug":"markdown","permalink":"http://destinytaoer.cn/tags/markdown/"}]},{"title":"gulp 自动化构建工具","date":"2017-07-26T06:59:17.000Z","path":"/posts/429b6dfd/","text":"前言gulp简介gulp是一款常用的自动化构建工具,用于压缩、打包你的项目代码与文件。其他的类似的工具有grunt、webpack等。 gulp的优点 易于使用通过代码优于配置的策略,Gulp 让简单的任务简单,复杂的任务可管理。 构建快速利用 Node.js 流的威力,你可以快速构建项目并减少频繁的 IO 操作。 插件高质Gulp 严格的插件指南确保插件如你期望的那样简洁高质得工作。 易于学习通过最少的 API,掌握 Gulp 毫不费力,构建工作尽在掌握:如同一系列流管道。 下面只是介绍gulp的基本用法和常用插件。详情查看:gulp中文网 安装与使用1. 全局安装 gulp$ npm install --global gulp 2. 开发依赖安装$ npm install --save-dev gulp 3. gulpfile.js 文件在项目根目录下创建一个名为 gulpfile.js 的文件 var gulp = require('gulp');gulp.task('default', function() { // 将你的默认的任务代码放在这}); 4. 运行 gulp$ gulp 默认的名为 default 的任务(task)将会被执行,一般都把所有需要执行的放进default任务中想要单独执行特定的任务(task),请输入 gulp 任务名,就会运行gulpfile.js文件中指定的任务。 插件gulp本身并没有什么作用,需要依赖于插件来完成压缩、打包等功能。插件在gulpfile.js中配置好后,通过gulp 任务名执行 gulp-rev给文件添加版本号,在文件内容修改后,同时修改版本号,使得浏览器识别出来而不是用缓存里的文件,从而使用户看到最新的效果。 gulp-rev-replace在文件名改变后,在index文件里改变替换文件的引用 gulp-useref在html里面可以通过注释的方法,告诉gulp哪些文件要合并,合并后叫什么文件格式: <!-- build:css css/combined.css --><link href=\"css/one.css\" rel=\"stylesheet\"><link href=\"css/two.css\" rel=\"stylesheet\"><!-- endbuild --><!-- build:js scripts/combined.js --><script type=\"text/javascript\" src=\"scripts/one.js\"></script> <script type=\"text/javascript\" src=\"scripts/two.js\"></script> <!-- endbuild --> gulp-filter过滤器,两种操作,筛选、恢复 gulp-uglify压缩js代码 gulp-csso压缩css代码 gulp-watch监听文件的改变,自动执行任务,修改了文件之后,自动打包,不用我们手动执行任务 gulp-postcss与autoprefixer插件进行结合,来自动添加前缀 gulp-concat直接把多个文件合并成一个文件 gulp-responsive把大图片按照一定规则生成一系列的响应式图片 gulpfile.js基本设置//所有的依赖项var gulp = require('gulp');var rev = require('gulp-rev');var revReplace = require('gulp-rev-replace');var useref = require('gulp-useref');var filter = require('gulp-filter');var uglify = require('gulp-uglify');var csso = require('gulp-csso');//执行的任务gulp.task('default', function() {var jsFilter = filter('**/*.js',{restore:true}); //过滤出js文件的变量var cssFilter = filter('**/*.css',{restore:true}); //过滤出css文件的变量var indexHtmlFilter = filter(['**/*','!**/index.html'],{restore:true}); //过滤出所有文件的变量,但是防止了改变index的文件名//返回到压缩文件return gulp.src('src/index.html')//执行任务的源文件,也就是水流 .pipe(useref())//找到所有需要合并压缩的文件,并扔到流里 .pipe(jsFilter)///找出js文件 .pipe(uglify())//压缩js代码 .pipe(jsFilter.restore)//把js文件扔回水流里 .pipe(cssFilter)//找到css文件 .pipe(csso())//压缩css代码 .pipe(cssFilter.restore)//把css文件扔回流里 .pipe(indexHtmlFilter)//找到所有文件 .pipe(rev())//添加版本号 .pipe(indexHtmlFilter.restore)//再扔回流里 .pipe(revReplace())//替换文件引用 .pipe(gulp.dest('dist'));//最后把所有文件放到dist文件夹}); 当然,你也可以把不同的操作分开,最终再放入default任务中 // 压缩 public 目录 cssgulp.task('minify-css', function() { return gulp.src('./public/**/*.css') .pipe(minifycss()) .pipe(gulp.dest('./public'));});// 压缩 public 目录 htmlgulp.task('minify-html', function() { return gulp.src('./public/**/*.html') .pipe(htmlclean()) .pipe(htmlmin({ removeComments: true, minifyJS: true, minifyCSS: true, minifyURLs: true, })) .pipe(gulp.dest('./public'))});// 压缩 public/js 目录 jsgulp.task('minify-js', function() { return gulp.src('./public/**/*.js') .pipe(uglify()) .pipe(gulp.dest('./public'));});// 执行 gulp 命令时执行的任务gulp.task('default', [ 'minify-html','minify-css','minify-js']); 注释写成/*! 的形式,就不会被压缩,可以用来写版权声明等信息 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"gulp","slug":"gulp","permalink":"http://destinytaoer.cn/tags/gulp/"}]},{"title":"html语义化","date":"2016-12-12T00:39:24.000Z","path":"/posts/d98c97bb/","text":"前言HTML是超文本标记(Hyper Text Markup Language)的缩写,在网页设计中又把它称为网页的结构层。它的学习很简单,只要多利用业余时间去记忆、练习,一到两天时间就能掌握,并写出一个简单页面。 这里推荐一个快速入门的网址:http://www.w3school.com.cn/ 一、对于html的学习 首先是对html的整体结构的认识,即<!DOCTYPE html>的声明、html标签、head标签、body标签; 其次是对head里面的标签的认识和使用,如meta、link、title、script、style等,在网页的优化上特别重要; 最后是对body里面的标签的认识和使用,这也是网页上面呈现的内容,学html大部分时间都要花在这上面。要对常用标签的含义、用法、性质以及自带的属性都要熟练掌握,不常用标签能知道含义以及用法。 要掌握的精髓就在于在什么样的情况下运用哪个标签才能达到最好的效果。 二、标签语义化其重要作用在于: 网页结构合理 ; 利于开发调试和后期维护(让自己和别人能够比较容易看懂代码); 利于搜索引擎SEO优化。搜索引擎不能识别内容,只能识别标签语义从而知道这部分是什么内容(让搜索引擎能看懂)。有了良好的结构和语义你的网页内容自然容易被搜索引擎抓取; 方便其他设备解析(如屏幕阅读器、盲人阅读器、移动设备)。 但是,必须认识到,并不是说我们只能使用有语义的标签,而应当是在需要有语义,需要被SEO识别的情况下才必须使用有语义标签(如自己网页的主题以及重要内容等)。在不需要的情况下,也根据情况使用无语义标签。如div加CSS的页面布局、span添加一些只为实现效果的块或者描述,不需要有语义,不然也容易造成语义混乱。这是因为由标签传达的含义比浏览器显示文本的方式更为重要 文字 在有一段文字显示的情况下,必须使p标签来包含。里面可含有无语义标签div/span以及其他有语义的标签。 如:blockquote块引用,长引用(要添加cite属性引用地址)、q短的行内引用cite定义引用。可使用该标签对参考文献的引用进行定义,比如书籍或杂志的标题著作的标题、address文档作者或拥有者的联系信息、code代码abbr缩写(要添加title标签说明原文)、time时间、mark标注、ruby注释、strong强调 (特别注意,这个标签权重很高,用于特别强调的文本。搜索引擎对其有很高的识别。)、details可展开样式(details里面使用添加标题,后面接展开内容)等等…… 标题使用h1,h2,h3,h4标签,其中h5,h6权重太小一般不使用。其中的样式,即字体大小、颜色等都可以用CSS定义重新定义; 标签中应该使用的是有含义的。基于内容的样式标签会告诉浏览器它所包含的文本具有特定的含义、上下文或者用法。是浏览器和搜索引擎所能识别的。不应该使用纯粹为了设定样式而存在的标签。设定样式应当由样式表(CSS)完成。 图片 如果图片作为HTML的一部分,需要被搜索引擎识别,则用img,不需要,则可以使用背景来显示图片; img标签中的alt和title属性。其中,alt属性用于图片描述,是给搜索引擎看的,图片无法显示时,显示alt中的文字。title属性也用于图片描述,是给用户看的,鼠标移动到图片时显示title中的文字。对于img标签,两个属性都尽量添加。(对于title值,在很多元素中都可以使用,比如在布局中无法完全显示的一条新闻或者消息等,在鼠标移动到上面时显示完全的内容是很好的一种用户体验); figure元素和figcaption元素。figure元素用于包含图片和图注,figurecaption元素用于表示图注文字。在有图片和图注的情况下,使用这两个元素会使页面语义更好。 表格 表格中有table、tr、td、th、caption、thead、tbody、tfoot。语义上,th为表头单元格,caption为表格标题,thead、tbody、tfoot把表格分为三部分。这三样在效果上并不需要用到,但在良好的语义上,尽量使用 表单 lable绑定控件。lable使用于关联控件,解释控件的意义以及有一定点击效果; placeholder占位符值和value值。表单中文本框的默认值,类似提示文本。在需要用户输入文字的控件中尽量使用; fieldset表单控件分组。(只在有需要的时候使用,多数表单不分组),legend标签为 fieldset 元素定义标题。 新增标签在HTML5中添加了很多结构标签,增强了页面布局结构的语义,下面举例: header头部、标题 nav导航 section内容块区 article 文章 aside辅助信息 hgroup标题组合 footer页脚 figure独立的流内容 生命的意义不仅是活着,而是我们给别人的生命带来了何种不同。","tags":[{"name":"web前端","slug":"web前端","permalink":"http://destinytaoer.cn/tags/web前端/"},{"name":"html","slug":"html","permalink":"http://destinytaoer.cn/tags/html/"}]}]