Hexo


  • Home

  • Archives

Web前端的知识之旅哟——预编译

Posted on 2018-01-02

• 我们在书写js代码的时候,会发现两点和c/c++语言不同的地方。第一个是当我们在后面定义了一个函数之后,我们在定义函数之前使用这个函数也是可以的。第二个是我们在后面声明的一个变量,但是在前面调用这个变量的时候并不会报错而是undefiend。

这两点不同在js中被称为函数声明提升和变量声明提升,函数声明提升是一种整体提升,它会把函数声明和函数体一起提升到前面。变量声明提升则是一种局部提升,它仅仅将变量的声明提前了,但是并没有将赋值也一起提前。

那么为什么会出现这种提升的现象呢?

这是因为js运行的时候有一个阶段叫做预编译阶段,而我们的声明提升现象都是发生在预编译的时候哟~

预编译

• js运行三部曲

1.语法分析

2.预编译

3.解释执行

语法分析:js引擎在解析js代码之前,会先通篇扫描一下,找出低级的语法错误,比如写错大括号之类的。

编译执行:我们前面提到js是一种解释型语言,编译一行执行一行,当语法分析没有问题,并且已经完成预编译阶段之后,就开始解释执行代码。

这里我们着重介绍预编译。

预编译前奏

在介绍预编译之前,我们有两个重要概念需要掌握。

1.imply global 暗示全局变量。

如果任何变量未经声明就赋值使用,此变量就会为全局对象window所有,并且成为window对象的一个属性。


1. window.a = 123;
2. window.a === a // true;
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

或者


1. a = 123;
2. window.a===a  // true
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

2.一切声明的全局变量,都是window的属性。


1. var a = 123;
2. console.log(window.a); // 123
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

• 这样看不论全局变量有没有声明,似乎都会成为全局对象上的属性,那么两者之间有什么区别呢?

区别在于:经过声明的全局变量不能通过delete操作来删除,但是未经声明的全局变量可以被删除。


1. a = 123;
2. console.log(window.a === a)  // true
3. delete window.a;
4. console.log(window.a); // undefiend
5. var b = 123;
6. delete window.b;
7. console.log(window.b); // 123
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

正是这一种特性,导致es5有一种弊端,我们总会在无形中声明一些全局变量。


1. function test () {
2.       var a = b = 0;
3. }
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这段代码的原意是:在函数体中声明两个变量a、b,然后初始化a、b都是0。但是我们这么写之后,a经过了声明,但是b却没有声明,这时候b就会成为一个全局变量。

了解这两点之后,我们正式介绍一下预编译的过程。

预编译的过程我总结为以下四步:

1.创建AO对象。

2.寻找形参和变量声明,将变量和形参作为AO对象的属性名添加到对象中,值为undefined。值得注意的是,函数声明不叫变量。

3.将实参值和形参值相统一。

4.在函数体里面寻找函数声明,将函数名作为属性名,值为这个函数的函数体。

函数在执行的前一刻会产生一个上下文,这个上下文就是Activeaction Object对象,简称AO对象。

AO = {}

这个对象是空的,但是里面有一些我们看不到的却存在的隐式属性,比如this: window属性和arguments: [];属性

这个对象用来存放一些属性和方法,这些属性和方法就按照前面的四步来产生。


1. function test (a, b) {
2.       console.log a 
3.       function a () {}
4.       a = 222;
5.       console.log a
6.       function b () {};
7.       console.log b 
8.       var b = 111;
9.       var a ;
10. }
11. test(1)
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这里我们用这一个样例代码来简单介绍一下预编译的过程。

首先第一步,创建一个AO对象。

var AO = {};

第二步,寻找形参值和变量声明,并且将值赋为undefined。


1. AO = {
2.       a: undefined,
3.       b: undefined
4. }
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

3.将实参值和形参值相统一。这里因为属性名都已经存在了,所以直接赋值就可以了。


1. AO = {
2.       a: 1,
3.       b: undefined
4. }
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

4.寻找函数声明,将函数体赋值给属性。


1. AO = {
2.       a: function () {},
3.       b: function () {}
4. }
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这样在编译执行之前,我们预编译阶段创建的AO对象就是这个样子了,这个时候我们再看看分别打印的值是什么。

第一个console.log a –> function () {}

第二个console.log a –> 222 因为执行了a = 222这一行代码,所以重新赋值了。

第三个console.log b –> function () {}

• var b = function () {}这种不叫做函数声明,这个函数是赋值给b变量的,b变量是声明。


1. function fn(a){
2.       a//function
3.       d//function
4.       var a = 123;
5.       a//123
6.       function a () {}
7.       b//undefined
8.       var b = function () {}
9.       b//function
10.       function d (){}
11. }
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这里的var b = function () {}只是声明了b变量,在第四步寻找函数声明里面并不会把b赋值成function () {},因为后面的函数并不是声明,当代码开始解释执行之后,执行到这一行之后才把b赋值成这个函数。

• 寻找变量声明的时候,不会管里面的代码到底会不会执行,执行是后面的事,这里只负责寻找所有变量。


1. funciton test(b) {
2.       a //undefined 
3.       if(1 > 5){
4.             var a = 123;
5.             function b () {}
6.       }
7.       a//undefined
8.       b//function
9.       var b = 234;
10.       b// 234
11. }
12. test(2);
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

打印第一个a的时候并不会报错而是undefined,当a没有声明的时候才会报错,因此这里a是有声明的,只是没有赋值而已,它根本不看有没有if,if的条件是不是真对寻找变量声明都没有关系。

第二步寻找形参和变量声明时候的AO对象:


1. AO = {
2.       a: undefined,  //这里的a虽然在if里面但是也被声明了
3.       b: undefined
4. }
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

以上就是我总结的预编译的知识点,希望对大家有帮助哟!~

Web前端的知识之旅哟——类型转换

Posted on 2018-01-02

我们在前面的运算符的部分提过了这个类型转换,这篇文章就主要介绍一下什么是类型转换。

 显示类型转换

类型转换,自然是把数据的类型改变了,那么我们怎么才能知道数据的类型是否发生了改变呢?

我们有一个操作符typeof可以检测数据的类型。



1. console.log(typeof(123)); // number
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

typeof能返回的类型一共只有6种:

numner、string、boolean、undefined、object、function

• 数组和null类型的都属于object。其实null并不是一种对象,只是因为历史遗留性的问题,null通常用来作为对象占位符,所以被浏览器归到了object里面了。

• NaN属于number类型。虽然是非数,但是非数也是数字的一种。

• 同时,typeof返回的结果其实是一种字符串,我们可以用typeof来测试。



1. console.log( typeof(typeof(a))); // string
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

1.Number(mix)

这个方法是可以把其他类型的数据转换成数字类型的数据。


1. var demo = Number(‘123’);
2. demo // number123
3. demo = Number(true)
4. demo // 1
5. demo = Number(undefined)
6. demo // NaN
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

2.parseInt(string, radix)

这个方法是将字符串转换成整型类型数字的。其中第二个参数radix基底是可以选择的参数。

当radix为空的时候,这个函数的作用仅仅是将字符串转换成数字。

当参数string里面既包括数字字符串又包括其他字符串的时候,它会将看到其他字符串就停止了,不会继续转换后面的数字型字符串了。


1. parseInt(‘123abc345’) // 123
2. parseInt(‘abc123’) // NaN
3. parseInt(‘123’) // 123
4. parseInt(‘abc’) // NaN
5. parseInt(true) // NaN
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

当radix不为空的时候,这个函数可以用来作为进制转换,第二个参数的作用则是,我们把第一个参数的数字当成几进制的数字来转换成十进制。

• radix参数的范围是2-36。



1. var demo = 10;
2. parseInt(demo, 16) // 16
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

将十六进制的‘10’转换成十进制的16。

3.parseFloat(radix)

这个方法和parseInt方法类似,是将字符串转换成浮点类型的数字,同样是碰到第一个非数字型字符停止,但是由于浮点型数据有小数点,所以它会识别第一个小数点以及后面的数字,但是第二个小数点就无法识别了。


1. parseFloat(‘123.2.3’) // 123.2
2. parseFloat(‘123.2abc’) // 123.2
3. parseFloat(‘123.abc’) // 123
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

4.toString(radix)

这个方法和前面的都一点不同,它是对象上的方法,任何数据类型都可以使用,转换成字符串类型,涉及到包装类的一些知识。

同样radix基底是可选参数,当为空的时候,仅仅代表将数据转化成字符串。



1. var demo = 123;
2. typeof demo.toString(); // string   123
3. typeof true.toString() // string true
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

当写了radix基底的时候,则代表我们要将这个数字转化成几进制的数字型字符串。


1. var demo = 10;
2. demo.toString(16) // A
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

• undefiend和null没有toString方法。

5.String(mix)

和Number类似,把任何类型转换成字符串类型。


1. typeof(String(123)); // string
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

6.Boolean(mix)

和Number类似,把任何类型转换成布尔类型。


1. Boolean(0); // false
2. Boolean(undefined); // false
3. Boolean(null); // false
4. Boolean(‘’); // false
5. Boolean(NaN); // false
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

隐式类型转换

1.isNaN()

这个方法可以检测数据是不是非数类型。


1. isNaN(NaN); // true
2. isNaN(‘abc’); // true
3. isNaN(123); // false
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这中间隐含了一个隐式转换,它会先将你传的参数调用一下Number方法之后,再看看结果是不是NaN,不过这个方法可以检测NaN本身。

2.算术运算符

在前面介绍算术运算符的时候,我们就提到了类型转换。

• ++就是现将数据调用一遍Number之后,再自加一。


1. var demo = ‘abc’;
2. demo ++; //NaN
3. demo = ‘123’;
4. ++demo; //124
5. demo = ‘123’;
6. demo++;  //123
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

放在后面写++,虽然是执行完之后才加一,但是执行之前就会调用Number进行类型转换。

 • 同样一目运算符也可以进行类型转换。

+、-、*、/在执行之前都会先进行类型转换,都转换成数字类型的在进行运算。


1. var num = false;
2. +num; // 0
3. var demo = true;
4. -demo; // -1
5. var demo = ‘abc’;
6. +demo; // NaN
7.  1 ‘2’; // 2
8. true false; // 0
9. false / false; // NaN
10. true / false; //infinity无穷大
11. -true / false; //-infinity
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

• 逻辑运算符也会隐式调用类型转换

&&和||都是先把表达式调用Boolean,换成布尔值再进行判断,看看是true还是false,不过返回的结果还是本身表达式的结果。

!取反操作符返回的结果也是调用Boolean方法之后的结果。



1. !‘abc’; // false
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

• 当然也有不发生类型转换的比较运算符

