Acc

前端知识整理

整理一些常用的前端知识

全栈开发

LINK

  • box-sizing
  • BFC
  • 块级元素,内联元素
  • 浮动
  • AMD和CMD
  • 标签上title属性与alt属性的区别
  • 标签语义化
  • html5新特性
  • CSS的选择器
  • CSS伪类与CSS伪对象
  • 等高布局
  • px、em
  • link 和@import
  • position的absolute与fixed
  • 闭包
  • JS实现面向对象和继承机制
  • Prototype模式
  • this
  • 冒泡和捕获
  • null和undefined的区别
  • flex
  • 立即执行函数 IIFE
  • EVAL和new function的区别
  • inline-block

BFC

  • 块格式化上下文块格式化上下文,内部元素和外部元素相互隔离,使内外元素的定位不会互相影响,可以闭合浮动,防止与浮动元素重叠
    块格式上下文是页面CSS 视觉渲染的一部分,用于决定块盒子的布局及浮动相互影响范围的一个区域。

BFC的创建方法

  • 根元素或其它包含它的元素;
  • 浮动 (元素的float不为none);
  • 绝对定位元素 (元素的positionabsolutefixed);
  • 行内块inline-blocks(元素的display: inline-block);
  • 表格单元格(元素的display: table-cell,HTML表格单元格默认属性);
  • overflow的值不为visible的元素;
  • 弹性盒flex boxes (元素的display: flexinline-flex);
    但其中,最常见的就是overflow:hidden、float:left/right、position:absolute。也就是说,每次看到这些属性的时候,就代表了该元素以及创建了一个BFC了。
    一个BFC包含创建该上下文元素的所有子元素,但不包括创建了新BFC的子元素的内部元素。

BFC特性

  • 内部的盒会在垂直方向一个接一个排列(可以看作BFC中有一个的常规流);
  • 处于同一个BFC中的元素相互影响,可能会发生margin collapse;
  • 每个元素的margin box的左边,与容器块border box的左边相接触(对于从左往右的格式化,否则相反)。即- 使存在浮动也是如此;
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然;
  • 计算BFC的高度时,考虑BFC所包含的所有元素,连浮动元素也参与计算
  • 浮动盒区域不叠加到BFC上;

块级元素

- 简述 sample remark
块级元素 另起一行的方式一直往下排 address,blockquote,center,dir,div,dl,filedset,form,h1-h6,hr,ol,ul,p,pre,table
内联元素 displayinlineinline-blockinline-table 一行并排显示,只能容纳文本或者其他内联元素 a,b,br,cite,em,i,img,input,label,span,small,strong - width,height无效 -margin,padding 上下无效
可变元素 button,del,iframe,ins,object,script -

浮动

  • 导致常规流环绕在它的周边

    浮动会漂浮于普通流之上,像浮云一样,但是只能左右浮动。正是这种特性,导致框内部由于不存在其他普通流元素了,表现出高度为0(高度塌陷)。
    a. 添加额外标签,例如


    b. 使用br标签和其自身的html属性,例如

    c. 父元素设置 overflow:hidden;在IE6中还需要触发hasLayout,例如zoom:1;
    d. 父元素设置 overflow:auto 属性;同样IE6需要触发hasLayout
    e. 父元素也设置浮动
    f. 父元素设置display:table
    g. 使用:after 伪元素;由于IE6-7不支持:after,使用 zoom:1触发 hasLayout。
    在CSS2.1里面有一个很重要的概念,那就是 Block formatting contexts (块级格式化上下文),简称 BFC
    创建了BFC的元素就是一个独立的盒子,里面的子元素不会在布局上影响外面的元素,同时BFC仍然属于文档中的普通流。
    IE6-7的显示引擎使用的是一个称为布局(layout)的内部概念。

AMD和CMD 规范的区别?

html5新特性

a. HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。
b. 拖拽释放(Drag and drop) API
c. 语义化更好的内容标签(header,nav,footer,aside,article,section)
d. 音频、视频API(audio,video)
e. 画布(Canvas) API
f. 地理(Geolocation) API
g. 本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失
h. sessionStorage 的数据在页面会话结束时会被清除
i. 表单控件,calendar、date、time、email、url、search
j. 新的技术webworker, websocket
移除的元素:
a. 纯表现的元素:basefont,big,center, s,strike,tt,u
b. 对可用性产生负面影响的元素:frame,frameset,noframes

CSS的选择器

元素选择器:* 、E、 E#id、 E.class
关系选择器:E、F、E>F、E+F、E~F
属性选择器:E[att]、E[att="val"]、E[att~="val"]、E[att^="val"]、E[att$="val"]、E[att*="val"]、E[att|="val"]
伪类选择器:E:link、E:visited、E:hover、E:active、E:focus、E:lang(fr)、E:not(s)、E:root、E:first-child、E:last-chil
伪对象选择器:E:first-letter/E::first-letter、E:first-line/E::first-line、E:before/E::before、E:after/E::after、E::selection

CSS伪类与CSS伪对象

