一年前写了一篇JavaScript八张思惟导图,主要是对前端JavaScript知识点的一个系统的整理和总结。本篇文章用了近一个月时间,搜集整理了网上各类面试笔试题及本人针对前端的一些理解以及各路大神针对前端难点部分的详细介绍,能够做为之后面试或者考察面试人员的参考。 相信经过这两篇文章的学习,必定会让你对前端有一个更深的认识。javascript
后续会持续更新......css
string number boolean undefined nullhtml
typeof null === 'object' // true
typeof undefined === 'undefined' // true
==比较以前会先进行类型转换,即不会对类型进行比较。例如:前端
12 == '12' // true
true == 1 // true
false == '0' // true
复制代码
===会比较数值和类型。例如:vue
12 === '12' // false
12 === 12 // true
true === 1 // false
false === '0' // false
复制代码
JS在使用运算符号或者对比符时,会自带隐式转换,规则以下:java
-、*、/、% :一概转换成数值后计算node
+:jquery
[1].toString() === '1'nginx
{}.toString() === '[object object]'git
NaN !== NaN 、+undefined 为 NaN
"Attribute"是在HTML中定义的,而"property"是在DOM上定义的。为了说明区别,假设咱们在HTML中有一个文本框:
<input type="text" value="Hello">
const input = document.querySelector('input');
console.log(input.getAttribute('value')); // Hello
console.log(input.value); // Hello
复制代码
可是在文本框中键入“ World!”后:
console.log(input.getAttribute('value')); // Hello
console.log(input.value); // Hello World!
复制代码
定义: 全局属性 NaN 的值表示不是一个数字(Not-A-Number)
如何判断一个值是不是NaN: 等号运算符(== 和 ===) 不能被用来判断一个值是不是 NaN。必须使用 Number.isNaN() 或 isNaN() 函数。
NaN === NaN; // false
Number.NaN === NaN; // false
isNaN(NaN); // true
isNaN(Number.NaN); // true
复制代码
须要考虑三个问题:
检查对象的“值相等”的一个强大的方法,最好是依靠完善的测试库,涵盖了各类边界状况。Underscore和Lo-Dash有一个名为_.isEqual()方法,用来比较好的处理深度对象的比较。您可使用它们像这样:
// Outputs: true
console.log(_.isEqual(obj1, obj2));
复制代码
'use strict' 是用于对整个脚本或单个函数启用严格模式的语句。严格模式是可选择的一个限制 JavaScript 的变体一种方式 。
优势:
缺点:
总的来讲,我认为利大于弊,我历来不使用严格模式禁用的功能,所以我推荐使用严格模式。
.call和.apply都用于调用函数,第一个参数将用做函数内 this 的值。然而,.call接受逗号分隔的参数做为后面的参数,而.apply接受一个参数数组做为后面的参数。一个简单的记忆方法是,从call中的 C 联想到逗号分隔(comma-separated),从apply中的 A 联想到数组(array)。
function add(a, b) {
return a + b;
}
console.log(add.call(null, 1, 2)); // 3
console.log(add.apply(null, [1, 2])); // 3
复制代码
.call和.apply是当即执行的, .bind 返回函数的副本,但带有绑定上下文!它不是当即执行的。
const person = { name: 'Lydia' }
function sayHi(age) {
console.log(`${this.name} is ${age}`)
}
sayHi.call(person, 21)
sayHi.bind(person, 21)
结果: Lydia is 21 function
复制代码
摘自MDN:
bind()方法建立一个新的函数, 当被调用时,将其 this 关键字设置为提供的值,在调用新函数时,在任何提供以前提供一个给定的参数序列。
根据个人经验,将this的值绑定到想要传递给其余函数的类的方法中是很是有用的。在 React 组件中常常这样作。
var arr = [];
if (Array.isArray(arr) && arr.length === 0) {
console.log('是空数组');
}
// Array.isArray是ES5提供的,若是不支持。用下面的方案。
if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}
复制代码
数组乱序:
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr.sort(function () {
return Math.random() - 0.5;
});
复制代码
数组拆解:
// flat: [1,[2,3]] --> [1, 2, 3]
Array.prototype.flat = function() {
return this.toString().split(',').map(item => +item )
}
复制代码
以上4种操做均会改变数组自己
map用法:
let array = [1, 2, 3, 4, 5];
let newArray = array.map((item, i, arr) => {
return item * 2;
});
console.log("array:", array); // [1, 2, 3, 4, 5]
console.log("newArray:", newArray); // [2, 4, 6, 8, 10]
// 此处的array接受map方法运算以后的返回值
// 可是map方法并不能改变原来的数组
复制代码
forEach用法:
let array = [1, 2, 3, 4, 5];
let newArray = array.forEach((item, i, arr) => {
console.log('item:' + item + ', index:' + i);
// array[i] = item * 2; // 能够用这种方式改变原始数组的值
});
console.log("array:", array); // [1, 2, 3, 4, 5]
console.log("newArray:", newArray); // undefined
// forEach方法没有返回值
复制代码
Object.prototype.hasOwnProperty()
复制代码
for循环
for (let property in obj) {
console.log(property);
}
复制代码
可是,这还会遍历到它的继承属性,在使用以前,你须要加入obj.hasOwnProperty(property)检查。
Object.keys()
Object.keys(obj).forEach((property) => { ... })
复制代码
Object.keys()方法会返回一个由一个给定对象的自身可枚举属性组成的数组。
Object.getOwnPropertyNames()
Object.getOwnPropertyNames(obj).forEach((property) => { ... })
复制代码
Object.getOwnPropertyNames()方法返回一个由指定对象的全部自身属性的属性名(包括不可枚举属性但不包括 Symbol 值做为名称的属性)组成的数组。
for loops
for (let i = 0; i < arr.length; i++) { ... }
复制代码
forEach
arr.forEach((item, index, arr) { ... })
复制代码
map
arr.map((item, index, arr) => { ... })
复制代码
匿名函数能够在 IIFE 中使用,来封装局部做用域内的代码,以便其声明的变量不会暴露到全局做用域。
(function() {
// 一些代码。
})();
复制代码
匿名函数能够做为只用一次,不须要在其余地方使用的回调函数。当处理函数在调用它们的程序内部被定义时,代码具备更好地自闭性和可读性,能够省去寻找该处理函数的函数体位置的麻烦。
setTimeout(function() {
console.log('Hello world!');
}, 1000);
复制代码
匿名函数能够用于函数式编程或 Lodash(相似于回调函数)。
const arr = [1, 2, 3];
const double = arr.map(function(el) {
return el * 2;
});
console.log(double); // [2, 4, 6]
复制代码
IIFE( 当即调用函数表达式)是一个在定义时就会当即执行的 JavaScript 函数。
(function () {
statements
})();
复制代码
这是一个被称为 自执行匿名函数 的设计模式,主要包含两部分。第一部分是包围在 圆括号运算符 () 里的一个匿名函数,这个匿名函数拥有独立的词法做用域。这不只避免了外界访问此 IIFE 中的变量,并且又不会污染全局做用域。
第二部分再一次使用 () 建立了一个当即执行函数表达式,JavaScript 引擎到此将直接执行函数。
当初始的 HTML 文档被彻底加载和解析完成以后,DOMContentLoaded事件被触发,而无需等待样式表、图像和子框架的完成加载。
window的load事件仅在 DOM 和全部相关资源所有完成加载后才会触发。
下面将对以下数据进行判断它们的类型
var bool = true
var num = 1
var str = 'abc'
var und = undefined
var nul = null
var arr = [1, 2, 3]
var obj = {a: 'aa', b: 'bb'}
var fun = function() {console.log('I am a function')}
复制代码
typeof: 适合基本的数据类型和函数
console.log(typeof bool); // boolean
console.log(typeof num); // number
console.log(typeof str); // string
console.log(typeof und); // undefined
console.log(typeof nul); // object
console.log(typeof arr); // object
console.log(typeof obj); // object
console.log(typeof fun); // function
复制代码
由结果可知typeof能够测试出number、string、boolean、undefined及function,而对于null及数组、对象,typeof均检测出为object,不能进一步判断它们的类型。
instanceof: 判断对象类型,基于原型链去判断。
obj instanceof Object: 左操做数是一个对象,右操做数是一个函数构造器或者函数对象,判断左边的操做数的原型链_proto_属性是否有右边这个函数对象的proptotype属性。
console.log(bool instanceof Boolean);// false
console.log(num instanceof Number); // false
console.log(str instanceof String); // false
console.log(und instanceof Object); // false
console.log(arr instanceof Array); // true
console.log(nul instanceof Object); // false
console.log(obj instanceof Object); // true
console.log(fun instanceof Function);// true
var bool2 = new Boolean()
console.log(bool2 instanceof Boolean);// true
var num2 = new Number()
console.log(num2 instanceof Number);// true
var str2 = new String()
console.log(str2 instanceof String);// true
function Animation(){}
var ani = new Animation()
console.log(ani instanceof Animation);// true
function Dog(){}
Dog.prototype = new Animation()
var dog = new Dog()
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animation);// true
console.log(dog instanceof Object); // true
复制代码
从结果中看出instanceof不能区别undefined和null,并且对于基本类型若是不是用new声明的则也测试不出来,对因而使用new声明的类型,它还能够检测出多层继承关系。
constructor: 返回对建立此对象的函数的引用
console.log(bool.constructor === Boolean); // true
console.log(num.constructor === Number); // true
console.log(str.constructor === String); // true
console.log(arr.constructor === Array); // true
console.log(obj.constructor === Object); // true
console.log(fun.constructor === Function); // true
console.log(ani.constructor === Animation); // true
console.log(dog.constructor === Dog); // false
console.log(dog.constructor === Animation);// true
复制代码
null 和 undefined 是无效的对象,所以是不会有 constructor 存在的,这两种类型的数据须要经过其余方式来判断。
函数的 constructor 是不稳定的,这个主要体如今自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失。因此dog.constructor === Animation 而不是 Dog
Object.prototype.toString.call
console.log(Object.prototype.toString.call(bool)); //[object Boolean]
console.log(Object.prototype.toString.call(num)); //[object Number]
console.log(Object.prototype.toString.call(str)); //[object String]
console.log(Object.prototype.toString.call(und)); //[object Undefined]
console.log(Object.prototype.toString.call(nul)); //[object Null]
console.log(Object.prototype.toString.call(arr)); //[object Array]
console.log(Object.prototype.toString.call(obj)); //[object Object]
console.log(Object.prototype.toString.call(fun)); //[object Function]
console.log(Object.prototype.toString.call(dog)); //[object Object]
复制代码
原理(摘自高级程序设计3):在任何值上调用 Object 原生的 toString() 方法,都会返回一个 [object NativeConstructorName] 格式的字符串。每一个类在内部都有一个 [[Class]] 属性,这个属性中就指定了上述字符串中的构造函数名。 可是它不能检测非原生构造函数的构造函数名。
使用jquery中的$.type
console.log($.type(bool)); //boolean
console.log($.type(num)); //number
console.log($.type(str)); //string
console.log($.type(und)); //undefined
console.log($.type(nul)); //null
console.log($.type(arr)); //array
console.log($.type(obj)); //object
console.log($.type(fun)); //function
console.log($.type(dog)); //object
复制代码
$.type()内部原理就是用的Object.prototype.toString.call()
添加操做
let element = document.createElement("div"); // 建立元素
body.appendChild(element); // 将一个节点添加到指定父节点的子节点列表末尾
复制代码
删除操做
var oldChild = node.removeChild(child); // 删除子元素
ChildNode.remove() // 删除元素
复制代码
修改操做
Node.innerText // 修改元素文本内容
Element.innerHTML // 设置或获取描述元素后代的HTML语句
复制代码
查找操做
Document.getElementById() // 返回对拥有指定 id 的第一个对象的引用
Document.querySelector() // 返回文档中匹配指定的CSS选择器的第一元素
Document.querySelectorAll() // 返回与指定的选择器组匹配的文档中的元素列表
复制代码
浏览器下载除JS外的资源时,会并行下载,以提升性能。但下载JS脚本时,会禁止并行下载(称为脚本阻塞Scripts Block Downloads)。浏览器遇到JS时,必须等JS下载,解析,执行完后,才能继续并行下载下一个资源。缘由是JS可能会改变页面或改变JS间的依赖关系,例如A.js中用document.write改变页面,B.js依赖于A.js。所以要严格保证顺序,不能并行下载。
因为浏览器在遇到<body>标签前是不会渲染页面的,为了不白屏,一般的建议是将JS放到标签底下,能够有最佳的用户体验。
按推荐度排序:
动态建立<script>标签(Dynamic Script Element)
var script = document.createElement('script'); // 建立script标签
script.type = "text/javascript";
script.src = "A.js";
document.getElementsByTagName('head')[0].appendChild(script); // 塞进页面
复制代码
先用document.createElement(‘script’)生成一个script标签,再设置它的src属性,最后将其插入到<head>中。
script标签被插入到页面的DOM树后,就会开始下载src属性指定的脚本。并且经过动态脚本元素下载脚本是异步的,不会阻塞页面的其余下载和处理过程,所以script标签插入<head>中也没问题。
Script async
<script type="text/javascript" src="A.js" async></script>
复制代码
浏览器解析到HTML里的该行script标签,发现指定为async,会异步下载解析执行脚本。
async 是HTML5里为script标签新增的属性,对于低版本浏览器会存在兼容性问题。
它会在下载完成后马上执行,而不是会等到DOM加载完成以后再执行,因此仍是有可能会形成阻塞。
这种方式只适用于引用外部js文件的<script>标签。
添加async属性的js文件不该该使用document.write方法。
对多个带有async的js文件,它不能保证按顺序执行,它是哪一个js文件先下载完就先执行哪一个。
Script defer
<script type="text/javascript" src="A.js" defer></script>
复制代码
浏览器解析到HTML里的该行script标签,发现指定为defer,会暂缓下载解析执行脚本。而是等到页面加载完毕后,才加载脚本(更精确地说,是在DOM树构建完成后,在window.onload触发前,加载defer的脚本)。
defer也是只适用于外部js文件,也不能在js中使用document.write方法。
能够保证多个js文件的执行顺序就是它们在页面中出现的顺序。
经过判断Global对象是否为window,若是不为window,则当前脚本运行在node.js环境中。
this === window ? 'browser' : 'node';
复制代码
基础数据类型与栈内存
JS中的基础数据类型,这些值都有固定的大小,每每都保存在栈内存中,由系统自动分配存储空间。咱们能够直接操做保存在栈内存空间的值,所以基础数据类型都是按值访问。
数据在栈内存中的存储与使用方式相似于数据结构中的堆栈数据结构,遵循后进先出的原则。
基础数据类型: Number String Null Undefined Boolean
引用数据类型与堆内存
与其余语言不一样,JS的引用数据类型,好比数组Array、对象Object、函数Function,它们值的大小是不固定的。引用数据类型的值是保存在堆内存中的对象。JavaScript不容许直接访问堆内存中的位置,所以咱们不能直接操做对象的堆内存空间。
在操做对象时,其实是在操做对象的引用而不是实际的对象。所以,引用类型的值都是按引用访问的。这里的引用,咱们能够粗浅地理解为保存在栈内存中的一个地址,该地址与堆内存的实际值相关联。
总结:
栈内存 | 堆内存 |
---|---|
存储基础数据类型 | 存储引用数据类型 |
按值访问 | 按引用访问 |
存储的值大小固定 | 存储的值大小不定,可动态调整 |
由系统自动分配内存空间 | 由开发人员经过代码分配 |
主要用来执行程序 | 主要用来存放对象 |
空间小,运行效率高 | 空间大,可是运行效率相对较低 |
先进后出,后进先出 | 无序存储,可根据引用直接获取 |
防抖与节流函数是一种最经常使用的 高频触发优化方式,能对性能有较大的帮助。
防抖 (debounce): 将屡次高频操做优化为只在最后一次执行,一般使用的场景是:用户输入,只需再输入完成后作一次输入校验便可。
节流(throttle): 每隔一段时间后执行一次,也就是下降频率,将高频操做优化成低频操做,一般使用场景: 滚动条事件 或者 resize 事件,一般每隔 100~500 ms执行一次便可。
function throttle(method, context) {
clearTimeout(method.tID);
method.tID = setTimeout(function () {
method.call(context);
}, 1000);
}
复制代码
用法:
function showTime() {
console.log("nowDate:" + new Date().toLocaleDateString());
}
setInterval(function () {
throttle(showTime);
}, 2000);
复制代码
模块化开发在现代开发中已经是必不可少的一部分,它大大提升了项目的可维护、可拓展和可协做性。一般,咱们 在浏览器中使用 ES6 的模块化支持,在 Node 中使用 commonjs 的模块化支持。
分类:
require与import的区别
单页Web应用(single page web application,SPA),就是只有一张Web页面的应用,是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用程序。
单页应用SPA | 多页应用MPA | |
---|---|---|
组成 | 一个外壳页面和多个页面片断组成 | 多个完整页面构成 |
资源共用(css,js) | 共用,只需在外壳部分加载 | 不共用,每一个页面都须要加载 |
刷新方式 | 页面局部刷新或更改 | 整页刷新 |
url 模式 | a.com/#/pageone a.com/#/pagetwo |
a.com/pageone.html a.com/pagetwo.html |
用户体验 | 页面片断间的切换快,用户体验良好 因为要一次加载全部的资源(html/js),故首屏加载慢 |
页面切换加载缓慢,流畅度不够,用户体验比较差 首屏加载很快 |
转场动画 | 容易实现 | 没法实现 |
数据传递 | 容易 | 依赖 url传参、或者cookie 、localStorage等 |
搜索引擎优化(SEO) | 须要单独方案、实现较为困难、不利于SEO检索。 Prerender预渲染优化SEO |
实现方法简易 |
试用范围 | 高要求的体验度、追求界面流畅的应用 | 适用于追求高度支持搜索引擎的应用 |
开发成本 | 较高,常需借助专业的框架 | 较低,但页面重复代码多 |
维护成本 | 相对容易 | 相对复杂 |
如下是移动端的优化方案,大部分Web端也一样适用
事件循环是指: 执行一个宏任务,而后执行清空微任务列表,循环再执行宏任务,再清微任务列表
功能检测(feature detection)
功能检测包括肯定浏览器是否支持某段代码,以及是否运行不一样的代码(取决于它是否执行),以便浏览器始终可以正常运行代码功能,而不会在某些浏览器中出现崩溃和错误。例如:
if ('geolocation' in navigator) {
// 可使用 navigator.geolocation
} else {
// 处理 navigator.geolocation 功能缺失
}
复制代码
Modernizr是处理功能检测的优秀工具。
功能推断(feature inference)
功能推断与功能检测同样,会对功能可用性进行检查,可是在判断经过后,还会使用其余功能,由于它假设其余功能也可用,例如:
if (document.getElementsByTagName) {
element = document.getElementById(id);
}
复制代码
很是不推荐这种方式。功能检测更能保证万无一失。
UA 字符串
这是一个浏览器报告的字符串,它容许网络协议对等方(network protocol peers)识别请求用户代理的应用类型、操做系统、应用供应商和应用版本。它能够经过navigator.userAgent访问。 然而,这个字符串很难解析而且极可能存在欺骗性。例如,Chrome 会同时做为 Chrome 和 Safari 进行报告。所以,要检测 Safari,除了检查 Safari 字符串,还要检查是否存在 Chrome 字符串。不要使用这种方式。
考虑到历史缘由及现代浏览器中用户代理字符串(userAgent)的使用方式,经过用户代理字符串来检测特定的浏览器并非一件轻松的事情。因此使用用户代理检测是最后的选择。
用户代理检测通常适用如下的情形:
可使用navigator.userAgent。
同源策略限制了从同一个源加载的文档或脚本如何与来自另外一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。
下表给出了相对http://store.company.com/dir/page.html同源检测的示例:
URL | 结果 | 缘由 |
---|---|---|
store.company.com/dir2/other.… | 成功 | 只有路径不一样 |
store.company.com/dir/inner/a… | 成功 | 只有路径不一样 |
store.company.com/secure.html | 失败 | 不一样协议 ( https和http ) |
store.company.com:81/dir/etc.htm… | 失败 | 不一样端口 ( http:// 80是默认的) |
news.company.com/dir/other.h… | 失败 | 不一样域名 ( news和store ) |
不一样标签页间的通信,本质原理就是去运用一些能够 共享的中间介质,所以比较经常使用的有如下方法:
按实际使用量排序(我的理解):
CORS 跨域
nginx反向代理
WebSockets
JSONP 只支持GET请求
hash + iframe 只支持GET请求
postMessage 只支持GET请求
document.domain
目前常见的存储方式为如下三种:
在H5出现以前,数据都是存储在cookie中的。为了解决cookie的局限性引入了Web存储,indexedDB用于客户端存储大量结构化数据(包括, 文件/ blobs)。
共同点:都是保存在浏览器端、且同源的
区别:
Cookie | localStorage | sessionStorage | indexedDB | |
---|---|---|---|---|
容量大小 | 4kb左右 | 5M左右 | 5M左右 | 无限容量 |
过时时间 | 只在设置的过时时间以前一直有效, 即便窗口或者浏览器关闭 |
始终有效 | 当前浏览器窗口关闭前有效 | 始终有效 |
存储方式 | 浏览器和服务器间来回传递 | 本地保存 | 本地保存 | 本地保存 |
做用域 | 在同源窗口中共享 | 在同源窗口中共享 | 在同源窗口而且同一窗口中共享 | 在同源窗口中共享 |
XSS(跨站脚本攻击)几种形式,防范手段,过滤哪些字符
csrf(跨站请求伪造)原理,实现,防范手段
sql注入
命令行注入
DDoS(Distributed Denial of Service) 又叫分布式拒绝服务
流量劫持 DNS劫持 HTTP劫持
服务器漏洞
现代浏览器为JavaScript创造的 多线程环境。能够新建并将部分任务分配到worker线程并行运行,两个线程可 独立运行,互不干扰,可经过自带的 消息机制 相互通讯。
限制:
可用 chrome 中的 timeline 进行内存标记,可视化查看内存的变化状况,找出异常点。
lidaguang1989.github.io/2018/01/jav…
function myTrim(str) {
let reg = /^\s+|\s+$/g;
return str.replace(reg, "");
}
console.log(myTrim(' asdf '));
复制代码
link > visited > hover > active
content 属性专门应用在 before/after 伪元素上,用于插入额外内容或样式。可减小标签的使用。
伪元素 -- 在内容元素的先后插入额外的元素或样式,可是这些元素实际上并不在文档中生成。
它们只在外部显示可见,但不会在文档的源代码中找到它们,所以,称为“伪”元素。例如:
p::before {content:"第一章:";}
p::after {content:"Hot!";}
p::first-line {background:red;}
p::first-letter {font-size:30px;}
复制代码
伪类 -- 将特殊的效果添加到特定选择器上。它是已有元素上添加类别的,不会产生新的元素。例如: a:hover {color: #FF00FF} p:first-child {color: red}
浏览器的默认字体都是16px,那么1em=16px,以此类推计算10px=0.625em
为了简化font-size的换算,通常都会在body中写入如下代码
body { font-size: 62.5%; } /* 公式16px*62.5%=10px */
复制代码
em的值并非固定的
em会继承父级元素的字体大小(参考物是父元素的font-size)
em中全部的字体都是相对于父元素的大小决定的;因此若是一个设置了font-size:1.2em的元素在另外一个设置了font-size:1.2em的元素里,而这个元素又在另外一个设置了font-size:1.2em的元素里,那么最后计算的结果是1.2X1.2X1.2=1.728em
页面渲染时,dom 元素所采用的 布局模型。可经过box-sizing进行设置。
默认值,标准盒子模型。 width 与 height 只包括内容的宽和高, 不包括边框(border),内边距(padding),外边距(margin)。注意: 内边距、边框和外边距都在这个盒子的外部。 好比说,.box {width: 350px; border: 10px solid black;} 在浏览器中的渲染的实际宽度将是 370px。
尺寸计算公式:
width = 内容的宽度
height = 内容的高度
宽度和高度的计算值都不包含内容的边框(border)和内边距(padding)。
width 和 height 属性包括内容,内边距和边框,但不包括外边距。这是当文档处于 Quirks模式 时Internet Explorer使用的盒模型。注意,填充和边框将在盒子内 , 例如, .box {width: 350px; border: 10px solid black;} 致使在浏览器中呈现的宽度为350px的盒子。内容框不能为负,而且被分配到0,使得不可能使用border-box使元素消失。
尺寸计算公式:
width = border + padding + 内容的宽度
height = border + padding + 内容的高度
通过定位的元素,其position属性值必然是relative、absolute、fixed或sticky。
block | inline-block | inline | |
---|---|---|---|
大小 | 填充其父容器的宽度 | 取决于内容 | 取决于内容 |
定位 | 重新的一行开始,而且不容许旁边有 HTML 元素(除非是float) | 与其余内容一块儿流动,并容许旁边有其余元素 | 与其余内容一块儿流动,并容许旁边有其余元素。 |
可否设置width和height | 能 | 能 | 不能 设置会被忽略 |
可使用vertical-align对齐 | 不能够 | 能够 | 能够 |
边距(margin)和填充(padding) | 各个方向都存在 | 各个方向都存在 | 只有水平方向存在。垂直方向会被忽略。 尽管border和padding在content周围,但垂直方向上的空间取决于'line-height' |
浮动(float) | - | - | 就像一个block元素,能够设置垂直边距和填充。 |
水平居中
垂直居中
水平垂直居中
!important > 行内样式 > #id > .class > tag > * > 继承 > 默认
选择器 从右往左 解析
浏览器从最右边的选择器(关键选择器)开始查找,根据关键选择器,浏览器从 DOM 中筛选出元素,而后向上遍历被选元素的父元素,判断是否匹配。
例如,对于形如p span的选择器,浏览器首先找到全部<span>元素,并遍历它的父元素直到根元素以找到<p>元素。对于特定的<span>,只要找到一个<p>,就知道已经匹配并中止继续匹配。
基于以上原理,为了编写高效CSS,应注意如下几点:
优势:
缺点:
区别:
CSS能够拆分红2部分:公共CSS 和 业务CSS:
响应式设计就是网站可以兼容多个终端,而不是为每一个终端作一个特定的版本
基本原理是利用CSS3媒体查询,为不一样尺寸的设备适配不一样样式
对于低版本的IE,可采用JS获取屏幕宽度,而后经过resize方法来实现兼容
$(window).resize(function () {
screenRespond();
});
screenRespond();
function screenRespond(){
var screenWidth = $(window).width();
if(screenWidth <= 1800){
$("body").attr("class", "w1800");
}
if(screenWidth <= 1400){
$("body").attr("class", "w1400");
}
if(screenWidth > 1800){
$("body").attr("class", "");
}
}
复制代码
// 把上、左、右三条边隐藏掉(颜色设为 transparent)
#demo {
width: 0;
height: 0;
border-width: 20px;
border-style: solid;
border-color: transparent transparent red transparent;
}
复制代码
当使用translate()时,元素仍然占据其原始空间(有点像position:relative),这与改变绝对定位不一样。
一本为新一代CSS所写的新一代CSS图书。在我所知的技术专家中,没人比Lea Verou更能领会新一代CSS的精髓。 ——Jeffrey Zeldman, 《网站重构》做者