===严格等于

!==严格不等于


1. ‘123’ === 123; // false;
2. true === ‘true’; // false
3. 1 !== ‘1’; // true
4. 1 !== 1; // false
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

Web前端的知识之旅哟——初识JavaScript

Posted on 2018-01-02

这里是总结的一小点的web历史知识,并不知道有没有用:

• Mosaic是互联网历史上第一个普遍使用和能够显示图片的网页浏览器,1993年问世。

• 后来由于商标权的转让,原本的开发团队又开发了Netscape Navigator网景浏览器,也是现在很多浏览器的前身。

• js作为Netscape Navigator浏览器的一部分首次出现在1996年,它最初的设计目标是改善网页的用户体验,js的作者是Brendan Eich。

• 起初js被命名为LiveScript,后因为和Sun公司合作,Sun公司的Java很出名,因为市场宣传需要,所以改名为JavaScript,后来Sun公司被Oracle公司收购,因此js的版权现在归Oralcle所有。

浏览器的组成

前面提到过,浏览器主要有两部分组成:shell外壳部分和内核部分,其实内核还包括了很多东西。

1.渲染引擎,内核里的渲染引擎主要作用于html和css部分,定义了语法规则、渲染规则以及渲染路径和速度等等。

2.js引擎。

2001年发布了ie6,首次实现对js引擎的优化。

2008年Google发布了Chrome,它是采用优化后的js引擎,引擎代号V8,因能把js代码直接转化成机械码0101来执行,进而以速度快而闻名。

后来Firefox也推出了具有强大功能的js引擎

Firefox 3.5 TraceMonkey(对频繁执行的代码做了路径优化)

Firefox 4.0 JeagerMonkey

3.其他模块。

JavaScript的特点

1.解释性语言——不需要编译代码,可以跨平台。

像php、js、jsp都是解释性语言。

2.单线程——js是单线程的语言,同时只能执行一件事情。

3.ECMA标准——为了统一js的规则,推出了ECMA标准,因此js也称为ECMAScript。

JavaScript执行队列

js中有一个重要的概念就是执行队列。

js只有一个主线程,它是单线程的。

其他模块把任务分解成好多的小模块,这些小模块排成一个队列,队列最前面的进入主线程执行,执行完之后第二个进入主线程执行,这个队列就是js的执行队列。有点像操作系统里面的轮转时间片。

JavaScript三大部分:ECMAScript、DOM、BOM

• ECMAScript是符合ECMA标准的基本javascript。

• DOM是Document Object Model文档对象模型,可以操作页面的代码,可以操作html和css部分。DOM是非常非常重要的部分。

• BOM是Browser Object Model浏览器对象模型,操作浏览器shell的。因为每一个浏览器厂家的不同,导致我们在每一个浏览器操作BOM都不一样,因此这里大概了解一下就可以了。

如何引入JavaScript代码

到这里我们大概了解javascript是什么东西了,那么我们如何在html页面里面引入js代码呢?

1.页面内嵌script标签

我们可以在<head>标签里面或者<body>标签里面写一个<script></script>,这个标签有一个type属性,如果要写的话就写完整的”text/javascript”,要不然就不写,浏览器会默认是这个type值,如果写还写错的话浏览器就会报错。

写完标签之后,我们就可以在这个标签里面写js代码了。

2.引入外部js文件

script标签除了可以在里面直接写代码之外,还可以写一个src属性来引入外部的js文件。

• 有一点值得注意的是,一个script标签只能在里面写代码或者引入外部js文件,不能既引入又在里面写代码。

• 一个script标签就是一个代码块,一个页面可以引入多个代码块。

• 为了符合传统页面的web标准(w3c标准的一项):结构、样式、行为相分离,我们一般采用第二种引入外部js文件的方法。我们的html、css、js最好放在专门的文件里面,然后在html里面引入外部文件。

• 浏览器在加载我们的html文件的时候,当遇到link标签的时候会异步加载,但是到script标签的时候并不会异步加载,而是会完全不加载后面的内容,而是去下载这个js文件,并且执行js文件里面的内容,之后下载并且执行完全部的js内容之后,浏览器才会继续执行html后面的代码。

这样就导致了一个问题,如果js是操作DOM的话,我们页面的DOM还没有出来,js就操作,就会出现错误,而且写在前面如果js文件比较大的话,就会导致页面一直没有内容。

因此,为了避免这种情况的出现,我们一般把script标签写在body标签里面的最后一行。

JavaScript基本语法

• 变量声明

js是一种弱数据类型的语言,任何类型的变量都用关键字var来声明。



1. var arr = [1, 2, 3];
2. var num = 123;
3. var string = “abc”;
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

赋值可以在声明的同时赋值也可以在后面赋值。



1. var num = 123;
2. var num;
3. num = 123;
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这两种方法是一样的效果。

同时,我们有一种单一var模式,当我们要声明多个变量的时候,为了节省代码量,一般只写一个var:



1. var num1 = 123,
2.       num2 = 123,
3.       num3 = 123;
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

变量名要上下对齐,这样结构能加清晰,也能节省很多代码。

• 变量命名规则

1.以英文字母、_、$符号开头。

2.变量名可以包括数字。

3.不可以使用系统自带的关键字、保留字作为变量名。

关键字是被系统定义了语法的单词,像var、window、if、else这一类都算作关键字。(关键字在编辑器里面是可以变色的)

保留字是为以后升级可能会变成关键字做的保留,像java、int、enum、abstract、short、boolean等等都是保留字。

值类型

js中的数据的值主要分为两大类:

1.不可改变的原始值

主要有:Number、String、Boolean、undefined、null

这些数据一般叫做栈数据

undefined是未定义的意思,而null是空的意思,他们俩的区别在于,null有值,不过这个值是空值,而undefined是未定义,完全没有值的意思。null一般用作占位。


1. var demo = null;
2. console.log(demo); // null
3. var a;
4. console.log(a); //undefined
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

我们在浏览器上按F12,打开控制台,就可以看到console.log的结果了。

2.引用值

主要有:数组array、对象object、函数function

这些数据一般叫做堆数据


1. var arr = [1, 2, 3, 4];
2. var object = {
3.       name: ‘demo’,
4.       age: ‘18’
5. }
6. console.log(arr); //1,2,3,4
7. console.log(object); //[Object Object]
8. console.log(object.name); // demo
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

那么这两种数据类型的区别在哪里呢?

我们举一个例子:


1. var num = 123,
2.       num1 = num;
3. num = 234;
4. console.log(num); //234
5. console.log(num1); //123
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

我们发现num的改变对num1完全没有影响。


1. var arr = [1, 2, 3],
2.       arr1 = arr;
3. arr.push(4);
4. arr.push(5);
5. console.log(arr); //1,2,3,4,5
6. console.log(arr1); //1,2,3,4,5
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

我们发现我们根本没有改变arr1的值,只是改变了arr的值,但是arr1也跟着改变了,这就是二者之间的第一个区别。

不过,如果我们是给arr重新赋值一个新的数组的话,那么arr1并不是这个新的数组。

arr = [1, 2, 3, 4, 5];

arr1 –> 1, 2, 3

这是为什么呢?

因为原始值是存放在栈里面的,而引用值是存放在堆里面的,原始值的赋值是把值的内容赋值一份给另一个变量,但是引用值却不是这样。引用值的变量名存在栈里面,但是值却是存在堆里面的,栈里面的变量名只是指向了一个堆空间,这个堆空间存的是我们一开始赋的值,当我们写arr1 = arr的时候,其实是把arr1指向了和arr指向的同一个的堆空间,这样当我们改变arr的内容的时候,其实就是改变了这个堆空间的内容,自然同样指向这个堆空间的arr1的值也随着改变了。

9q83czd7u5i8vxso

• 栈内存一点被赋值了,就不可以改变了,我们即使给num重新赋值为234,也是在栈里面重新开辟了一块空间赋值234,然后把num指向了这个空间,前面那个存放123的空间还存在,只是没有指针指向这里罢了。

第二点区别则是:原始值不可以被改变,引用值可以被改变。


1. var arr = [1, 2, 3, 4];
2. arr.length = 2;
3. console.log(arr); // 1,2
4. var str = “1234”;
5. str.length = 2;
6. console.log(str); // 1234
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这里涉及了一个包装类的概念,我们后面会提到。

JavaScript语句基本规则

1.语句后面要用英文分号结束 “;”

2.js语法错误会引发后面的代码终止,但不会影响其他的js代码块。这里仅限于逻辑错误,低级的语法错误会导致代码全都执行不了。

3.书写要规范,=、+、-、/、%两边都要留有空格。


1. num + 1;
2.  
3. num = num + 2;
4.  
5. num = num / 2;
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

一些公司还会有自己的其他编码规范,比如百度公司就会要求小括号和大括号左右两边留有空格。


1. for () {}
2.  
3. if () {}
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这些都是良好的编码习惯,养成这些习惯有助于我们以后的工作。

JavaScript运算符

• 算术运算符

  1.  + 运算符

• 数学上的相加功能

• 拼接字符串

字符串和任何数据相加都会变成字符串


1. var num = 1 + 2 + ‘3’;
2.  
3. console.log(num); //33
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

算术运算符的优先级是从左到右的。

2. – 运算符

• 数学上的相减功能

3. * 运算符

• 数学上的相乘功能

4. / 运算符

• 数学上的相除功能

  1. % 运算符

• 数学上的取余功能

  1. = 运算符

• 赋值运算符,优先级最低

7. == 运算符

• 比较运算符中的等于,不过两个等号的等于属于不严格等于,严格等于是“===”三个等号。

  1. () 运算符

• 和数学上一样,加括号的部分优先级最高


1. var num = 1 + ‘2’ + (1 + 1);
2.  
3. console.log(num); // 122
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

9. ++ 运算符

• 自加一运算,当写在变量前面的时候是先加1再执行运算,写在变量后面的时候是先运算再加1。


1. var num = 1;
2.  
3. console.log(num++); // 1
4.  
5. console.log(num); //2
6.  
7. console.log(++num); // 3
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

相类似的运算还有 — ,用法和 ++ 一样,不过是减法操作。

  1. += 运算符

让变量加多少


1. var num = num + 10;
2.  
3. var num += 10;
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这两种操作是一样的效果,第二种是第一种的简写形式。

相同的还有 -=、/=、*-、%= 等等


1. var num = 3;
2.  
3. console.log(num %= 4); //3
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

• 比较运算符

比较运算符有 > 、< 、>= 、<= 、!= 、== 不严格等于、===严格等于

这里介绍一下不严格等于和严格等于的区别