CSS 引入伪类和伪元素的概念是为了描述一些现有CSS无法描述的东西
根本区别在于:它们是否创造了新的元素(抽象)
伪类:一开始用来表示一些元素的动态状态,随后CSS2标准扩展了其概念范围,使其成为了所有逻辑上存在但在文档树中却无须标识的“幽灵”分类
伪对象:代表了某个元素的子元素,这个子元素虽然在逻辑上存在,但却并不实际存在于文档树中

请写出多种等高布局

a. 假等高列:使用背景图片,在列的父元素上使用这个背景图进行Y轴的铺放,从而实现一种等高列的假像
b. 给容器div使用单独的背景色(固定布局)(流体布局):用

元素中的最大高度撑大其他的
容器高度
c. 创建带边框的两列等高布局:用border-left来做,只能使用两列。
d. 使用正padding和负margin对冲实现多列布局方法:在所有列中使用正的上、下padding和负的上、下margin,并在所有列外面加上一个容器,设置overflow:hiden把溢出背景切掉
e. 使用边框和定位模拟列等高:但不能使用在多列
f. 模仿表格布局等高列效果:兼容性不好,在ie6-7无法正常运行

在CSS样式中常使用px、em,各有什么优劣,在表现上有什么区别?

px是相对长度单位,相对于显示器屏幕分辨率而言的。
em是相对长度单位,相对于当前对象内文本的字体尺寸。
px定义的字体,无法用浏览器字体放大功能。
em的值并不是固定的,会继承父级元素的字体大小,1 ÷ 父元素的font-size × 需要转换的像素值 = em值。

a. link属于HTML标签,而@import是CSS提供的,且只能加载 CSS
b. 页面被加载时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载
c. import只在IE5以上才能识别,而link是HTML标签,无兼容问题
d. link方式的样式的权重 高于@import的权重
e. 当使用 Javascript 控制 DOM 去改变样式的时候,只能使用 link 方式,因为 @import 眼里只有 CSS ,不是 DOM 可以控制

position的absolute与fixed共同点与不同点

相同:
a. 改变行内元素的呈现方式,display被置为block
b. 让元素脱离普通流,不占据空间
c. 默认会覆盖到非定位元素上
区别:
absolute的”根元素“是可以设置的,而fixed的”根元素“固定为浏览器窗口。
当你滚动网页,fixed元素与浏览器窗口之间的距离是不变的。

absolute:生成绝对定位的元素,相对于 static 定位以外的第一个祖先元素进行定位

fixed:生成绝对定位的元素,相对于浏览器窗口进行定位。 (IE6不支持)
relative:生成相对定位的元素,相对于其在普通流中的位置进行定位
static:默认值。没有定位,元素出现在正常的流中

Gulp 自动刷新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var gulp = require('gulp');
var less = require('gulp-less')
var connect = require('gulp-connect');
gulp.task("webserver", function() {
connect.server({
livereload: true
});
})
gulp.task('css', function() {
gulp.src("*.css").pipe(connect.reload())
})
gulp.task('less', function() {
gulp.src("*.less").pipe(less()).pipe(gulp.dest("./")).pipe(connect.reload())
})
gulp.task('watch', function() {
gulp.watch("*.less", ['less'])
})
gulp.task("default", ['webserver', 'watch'])

闭包

内部函数引用外部变量
模块化,可重用,实现信息隐藏
优:
封装私有属性和私有方法,加强封装性,可以达到对变量的保护作用。
更好的组织代码,比如模块化
缺:
增加了内存的消耗,并且在某些浏览器下,由于垃圾回收机制不同,有可能导致内存溢出
增加复杂度
由于闭包内部变量优先级高于外部变量,所以多查找作用域链中的一个层次,就会在一定程度上影响查找速度。

变量和函数的所有声明都会在任何代码被执行前首先被处理
函数声明和变量声明总是被JavaScript解释器隐式地提升到包含他们的作用域的最顶端。
function优先声明于var。
函数表达式中只会提升名称,函数体只有在执行到赋值语句时才会被赋值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function foo() {
bar();
var x = 1;
}
function foo() {//等同于
var x;
bar();
x = 1;
}
function test() {
foo(); // TypeError "foo is not a function"
bar(); // "this will run!"
var foo = function () { }// 函数表达式被赋值给变量'foo'
function bar() { }// 名为'bar'的函数声明
}

JS实现面向对象和继承机制

创建对象方法:
a. 利用json创建对象
b. 使用JavaScript中的Object类型
c. 通过创建函数来生成对象
继承机制:
a. 构造函数绑定,使用call或apply方法,将父对象的构造函数绑定在子对象上
b. prototype模式,继承new函数的模式
c. 直接继承函数的prototype属性,对b的一种改进
d. 利用空对象作为中介
e. 在ECMAScript5中定义了一个新方法Object.create(),用于创建一个新方法
f. 拷贝继承,把父对象的所有属性和方法,拷贝进子对象,实现继承。参考《JavaScript中的对象克隆》

Prototype模式