当我们比较两个数据的时候,是先转化成同一个类型的数据之后再进行比较的。不严格等于就是说这两个数据进行了转化之后,他们的值相同,则整两个数据相等。而严格等于则是两个数据不进行数据转化也相等。


1. “2” === 2 // false
2.  
3. “2” == 2 //true
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

同时,NaN不等于任何数据,包括它本身,但是undefined就等于它本身。


1. NaN == NaN // false
2.  
3. undefined == undefined // true
4.  
5. var demo = !!“abc”; // true
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这里的demo要进行取反运算,先进行了类型转换为布尔值true,两次取反之后依然是true,这个可以用来作为数据转换成布尔值。

• 逻辑运算符

逻辑运算符主要是 && 和 || —— 与和或



1. var demo = 1 < 2 && 3; // 3
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

&&的作用是只有是true的时候,才会继续往后执行,一旦第一个表达式就错了,后面的第二个表达式根本不执行。如果表达式的返回结果都是true的话,那么这里&&的返回结果是最后一个正确的表达式的结果。样例中的demo是3。

||的作用是只要有一个表达式是true的,那么就结束,后面的就不走了,并且返回的结果是这个正确的表达式的结果,如果都是false的表达式的话,那么返回结果就是false。



1. var demo = 2 < 1 || (1 == 1); // true
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

一般来说,&&有当做短路语句的作用,因为运算符的运算特点,只有第一个条件成立的时候,才会运行第二个表达式,所以我们可以把简单的if语句用&&来表现出来。


1. if(flag) {console.log(‘hello’)};
2.  
3. flag && console.log(‘hello’);
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这两个语句是同样的含义。

一般来说,||有当做赋初值的作用,有时候我们希望函数参数有一个初始值,再不使用ECMA6的语法的情况下,最好的做法就是利用或语句。


1. function demo (example) {
2.  
3.       var example = example || 100;
4.  
5. }
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

当我们调用demo这个函数并且正确传值的时候,函数内部的变量example就是我们传的值,但是如果由于我们疏忽忘记传值的话,那么里面的example就是我们的默认值100。

不过这里也有一种缺点,当我们传的参数是一个布尔值的时候,并且传的是false,那么||语句的特点就会忽略掉我们传递的这个参数值而去赋成默认的初始值了,所以为了解决这个弊端,我们就需要利用es6的一些知识了。

• 默认为false的值

数据中所有的值都可以被转换成true或false,但是true的值实在太多了,因此我们只需要记住false的值,其他的都是true。

默认为false:undefined、null、””、NaN、0、false。

今天总结的知识点就这一些了,希望对大家有帮助哟~

Web前端的知识之旅哟——css背景图片和其他

Posted on 2018-01-02

溢出打点

我们首先来介绍几个属性构成的文字溢出打点的功能。溢出打点就是当文字超过我们所规定的范围之后,后面的全部文字就会变成“…”的形式来出现。

• 单行文字溢出打点

单行文字的溢出打点需要三个属性来配合使用。

<div>

      单行文字溢出测试单行文字溢出测试单行文字溢出测试单行文字溢出测试单行文字溢出测试单行文字溢出测试单行文字溢出测试单行文字溢出测试

</div>