this指的是:调用函数的那个对象。
a. 纯粹的函数调用,属于全局性调用,因此this就代表全局对象Global。
b. 作为对象方法的调用,这时this就指这个上级对象。
c. 作为构造函数调用,就是通过这个函数new一个新对象(object)。这时,this就指这个新对象。
d. apply与call的调用,它们的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象。

冒泡和捕获

阻止冒泡
event.stopPropagation()
event.cancelBubble=true。
阻止默认事件
event.preventDefault()
event.returnValue=false。

1
2
3
4
5
6
7
8
9
10
11
12
function addEvent(obj,type,handle){
try{ // Chrome、FireFox、Opera、Safari、IE9.0及其以上版本
obj.addEventListener(type,handle,false);
}catch(e){
try{ // IE8.0及其以下版本
obj.attachEvent('on' + type,handle);
}catch(e){ // 早期浏览器
obj['on' + type] = handle;
}
}
}
addEvent(document.getElementById("demo"),"click",myAlert);

null:
a. null是一个表示”无”的对象,转为数值时为0
b. null表示”没有对象”,即该处不应该有值。
undefined:
a. undefined是一个表示”无”的原始值,转为数值时为NaN。
b. undefined表示”缺少值”,就是此处应该有一个值,但是还没有定义。

  • 括号内部不能包含语句,当解析器对代码进行解释的时候,先碰到了(),然后碰到function关键字就会自动将()里面的代码识别为函数表达式而不是函数声明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 最常用的两种写法
(function(){ /* code */ }()); // 老道推荐写法
(function(){ /* code */ })(); // 当然这种也可以
// 括号和JS的一些操作符(如 = && || ,等)可以在函数表达式和函数声明上消除歧义
// 如下代码中,解析器已经知道一个是表达式了,于是也会把另一个默认为表达式
// 但是两者交换则会报错
var i = function(){ return 10; }();
true && function(){ /* code */ }();
0, function(){ /* code */ }();
// 如果你不怕代码晦涩难读,也可以选择一元运算符
!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }();
// 你也可以这样
new function(){ /* code */ }
new function(){ /* code */ }() // 带参数
  • 立即执行函数在模块化中也大有用处。用立即执行函数处理模块化可以减少全局变量造成的空间污染,构造更多的私有变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 创建一个立即执行的匿名函数
// 该函数返回一个对象,包含你要暴露的属性
// 如下代码如果不使用立即执行函数,就会多一个属性i
// 如果有了属性i,我们就能调用counter.i改变i的值
// 对我们来说这种不确定的因素越少越好
var counter = (function(){
var i = 0;
return {
get: function(){
return i;
},
set: function( val ){
i = val;
},
increment: function() {
return ++i;
}
};
}());
// counter其实是一个对象
counter.get(); // 0
counter.set( 3 );
counter.increment(); // 4
counter.increment(); // 5
counter.i; // undefined i并不是counter的属性
i; // ReferenceError: i is not defined (函数内部的是局部变量)
1
2
3
4
5
1 var jsonStr = "{'a:':'b'}";
2 var object = eval(jsonStr); //会报错
不加括号eval时,js会把{}当成代码块,而'a':'b'当成语句来进行解析,那么肯定会报语法错误;
'(' + jsonStr + ')'后,代码字符串变成 ({'a':'b'}),那么该代码是个正确的js赋值代码
3 var object = eval('(' + jsonStr + ')'); //则会正确解析
  • 他们的区别在于:作用域不同

    1
    2
    3
    4
    5
    6
    7
    8
    var str = 'console.log(a)';
    var a = 0;
    (function() {
    var a = 1;
    eval('(' + str + ')'); //返回1
    window.eval('(' + str + ')'); //返回0
    (new Function('return ' + str))(); //返回0
    })();
  • 对于JS的函数作用域来说,变量作用域有任意层级,即 其他函数内部定义的函数可以调用父函数的局部变量,而内部函数里定义的函数不仅可以调用父函数的局部变量,还可以调用祖父函数的局部变量,以此类推* —— 摘自 《Javascript编程精解》

因此,对于上述例子来说,window.evalnew Function都是全局作用域的,即他们只能调用全局变量;而eval是局部函数,即他可以调用其父函数的局部变量。

Function.bind

1
2
3
4
5
6
Function.prototype.bind = function (scope) {
var fn = this;
return function () {
return fn.apply(scope);
};
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP
? this
: oThis || this,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}

函数表达式

var getNamefunction getName 都是声明语句,
区别在于 var getName函数表达式,而 function getName函数声明
事实是函数声明会覆盖变量声明。

inline-block

既拥有了block元素可以设置widthheight的特性,又保持了inline元素不换行的特性。
inline元素之间就有空隙出现,空白符! font-size:0px;

JAVASCRIPT 装载和执行

浏览器是并行加载css文件,串行加载js文件。

apply && this

apply:应用某一对象的一个方法,用另一个对象替换当前对象。
call:调用一个对象的一个方法,以另一个对象替换当前对象。
可以用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象

1
2
function.apply([thisObj[,argArray]])
function.call([thisObj[,arg1[, arg2[, [,.argN]]]]])

Math.max.apply(null, [a, b, c, d, ...])