1. div {
2.       width: 300px;
3.       height: 20px;
4.       background-color: red;
5.       color: black;
6. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

本来的效果是这样的:

yichu

我们现在给div增加属性:


1. div {
2.       width: 300px;
3.       height: 20px;
4.       background-color: red;
5.       color: black;
6.       overflow: hidden;
7.       white-space: nowrap;
8.       text-overflow: ellipsis;
9. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

现在的效果就变成了我们想要的溢出打点的样子:

yichu

现在介绍一下这三个属性的意思。

1.overflow:hidden;实现的是让文字溢出容器的部分隐藏起来,方便后面的打点功能。

2.white-space:nowrap;让文字不换行。文字的默认状态是换行的,当到达容器壁之后自动换到下一行,这个属性让文字一直在一行显示,即使到了容器壁也不换行。

3.text-overflow:ellipsis;文字溢出之后,怎么处理。这里的处理方式是以点状显示。

这样三条属性配合起来使用,就可以达成单行文字溢出打点的功能了。

• 多行文字溢出打点

其实现在虽然有属性可以达到多行文字溢出打点的功能,但是兼容性十分不好,除了移动端的网页——因为移动端的浏览器一般版本都比较高——之外,pc端的网页一般都是用其他的方式来实现。像百度就是通过计算文字的宽高,然后在最后手写“…”来实现的多行文字溢出打点效果。

而如果我们想要以属性的方式来完成溢出打点的功能的话,就要用到以下的属性了:


1. white-space: normal;
2. -webkit-line-clamp: 3;
3. text-overflow: ellipsis;
4. display: -webkit-box;
5. -webkit-box-orient: vertical;
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这里的-webkit-前缀的意思是兼容webkit内核的浏览器,现在还有很多浏览器不支持line-clamp这个属性,只有webkit的较高的版本勉强支持。

zhichi

box-orient也是非常勉强的,因此这个功能虽然存在,但是由于兼容性的问题,很少有公司会使用。

• line-clamp属性的意思是让文字显示几行。

display: -webkit-box;是css3.0里面的一个属性,这里暂时不过多介绍,大家了解这一种打点方式即可。

背景图片属性

我们知道<img>标签可以来展示图片,但是如果我们想要在图片上面写字的话,这个标签就不好用了,这个时候就需要用到一个属性叫做background-image背景图片属性。



1. background-image: url();
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

url里面放本地绝对地址或者本地相对地址或者网上的链接都可以,这样我们就可以给一个元素设置背景图片了,然后元素里面正常写文字就可以。

还有一些其他的属性专门用来修饰背景图片的样式的:

• background-size属性

这个属性可以让我们设置背景图片的大小。

它的值有很多种书写方式:

1.cover覆盖

这个属性值可以让浏览器以一张图片尽可能填充满我们的容器,当图片大的时候会截掉多余的部分。

它的填充机制是:先找图片宽或者高的其中的一个,固定这一个宽或者高变成容器的宽或者高之后,让另一边等比例的放大或者缩小,当这个另一边可以填充满容器的时候,就把多余的部分裁掉,然后采用这一种方式,如果这种方式填充不满的话,如果刚才固定的宽,那么这一次就固定高度,让宽度变化。这两种方式里面一定会有一种方式是可以使用的。

2.contain包含

这个属性值是让浏览器尽可能展示出来图片的全部信息。如果还剩余很多空间的话,那么就填充相同的图片。

它的填充机制和cover是一样的,不过它固定一条边之后,是让另外一条边可以全部显示,而不是可以填充满容器。

3.设置x y 像素值



1. background-size:50px 50px;
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这样会让浏览器强行把图片压缩成50*50的比例大小。

4.百分数



1. background-size: 50% 50%;
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这样会让图片占容器宽高的50%——记住,子级元素的百分比相对的数值是父级里面的这个属性的值,比如父级的高度是100px,那么子级的50%就是50px。

• background-repear属性

这个属性可以设置背景图片是否可以重复显示,默认是重复的repeat。也就说默认状态下,容器空余很多的时候,就会有相同的图片来填充容器剩余空间。

而值为no-repeat的时候,不论容器剩余多少空间,都不会进行图片复制填充了

• background-size属性

这个属性可以设置背景图片开始的位置,它的值同样有很多种:

1.像素



1. background-position: 50px 50px;
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这样背景图片就会从容器的x轴50px y轴50px的位置开始显示。

2.百分比



1. background-size:50% 50%;
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

百分比一定要把两个值都写上!

值得注意的是:百分比的基准点是图片的中心点,当时50% 50%的时候,图片刚好会在容器的正中央显示。像素的基准点是图片的左上角的点。

• 有一点比较抽象的定义需要记住:图片是用来展示图片信息的,如果这个图片不是用来展示这个图片的内容而是用来修饰一些东西,比如网站的logo,这起到类似艺术字的作用的图片,的时候,一般是用作背景图片的。

如何让背景图片出不来的时候显示文字

有的时候我们的网页会被用户禁止加载图片和css样式,如果我们没有给背景图片设置任何信息的话,那么用户就会完全不知道这个空白的地方是什么东西,所以我们要让图片加载不出来的时候能够有文字展示出来,告诉用户这里是什么东西。

我们有两种方法可以实现这种效果:

1.利用text-indent属性

我们利用首行缩进,然后配合让white-space:nowrap和overflow:hidden;让元素内部的文字在有css的时候,会被缩进到元素外面并且被隐藏起来。当css不能加载的时候,文字不会被缩进,所以可以展示出来。

这是比较传统的做法。

2.背景图片放到padding里面,高度强制为0



1. padding-top: 100px
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

要知道background-image是可以放到padding里面的,我们利用padding-top撑起来元素的内容区,然后元素本身的高度为0,这样当有css样式的时候,我们配合overflow:hidden一起使用,就可以让文字隐藏,没有css样式的时候,文字就会正常显示出来。

这种方式现在用的更多一些。

Web前端的知识之旅哟——浮动模型与伪元素

Posted on 2018-01-02

浮动模型

在最开始,我们首先写一个二级结构:

<div class=”wrapper”>

<div class=”content”>1</div>

<div class=”content”>2</div>

<div class=”content”>3</div>

</div>


1.  
2. .wrapper {
3.       width:400px;
4.       height: 100px;
5.       border: 1px solid red;
6. }
7. .content {
8.       width: 100px;
9.       height: 100px;
10.        background-color: black;
11.       color: white;
12. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

我们现在在浏览器上能看到的应该是这个样子的:

float

那么我们现在给content加上一个特殊的属性:float,看看现在的页面上呈现的布局是什么样子的?



1.  
2. .content {
3.       width: 100px;
4.       height: 100px;
5.       float: left;
6.       background-color: black;
7.       color: white;
8. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

是不是页面变成了这个样子的?

float2

这就是我们这个float属性的效果哟~

那么我们下面来正式介绍一下float属性吧

float浮动属性

float属性可以让元素像站队列一样浮动起来,它会让本来占满整行的元素只按照内容和设置的大小来在父级里面进行站队排列,当这一行剩余的空间不足以再放下一个元素的时候,元素就会自动换行,到下一行去进行浮动排列。当容器不够大的时候,虽然内容会超出容器的范围,但是超出之后仍然是按照相同的队形来进行站队。

float3

浮动起来的元素会像absolute的元素脱离文档流,但是不会脱离文字流,这是什么意思呢?

我们来举一个例子:

<div class=”top”></div>

<div class=”bottom”>我是文字,我能看到文字流哟~</div>


1. .top {
2.       width: 100px;
3.       height: 100px;
4.       background-color: red;
5.       float:left;
6. }
7. .bottom {
8.       width: 200px;
9.       height: 200px;
10.       background-color: black;
11.       color: white;
12. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

现在我们可以看到,在页面上呈现出来的效果是这个样子的:

float4

• 脱离文档流的意思就是正常的元素看不到它了,这一点很类似absolute属性,不脱离文字流的意思则是display属性是inline或者inline-block的元素还是可以看到它的,文字本身是inline属性的。

接下来,我们讲.bottom这个div的display改成inline-block;之后再看一下效果。


1. .bottom {
2.       width: 200px;
3.       height: 200px;
4.       background-color: black;
5.       color: white;
6.       display: inline-block;
7. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

我们发现下面的黑色的方块并没有移动到下一行,而是紧跟着红色浮动方块进行了排列,但是我们并没有给黑色方块也设置浮动效果啊?

float5

这是因为,float属性会自动将这个元素的display给改成inline-block的,也就是说,不论你给display加上什么值,只要有float属性,那么这个元素就是inline-block属性的,这也就是为什么红色浮动方块没有独占一行的原因了。

• float属性只有两个值:left和right,默认的状态是没有值none。

• float:right的效果就是从右边开始排列,刚好和left是相反的效果。

那么我们来总结一下,float属性到底是干嘛的呢?

1.对元素进行布局。

2.像absolute一样,让元素浮动起来,产生自己独有的浮动流。

浮动流有两个效果:

① 脱离标准的文档流,但不会脱离文字流 ,正常的元素看不到它,但是有文字属性inline或者文字本身可以看到它。

② 在内部会把改元素变换成inline-block属性的元素。

那么我们什么时候使用浮动属性呢?

• 开发中,一般是进行网状布局的时候使用float属性。当我们不知道容器里面会盛放多少个子元素,但是这些子元素又是按照一样的格式进行排列,我们设置浮动来进行流式布局。

taobao

• 浮动属性还可以让我们实现报纸那样文字包围在图片四周的效果:

baozhi

想到一点小常识

• 首先要记住,行级元素里面不能放块级元素。

• a标签里面不能再放a标签了。

• p标签内部不能放div标签,一旦写这种结构了:

<p>

      <div></div>

</p>

浏览器会自动将这种结构给转换成:

<p></p>

<div></div>

当然,p标签里面也不要放ul标签,也不要再放一个p标签哟~

如何清除浮动流呢

我们说了,既然元素浮动起来之后,正常的元素就看不到它了,那么包裹它的父级自然也看不到它了,我们想让父级根据里面浮动的子元素来自适应宽高,如果不清除浮动效果的话,就会变成这个样子:

float6

父级只剩下一条线了!

因此清除浮动是我们必须要做的事情。

那么怎么来清除浮动呢?

1.一个野路子,我们在父级里面的内容区最后加一个p标签。

<div class=”wrapper”>

      <div class=”content”>1</div>

      <div class=”content”>2</div>

      <div class=”content”>3</div>

      <div class=”content”>4</div>

      <p class=”clear”></p>

</div>

我们给这个p标签增加清除浮动的样式:


1. .clear {
2.       clear: both;// clear属性专门用来清除浮动的,虽然有还有left和right值,但是我们只要清除浮动一般都写both值。
3. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

现在我们看一下页面效果,父级的wrapper已经正常包裹住了子元素。

但是实际上,并不是父级清除了浮动流,而是被p撑开了,p.clear标签能看到上面浮动的元素,wrapper能看到不浮动的p标签,因此就把p标签包裹进去了,仅此而已。

我们要知道,html是做结构规划的,这个p标签作为功能标签出现了,这种代码在html里面是不允许出现的,所以我们要尽可能避免这种情况,因此这种方法不适用。

2.添加伪元素 <— 我们使用这种方式

首先我们要介绍一下伪元素。

伪元素是一种不能单独存在的元素,它必须要依附于其他正式的元素标签上使用,单独写是没有任何意义的。伪元素最常用的一共有两个:after和before。


1. span::before{}
2.  
3. span::after{}
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

• 虽然一个冒号浏览器也能识别,但是规范写法是两个冒号哟~

我们现在举一个例子来介绍一下这两个伪元素的用法:

<span>举个例子</span>


1. span {
2.       background-color: yellow;
3. }
4. span::before {
5.       content: ‘现在我们来’;
6.       background-color: red;
7. }
8. span::after {
9.       content:‘,这就是效果’;
10.       background-color: black;
11.       color: white;
12. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

after

当我们不想改变html结构,有想要增添一些东西的时候,伪元素after和before就非常的实用,看到这个例子大家也就明白了它们的用处了。

• 不过要注意的是,写伪元素,即使内容是空的,也要加上content这个属性: content:”;

• 既然是伪元素,那么自然也属于元素了,我们可以改变伪元素的display为block,从而可以改变宽高等块级元素才有的样式。

那么了解了伪元素之后,我们根据第一种方式,为父级元素添加一个after伪元素,让这个伪元素专门实现清除浮动的功能即可:


1. .wrapper::after {
2.       content: ‘’;
3.       clear:both;
4.       display: block; // 能清除浮动的元素,必须是块级元素!!
5. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

我们通常使用的清除浮动的方法,就是这一种。

那么现在问题来了,ie6、ie7并没有伪元素这种东西,怎么办?

• 前面我们介绍了bfc,这里我们介绍ie6ie7独有的一个东西——hasLayout。只要触发了hasLayout就和触发bfc有差不多的作用,能够触发这个东西的属性有很多,其中最无害的属于zoom属性了。


1. .wrapper {
2.       zoom:1//视口同比例放大还是缩小,1就是不变
3. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

当我们写上这个元素的时候,ie6ie7也就可以清除浮动了。

不过我们其他的浏览器并不需要zoom这个属性,这个属性只是为了ie6和ie7准备的,所以这个时候我们需要一点点css hack,我们在zoom前面加一个号, **zoom: 1; 这个符号只有ie6和ie7能够识别,其他的浏览器都不识别,这样就可以让只有ie6和ie7去读这一行属性,其他浏览器直接忽略。顺便一提属性前面加上’_**‘之后,就只有ie6可以识别了。_zoom: 1;

3.触发bfc的方式来清除浮动

有很多的属性都可以触发bfc:

① 给.wrapper添加overflow:hidden; 可以让父级包裹住浮动子元素。

② 给.wrapper添加display: inline-block; 可以让父级彻底包裹住浮动子元素。

③ 给.wrapper添加position:absolute; 可以让父级彻底包裹住浮动子元素。

这三种方式虽然都可以清除浮动,但是都会改变样式,不符合开发规范,因此我们也基本都不使用。

导航栏的小应用

浮动模型最常见的作用就是制作导航栏,代码其实也很简单:

<ul>

      <li><a href=””>毛衣</a></li>

      <li><a href=””>牛仔裤</a></li>

      <li><a href=””>风衣</a></li>

      <li><a href=””>卫衣</a></li>

      <li><a href=””>毛裤</a></li>

</ul>

<style>

</style>

这样我们就大致实现了一个淘宝上面的导航的效果。

• 最后,我们学习了浮动模型之后,也可以用这种方式实现三栏布局哟~

<div class=”left”></div>

<div class=”right”></div>

<div class=”mid”></div>


1. .left {
2.       float: left;
3.       width: 100px;
4.       height: 100px;
5.       background-color: orange;
6. }
7. .right {
8.       float: right;
9.       width: 100px;
10.       height: 100px;
11.       background-color: red;
12. }
13. .mid {
14.       height: 100px;
15.       margin-left: 100px;
16.       margin-right: 100px;
17.       background-color: blue;
18. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

不过依然要记住把mid放在后面写!

这次的知识点就总结到这里哟~

Web前端的知识之旅哟——定位与层模型

Posted on 2018-01-02

层模型


css中元素的层次模型主要是由position这个属性来决定的。


position属性:position的意思是定位,同样这个属性的作用就是给元素施加定位。它一共有四个值,分别是static、absolute、relative、fixed。


static


• static是默认的属性,当我们没有写position属性的时候,元素默认的定位就是static定位。


absolute


• absolute是绝对定位的意思,它会使元素脱离本来的位置再进行定位,它会使元素像立交桥一样出现空间上的分层,当元素脱离原来的位置之后,其他的元素就会看不到这个元素。同时,absolute也可以触发bfc。


• 同时,当我们改变定位之后,这个元素就有四个属性可以使用了,分别是left、right、top、bottom。这四个属性分别可以设置当前元素距离左边、右边、上边和下边的距离为多少,但是四个属性很少一起出现,一般都是两两一对出现,其中left和top是一对,right和bottom是一对。


  1. div {
  2.  
  3.       width: 100px;
  4.  
  5.       height:100px;
  6.  
  7.       position: absolute;
  8.  
  9.       left: 100px;
  10.  
  11.       top: 100px;
  12.  
  13. }
CSS

这个div就会脱离原来的位置,然后距离浏览器上边框和左边框分别100px的距离。


• 最后一点,absolute的参照物是距离它最近的有定位(除了static)的父级,当每一个父级都没有定位的时候,元素会相对于浏览器边框进行定位。


relative


• relative是相对定位的意思,它会让元素保留原来的位置再进行定位,后面的元素可以看到它本来的位置。


• 当position改成relative之后,left、top、right、bottom进行的定位就会变成相对于自身的位置进行移动了。


• relative的参照物是元素自身。


• 当我们仅仅给元素设置position:relative;并没有设置left、right、top、bottom属性的时候,元素的定位是没有发生任何改变的,因为这个特性,一般在开发中,relative都是用作设置参照物的,一个absolute元素要相对于那个元素进行移动,就给那个元素设置relative的定位就可以了。


我们通过例子来看一下absolute和relative的区别。


我们现在有这样一个结构:


<div class=”wrapper”>

      <div class=”box”>

            <div class=”content”></div>

      </div>

</div>


  1. .wrapper {
  2.       width: 200px;
  3.       height: 200px;
  4.       background-color: orange;
  5.       margin-top: 100px;
  6.       margin-left: 100px;
  7. }
  8. .box{
  9.       width:100px;
  10.       height: 100px;
  11.       background-color: black;
  12.       margin-left:100px;
  13. }
  14. .content{
  15.       width: 50px;
  16.       height: 50px;
  17.       background-color: yellow;
  18. }
CSS

这个时候时候我们在浏览器中看到的样式是这个样子的:


absolute


现在我们给content加上定位的样式。


  1. .content{
  2.       position:absolute;
  3.       left: 50px;
  4.       width: 50px;
  5.       height: 50px;
  6.       background-color: yellow;
  7. }
CSS

这个时候浏览器中的样式就会发生改变,content那个黄色的小方块会跑到橘黄色的方块外面:


absolute2


这是因为,当我们给content设置position:absolute;之后,浏览器在渲染的时候,会先向上找到box这个div,看看这个div有没有定位,因为没有,所以继续向上找wrapper,依然没有,再向上找body,还是没有,所以最后就是相对于浏览器边框定位,这个时候content的left属性就是相对于浏览器边框左边有50px的距离的意思。


现在我们把content的定位换成relative,浏览器中的结果变成了这个样子:


abso3


本来content黄色小方块在黑色方块的左上角,然后relative相对与自身的位置进行定位,这个时候的left属性的意思就是相对于本来在黑色左上角的那个位置向右移动了50px的距离,也就是现在这个黄色小方块所在的位置。


因此,总结一下absolute和relative的特点如下:


• absolute:


1.脱离原来位置进行定位


2.相对于最近的有定位的父级进行定位,如果没有那么相对于浏览器边框定位。


• relative:


1.保留原来位置定位


2.相对于最近的有定位的父级进行定位


一般被用来设置参照物


fixed


fixed定位是相对于视口的定位,我们在网页上都见过左右两边不随着滚轮滚动而改变位置的广告栏,这种广告栏就是用fixed定位的。


<div class=”fixed”></div>


  1. .fixed {
  2.       position: fixed;
  3.       right: 0px;
  4.       top: 200px;
  5.       height: 200px;
  6.       width: 50px;
  7.       background-color: red;
  8. }
CSS

这段代码中,div.fixed这个元素就是一直在视口的右边,不随着我们滚动而改变相对于视口的位置。


最后提一点


• 值得注意的是,当我们写这样一段代码的时候:


<div class=”demo”></div>


  1. .demo{
  2.       position: absolute;
  3.       margin-top: 200px;
  4.       height: 200px;
  5.       width: 50px;
  6.       background-color: red;
  7. }
CSS

我们把absolute换成relative之后,会发现整个div会向上移动一小段距离,这是为什么呢?


答案其实就在上一篇的文章里,margin合并问题——body标签本身有8px的margin,而四个方向的margin自然包括了margin-bottom,我们为div.demo设置了margin-top,就会导致margin合并的问题发生,当position是relative的时候,并没有触发bfc,所以中间的距离会取二者的最大值,也就是200px,当position是absolute的时候,因为触发了bfc效果,从而消除掉margin合并的bug,因此中间的距离是200+8=208px。


一点小应用


1.我们学习了定位之后,就可以实现前面文章提到的元素水平垂直居中的效果了哟~


只要我们给一个div加上下面的样式:


  1. div {
  2.       width: 100px;
  3.       height: 100px;
  4.       position: absolute;
  5.       left: 50%;
  6.       top: 50%;
  7.       margin-left: -50px;
  8.       margin-top: -50px;
  9.       background-color: red;
  10. }
CSS

这个div就会在有定位的父级里面是水平垂直居中了哟~


2.我们还可以实现多栏布局了!


首先我们写三个div,分别起类名为left、mid、right,然后分别加上如下的样式:


<div class=”left”></div>

<div class=”right”></div>

<div class=”mid”></div>


  1. * {
  2.       margin: 0px;
  3.       padding: 0px;
  4. }
  5. div {
  6.       height: 100px;
  7. }
  8. .left {
  9.       position: absolute;
  10.       left: 0;
  11.       width: 100px;
  12.       background-color: yellow;
  13. }
  14. .right {
  15.       position: absolute;
  16.       right: 0;
  17.       width: 100px;
  18.       background-color: #ffc;
  19. }
  20. .mid {
  21.       margin-left: 100px;
  22.       margin-right: 100px;
  23.       background-color: #fcc;
  24. }
CSS

我们首先固定左侧和右侧的两个div,然后让中间的div分别给左侧和右侧留出一个固定宽度的margin之后,让自身自适应屏幕的大小即可实现三栏布局效果。


• 要注意的是,div.mid记得写在后面,如果写在最前面的话,因为div是block块级元素会独占一行,这样就会把左侧和右侧的div给挤到下一行了。当然我们给.left和.right都加上top:0px;之后,这个问题也就不用考虑了。


这次的层模型总结就到这里了,希望对大家有帮助哟~


Web前端的知识之旅哟——margin合并与塌陷BUG及解法

Posted on 2018-01-02

其实css也不是极其完善的,其中也存在着或多或少的bug,有些我们可能从来不会遇到,有些我们可能会经常遇到,这次介绍的两个bug是属于cssbug中的很经典的两个bug——margin合并与margin塌陷问题。

margin合并现象

• 我们现在写两个span标签,并且给它们两个分别加上margin-right和margin-left的样式。

<span class=”left”>left</span>

<span class=”right”>right</span>


1. .left {
2.       margin-right: 10px;
3.       background-color: red;
4. }
5. .right {
6.       margin-left: 10px;
7.       background-color: yellow;
8. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

我们会发现,这两个span之间的距离正是我们所想的那样是20px的宽度,但是我们现在再写两个div,然后分别给它们加上margin-bottom和margin-top的样式,我们再来看看效果。

<div class=”top”>top</div>

<div class=”bottom”>bottom</div>


1. .top {
2.       margin-bottom: 10px;
3.       background-color: red;
4. }
5. .bottom {
6.       margin-top: 10px;
7.       background-color: yellow;
8. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这次我们惊奇的发现,这两个div上下之间的距离,并不是我们所想的那样是相加的20px,而是只有10px!

这个现象就是标题所说的margin上下合并现象。

我们尝试改变每一个div的margin-top或者margin-bottom的值,最后发现:二者上下之间的距离是取得两个数值之中的最大值。

如果div.top的margin-bottom是100px,div.bottom的margin-top是50px的话,那么二者之间的距离就是100px。

margin塌陷现象

•  当我们给这样一个结构的两个div分别设置margin-top的时候,这个bug就会出现了。

<div class=”wrapper”>

      <div class=”content”></div>

</div>


1. .wrapper {
2. width: 100px;
3. height: 100px;
4. margin-top: 100px;
5. margin-left: 100px;
6. background-color: yellow;
7. }
8.  
9. .content {
10.       width: 50px;
11.       height: 50px;
12.       margin-top: 50px;
13.       margin-left: 50px;
14.       background-color: red;
15. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

我们写这段代码的原意是想要一个100100大小的父级div,然后里面有一个5050大小的子级div,然后让这个div在父级div的右下角,同时父级div距离浏览器的边框有100px的距离。

margin

当我们运行这段代码的时候,我们会发现,实际的结果是这个样子的:

margin-2

子级div的margin-left生效了但是好像margin-top并没有生效?

其实并不是,margin-top也生效了,但是这里的margin-top的效果并不是我们所想的那样距离父级div的距离是50px,而是子级的div距离浏览器边框的距离是50px,由于本身父级div有一个margin-top的值,所以就导致了我们子级的margin-top的效果并没有显现出来,我们再改变一下子级div的margin-top的值,改成200px,我们又会惊奇的发现,子级div不仅没有距离父级div有了一段距离,反而带动了父级div一起向下移动了!这就是margin塌陷现象。

那么对于这两个问题我们要怎么解决呢?

margin塌陷的解法

解法一共有两种:

1.利用border来触发bfc的效果。

2.利用overflow属性来触发bfc的效果。

• 那么什么是bfc呢?

bfc全称是block format context——块级格式化上下文,我们有一些css语法会触发bfc,从而带来的效果是我们触发bfc的元素的渲染规则和普通元素的渲染规则变得不一样,从而可以解决塌陷问题。

margin塌陷的问题很容易让我们联想到,子级div之所以没有相对父级移动,是因为它看不到父级的边界,只能看到浏览器的边界,这样我们给父级加一个子级能看到的边界,这个问题是不是就解决了?

所以我们在父级div.wrapper里面添加一个属性:border-top: 1px solid red;现在我们再来看一下效果,发现果然content和wrapper解除了绑定,子级div能看到父级的边界了。但是这样就会改变父级div的样式,不符合开发要求,因此这种方法虽然可以解决问题但是是完全无法使用的。

• 什么又是overflow呢?

overflow是一个css属性,它可以设置当内容区超过了当前元素的区域的时候,我们采取怎样的处理方式,这个属性也可以触发bfc。

现在我们可以在父级div.wrapper里面加一条属性:overflow:hidden;这条属性的意思是溢出隐藏。现在我们可以发现,在外观没有改变的同时,子级div和父级div解除了绑定,也可能正常移动了!因此我们一般采用这种方式来解决margin塌陷的问题。

虽然overflow:hidden;的方式可以采用,但是也不是没有缺点的,一旦我们用过js代码改变了子级div的位置,就会有导致子级一部分内容因为溢出被隐藏的风险。

margin合并的解法

了解了margin塌陷的解法之后,我们就很容易可以理解margin合并的解法了。

我们给每一个div分别加上一个父级包裹层,然后给父级包裹层都加上overflow:hidden;

<div class=”wrapper”>

      <div class=”top”>top</div>

</div>

<div class=”wrapper”>

      <div class=”bottom”>bottom</div>

</div>


1. .wrapper{
2.       overflow: hidden;
3. }
4. .top {
5.       margin-bottom: 100px;
6.       background-color: red;
7. }
8. .bottom {
9.       margin-top: 100px;
10.       background-color: red;
11. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这样通过父级div来触发bfc就可以解决margin合并的问题了。

那么今天的东西就这么多,希望对大家有所帮助哟~

Web前端的知识之旅哟——简单的文字样式和盒模型

Posted on 2018-01-02

上一篇文章简单的介绍了一下css的引入方式,这一篇打算介绍一些基础的样式和盒子模型。

• 其实我们css有很多很多的样式,我们不可能一一记住每一个样式的值,其实我们只需要记住一些常用的样式的意思,然后去http://www.css88.com这个网站去查询样式的具体的值就可以了,当然查询一些样式的作用也是可以的~

一些简单的文字样式

• 首先我们介绍一下样式的构成,样式都是由属性名和属性值构成的,名和值之间用:(冒号)分隔,属性和属性之间用;(分号)分隔。

我们首先来写几个样式。


1. p {
2.  
3.      font-size:20px;
4.  
5.      font-weight: bold;
6.  
7.      font-family: arial;
8.  
9.      font-style: italic;
10.  
11.      color: red;
12.  
13. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

那么我们来分别介绍一下这几条样式:

• font-size属性

这条属性是设置文字的大小的,文字大小默认是16px,我们在例子中就是将p标签里面的文字设置成20px大小,值得注意的是,这条属性其实是设置的文字的高度而不是宽度。

这里我们就要介绍一下px了:px是像素的意思,这是一种相对大小,并不是絶対大小,因为每一个像素点的大小都是不同的,我们的屏幕都是由很多个像素点组成的。

• font-weight属性

这条属性是设置的文字的粗细程度的,默认值是normal,当我们设置成bold的时候,这个p标签就和strong标签没什么区别了,这就是为什么很多标签我们都不用,因为通过修改样式就可以达到和其他标签一样的效果。

这条属性常用的值有lighter、normal、bold、bolder,其次我们还可以写100-900的数字,其中lighter大概是100左右,normal大概是400左右,bold应该是700左右。

• font-family属性

这个属性的作用是设置文字的样式,是黑体还是宋体还是什么其他的字体,默认是arial字体,其他还有很多很多的字体,我们可以到css88上面去查找。不过我们写英文字体的时候,属性值是不需要加引号的,写中文的时候则需要加引号。



1. font-family: ‘黑体’;
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

• font-style属性

这个属性的作用是设置文字是否斜体,italic就是斜体的意思,通过设置这个属性我们就可以让p标签达到和em标签一样的效果了。

• color属性

这个属性的作用是设置文字的颜色,并不是font-color。

文字颜色的色值有三种表达方式。

1.英文单词,比如red、black、blue等等。

2.三位十六进制组成光学三原色红绿蓝 每一个的值都是00-ff,00代表空,ff代表满,例如#000000就是黑色的意思。其中,如果每连续的两位都是一样的并且3组数字都是这种情况的时候,我们就可以两两合并只写一个数值就可以了,比如#ffffff —> #fff、 #55ffcc —> #5fc;

3.通过rgb(xx,xx,xx)属性值来设置颜色,其实和第二种是一个意思,只是把十六进制换成了十进制,rgb就是red、green、blue的缩写,其中的三个数值每一项的范围都是0-255,例如红色就是rgb(255, 0, 0)。

对文字的处理大概就这么多,我们再来介绍一下其他的一些简单的样式。

• text-indent属性

这个属性的作用是设置首行文字的缩进,值有两种单位,一种是px,一种是em。

这里就要提一下em和px的区别了。

• px虽然是一个相对长度单位,但是我们可以变相地理解为它是一个差不多固定长度的单位,我们设置100px的时候,基本上每一个宽度被设置成100px的元素都是一样的宽度。

• em则是一个真正的相对长度单位,它相对的是当前元素内的文字的大小,也就是说 1em = 1 * font-size;如果我们设置font-size是20px的话那么1em也就是20px的大小,我们只要将text-indent设置成2em就可以首行缩进2个文字大小了。

• border属性



1. border: 1px solid red;
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

border是边框的意思,这个属性也是设置元素边框的属性。

这其实是一个复合属性,它是由border-width、border-style、border-color三个属性复合而成的。分别设置的边框的边度,边框的样式,边框的颜色,其中边框的样式有很多种,基本常用的只有solid实线、dotted短虚线、dashed长条虚线三种样式。

border-width也是一个复合属性,它可以按照上右下左的顺序来分别设置四个边框的宽度值。

• text-align属性

这个属性是设置文字的位置的属性,它的值也是有三种,分别是center文字左右居中、left文字左对齐、right文字右对齐。

• line-height属性

这个属性是设置一行文字所占的高度的属性,默认状态是和字体大小一样的值。

• 当我们想要让单行文字在容器内部上下居中的时候,我们只需要让height = line-height即可。

• 多行文字居中我们现在还没有专门的属性可以做到这一点,不过我本人一般是在文字部分外面包裹一层div标签,然后让div标签在父级元素水平上下居中来实现的。(并不知道这么做对不对…)

• text-decoration属性

这个属性的意思是文字装饰的意思,可以来设置文字是否有下划线、上划线、中划线,分别对应的属性值是underline、overline、line-through。

• cursor属性

这个属性则是设置我们的鼠标移入到这个元素中的时候,鼠标会变成什么样子。它的值有很多很多,我们同样可以到css88上去查看。不过一般常用的是cursor: pointer;这一条属性,它会让我们鼠标移入这个元素的时候,鼠标变成可以点击的小手的状态。

现在我们就可以来模拟一下a标签的样式了。

<p>www.baidu.com</p>


1. p {
2.  
3.       color: rgb(0, 0, 238);
4.  
5.       text-decoration: underline;
6.  
7.       cursor: pointer;
8.  
9. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这个时候www.baidu.com的样式和我们直接用a标签写一个www.baidu.com的样式基本是一模一样的。

伪类

下面介绍一下伪类。

我们可以通过在标签名后面添加伪类来达到一些效果。

• hover伪类

这个伪类可以让我们设置当鼠标移入元素的时候会改变元素的样式。


1. a:hover {
2.  
3.      font-size: 20px;
4.  
5.      color: #424242;
6.  
7. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

hover: 当鼠标以移入时候的动作和样式。

给a标签设置这样一个伪类之后,我们就可让鼠标移入a标签之后,文字放大改变颜色了。

伪类当然不止hover一个,还有很多其他的伪类,我就不一一介绍了,暂时hover用的最多。

• 值得一提的是,伪类也有权重值的,它的权重值和class一样是10点,也就是说如果伪类的权重值达不到前面的权重值的话,那么样式也是不会修改的哟~

<a href=”www.baidu.com”>www.baidu.com</a>

这个时候如果我们再用上面设置的那个伪类样式的话,鼠标移入只会有文字放大效果而不会有变色效果,因为行间样式的权重值有1000点,而a+hover也只有1+10=11点,所以颜色是不会生效的。

盒子模型

最后我们再来介绍一下盒模型的相关知识。

我们要知道,一个元素是由四部分组成的:margin、border、padding、content,分别是外边距、边框、内边距、内容区的意思,其中content不是由属性构成的,而是由我们写的东西和width、height属性构成的。

• margin:它设置的是这个元素距离外面靠近它的其他元素或者浏览器边框的距离。这是一个复合属性,它其实是由margin-top、margin-right、margin-bottom、margin-left组成的,当然也可以分开设置每一个属性的属性值。这个复合属性的值也有4种写法:

1.4个值。如果写的是四个值,如margin: 10px 20px 30px 50px;这样的话,其分别按照上右下左的顺序来设置四个外边距的大小。

2.3个值。如果写的是三个值,如margin: 10px 20px 30px;这样的话,其分别按照上、左右、下的顺序来设置四个外边距的大小,中间的那个属性值设置的是左右的外边距。

3.2个值。如果写的是两个值,如margin: 10px 20px;这样的话,其分别按照上下、左右的顺序来设置四个外边距的大小。

4.1个值。这个没什么好说的…四个方向都是这个值。

• margin其实不属于一个盒子的模型部分,一个元素的盒子模型只有border、padding、content。

盒模型的计算问题

我们现在一个盒子有10px的margin、5px的border、10px 20px 30px 40px的padding和100px的content,那么这个盒子的宽高分别是多少呢?

答案是:

width = 5 + 40+ 100 + 20+ 5 = 170px;

height = 5 + 10 + 100 + 30 + 5 = 150px;

• 宽度的计算是:5px的border+40px的padding-left+100px的content+20px的padding-right+5px的border=170px;

• 高度的计算是: 5px的border+10px的padding-top+100px的content+30px的padding-bottom+5px的border=150px;

那么怎么查看我们设置的元素的样式呢?

只需要鼠标在页面上右键审查元素或者查看,或者是按住F12(windows系统的)就可以打开,这个时候找到我们所要查看样式的元素就可以了。

• 这个时候我们会发现,body元素竟然有一个默认的8px的margin!同时我们还发现p标签默认的也有一些margin,这对于我们是非常不利的,因为这些样式都是在我们意料之外的样式,可能对我们的布局造成影响,那么我们怎么去掉这些默认样式呢?

• *,通配符选择器的作用就体现出来了。我们在开发中一般将通配符选择器用来初始化样式。因为通配符的优先级最低,只有0点,我们在后面如果想要加样式,随便一个样式设定都会高于通配符选择器,但是如果没有设置的话,浏览器就会默认样式为我们设置的初始化样式。一般初始化的样式有以下几种:


1. * {
2.      margin: 0px;
3.      padding: 0px;
4.      list-style: none;
5.      text-decoration: none;
6.      color: #424242;
7. }
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

那么今天总结的东西就这些哟~希望对大家有所帮助。

Web前端的知识之旅哟——初识css与css选择器

Posted on 2018-01-02

前面总结完了html部分的基础内容之后,我总结了一下一下css部分的内容,希望对大家有所帮助~

初识CSS

• css的全称为cascading style sheet 层叠样式表,它的主要作用是为我们的html标签添加各种各样的样式和修饰效果。

• 这里我总结的css属于css2.0的知识点,css3.0的知识我打算在后面的文章里面总结。

• 其实html+css部分的知识点总共站前端的知识总量的1%-2%,但是却占了20%-30%的重要度,所以我们一定不能轻视html和css。(这是针对最近网上有很多人学习前端忽视html和css说的…)

首先我们要介绍一下,html页面如何引入我们的css样式

css的引入方式一共有4种:

1.行间样式 直接在html 的标签里面写style属性 前面两篇里面的更改标签的样式都是用的这一种方式

2.页面级css 在head标签里面添加一个style标签

<style type=”text/css”></style>

这里的style标签的type要不不写,不然就要写正确,只要书写错误,这个样式就不会生效。

3.外部css文件 <—我们选择这种方式

我们在外面创建一个.css后缀的文件,然后在html里面引入这个外部的css文件即可。

在head标签里面加上一个link标签。

<link rel=”stylesheet” href=””>

• link标签里面的href属性上写我们建立的css文件的地址,最好用相对地址的形式。

我们为什么要选择这种加载方式?

因为link加载不会阻塞html的加载,html和css属于异步加载

4.import方式引入(已经弃用)

在head标签里面写一个style标签,在第一行写上@import url();url里面写上css文件的地址,可以加引号也可以不加引号。

这种引入方式有几种缺点导致它现在被废弃使用:

1.必须写在第一行,若有多个则一起写在最前面。

2.ie6的环境下,只能使用最多31次,这个数字据说是阿里的开发人员一点一点测试出来的。

3.程序读到import的时候,会忽略掉import,等到html里面的所有内容包括图片在内的所有资源全都加载完之后才加载import的css文件,也就是说,import引入的css文件和html的加载是同步进行的。

• 这里有一点不得不说明的是,link标签引入和style标签修改样式二者之间并没有什么优先级,谁写在前面谁就先执行,写在后面的css文件会覆盖掉前面的css文件。有时候会因为网速问题,link写在上面,但是link还没有加载进来,所以先运行了后面的style,这种问题是网速导致的,并不是二者本身拥有优先级的问题。

介绍完了如何引入css文件之后,我们再来介绍一下css选择器的知识

• css选择器的作用是让我们找到我们想要修改样式的元素,然后为其修改样式。

我们的选择方式有很多种:

1.id选择器

我们给元素添加一个id属性,这个id是唯一标识,一个元素只能有一个id,一个id也只能给一个元素。然后我们在css文件中,通过#id {}的方式,就可以选择到我们添加id的那个元素了。

<div id=”demo”></div>



1. #demo {
2.  
3.         background-color: red;
4.  
5.         width: 100px;
6.  
7.         height: 100px
8.  
9. }(这些css样式是写在css文件中的)
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

2.class类选择器

在元素的属性中写一个叫做class的属性,这个属性是为这个元素添加一个类名,每一个元素可以有多个类名,同一个类名也可以赋给很多个元素。然后我们在css文件中,通过.class {} 的方式来选择出添加了类名的元素。

<div class=”demo”></div>



1. .demo {
2.  
3.         background-color: red;
4.  
5.         width: 100px;
6.  
7.         height: 100px
8.  
9. }(这些css样式是写在css文件中的)
CSS; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

3.标签选择器

div{}  只要是div的标签就会被选择出来。

• 这里有一个很重要的编程思想:我们先写css在写html,是我们自己在创造标签,而如果我们现在html再写css的话,是我们在添加样式。比如:我们在em加上font-weight: bold;的样式,这样我们就创造了一个加粗斜体的标签。

4.通配符选择器 {} 所有的标签都会被选择出来加上样式,body标签页包含在内。所以如果{background-color: red}的话,那么整个页面都会变红,因为我们同时给body元素也添加了背景颜色。

• 我们在单独的样式后面加上 !important之后,这个样式就会被赋予最高级的优先级,在没有特殊情况下,后面怎么添加样式都不会覆盖或者修改这个样式。比如:background-color: red !important;没有特殊情况的话后面怎么加样式都是红色的。

5.属性选择器

[id] {} 这样有id属性的标签就都会被选择出来。

我经过测试发现:

优先级 !important > 行间样式 > id > class|属性 > 标签 > * 

但是我们不必背这些东西,我们只需要记住他们每一种选择器的权重值就可以了。

CSS选择器 权重值
!important 无穷大
行间样式 1000
id 100
class、属性、伪类 10
标签、伪元素 1
通配符 0

• 值得一提的是,在数学中无穷大+1依然是无穷大,但是在css选择器的权重值里面,无穷大+1 > 无穷大。

有了权重值  我们就可以了解父子选择器了

6.父子选择器  (派生选择器)

div p {}

给div下面的p加样式 这时候的p的权重值是加和的结果。

• 在实际开发中,我们因为要注意浏览器寻找时候的耗能,一般父子选择器不超过4层。

.wrapper .box .content .name  一般不超过像这样的四层。

7.直接子元素选择器

div>strong

div直接子元素里面的strong,div的子元素里面的不是div的直接子元素的strong就不符合要求。

<div>

<strong></strong>

</div>

√

<div>

<em>

<strong></strong>

</em>

</div>

×

id和class也是可以使用父子选择器的哟~

8.并列选择器

<p class=”select”></p>

<div class=”select”></div>

怎么选择出类名是select的div呢?

我们可以使用div.select {} 来选择出来

这种方式是只有div和.select同时作用在一个标签上的时候才会被选择出来,书写的时候标签名放在前面,其他的放在后面。

9.分组选择器

<p></p>

<strong></strong>

<em></em>

<div></div>

我们要想同时给四种标签都加上color: red的样式,不可能把四个标签都写一遍样式,因此要用分组选择器。

div, p, em, strong {} 这样的写法,我们可以把前面写的所有的标签都选择出来加上样式,中间是用逗号连接的。这个样子四种标签就全都被选择出来并且都加上了统一的样式。

最后有一个很重要的问题,那就是父子选择器的时候浏览器是怎么检索的?

div p strong em span 这样的选择器,浏览器是怎么找的?是从左往右,还是从右往左?

答案是从右往左哟~

这是为什么呢?

• 因为如果是从左往右寻找的话,每找到一个父级标签,都要把它下面的所有标签都遍历一遍,看看有没有我们下一个标签,上面那个选择器中,浏览器会先找到div这个标签,然后把div下面所有的子元素都遍历一遍后,找到strong这个标签,然后再把strong这个标签下面的所有元素遍历一遍,找到em这个标签,以此类推,这样是十分消耗性能并且速度非常慢的。

• 而如果是从右往左的话,那么浏览器只需要先找到span标签,然后从span这个节点向上寻找,只要找到em就可以停止寻找,以此类推,不必遍历所有的节点,而且需要遍历的点非常的少,这样的好处显而易见,速度非常快,而且不耗性能。

最后有一些需要说

• 我们一般不给标签加id,而是通过添加class类名来选择的,因为id代表唯一标示,我们一般用id来做标记,后台的php会提取出来id,然后换成他们的标记,因此可能会导致我们的选择器选择不出来我们想要的标签。

• 我们写类名的时候,一定要注意语义化,要符合语义化标准,要用英文单词去命名,而不是用看不懂的abc之类的类名。

希望以上的知识会对大家有所帮助哟~

Web前端的知识之旅哟——html中的标签

Posted on 2018-01-02

上一篇文章大概介绍了一下html的一些知识,这一篇打算开始正式介绍html里面的一些标签结构了。

• html中的标签数量是很多的,据人统计大概有300个左右,并且每年都会以20-30个的速度增加着,但是这么多的标签我们不必都去记住,因为很多标签都是不常用的或者可以用基础的标签搭配组合,实际上我们需要掌握的大概在30个左右。

• 在前端开发中我们要知道,并不是你用的技术多么先进就显得多么厉害,我们要考虑到代码的可读性以及后期的可维护性,用常见的标签来写才会让其他人都能读懂你的代码。

• 代码中还有一点很重要的就是要勤写注释哟~ 顺便一提在html中的注释形式是<! – – your code – – >

好了前言说完了,我们正式开始介绍一些标签吧!

(这里的标签都是属于html4中的内容,html5会有新的标签和新的内容,我在后面的文章中再介绍。)

几个基础的标签

• p标签

<p></p>是段落标签,在<p></p>中间写的内容会当做一个段落来处理。

p标签的特点是独占一行,并且段落上下都会有一定的间隔距离。

• 标题标签 h1-h6

标题标签的作用是着重显示文字,一般用在标题上,它会将里面的文字加粗放大并且独占一行。其中h4的默认大小是正常的文字大小,不过是加粗的。

<h1></h1><h2></h2><h3></h3><h4></h4><h5></h5><h6></h6>

• strong标签

<strong></strong>标签的作用是将里面的文字加粗处理。

• em标签

<em></em>的作用是将里面的文字变成斜体。

• del标签

<del></del>是删除标签,它会在里面的文字的中间画一条横线,一般在打折的时候使用。

• address 标签

<address></address>是地址标签,它会将里面的内容变成斜体并且独占一行。

这六个是很基础很简单的标签,作用也是显而易见,还有另外一种结构化标签,它们没有特殊的效果,而是用来当做容器来盛放其他的标签,这有点类似于每个家庭中都会单独分出来厨房卧室大厅等区域,然后每个区域中还有各种各样的设备,这里的家庭中的区域就是我们的结构化标签的作用。

结构化标签还有另外一个作用就是用来为里面的子元素设置样式。一般的元素如果某一条属性没有被开发者设置样式的话,它会自动继承父级元素的相应属性的样式。

比如我们现在有三个p标签,我们想让三个p标签里面的文字都变成红色,给三个p标签都写上color:red 是非常麻烦的,最简单的方法是将三个p标签都放到一个结构化标签里面,给这个结构化标签一个color:red的样式,这样里面的三个p标签就都会有这个样式了。

这两点作用是最常见的,因此我们在写一个页面之前,最先考虑的就是结构问题,因此一般先写结构化标签。

下面我们就介绍最常见的两个结构化标签。

• div

<div></div>标签可以说是我们在前端开发中用的最多的标签了。

• span

<span></span>标签里面多数情况下盛放文字或者小icon之类的小物件。

我们现在为div标签设置一下样式,并且在中间加一些文字。

<div style=”width: 100px; height:100px; background-color: red”>这是一个实例的结构化标签,一切正常</div>

我们发现文字会在这个div标签的边界处自动换行,也就是说这个div标签圈定了一个范围,里面的文字或者其他标签都默认在这个范围里面显示。

但是当我们在中间书写的不是中文而是一串英文字符的时候,我们会发现这一串英文字符在div的边界处并没有换行,而是一直显示下去,这是为什么呢?

文字分隔符与编码集

• 这是因为我们的每一个汉字,计算机都会认出来是一个单独的单词,每一个汉字都会默认地和其他汉字分隔开,但是英文字母却不会默认地分隔开,因为计算机不知道多少个英文字母才算是一个单词,因此我们需要手动为其添加分隔符。

而这个分隔符我们也不陌生,就是我们常用的空格,只要我们在这一串字符中间加几个空格,那么被空格隔开的字符就会被当做是一个单词从而与其他的单词分隔开。

那么现在问题来了,空格的作用是当做分隔符来使用,并不是我们所想的那种空白的一个格,那么我们怎么在html中写空白格呢?

• 这里我们就要提到一个名词叫做编码集了。我们在书写html的时候,很多特殊的符号是无法写出来的,这个时候我们只能用编码来让浏览器识别我们所想的符号。编码的格式是&编码; 千万不能忘记后面的分号哟~

• 空格的编码就是&nbsp; 当我们写多个&nbsp;的时候,在页面中我们也就可以看到多个空白格了。

• 其次,用来当做标签的尖括号<>也是无法正常通过符号来显示出来的,我们同样需要用编码集让浏览器识别出来。< 小于号的编码是&lt; less than的意思,同理,> 大于号的编码时&gt; great than的意思。我们只要在html中写这两个编码,那么大于号和小于号就可以正常显示出来了哟~我记得有一个表情是 &gt;_&lt;~

• 同样的,回车也是属于分隔符,在html中回车是没有作用的,我们想要在网页上让文字显示出回车换行的效果的话,编码同样也是没有办法实现的,我们需要一个标签叫做<br>标签,这个标签的作用就是换行。w3c标准中提到:<br> 标签是空标签(意味着它没有结束标签,因此这是错误的:<br></br>)。在 XHTML 中,把结束标签放在开始标签中,也就是 <br />。

一些重要的标签

• ol li 

<ol><li></li></ol>这是一组标签,它们二者都是成对出现的,每一个标签单独出现都是没有意义的事情。

这一组标签叫做有序列表,ol是外面的列表框,li是里面的子项,并且每一个li子项的前面都会带有序号。

ol

• ol有一个属性叫做type属性,这个属性的作用是用来设置每一个子项前面的显示内容的。默认情况下按照数字来排序的,我们可以改成type=”a” ,这样前面序号是按照小写字母来排序的。

ol-typea

同样的,type的属性值还可以设置成A–>按照大写字母来排序;i—>按照i的个数来排序(罗马数字?);I—>大写I的个数来排序,除此之外,设置成其他的属性都是错误的,而错误的情况下ol会按照默认的数字来排序,2和b等都算是错误的值哟~

• ol的第二个属性叫做reversed属性,当我们给ol加上reversed=”reversed”的时候,子项就会变成倒序来排列。这个属性直接写reversed也是可以的,不过我同样认为reversed=”reversed”才是规范的写法。

• ol的第三个属性叫做start属性,这个属性的意思是我们让子项从第几个序号开始显示,当我们写start=”2″的时候,前面的序号就会变成2、3、4 而不是默认的1、2、3,字母也是同样的道理。

但是有一个很重要的问题就是,我们在哪个网页看到文字前面有这些什么数字啊字母啊的序号吗?

所以最后的结果就是,我们基本很少用到ol、li标签哟~

• ul li

<ul><li></li></ul>

这一组标签是无序列表,除了前面的序号都变成了点(• )之外,其他的和有序列表基本一样。

• ul同样有一个type属性,这个属性的值设置的是每一个子项前面显示的符号的形式,默认的值是disc圆点,当值是square的时候,前面显示的就是小方块,值是circle 的时候前面显示的就是空心圆圈。

但是同样的道理,我们也没有在哪个网页上看到文字前面带有这些恶心的圆点方块之类的,因此我们在使用ul、li标签的时候,都会先把ul的默认样式list-style改成none,list-style: none;不过这已经属于css的部分了~

无序列表一般用来当做导航栏之类的,里面的结构样式都一样的部分,像淘宝什么的网页的导航栏就都是用ul、li来写的。

taobao

• a

<a></a>标签是一个非常重要的标签,它有一个必须写的属性叫做href —> hyperText reference 超文本链接,里面写的是地址。

a的英文单词是anchor锚点的意思,因此这个标签的作用主要有两点:

1.定点跳转我们指定的id的元素位置。这个用法需要我们在href中写上id的值  <a href=”#clickme”>点击我跳转</a>这样就会跳转到那个id是clickme的元素的位置

2.超链接。我们自href中写一个本地的或者网上的链接,比如www.baidu.com ,这样我们点击的时候就会跳转到这个网页上去了。

3.协议限定符。在href中我们可以写javascript代码,比如href=”javascript:while(1){alert(‘你中毒了’)}”,当我们写上这行代码的时候,我们点击这个a标签之后浏览器就会一直弹出对话框。

通常在移动端我们都用a标签来调用接口,比如:href=”phoneto:12234512345″ 调用手机的拨号功能来拨打电话,像美团外卖之类的就是用的这个功能。

• a标签默认的是蓝色的字体并且带有下划线,我们在页面初始化的时候通常也习惯与将a标签的颜色和下划线的默认属性都去掉。

   • img

<img></img>标签是image图片的意思,它有一个必备的属性叫做src –->source,这个src属性的值就是我们的图片的地址。一般来说我们给src填写两种值:

1.网上的链接

2.本地的链接

说道本地的链接就不得不提到本地链接的书写形式。本地链接分为两种:相对地址和绝对地址。而绝对地址我们通常是不用的,因为当文件上传到服务器上的时候,凡是用绝对地址写的链接统统都会失效的,因此我们都要选择相对地址。

相对地址中 ../的意思是返回当前文件的上一层目录 ,./的意思是当前文件所在的目录,比如说我们有一张图片和这个html文件在同一个文件夹下面,那么我们就可以写<img src=”./tupian.png”></img>

同时这个图片标签还有两个属性。

1.alt属性。这个属性是为其设置图片占位符,也就是说当图片因为网速或者链接错误等原因加载不出来的时候,就会显示alt里面我们设置的值。

2.title属性。图片提示符。当我们鼠标移入图片的时候,在鼠标旁边会出现一个黄色的小方块来显示这个title属性里面设置的值。

以上就是几个比较重要的标签的介绍了,还有一个不太常见也不太重要但是需要了解的标签,table标签。

• table

<table></table>是一个三级结构标签,它要搭配<tr><td></td></tr>这两个标签一起使用才可以。

table是表格的意思,<table><table>这个标签就是设置外层的表格,然后tr是表格的行,td是表格的数据单元,我们可以理解为列。

<table>

<tr>

<td></td>

<td></td>

</tr>

<tr>

<td></td>

<td></td>

</tr>

</table>

table标签的大概结构是这个样子的,同时td还有几个属性。

1.cellpadding内边距属性,我们可以为每一个单元格都设置内边距 cellpadding=”10px”;

2.cellspacing 属性,这个属性的作用规定单元之间的空间,当我们设置为0的时候就可以去掉边线了。

3.colspan属性,这个属性规定了这一个td占了几个单位,默认的一个td占一个单位,类似于excel中的合并单元格的作用。

我们现在一般都不用table标签了,这是一个结构化标签,以前用这个标签来给页面进行布局,但是现在我们直接用div + css来对页面进行布局。

那么为什么我们要弃用table标签呢?

说道这里我们就不得不提一下异步和同步的概念。

在生活中,我们常说的异步是指顺序的干两件事情,比如先吃饭,再玩游戏;同步的意思是同时干,一边吃饭一边打游戏。

但是在计算机领域中,异步指的是生活中的同步,同时加载的意思,同步则是生活中的顺序加载的意思。

这个概念一定要搞清楚。

table的缺点在于服务器把代码加载到本地服务器的过程中,本来是加载一行执行一行,但是table标签是里面的东西全都下载完之后才会显示出来,那么如果图片很多的话就会导致网页一直加载不出来,除非所有的图片和内容都加载完。以前的手机网速慢,厂家重视内容的展现而不是样式的展现,所以那个时候用table,而现在网速很快,大家都重视用户体验,当我们浏览淘宝店铺的时候,如果要等到所有的图片全都加载完之后才显示出来的话那也太蠢了,所以table标签现在我们基本放弃使用了。

但是基本不使用不代表不使用,有些情况下还是可以用table标签的哟~

最后我们再来介绍一个非常重要的标签——表单

<form></form>表单元素,这个元素可以让我们实现前端和后台的数据交互。

我们通过form表单向后台发送数据,数据都是由两部分组成的:数据名+数据内容。

表单都是成组出现的,里面有各种各样的元素。

我们先介绍一下form表单元素拥有的属性:

1.action属性 填写服务器地址,这个属性的意思是我们把数据传递到那个服务器。

2.method属性 传输方法,我们在这里填写通过什么方式来传输数据,一般填写的都是POST/GET这两种中的一个,虽然有其他的方式但是用的韩少,而post和get的区别我们在网络篇会有介绍,这里我们暂时都先写get方法吧。

介绍完属性之后,我们再介绍一下表单拥有的子元素:

   • input标签 这个标签是一个单标签,不需要闭合。

这个标签有一个type属性,而这个属性的值决定了这个input标签的类型是什么。

1.text  如果type=”text”的话,这个input标签就是一个输入框,我们可以在里面输入文字信息。

2.password 如果type=”password “的话,这个input标签就是一个密码框,我们在里面输入的文字信息都会以隐藏的形式展现出来。

3.submit 如果type=”submit “的话,这个input标签就是一个提交按钮,我们点击这个提交按钮之后就会把整个表单的数据发送到后台服务器上了。

我们刚才提到了发送数据一定要有数据名和数据内容,数据内容就是我们给input标签设置的value属性的值,而数据名我们就需要在input标签里面写一个name属性来告诉浏览器我们这个数据的名字是什么了。

这里我们写一个简单的用户提交的表单:

form

在浏览器上的显示内容是这个样子的:

form-dis

当我们随便写一个用户名和密码之后点击提交按钮,我们会发现我们的网页地址上后面出现了我们所传递的数据的信息。

?username=123&password=123 这里我们很容易就可以看出来数据的名字和数据的内容了。

同时,input还有其他的数据形式:

   • type=”radio”

   • type=”checkbox”

radio是单选框的意思,当我们给一个input设置radio的type之后,它就会变成一个圆点,我们可以选择这个圆点,但是我们写很多的单选框的时候,他们似乎都可以被选中,并没有单选的作用。这里是因为我们还没有为这一组单选框设置名字,当我们给几个radio都设置了同一个name的时候,它们就会变得只能选择一个了的单选框了。

form-radio-2

 

checkbox是复选框的意思,当input的type值设置成这个之后,和radio一样的道理,设置好数据的名字,我们可以同时选择很多的选项。

form-checkbox

   • 当我们开发的时候,我们其实是需要为每一项属性都设置一个默认的值的,像sex这种单选框,我们设置一个默认值之后,就会有一半的用户不需要去更改这个选项,会极大地提高用户体验。

   • 设置这个默认的值的方法就是添加一个checked=”checked”属性,我们在哪一个input标签里面设置了这个属性,那么哪一个选项就是默认被选择的状态

最后我们还有一个下拉列表的标签<select></select>

<select>

<option>山东</option>

<option>黑龙江</option>

<option>北京</option>

</select>

下拉列表的name属性是写在<select>标签上的,里面option中间填写的内容就是默认的数据值,但是如果我们给每一个option都加一个value属性的话,那么option中间添加的文字则不作为传递的数据的值,value的值作为传递的数据的值,同时下拉列表的默认选中的是第一个选项,如果我们要改变默认选项的话,要添加的属性是selected=”selected”而不是上面的checked。

那么我所总结的比较常用的重要的标签主要就有以上几种了,希望对大家有帮助哟~

标签的分类

html的标签主要分为两类:

1.行级/内联/行内元素 display: inline;

这一类元素的特点是:

   • 不沾满整行,元素所占空间完全由内容所控制

   • 不可以改变宽高

标签代表有:a em br select span strong

2.块级元素 display: block;

这一类元素的特点是:

   • 占满整行,无论内容多还是少

   • 可以改变宽高

标签代表有:address div form h1-h6 p ul ol li table

其实还有第三种标签,这一类标签既不属于行级元素也不属于块级元素,它们既不独占一行,又可以随意改变宽高,比如<img><input >标签。

1234

John Doe

31 posts
© 2018 John Doe
Powered by Hexo
|
Theme — NexT.Muse v5.1.3