Giter Club home page Giter Club logo

blog's Introduction

Hi there 👋

blog's People

Contributors

yym-yumeng123 avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

lhchrispaul3

blog's Issues

Linux每天一个命令行

你会用Linux命令行吗?


命令行对我们来说一直是一个很高深的东西,今天让我们进入gitbash一个个的来实验我们的Linux命令,来体验如何新建文件,文件夹,删除,移动等操作

基本命令

  • 查看当前完整路径
命令:pwd(Print Working Directory)
  • 查看当前目录下文件
# 不包括隐藏文件
$ ls    (list)

# 查看当前目录下所有文件(包括隐藏文件)
$ ls -a

# 查看当前目录下所有文件(包括隐藏文件)的详细信息
$ ls -al
  • 切换目录
$ cd /c/project
$ cd code
$ cd ../css
$ cd ~/Desktop    ~(表示家目录:家目录代表当前用户)
$ cd ..    回到上一层级
  • 创建文件
touch readme.md (touch 新建)
  • 删除文件
# 删除readme.md
rm readme.md 

# 删除node_modules文件夹,不提示
rm -rf node_modules
  • 重命名文件
mv readme.md README.md(作用是移动,类似图形剪切)
  • 创建文件夹
mkdir projects(创建一个叫project的文件夹)

这些是很基本的命令行,当然还有很多其他的命令,我们再来看一下文件路径


文件路径

  • 根目录
cd /    (代表最顶级的目录)
  • 家目录
cd ~    (我们知道任何系统都是多用户的,家目录就是当前所登陆的用户,所在的文件夹)
pwd
  • 当前目录
cd books
cd ./books  (.代表当前目录下的books文件)
  • 上级目录
cd ..    (..代表上级目录)
cd ../css

我们学了一点点的命令行,但是我们只能新建文件,却不能自己在命令行中编辑,感觉很受挫对不对,那我们怎么在Linux命令行中编辑我们的文件呢?我们就来学习一下 vim

比方说我们用命令行新建一个文件touch index.html,如何进入编辑模式呢?
$ vim index.html

但是我们会发现我们不能编辑,我们应该输入i或者a进入编辑模式,我们就可以在vim里输入任何想要输入的东西了,那我们怎么退出呢?先按esc退出输入模式,再次输入:wq或者:q!就进入命令行模式了,就这么简单,多练习就会了

  • 总结编辑器vim
1. vim a.md 初始进入编辑器命令模式
2. i或者a 进入编辑模式
3. 键盘左上角esc 进入命令命令模式
4. :wq 保存退出
5. :q! 不保存强制退出

前面是一些基本的操作,在后面我会每天学习一个Linux命令行,不断地更新在这里

  • 每天一个Linux命令: pwd命令
    Linux中用 pwd 命令来查看”当前工作目录“的完整路径。 简单得说,每当你在终端进行操作时,你都会有一个当前工作目录。 在不太确定当前位置时,就会使用pwd来判定当前目录在文件系统内的确切位置。
1.命令格式:
	pwd [选项]

2.命令功能:
	查看”当前工作目录“的完整路径

3.常用参数:
        一般情况下不带任何参数
        如果目录是链接时:
        格式:pwd -P  显示出实际路径,而非使用连接(link)路径。 
参考:

博客

Position定位全干货

定位

  • Position-设置定位方式
  • top,right,bottom,left,z-index --设置位置

top right bottom left

image

元素边缘距参照物的边缘的距离

Demo:

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>位置</title>
	<style>
		.sample{background-color: pink;}
		.sample{position: absolute;}

		/*.sample{top: 30px;left: 30px;}*/ 注释掉以后会距上边30px 距左边30px
		/*.sample{bottom: 30px;right: 30px;}*/注释掉以后div会被撑开
	</style>
</head>
<body>
	<div class="sample">sample</div>
</body>
</html>

z-index

image

z轴上的排序:默认为z-index:0; 正值越大,在z轴上越在上面,在下面的会被覆盖.

z-index:-value;值可为负值,在z-index:0;

是不是值越大约在上面呢?不一定

z-index栈

image

上图有两个定位元素,如果给z-index:1;元素这个定位,父元素设为z-index:9; z-index:100;的元素的祖先元素设为z-index:1; z-index红色元素盖在了绿色元素上

Demo:

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>z-index</title>
	<style>
		.sample0, .sample1{position: absolute;width: 200px;line-height: 150px;text-align: center;}
		.sample0{background-color: #ff0;}
		.sample1{background-color: pink;}

		.sample1{top: 100px;left: 100px;}正常情况下的排列是按照元素在文档流中的位置排的
			
		/*.sample0{z-index: 9;}*/    会在上面

		/*.container0, .container1{position: relative;}*/
		/*.container1{z-index: 99;}*/    
	</style>
</head>
<body>
	<div class="container0"><div class="sample0">sample 0</div></div>
	<div class="container1"><div class="sample1">sample 1</div></div>
</body>
</html>

position

  • position: static | relative | absolute | fixed

position:relative

  • 仍在文档流中
  • 参照物为元素本身
  • 可以改变z轴上的层级
  • 使用场景:绝对定位元素的参照物

image

Demo:

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>相对定位</title>
	<style>
		.container{width: 400px;line-height: 2;border: 1px dashed #aaa;}
		.sample{background-color: pink;}

		.sample{position: relative;}
		.sample{top: 10px;left: 30px;}
	</style>
</head>
<body>
	<div class="container">
		<div>相对定位元素的前序元素</div>
		<div class="sample">sample</div>
		<div>相对定位元素的后序元素</div>
	</div>
</body>
</html>

position:absolute

  • 默认宽度为内容宽度
  • 脱离文档流(浮起来了)
  • 参照物为第一个定位祖先/根元素
  • 使用场景:轮播头图
Demo:

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>绝对定位</title>
	<style>
		.container{width: 300px;margin: 50px;line-height: 2;border: 1px dashed #aaa;}
		.sample{background-color: pink;}

		/*.sample{position: absolute;}*/
		/*.sample{bottom: 10px;left: -30px;}*/
		/*.container{position: relative;}*/
	</style>
</head>
<body>
	<div class="container">
		<div>绝对定位元素的前序元素</div>
		<div class="sample">sample</div>
		<div>绝对定位元素的后序元素</div>
	</div>
</body>
</html>

position:fixed(固定定位)

  • 默认宽度为内容宽度
  • 脱离文档流
  • 参照物为视窗
  • 使用场景:固定顶栏 遮罩
Demo:

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>fixed定位</title>
	<style>
		.container{width: 400px;margin: 200px;line-height: 2;border: 1px dashed #aaa;}
		.sample{background-color: pink;}
		
		/*.sample{position: fixed;}*/    脱离文档流
		/*.sample{bottom: 0;left: 10px;}*/   相对于视窗定位
		/*.container{height: 1000px;}	*/
	</style>
</head>
<body>
	<div class="container">
		<div>绝对定位元素的前序元素</div>
		<div class="sample">sample</div>
		<div>绝对定位元素的后序元素</div>
	</div>
</body>
</html>
遮罩

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>遮罩</title>
	<style>
		.mask{
			position: fixed;
			top: 0;
			left: 0;
			z-index: 999;
			width: 100%;
			height: 100%;
			background-color: #000;
			opacity: 0.3;
		}
		.content{
			height: 3000px;
		}
	</style>
</head>
<body>
	<div class="mask"></div>
	<div class="content">content area</div>
</body>
</html>
固定顶栏

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>固定顶栏</title>
	<style>
		body{margin: 0;line-height: 1.8;}
		.top{background-color: pink;color: #fff;}
		.main{height: 3000px;background-color: #eee;}


		body{padding-top: 50px;}
		.top{position: fixed;top: 0;width: 100%;height: 50px;}
	</style>
</head>
<body>
	<div class="top">top bar</div>
	<div class="main">main content area</div>
</body>
</html>

使用定位怎么做布局?看个DEMO

三行自适应布局

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>三行自适应布局</title>
	<style>
		.head{
			position: absolute;
			top: 0;
			left: 0;
			width: 100%;
			height: 100px;
			background-color: #ccc;
		}
		.body{
			position: absolute;
			top: 100px;
			left: 0;
			bottom: 100px;
			right: 0;
			overflow: auto;
		}
		.content{
			height: 2000px;
		}
		.foot{
			position: absolute;
			bottom: 0;
			left: 0;
			width: 100%;
			height: 100px;
			background-color: #ccc;
		}
	</style>
</head>
<body>
	<div class="head">head</div>
	<div class="body">
	  <div class="content">content area</div>
	</div>
	<div class="foot">foot</div>
</body>
</html>

flex布局

最近这两天一直在学习关于移动端页面,而移动端页面一般很多用flex(弹性)布局,方便简洁,而且没有什么兼容性的问题,我们来看一下关于flex

说起兼容性,我们先用can I Use 看看flex兼容性如何

  • 弹性盒子,是一种布局方式,当页面需要适应不同的屏幕大小以及设备类型时,它依然能确保元素拥有更恰当的排布行为,弹性盒属于CSS 3部分,IE9 以下不支持,现代浏览器指的就是IE9及以上的浏览器

大部分浏览器都是支持的

那什么是flex弹性布局呢?

  • MDN flex给出了这样的定义:弹性布局是指通过调整其内元素的宽高,从而在任何显示设备上实现对可用显示空间最佳填充的能力。弹性容器扩展其内元素来填充可用空间,或将其收缩来避免溢出。
  • 块级布局更侧重于垂直方向、行内布局更侧重于水平方向,与此相对的,弹性盒子布局算法是方向无关的

在学习flex弹性布局之前,我们先看几个名词flex Terms

关于flex

  • flex container弹性容器: 包含着弹性项目的父元素。
  • flex item弹性元素: 弹性容器的每个子元素都称为弹性元素。
  • main axis主轴:弹性项目沿其依次排列的那根轴称为主轴(main axis)
  • cross axis辅轴:垂直于主轴的那根轴称为侧轴(cross axis)。

我们知道了flex弹性布局,如何在css中创建弹性容器

  • 创建flex container
    • display:flex :我们之前创建块级元素,行内元素,块级行内元素,都是用display来创建的,那我们的弹性布局就可以用display:flex

弹性元素flex itemflex弹性容器中的元素都是弹性元素

  • 弹性容器在文档流中的子元素
<div style="display: flex">
	<div>block</div>    // 块级元素在文档流中,弹性元素
	<div style="float: left;">float</div>    // 浮动元素在文档流,弹性元素
	<span>inline</span>        // 行内元素在文档流,弹性元素
	<div style="position: absolute;">position</div>    // 定位元素脱离文档流,不是弹性元素
	<div>
		<div>grandson</div>    // 父级不是弹性容器,不是弹性元素
	</div>
</div>

我们看一下flex布局的特点:

  • 方向
  • 弹性
  • 对齐

方向相关属性

  • flex-direction:row | row-reverse | column | column-reverse
    • flex-direction 属性指定了内部元素是如何在 flex 容器中布局的,定义了主轴的方向(正方向或反方向)
    • row 默认值

不同属性值下面,元素在页面下的展示

/* css */
.container{display: flex;}
.container1{flex-direction: row-reverse;}
.container2{flex-direction: column}
.container3{flex-direction: column-reverse}
/* html */
<div class="container container0">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

默认值:row
flex-direction: row-reverse;
flex-direction: column
flex-direction: column-reverse

  • flex-wrap:nowrap | wrap | wrap-reverse
    • flex-wrap 指定 flex 元素单行显示还是多行显示 。如果允许换行,这个属性允许你控制行的堆叠方向。
    • nowrap : 默认值
/* css */
.container{display: flex;}
.container1{flex-wrap: wrap;}
.container2{flex-wrap: wrap-reverse;}

/* html */
<div class="container container0">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
</div>

flex-wrap: nowrap;默认值
flex-wrap: wrap;
flex-wrap: wrap-reverse;

  • flex-flow: <'flex-direction'> || <'flex-wrap'>

    • flex-flow 属性是 flex-directionflex-wrap 的简写。
    • flex-flow: column-reverse wrap;
  • order : <integer>

    • order 属性规定了弹性容器中的可伸缩项目在布局时的顺序。元素按照 order 属性的值的增序进行布局。拥有相同 order 属性值的元素按照它们在源代码中出现的顺序进行布局。
    • 初始值为0
/* css */
.container{display: flex;}
.item2{order: 1;}
.item1{order: 10;}
.item3{order: -1;}

/* html */
<div class="container">
  <div class="item item1">order:1</div>
  <div class="item item2">order:2</div>
  <div class="item item3">order:3</div>
</div>

order

弹性相关属性

  • flex-basis: content | width
    • 设置flex item的初始宽高
    • 初始值为auto设置或检索弹性盒伸缩基准值,如果所有子元素的基准值之和大于剩余空间,则会根据每项设置的基准值,按比率伸缩剩余空间
    • width 值可以是一个数字后面跟着绝对单位例如 px, mm, pt; 该值也可以是一个百分数
    • content : 基于 flex 的元素自动调整大小。
/* Specify <'width'> */
flex-basis: 10em;
flex-basis: 3px;
flex-basis: auto;

/* Intrinsic sizing keywords */
flex-basis: fill;
flex-basis: max-content;
flex-basis: min-content;
flex-basis: fit-content;

/* Automatically size based on the flex item’s content */
flex-basis: content;

/* Global values */
flex-basis: inherit;
flex-basis: initial;
flex-basis: unset;
  • flex-grow:<number>
    • flex-grow 属性定义弹性盒子项(flex item)的拉伸因子。
    • 默认值为0,不能取负值
    • 如果没有显示定义该属性,是不会拥有分配剩余空间权利的
弹性布局元素宽度 = flex-basis + flex-grow / sum(flex-grow)*remain
                   基本宽度             占的比例          剩余空间
/* css */
.container{display: flex;}
.item{width: 100px;}
.item2{flex-basis: 300px;}
.item2{flex-grow: 1;}
.item3{flex-grow: 2;}
.item2, .item3{flex-basis: 0;}

/* html */
<div class="container">
  <div class="item item1">1</div>
  <div class="item item2">2</div>
  <div class="item item3">3</div>
</div>

flex-grow

  • flex-shrink:<number>
    • 指定了flex元素的收缩规则。flex 元素仅在默认宽度之和大于容器的时候才会发生收缩,其收缩的大小是依据 flex-shrink 的值。
    • 默认值为1,会平分压缩多出的空间,不允许负值
正常布局空间超出分配超出的负值空间
flex-basis + flex-shrink / sum(flex-shrink)*remain(负值)
/* css */
.container{display: flex;}
.item{flex-shrink: 0;}  //剩余空间没有弹性
.item2{flex-shrink: 2;}  //分到1/2剩余空间

/* html */
<div class="container">
  <div class="item item1">sets the flex shrink factor</div>
  <div class="item item2">sets the flex shrink factor</div>
  <div class="item item3">sets the flex shrink factor</div>
</div>

flex-shrink:1默认值为1平分

  • flex:none | <'flex-grow'> || <'flex-shrink'> || <'flex-basis'>
    • 初始值:0 1 auto,单个初始值
    • 简写
/* Basic values */
flex: auto;  // 相当于将属性设置为 flex: 1 1 auto
flex: initial;  // 相当于将属性设置为 flex: 0 1 auto
flex: none;  // 相当于将属性设置为 flex: 0 0 auto
flex: 2;

/* One value, unitless number: flex-grow */
flex: 2;

/* One value, width/height: flex-basis */
flex: 10em;
flex: 30px;

/* Two values: flex-grow | flex-basis */
flex: 1 30px;

/* Two values: flex-grow | flex-shrink */
flex: 2 2;

/* Three values: flex-grow | flex-shrink | flex-basis */
flex: 2 2 10%;

/* Global values */
flex: inherit;
flex: initial;
flex: unset;

语法可参考:flex属性

对齐相关属性

  • justify-content: flex-start | flex-end | end | space-between | space-around
    • 设置主轴(main-axis)上的对齐方式
    • flex-start默认值
描述
flex-start 从行首开始排列,每行第一个弹性元素与行首对齐,同时所有后续的弹性元素与前一个对齐
flex-end 从行尾开始排列,每行最后一个弹性元素与行尾对齐,其他元素将与后一个对齐
center 伸缩元素向每行中点排列,每行第一个元素到行首的距离将与每行最后一个元素到行尾的距离相同
space-between 在每行上均匀分配弹性元素,相邻元素间距离相同,即空白在子项之间每行第一个元素与行首对齐,每行最后一个元素与行尾对齐
space-around 在每行上均匀分配弹性元素,相邻元素间距离相同,即空白围绕着子项每行第一个元素到行首的距离和每行最后一个元素到行尾的距离将会是相邻元素之间距离的一半
/* css */
.container{display: flex;}
.fs{justify-content: flex-start;}
.fe{justify-content: flex-end;}
.c{justify-content: center;}
.sb{justify-content: space-between;}
.sa{justify-content: space-around;}

/* html */ 更换类名看到不同的效果
<div class="container fs">
  <div class="item item1">1</div>
  <div class="item item2">2</div>
  <div class="item item3">3</div>
</div>

justify-content

  • align-items:flex-start | flex-end | end | baseline | stretch
    • justify-content相同的方式在侧轴方向上将当前行上的弹性元素对齐。
描述
flex-start 元素紧靠 cross 轴起始边界
flex-end 元素紧靠 cross 轴结束边界
center 元素在 cross 轴居中,如果元素在 cross 轴上的高度高于其容器,那么在两个方向上溢出距离相同
baseline 所有元素向基线对齐, cross 轴起点到元素基线距离最大的元素将会于 cross 轴起点对齐以确定基线
stretch 弹性元素被在 cross 轴方向被拉伸到与容器相同的高度或宽度
/* css */ 设置在父容器上
.container{display: flex;}
.item1{line-height: 100px;}
.item2{line-height: 70px;}
.fs{align-items: flex-start;}
.fe{align-items: flex-end;}
.c{align-items: center;}
.s{align-items: stretch;}  //拉伸充满父容器
.b{align-items: baseline;}

/* html */ 更换类名看到不同的效果
<div class="container fs">
  <div class="item item1">1</div>
  <div class="item item2">2</div>
  <div class="item item3">3</div>
</div>

align-items

align-items

  • align-self:auto | flex-start | flex-end | center | baseline | stretch
    • 设置单个flex-itemcross-axis上的对齐方式
    • 对齐当前 flex 行中的 flex 元素,并覆盖 align-items
       的值. 如果任何flex元素的侧轴方向 margin 值设置为 auto,则会忽略 align-self
描述
auto 默认值,元素继承了它的父容器的 align-items 属性,如果没有父容器,则值为 "stretch"
flex-start 元素位于该行的 cross 轴的起始边界
flex-end 元素位于该行的 cross 轴的结束边界
center flex 元素会对齐到 cross-axis 的中间,如果该元素的 cross-size 的尺寸大于 flex 容器,将在两个方向均等溢出
baseline 如果弹性盒元素的行内轴与 cross 轴为同一条,则该值与 "flex-start" 等效,其它情况下,该值将参与基线对齐
stretch 元素被拉伸到与容器相同的高度或宽度

设置在子弹性元素上的对齐方式

  • align-content:flex-start | flex-end | center | space-between | space-around | stretch
    • 浏览器如何在容器的侧轴围绕弹性盒子项目分配空间。
    • 初始值stretch
/* css */ 设置在父容器上
.container{display: flex;}
.container{height: 800px;flex-flow: row wrap;align-items: flex-start;}

.container{align-content: flex-start;}
.container{align-content: flex-end;}
.container{align-content: center;}
.container{align-content: space-between;}
.container{align-content: space-around;}
.container{align-content: stretch;}

/* html */ 
<div class="container">
  <div class="item item1">1</div>
  <div class="item item2">2</div>
  <div class="item item3">3</div>
  <div class="item item4">4</div>
  <div class="item item5">5</div>
  <div class="item item6">6</div>
  <div class="item item7">7</div>
  <div class="item item8">8</div>
  <div class="item item9">9</div>
  <div class="item item10">10</div>
</div>

align-content


参考MDN flex

如何用刚学的flex布局做一个三行两列自适应布局呢?

html, body{height: 100%;}
body{display: flex;flex-flow: column;}
.head, .foot{height: 100px;}
.body{flex: 1;display: flex;}
.side{width: 200px;}
.main{flex: 1;}
.main{margin-left: 10px;}
.body{width: 960px;align-self: center;}	
<div class="head">head</div>
<div class="body">
	<div class="side">side</div>
	<div class="main">main</div>
</div>
<div class="foot">foot</div>

自适应布局

参考了MDN,如有不对,请帮忙指出

数组

创建数组

  • 用逗号隔开
var array = new Array()
var array =[1,2,3,true,'yym']

arr.length

  • 数组长度
var students = [
  {id:1,score:80},
  {id:2,score:70},
  {id:3,score:90}
]
students.length  //3
students = []
students.length  //0

获取数组元素

var students = [
  {id:1,score:80},
  {id:2,score:70},
  {id:3,score:90}
]
students[0]  //{id: 1, score: 80}
students[1].score = 60  //60  修改

arr.indexOf(searchElement)

  • 寻找元素,获得索引位置
var tel = [110,114,120]
tel.indexOf(110)  //0 索引位置
tel.indexOf(119)  //-1 没有返回-1

arr.forEach(callback)遍历

当前元素
当前元素索引值
整个数组
var students = [
	{id:1,score:80},
	{id:2,score:50},
	{id:3,score:70}
];
var editScore = function(item,index,array){
	item.score += 5;
};
students.forEach(editScore);


var scores = [60,70,80,90]
var newScores = []
var editScores = function(item,index,array){
  newScores.push(item+5)
}
scores.forEach(editScores)
console.log(newScores)

arr.reverse()

  • 将数组逆序,与之前不同的是它会修改原数组
var students = [
	{id:1,score:80},
	{id:2,score:50},
	{id:3,score:70}
];
students.reverse()

[{id: 3, score: 70}
{id: 2, score: 50}
{id: 1, score: 80}]

arr.sort([comparaFunction])

  • 传入一个回调函数
  • 改变原有数组
var students = [
	{id:1,score:80},
	{id:2,score:50},
	{id:3,score:70}
];
var byScore = function(a,b){
  return b.score - a.score
}
students.sort(byScore)
// {id: 1, score: 80}
// {id: 3, score: 70}
// {id: 2, score: 50}

arr.push(element1,element2...)

  • 返回的是数组长度
  • 往后添加数组
var students = [
	{id:1,score:80},
	{id:2,score:50},
	{id:3,score:70}
];
students.push({id:4,score:90})  //4

var a = new Array(1,2,3);
a.push(4);
console.log(a);//[1, 2, 3, 4]

arr.unshift(element1,element2...)

  • 往数组前添加
var a=new Array(1,2,3);
a.unshift(4);
console.log(a);//[4, 1, 2, 3]

arr.shirt()

  • 获取第一个数组并删掉
var students = [
	{id:1,score:80},
	{id:2,score:50},
	{id:3,score:70}
];

students.shift()  //{id: 1, score: 80}

var a=new Array(1,2,3);
a.shift();  //1
console.log(a); //[2, 3]

arr.pop

  • 获取最后一个,并删掉
var students = [
	{id:1,score:80},
	{id:2,score:50},
	{id:3,score:70}
];
students.pop()  //{id: 3, score: 70}

var a = new Array(1,2,3);
a.pop();  //3
console.log(a); //[1, 2]

arr.splice(index,howmany[,elements])

  • index 你要从哪里删(开始索引)
  • howmany 删掉多少(删除元素的位移)
  • 加入多少元素(插入的新元素,当然也可以写多个)
  • splice方法返回一个由删除元素组成的新数组,没有删除则返回空数组
  • 插入往前面插
替换

删除

添加

arr.reverse() arr.sort() arr.push() arr.unshift() arr.shift() arr.pop() arr.splice() 都改变了数组


arr.slice(begin[,end])

  • 从哪个索引位置开始,到哪里结束
  • 开始包含,结束不包含
  • 数组未改变
var num = [1,2,3,4,5,6]
num.slice(1,4)  // [2, 3, 4]
num // [1, 2, 3, 4, 5, 6]

arr.concat(value1,value2,...)

  • concat方法用于拼接数组
  • a.concat(b)返回一个a和b共同组成的新数组,同样不会修改任何一个原始数组,也不会递归连接数组内部数组
var a = [1,2,3,4,5];
var b = [6,7,8,9];
console.log(a.concat(b));//[1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(a); //[1, 2, 3, 4, 5]
console.log(b); //[6, 7, 8, 9]

arr.join(separator)

  • 分隔符
var a = [1,2,3,4,5];
console.log(a.join(',')); //1,2,3,4,5
console.log(a.join('-')); //1-2-3-4-5

arr.map(callback)

  • 遍历数组,回调函数返回值组成一个新数组返回,新数组索引结构和原数组一致,原数组不变
var scores = [60,70,80,90]
var addScore = function(item,index,array){
  return item+5
}
scores.map(addScore)

arr.reduce(callback,[initialValue])

  • 后面一个参数是初始值
var students = [
	{id:1,score:80},
	{id:2,score:50},
	{id:3,score:70}
];
var sum = function(previousResult,item,index,array){
	return previousResult+item.score;
};
students.reduce(sum,0);  // 200

JS运算符和表达式

操作符      

一元操作符

只能操作一个值的操作符叫做一元操作符。

递增(++)递减(--)操作符,有两个版本:

  • 前置型
    • 执行前置递增和递减操作时,变量的值都在语句被求值以前改变的(这种情况被称为副效应)
var age = 29;       
var anotherAge = --age + 2;
alert(age);         //输出28
alert(anotherAge);        //输出30
由于前置递增和递减操作与执行语句的优先级相等,因此整个语句会从左至有被求值,例:
var num1 = 2;
var num2 = 20;
var num3 = --num1 + num2;        //等于21
var num4 = num1 + num2;        //等于21
  • 后置型
    • 后置递增递减语法不变,但区别是:即递增递减操作是在包含它们的语句被求值之后才执行的,例:
var num1 = 2;
var num2 = 20;
var num3 = num1-- + num2;        //等于22
var num4 = num1 + num2;        //等于21
  • 在应用不同的值时,递增递减遵循以下规则:
    • 应用一个包含有效数字字符的字符串时,先将其转换为数字值,再执行加减一的操作
    • 应用一个不包含有效数字字符的字符串时,将变量值设为NaN。
    • 应用一个布尔值false或者true时,先将其转换为0或者1,再执行加减一的操作
    • 应用于浮点数时,执行加减一操作
    • 应用于对象,先调用对象的valueOf()方法取得一个可操作的值,然后将该值应用前述规则,如果结果NaN,调用toString()方法
var s1 = "2";     s1++;    //3
var s2 = "z";     s2++;    //NaN
var b = false;    b++;    //1
var f = 1.1;    f--;    //0.1000000000009(由于浮点舍入错误导致) 
var o = {
    valueOf: function(){
      return -1;       
    }
};         o--;      //-2

算数操作符

乘法

乘法操作符是由一个(*)表示,用于表示两个数值的乘积处理特殊值,遵循以下规则:

  • 如果操作数都是数值,执行常规乘法计算,如果乘积超过数值的表示范围,用Infinity或-Infinity表示;
  • 如果有一个操作数是NaN,结果是NaN;
  • 如果Infinity与0相乘,结果NaN;
  • 如果Infinity与Infinity相乘,结果是Infinity
  • 如果Infinity与非0数值相乘,结果是Infinity或者-Infinity;
  • 如果有一个操作符不是数值,则调用Number()将其转换为数值。

除法

除法操作符有一个(/)表示,例:var result = 66/11; 处理特殊值,遵循以下规则:

  • 如果操作数都是数值,执行常规除法计算,如果商超过数值的表示范围,用Infinity或-Infinity表示;
  • 如果有一个操作数是NaN,结果是NaN;
  • 如果0被0除,结果NaN;
  • 如果Infinity被Infinity除,结果是NaN
  • 如果非零的有限数被零除,结果是Infinity或者-Infinity;
  • 如果Infinity被任何非零数值除,结果是Infinity或者-Infinity;
  • 如果有一个操作符不是数值,则调用Number()将其转换为数值。

求模

求模(余数)操作符有一个(%)表示,例:var result = 26 % 5; //等于1,处理特殊值,遵循以下规则:

  • 如果操作数都是数值,执行常规除法计算,返回除得的余数;
  • 如果被除数是无穷大值而除数是有限大的值,结果NaN;
  • 如果被除数是有限大的数值而除数是零,结果NaN;
  • 如果Infinity被Infinity除,结果是NaN;
  • 如果被除数是有限大的数值而除数是无穷大的数值,则结果是被除数;
  • 如果被除数是零,则结果是零;
  • 如果有一个操作符不是数值,则调用Number()将其转换为数值。

加性操作符

加法操作符用(+)表示。 例: var result = 1 + 2; 处理特殊值,遵循以下规则:

  • 如果有一个操作数是NaN,则结果是NaN;
  • 如果是Infinity加Infinity,结果是Infinity;
  • 如果是-Infinity加-Infinity,结果是-Infinity;
  • 如果Infinity加-Infinity,结果是NaN;
  • 如果+0加+0,结果是+0;
  • 如果-0加-0,结果是-0;
  • 如果+0加-0,结果是+0;
  • 不过如果有一个操作符是字符串,则应用以下规则:
    • 如果两个操作数都是字符串,则拼接起来;
    • 如果只有一个操作符是字符串,则将另一个操作符转换为字符串,然后拼接
  • 如果有一个操作数是对象,数值或布尔,则调用它们的toString()方法取得相应的字符串值,然后再应用前面的关于字符串的规则,对于undefined和null,则调用String()函数取得字符串.
var result = 5 + 5;
alert(result);      // 10
var result1 = 5 + "5";
alert(result1);         // "55"

减法

减法操作符用(-)表示,var result = 2 - 1;处理特殊值,遵循以下规则:

  • 如果操作数都是数值,执行常规计算,返回结果;
  • 如果有一个操作数是NaN,结果NaN;
  • 如果是 Infinity 减 Infinity,结果是NaN;
  • 如果是 -Infinity 减 -Infinity,结果是NaN;
  • 如果是 Infinity 减 -Infinity,结果是 Infinity;
  • 如果是 -Infinity 减 Infinity,结果是 -Infinity;
  • 如果+0减+0,结果是+0;
  • 如果-0减+0,结果是-0;
  • 如果-0减-0,结果是+0;
  • 如果有一个操作符不是数值,则调用Number()将其转换为数值。在计算
var result1 = 5 - true ;    // 4 ,因为true转换为1
var result2 = NaN - 1 ;    // NaN
var result3 = 5 - "" ;     // 5, 因为""被转换为0
var result4 = 5 - null ;   // 5,因为null转换为0

关系操作符

关系操作符用于对两个值得比较,返回时布尔值。包括:小于(<)、大于(>)、大于等于(>=)、小于等于(<=)当关系操作数使用了非数值,遵循以下规则:

  • 如果两个操作符都是字符串,则比较两个字符转对应的字符编码值;
  • 如果一个操作数是数值,将另一个操作数转换为数值,比较;
  • 如果一个操作数是对象,则调用valueOf()方法,如果没有valueOf()方法,调用toString()方法,在比较;
  • 如果一个操作数是布尔,转换为数值,在比较

相等操作符

ECMAScript提供两组操作符:相等 和 不相等----先转换再比较,全等 和 不全等----仅比较而不转换

相等和不相等

相等操作符有==两个等号表示,返回布尔值,不相等操作符由!=叹号后跟等号组成,这两个操作符先转换再比较(强制转换)转换遵循基本原则:

  • 如果有一个操作符是布尔值,比较前转换为数值0或1
  • 如果一个操作数是字符串,另一个是数值,先将字符串转化为数值再比较
  • 如果一个操作符是对象,另一个不是,则调用对象的valueOf()方法,得到的基本值用前面的规则比较;
    • 两个操作符遵循以下规则:
      • null 和 undefined 是相等的
      • 比较相等性之前,不能将null 和 undefined转换任何值
      • 如果有个操作数是NaN,相等操作符返回false,不相等返回true. NaN不等于NaN
      • 如果两个操作数都是对象,比较它们是不是同一个对象,如果都指向同一个对象,则相等操作符返回true;否则,返回false.

全等和不全等

全等操作符由===三个等于号表示,只在两个操作数未经转换就相等的情况下返回true.

var result1 = ("55" == 55) ;    //true
var result2 = ("55" === 55) ;    //false

不全等操作符由!==一个感叹号后跟两个等号表示,在两个操作数未经转换就不相等的情况下返回true

var result1 = ("55" != 55) ;    //false
var result2 = ("55" !== 55) ;    //true

记住:null == undefined会返回true,因为它们是类似的值,null === undefined会返回false,因为它们不同类型


布尔操作符

布尔操作符一共有三个:非(NOT) 与(AND) 或(OR).

逻辑非

逻辑非由一个感叹号!表示,返回布尔值,逻辑非操作先将其转化为布尔值,然后取非对其求反.

  • 如果操作数是一个对象,返回false;
  • 如果操作符是一个空字符串,返回true;
  • 如果操作符是一个非空字符串,返回false;
  • 如果操作符是数值0 ,返回true;
  • 如果操作数是任意非0数值(包括Infinity),返回false;
  • 如果操作数是null,返回true;
  • 如果操作数是NaN,返回true;
  • 如果操作数是undefined,返回true;
alert(!false);    //true
alert(!"blue");    //false
alert(!0);    //true
alert(!NaN);    //true
alert(!"");    //true
同时使用两个逻辑非(!!)操作,实际上会模拟Boolean()转型函数的行为

逻辑与

逻辑与操作符由两个和号&&表示,有两个操作数, 例:var result = true && false;

第一个操作数 第二个操作数 结果
true true true
true false false
false true false
false false false

逻辑与操作可以应用于任何类型的操作数,不仅仅布尔值,其他数值类型,遵循以下规则:

  • 如果第一个操作数是对象,返回第二个操作值;
  • 如果第二个操作数是对象,则只有在第一个操作数的求值结果为true的情况下才会返回该对象;
  • 如果两个数都是对象,返回第二个操作数;
  • 如果第一个数null, 返回null;
  • 如果第一个操作数是NaN,则返回NaN;
  • 如果第一个操作数是undefined,则返回underfined;

逻辑与操作属于短路操作,即如果第一个操作数能够决定结果,不会对第二个操作数求值.

var found = true ;
var result = ( found && someUndefinedVariable ) ;    //会发生错误,不能使用未定义的值
alert( result ) ;   //这一行不会执行
var found = false ;
var result = ( found && someUndefinedVariable ) ;    //不会发生错误,短路操作
alert( result ) ;   // 会执行"false"

逻辑或

逻辑或操作符由两个||两个竖线符号表示,由两个操作符,例:var result = true || false;

第一个操作数 第二个操作数 结果
true true true
true false true
false true true
false false false

与逻辑与操作相似,也遵循类似规则:

  • 如果第一个操作数是对象,返回第一个操作值;
  • 如果第一个操作数的求值结果为false,则返回第二个操作数;
  • 如果两个数都是对象,返回第一个操作数;
  • 如果两个操作数都是null, 返回null;
  • 如果两个操作数都是NaN,则返回NaN;
  • 如果两个操作数都是undefined,则返回underfined;

逻辑或操作也属于短路操作,即如果第一个操作数为true,不会对第二个操作数求值.

var found = true ;
var result = ( found || someUndefinedVariable ) ;    //不会发生错误
 alert( result ) ;   // 会执行"true"
var found = false ;
var result = ( found && someUndefinedVariable ) ;    // 会发生错误
alert( result ) ;   //  不会执行

条件操作符

语法:variable = boolean_expression ? true_value : false_value;

var max = ( num1 > num2 ) ? num1 :num2 ;
表达式意思是:如果num1>num2(表达式返回true),将num1赋值给max;如果false,将num2赋值给max.

赋值操作符

简单的赋值操作符由等于号=表示,作用是把右边的值赋给左边的量,例:var num = 10;

  • 如果等号前面再加其他操作符,可以完成复合赋值操作,例:
var num = 10;
num = num + 10;    ==>    num += 10;
x += y // 等同于 x = x + y
x -= y // 等同于 x = x - y
x *= y // 等同于 x = x * y
x /= y // 等同于 x = x / y
x %= y // 等同于 x = x % y
x >>= y // 等同于 x = x >> y
x <<= y // 等同于 x = x << y
x >>>= y // 等同于 x = x >>> y
x &= y // 等同于 x = x & y
x |= y // 等同于 x = x | y
x ^= y // 等同于 x = x ^ y

逗号操作符

逗号操作符可以在一条语句中执行多个操作,例:var num1 = 1, num2=2, num3=3;

  • 逗号操作符多用于声明多个变量,除此之外,还可以赋值.用于赋值时,逗号操作符总会返回表达式中最后一项
var num = ( 5 , 1 , 4 , 8 , 0) ;    //num值为0
虽然不常见,但是这个例子可以理解逗号的这种行为

对象操作符

  • new
    • 可以获取一个对象示例
  • delete
    • 可以删除一个对象的属性
  • .
    • 获取对象属性
  • []
    • 获取对象属性的值
  • instanceof
    • 判断某个变量是否是某个对象的实例
  • in
    • 判断某个属性是否在对象中

参考

这些都是一些常见的操作符,好好掌握,嘿嘿,还有 位操作符 还没太熟练,在研究一下,继续努力

DOM 节点操作

DOM

  • Document Object Model(文档对象模型)
    • 文档对象模型 (DOM) 是HTML和XML文档的编程接口。它给文档(结构树)提供了一个结构化的表述并且定义了一种方式—程序可以对结构树进行访问,以改变文档的结构,样式和内容。
  • DOM Core
  • DOM HTMl
  • DOM Style
  • DOM Event

DOM树

DOM树

节点遍历

image.png

document 对象

每个载入浏览器的HTML文档都会成为document对象。document对象包含了文档的基本信息,我们可以通过JavaScript对HTML页面中的所有元素进行访问、修改。

  • document对象有很多属性来描述文档信息
 document.doctype  //获取格式
document.title  //获取标题
document.characterSet
document.head
document.body
document.images
  • document.location
    • document.location 也可直接使用 location
document.location === location //true
document.location === window.location  //true

location属性返回一个只读对象,提供了当前文档的URL信息

// 假定当前网址为http://user:[email protected]:4097/path/a.html?x=111#part1

document.location.href //"http://user:[email protected]:4097/path/a.html?x=111#part1"
document.location.protocol // "http:"
document.location.host // "www.example.com:4097"
document.location.hostname // "www.example.com"
document.location.port // "4097"
document.location.pathname // "/path/a.html"
document.location.search // "?x=111"
document.location.hash // "#part1"
document.location.user // "user"
document.location.password // "passed"

// 跳转到另一个网址
document.location.assign('http://www.google.com')
// 优先从服务器重新加载
document.location.reload(true)
// 优先从本地缓存重新加载(默认值)
document.location.reload(false)
// 跳转到另一个网址,但当前文档不保留在history对象中,
// 即无法用后退按钮,回到当前文档
document.location.assign('http://www.google.com')
// 将location对象转为字符串,等价于document.location.href
document.location.toString()
  • document.open()、document.close()
    • document.open方法用于新建一个文档,供write方法写入内容。它实际上等于清除当前文档,重新写入内容
    • document.close方法用于关闭open方法所新建的文档。一旦关闭,write方法就无法写入内容了。
  • document.write()
    • document.write方法用于向当前文档写入内容。只要当前文档还没有用close方法关闭,它所写入的内容就会追加在已有内容的后面。
document.open();
document.write("hello");
document.write("world");
document.close();

Element

Element 对象可以拥有类型为元素节点、文本节点、注释节点的子节点,DOM提供了一系列的方法可以进行元素的增、删、改、查操作

  • nodeName:元素标签名,还有个类似的tagName
  • nodeType:元素类型
  • className:类名
  • id:元素id
  • children:子元素列表(HTMLCollection)
  • childNodes:子元素列表(NodeList)
  • firstChild:第一个子元素
  • lastChild:最后一个子元素
  • nextSibling:下一个兄弟元素
  • previousSibling:上一个兄弟元素
  • parentNode、parentElement:父元素

节点操作

获取节点

  • getElementById
    • getElementById方法返回匹配指定ID属性的元素节点。如果没有发现匹配的节点,则返回null
element = document.getElementById(id)
==>
var elem = document.getElementById("test");
  • getElementsByTagName
    • getElementsByTagName方法返回所有指定标签的元素(搜索范围包括本身)。返回值是一个HTMLCollection对象,也就是说,搜索结果是一个动态集合,任何元素的变化都会实时反映在返回的集合中。这个方法不仅可以在document对象上调用,也可以在任何元素节点上调用。
collection = element.getElementsByTagName(tagname)
collection = element.getElementsByTagName(tagname)[index]

collection = element.getElementsByTagName("*")//通配符
==>
var paras = document.getElementsByTagName("p");
  • getElementsByClassName
    • getElementsByClassName方法返回一个类似数组的对象(HTMLCollection类型的对象),包括了所有class名字符合指定条件的元素(搜索范围包括本身),元素的变化实时反映在返回结果中。这个方法不仅可以在document对象上调用,也可以在任何元素节点上调用。
collection = element.getElementsByClassName(classname)
collection = element.getElementsByClassName(classname)[index]
==>
var elements = document.getElementsByClassName('tab');

getElementsByClassName方法的参数,可以是多个空格分隔的class名字,
返回同时具有这些节点的元素。
document.getElementsByClassName('red test');  //顺序无关
兼容性
function getElementsByClassName(element, names) {
    if (element.getElementsByClassName) {    //特性侦测
        return element.getElementsByClassName(names);    //优先W3C规范
    } else {
        var elements = element.getElementsByTagName('*');    //获取所有后代元素
        var result = [];
        var element,
            classNameStr,
            flag;
        names = names.split(' ');
        for (var i = 0; element = elements[i]; i++) {
            classNameStr = ' ' + element.className + ' ';
            flag = true;
            for (var j = 0, name; name = names[j]; j++) {
                if (classNameStr.indexOf(' ' + name + '') == -1) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                result.push(element);
            }
        }
        return result;
    }
}
  • getElementsByName
    • getElementsByName方法用于选择拥有name属性的HTML元素,比如form、img、frame、embed和object,返回一个NodeList格式的对象,不会实时反映元素的变化。
// 假定有一个表单是<form name="x"></form>
var forms = document.getElementsByName("x");
forms[0].tagName // "FORM"

在IE浏览器使用这个方法,会将没有name属性、但有同名id属性
的元素也返回,所以name和id属性最好设为不一样的值。
  • querySelectorl
    • querySelector方法返回匹配指定的CSS选择器的元素节点。如果有多个节点满足匹配条件,则返回第一个匹配的节点。如果没有发现匹配的节点,则返回null。
list = element.querySelector(selector)
==>
var el1 = document.querySelector(".myclass");
var el2 = document.querySelector('#myParent > [ng-click]');

querySelector方法无法选中CSS伪元素。
  • querySelectorAll
    • querySelectorAll方法返回匹配指定的CSS选择器的所有节点,返回的是NodeList类型的对象。NodeList对象不是动态集合,所以元素节点的变化无法实时反映在返回结果中。
elementList = document.querySelectorAll(selectors);

querySelectorAll方法的参数,可以是逗号分隔的多个CSS选择器
返回所有匹配其中一个选择器的元素。

var matches = document.querySelectorAll("div.note, div.alert");

创建节点

  • createElement()
    • createElement方法用来生成HTML元素节点。
element = document.createElement(tagName)
==>
var newDiv = document.createElement("div");
  • createTextNode()
    • createTextNode方法用来生成文本节点,参数为所要生成的文本节点的内容。
var newDiv = document.createElement("div");
var newContent = document.createTextNode("Hello");
  • createDocumentFragment()
    • createDocumentFragment方法生成一个DocumentFragment对象。
var docFragment = document.createDocumentFragment();

DocumentFragment对象是一个存在于内存的DOM片段,但是不属于当前文档,常常用来生成较复杂的DOM结构,然后插入当前文档。这样做的好处在于,因为DocumentFragment不属于当前文档,对它的任何改动,都不会引发网页的重新渲染,比直接修改当前文档的DOM有更好的性能表现。

修改节点

  • element.textContent
    • 节点及其后代节点的文本内容
<li class="user">我是li元素</li>

user.textContent  //我是li元素
user.textContent = "yym"
==>
<li class="user">yym</li>
  • element.innerText
    • 节点及其后代节点的文本内容
    • ff不支持

插入节点

  • appendChild()
    • 在元素末尾添加元素
var achild = element.appendChild(achild)
==>
var newDiv = document.createElement("div");
var newContent = document.createTextNode("Hello");
newDiv.appendChild(newContent);
  • insertBefore()
    • 在某个元素之前插入元素
var achild = element.insertBefore(achild,referenceChild)
==>
var newDiv = document.createElement("div");
var newContent = document.createTextNode("Hello");
newDiv.insertBefore(newContent, newDiv.firstChild);
  • replaceChild()
    • replaceChild()接受两个参数:要插入的元素和要替换的元素
newDiv.replaceChild(newElement, oldElement);

删除节点

  • removeChild()
child = element.removeChild(child)

innerHTML

  • element.innerHTML
    • 节点的html内容
  • 内存泄露
  • 安全问题
var users = document.getElementById('users');
var ul = users.getElementsByTagName('ul')[0];

var li = document.createElement ("li");
li.className = 'user';
ul.appendChild(li);

li.innerHTML = '![](4.jpg)\
                <a href="/user/4">' + userName + '</a>';
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>innerHTML安全问题</title>
    <style>
    	html, body,h2, ul, li{margin: 0;padding: 0;}
		body{font-family: arial;}
		#users{margin: 30px;width: 210px;box-shadow: 0px 1px 2px #bbb;}
		h2{height: 50px;line-height: 50px;padding-left: 20px;font-size: 18px;border-bottom: 1px solid #dfdfdf;}
		ul{padding: 10px 0;overflow: hidden;}
		.user{float: left;width: 50px;margin: 10px;list-style: none;}
		.user a{color: #666;text-decoration: none;font-size: 12px;}
    </style>
</head>
<body>
    <div id="users">
        <h2>8882人在学习该课程:</h2>
        <ul>
            <li class="user">
                ![](1.jpg)
                <a href="/user/1">Satoshi</a>
            </li>
            <li class="user">
                ![](2.jpg)
                <a href="/user/2">春来草青</a>
            </li>
            <li class="user">
                ![](3.jpg)
                <a href="/user/3">Kash</a>
            </li>
        </ul>
    </div>
    <script>
var users = document.getElementById('users');
var ul = users.getElementsByTagName('ul')[0];

var li = document.createElement ("li");
li.className = 'user';
ul.appendChild(li);

        var userName = '</a><a onclick="alert(1);" href="#">lifeng'; // 安全问题
        // var userName = '</a><a onclick="document.documentElement.innerHTML=\'我是黑客!\'" href="#">lifeng';
        li.innerHTML = '![](4.jpg)\
                <a href="/user/4">' + userName + '</a>';
    </script>
</body>
</html>

编码规范

自己以前的命名规范,以及编码规范比较乱,现在准备用这些,让代码变得干净

命名技巧

  • 语义化
  1. 语义化标签优先
  2. 基于功能命名、基于内容命名、基于表现命名
  3. 简略、明了、无后患

(大声叫出它的名字,翻译成英文)

<!-- 不好  -->
<div class="article">
  <div class="article_title">编码规范</div>
  <div class="the_content">今天讲的内容是编码规范
     <div class="darkbold">yym</div> 学生学习编码</div>
</div>
<!-- 好 -->
<article>
  <h1>编码规范</h1>
  <p>今天讲的内容是编码规范
     <b>yym</b> 学生</p>
</article>

命名规范

  • 所有命名都使用英文小写
推荐:<div class="main"></div> 
不推荐: <div class="Main"></div> 
  • 命名用引号包裹
推荐:<div id="header"></div> 
不推荐: <div id=header></div> 
  • 用中横线连接
推荐:<div class="mod-modal"></div> 
不推荐: <div class="modModal"></div> 
  • 命名体现功能,不涉及表现样式(颜色、字体、边框、背景等)
推荐:<div class="text-lesser"></div>
不推荐: <div class="light-grey"></div>

常见命名

.wrap或.wrapper -- 用于外侧包裹
.container或 .ct -- 包裹容器
.header -- 用于头部
.body -- 页面 body
.footer -- 页面尾部
aside、sidebar -- 用于侧边栏
.content -- 和header footer 对应,用于主要内容
.navigation -- 导航元素
.pagination -- 分页

.tabs > .tab -- tab 切换
.breadcrumbs -- 导航列表、面包屑
.dropdown -- 下拉菜单
.article -- 文章
.main -- 用于主体
.thumbnail -- 头像,小图像
.media -- 媒体资源
.panel -- 面板
.tooltip -- 鼠标放置上去的提示
.popup -- 鼠标点击弹出的提示

.button、.btn -- 按钮
.ad -- 广告
.subnav -- 二级导航
.menu -- 菜单
.tag -- 标签
.message或者.notice -- 提示消息
.summary -- 摘要
.logo -- logo
.search -- 搜索框
.login -- 登录

.register -- 注册
.username -- 用户名
.password -- 密码
.banner -- 广告条
.copyright -- 版权
.modal或者 .dialog -- 弹窗

CSS规范

  • 书写规范
  1. tab 用两个空格表示
  2. css的 :后加个空格, {前加个空格
  3. 每条声明后都加上分号
  4. 换行,而不是放到一行
  5. 颜色用小写,用缩写, #fff
  6. 小数不用写前缀, 0.5s -> .5s;0不用加单位
  7. 尽量缩写, margin: 5px 10px 5px 10px -> margin: 5px 10px
/* Not recommended */
.test {
  display: block;
  height: 100px
}
/* Recommended */
.test {
  display: block;
  height: 100px;
}


/* Not recommended */
h3 {
  font-weight:bold;
}
/* Recommended */
h3 {
  font-weight: bold;
}


/* Not recommended: missing space */
#video{
  margin-top: 1em;
}

/* Not recommended: unnecessary line break */
#video
{
  margin-top: 1em;
}
/* Recommended */
#video {
  margin-top: 1em;
}


/* Not recommended */
a:focus, a:active {
  position: relative; top: 1px;
}
/* Recommended */
h1,
h2,
h3 {
  font-weight: normal;
  line-height: 1.2;
}


/* Always put a blank line (two line breaks) between rules. */
html {
  background: #fff;
}

body {
  margin: auto;
  width: 50%;
}


/* Not recommended */
@import url("//www.google.com/css/maia.css");

html {
  font-family: "open sans", arial, sans-serif;
}
/* Recommended */
@import url(//www.google.com/css/maia.css);

html {
  font-family: 'open sans', arial, sans-serif;
}

JSON语法总结

曾经有一段时间,XML是互联网上传输结构化数据的事实标准,但很多人认为XML过于繁琐,冗长.为了解决这一问题,2006年Duglas Crockford把JSON(javaScript Object Notation,对象表示法)作为IETFRFC4627提交给IETF,而JSON的应用早在2001年就开始了,JSON是javascript的严格的子集,表示结构化数据
关于JSON,它是一种数据结构,不是一种编程语言

语法

  • 简单值: 使用与JavaScript相同的语法,可以在JSON中表示字符串 数值 布尔值和null,不支持undefined
  • 对象: 对象做为一种复杂数据结构,表示是一组无序键值对
  • 数组: 数组也是一种复杂的数据结构,表示一组有序的值得列表,可以通过数值的索引来访问其中的值

简单值

最简单的JSON数据形式就是简单值.

5  //JSON表示5的方式
"Hello World"  //JSON字符串必须使用双引号

对象

JSON中的对象与JavaScript字面量有一些不同,下面是Js字面量:

var person = {
  name : "yym",
  age : 24
}

JSON中的对象要求给属性加引号

// 不用声明变量
{
  "name" : "yym",
  "age" : 24,
  "school" : {
    "location" : "beijing"
  }
}

数组

JSON数组也没有变量和分号

[
  {
    "title": "pro Js",
    "author": [
      "yym"
    ],
    "edition": 3,
    "year" : 2011
  },
  {
    "title": "pro Js",
    "author": [
      "yym"
    ],
    "edition": 2,
    "year" : 2015
  },
  {
    "title": "pro Js",
    "author": [
      "yym"
    ],
    "edition": 1,
    "year" : 2011
  }  
]

对象和数组通常是JSON数据结构最外层,利用他们可以创造出各种各样的数据结构


JSON对象

早期JSON解析器基本上使用JS的eval()函数,由于JSON是Javascript语法的子集,因此eval()可以解析并返回JavaScript对象和数组

JSON对象有两个方法:

  • stringify() 把JavaScript对象序列化为JSON字符串
  • parse() 把JSON字符串解析为原生JavaScript的值
var book = {

    "title": "pro Js",
    "author": [
      "yym"
    ],
    "edition": 3,
    "year" : 2011
}
var jsonText = JSON.stringify(book)
//{"title": "pro Js","author": ["yym"],"edition": 3,"year" : 2011}

在序列化对象时,所有函数及原型成员都会有意忽略,不体现在结果中,值为undefined的任何属性也会被跳过,最终值为有效的JSON数据类型的实例属性

将JSON字符串直接传递给JSON.parse()可以得到相应的javaScript的值

var bookCopy = JSON.parse(jsonText)

序列化选项

实际上,JSON.stringify()除了要序列化的JavaScript对象外,还可以接受两个参数,第一个参数是过滤器,可以是数组,也可以是函数,第二个参数是一个选项,表示是否在JSON字符串中保留缩进

  • 过滤结果
// 过滤器是数组,结果中只包含数组中列出的对象
var book = {

    "title": "pro Js",
    "author": [
      "yym"
    ],
    "edition": 3,
    "year" : 2011
}
var jsonText = JSON.stringify(book,["title","edition"])
//{"title": "pro Js","edition": 3}
  • 字符串缩进
    JSON.stringify()第三个参数用于控制结果中的缩进和空白符,如果参数是一个数值,表示每个级别缩进的空格数 数值和字符串都不能超过10
var book = {
    "title": "pro Js",
    "author": [
      "yym"
    ],
    "edition": 3,
    "year" : 2011
}
var jsonText = JSON.stringify(book,null,4)
//
{

    "title": "pro Js",
    "author": [
        "yym"
    ],
    "edition": 3,
    "year" : 2011
}
  • **toJSON()**方法
    有时候,JSON.stringify()还是不能满足某些对象进行自定义序列化的需求,在某些情况下,可以给对象定义toJSON()方法,返回器自身的JSON数据格式
var book = {

    "title": "pro Js",
    "author": [
      "yym"
    ],
    "edition": 3,
    "year" : 2011,
      toJSON: function(){
        return this.title; //返回图书的书名
      }
};
var jsonText = JSON.stringify(book)

序列化对象顺序

  1. 如果存在toJSON()方法而且能通过它取得的有效值,则调用该方法,否则,返回对象本身.
  2. 如果提供第二个参数,应用这个函数过滤器,传入函数过滤器值是第1步返回的值
  3. 对第2步返回的每个值序列化
  4. 如果提供第三个参数,执行相应的格式化

解析选项

JSON.parse()方法也可以接受另一个参数,该参数是一个函数,在每个键值对上调用,这个函数被称为还原函数(reviver)

如果还原函数返回undefined,则表示要从结果中删除相应的键;如果返回其他值,则将该值插入到结果中.在日期字符串转换为Date对象时,经常要用到还原函数

var book = {

    "title": "pro Js",
    "author": [
      "yym"
    ],
    "edition": 3,
    "year" : 2011,
    releaseDate: new Date(2017,11,11)
};
var jsonText = JSON.stringify(book)

var bookCopy = JSON.parse(jsonText,function(key,value){
  if(key == "releaseDate"){
    return new Data(value)
  }else{
    return value
  }
})
alert(bookCopy.releaseDate.getFUllYear())

以上代码先为book对象新增一个属性,该属性保存Date对象,这个对象在经过序列化之后变成有效字符串,经过解析又在bookCopy中还原一个Date对象.


小结

  • JSON是一个轻量级的数据格式,可以简化表示复杂数据的工作量.JSON使用JavaScript语法的自己表示对象
  • JSON.stringify() JSON.parse()

inline-block有什么特性?如何去除缝隙?高度不一样的inline-block元素如何顶端对齐?

dispiay: inline-block;

  • 既呈现inline的特性,不占据一整行,
  • 宽度由内容宽度决定,
  • 有呈现block的特性,可设置宽高,内外边距。

使用CSS更改非inline-block水平元素为inline-block水平,元素之间会出现缝隙,应该怎么去除缝隙

  • 元素间留白间距出现的原因就是标签段之间的空格,因此,去掉HTML中的空格,自然间距就木有了
  • 使用margin负值
.space a {
    display: inline-block;
    margin-right: -3px;
}
  • 闭合标签处理
<div class="space">
    <a href="##">惆怅
    <a href="##">淡定
    <a href="##">热血</a>
</div>
  • 使用font-size:0
.space {
    font-size: 0;
}
.space a {
    font-size: 12px;
}
  • 使用letter-spacing
.space {
    letter-spacing: -3px;
}
.space a {
    letter-spacing: 0;
}
  • 使用word-spacing
.space {
    word-spacing: -6px;
}
.space a {
    word-spacing: 0;
}

顶端对齐

vertical-align:top

HTML知识点盘点

HTML简介


什么是HTML

HTML 是用来描述网页的一种语言。

  • HTML 指的是超文本标记语言: Hyper Text Markup Language
  • HTML 不是一种编程语言,而是一种标记语言
  • 标记语言是一套标记标签 (markup tag)
  • HTML 使用标记标签来描述网页
  • HTML 文档包含了HTML 标签及文本内容
  • HTML文档也叫做 web 页面

HTML标签(语法)

HTML 标记标签通常被称为 HTML 标签 (HTML tag)。

  • HTML 标签是由尖括号包围的关键词,比如
  • HTML 标签通常是成对出现的,比如
  • 标签对中的第一个标签是开始标签,第二个标签是结束标签
  • 开始和结束标签也被称为开放标签和闭合标签
    • 标签放在尖括号里 <>
    • 标签都是闭合的
    • 一个或多个属性值
    • 可嵌套
    • 注释
  • 书写规范
    • 小写
    • 属性值双引号
    • 嵌套缩进

HTML实例

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>HTML实例</title>
</head>
<body>
	<h1>我是标题标签</h1>
	<p>我是段落标签</p>
</body>
</html>

<!-- 解释-->
<!DOCTYPE html> — 文档类型,写成 <!doctype html> 也行。

<html></html> — <html>包含整个页面的内容。

<head></head>—<head>包含页面描述,CSS样式等,但不会被用户看到。

<body></body>—<body>包含了你想被用户看到的内容。

<meta charset="utf-8"> — 指定文档的字符编码为 UTF-8。

<title></title> — 设置页面的标题,显示在浏览器标签页上。

<!DOCTYPE> 声明

  • 首行 顶格

doctype 声明是不区分大小写的,以下方式均可:

<!DOCTYPE html>

<!DOCTYPE HTML>

<!doctype html>

<!Doctype Html>

HTML文档头部

<head>
  <meta charset="UTF-8">			<!-- 定义文档的字符编码 -->
  <title>title</title>			<!-- 文档标题 -->
  <meta name="keywordss" content="音乐...">			<!-- 描述文档的基本信息 -->
  <meta name="description" content="...">
  <meta name="viewport" content="width=device-width">
  <link rel="shortcut icon" href="favicon.ico">			<!-- 引入字体图标 -->
  <link rel="stylesheet" href="../css/style.css">			<!-- 引入css样式 -->
  <style>
    p{
	color: #999;			/*样式写在style里*/
    }
  </style>
</head>

HTML标签总结(常用)

文档章节标签

  • body 呈现给用户
  • header 头部
  • nav 导航
  • aside 和主要内容不相关的区域
  • article 相邻独立可重复主体
  • section 文档中的区域
  • footer 尾部
  • hx h1-h6 标题

文本标签

  • <a></a> 超链接
    • 创建指向另一个文档的链接
    • 创建一个文档内部的锚点
    • 链接到Email地址
  • em strong strong比em更强调
  • span 无语义
  • br 换行 单闭合标签
  • cite q 引用
    • cite引用的出处
    • q简短的一段文字
  • b i 格式化
    • 粗体但不想强调 b标签
    • 斜体 技术术语等i标签

组标签

  • div 分区(其他标签的容器)
  • p 段落
  • ul ol dl列表
    • 无序列表 ul li
    • 有序列表 ol li
    • 自定义列表dl dt dd
  • pre 经过格式化的内容(保留空格和换行)
  • blockquote 大段引用

资源标签

  • img 嵌入图片(自闭合图片)
<img src="../cover.jpg" alt="封面"
  • iframe嵌入页面(例如第三方广告)
<iframe src="http://www.163.com"></iframe>
  • object embed嵌入外部资源
嵌入一个flash插件

<object data="" type="application/x-shockwave-flash">
	<param name="movie" value="http://pdfReader.swf">
	<param name="flashvars" value="http://book.pdf">
</object>


<embed src="http://pdfReader.swf" type="application/x-shockwave-flash">
  • video audio视频 音频
<video controls poster="./res/poster.jpg"  >
    <source src="./res/video.mp4" type="video/mp4">
    <track kind="subtitles" src="./res/video.vtt" srclang="cn" label="cn">
    Your browser does not support the video tag.
  </video>
  
  可以自己在mdn 查看video属性

主流浏览器都兼容HTML5的新标签,对于 IE8 及以下版本不认识 HTML5的新元素,可以使用 JavaScript 创建一个没用的元素来解决,例如:

<script>document.createElement("header");</script>,也可以使用shiv来解决兼容性问题,详情可参考[HTML5 Shiv](https://github.com/afarkas/html5shiv)。
  • canvas svg
    • 基于像素的canvas
    • 矢量的svg
  • map area 热点区域

表格标签

跨行:

<table>
    <caption>照片冲印价格详情</caption>
    <thead>
      <tr><th>相片尺寸</th><th>富士</th><th>柯达</th></tr>
    </thead>
    <tbody>
      <tr><th>6寸</th><td>0.45</td><td>0.6</td></tr>
      <tr><th>全景6寸</th><td>0.45</td><td>0.6</td></tr>
      <tr><th>7寸</th><td>0.89</td><td>1</td></tr>
      <tr><th>8寸</th><td>1.69</td><td>2</td></tr>
      <tr><th>10寸</th><td>3.89</td><td>5</td></tr>
    </tbody>
    <tfoot>
      <tr><td colspan="3">运费8元/单,满99元免运费</td></tr>
    </tfoot>
  </table>
  
  
跨列:

<table class="table">
  <thead>
    <tr><th>区域</th><th>寄达地</th><th>首重(元/1000g)</th><th>续重(元/1000g)</th></tr>
  </thead>
  <tbody>
    <tr><th rowspan="2">一区</th><td>浙江、上海、江苏</td><td>6</td><td>1</td></tr>
    <tr><td>江西、安徽</td><td>7</td><td>1</td></tr>
    <tr><th>二区</th><td>北京、天津、河北</td><td>9</td><td>4</td></tr>
    <tr><th>三区</th><td>辽宁、甘肃、四川</td><td>10</td><td>4</td></tr>
    <tr><th>四区</th><td>吉林、黑龙江、云南</td><td>10</td><td>6</td></tr>
    <tr><th>五区</th><td>**、西藏</td><td>15</td><td>10</td></tr>
  </tbody>
</table>


表单标签

form表单标签的应用:

<form action="/login"  method="post" class="m-form">
    <fieldset>
      <legend>照片选择</legend>
      <label for="file">选择照片</label><input type="file" id="file">
    </fieldset>
    <fieldset>
      <legend>综合设置</legend>
      <div>选择尺寸:</div>
      <div>
        <input class="cb" type="checkbox" name="size" id="cb_0" value="5"><label for="cb_0" checked>5寸</label>
        <input class="cb" type="checkbox" name="size" id="cb_1" value="6"><label for="cb_1">6寸</label>
      </div>
      <div>选择相纸:</div>
      <div>
        <input class="rd" type="radio" name="material" id="rd_0" value="fushi"><label for="rd_0" >富士</label>
        <input class="rd" type="radio" name="material" id="rd_1" value="keda"><label for="rd_1" >柯达</label>
      </div>
      <div>
        <label for="delivery">配送方式:</label>
        <select id="delivery">
            <option value="0">快递</option>
            <option value="1">EMS</option>
            <option value="2" selected>平邮</option>
        </select>
      </div>
      <div>
        <label for="description">商品描述:</label>
        <input class="txt" type="text" id="description" placeholder="描述">
      </div>
      <div>
        <label for="feedback">意见反馈:</label>
        <textarea name="feedback" rows="4" id="feedback"></textarea>
      </div>
    </fieldset>
    <div>
      <button type="submit">提交</button>
      <button type="reset">重置</button>
    </div>
  </form>


属性及全局属性

所有标签(包括 ) 都有的属性,请自行学习此教程

  • accesskey
  • class
  • contenteditable
  • data-*
  • draggable
  • hidden
  • id
  • spellcheck
  • style
  • tabindex
  • title
    ...

实体字符

实体字符表示
  • &entity_name;
  • &#entity_number;
    • 有名字的 HTML 实体,用 &名字; 表示
    • 没有名字的 HTML 实体,用 &#十进制; 表示
    • 没有名字的 HTML 实体,还可以用 &#x十六进制; 表示
  1. 空格 &nbsp; &#160;
  2. 引号 &quot; &#34;
  3. 大于号 &gt; &#62;
  4. 小于号 &lt; &#60;
  5. 版权号 &copy; &#169;
  6. & &amp; &#38;

参考:

w3cschool

网易云课堂微专业

饥人谷

MDN

慕课


声明:本文章版权归本人所有,转载需经作者同意

单列 两列布局

先做个题目:

<!DOCTYPE html>
<html lang="en">
  
<head>
    <meta charset="UTF-8">
    <title>全等四宫格布局</title>
    <style type="text/css">
    * {margin: 0; padding: 0}
      
    html,body { height: 100%}
      
    .box {display: flex;
        /*列布局,两个类名column的div纵向排列*/
        flex-direction: column;
        width: 100%;height: 100%; }
      
    .column {        
        /*两个div都是占据剩余空间,所以纵向平分了*/
        flex: 1;
        /*设置column下面两个item也是弹性布局,flex-direction默认是row,即水平排列*/
        display: flex;}
      
    .column+.column {
        /*上下两个column中第二个的上外边距是10px,*/
        margin-top: 10px; }
      
    .item {
        /*两个item都占据剩余空间,所以水平平分。两个column都是。*/
        flex: 1;
        background: #009999;}
      
    .item+.item {
        /*左右两个item中的第二个item的左外边距是10px*/
        margin-left: 10px;}
    </style>
</head>
<body>
    <div class="box">
        <div class="column">
            <span class="item">1</span>
            <span class="item">2</span>
        </div>
        <div class="column">
            <span class="item">3</span>
            <span class="item">4</span>
        </div>
    </div>
</body>
</html>

HTML和CSS的学习也算是告了一个段落,后面就是JavaScript的学习了,在学习JS之前,把CSS布局总结一次

 什么是布局呢?其实说白了,就是我们写的样式呈现给用户就是我们在文档中的布局,随着用户体验的提升,简单的样式不能满足用户的需求,所以需要我们对页面整体布局来提高用户体验

单列布局

  • 一栏布局
    • 实现方式:定宽+水平居中
<title>单列布局</title>
  <style>
    .layout{
     /* max-width:560px;用最大宽度,当宽度变小时会以浏览器真是宽度为基准*/
      width: 560px;  /* 定宽 */   /*用宽度,当宽度变小时会出现滚动条*/
      margin: 0 auto;   /* 水平居中 */
    }
    #header{
      height: 60px;    /* 高度,背景颜色 */
      background: red;
    }
    #content{
      position: relative;   /* 父元素设置相对定位 */
    }
    #content .aside {
     position: absolute;/* 子元素设置绝对定位 */
      right: 0;
      width: 100px;
      height: 300px;
      background: green;
    }
    #content .main {
      margin-right: 110px; /* 盒模型距离左边110px; */
      height: 500px;
      background: pink;
    }
    #footer{
      height: 50px;
      background: yellow;
    }
  
  </style>
</head>
<body>
  <div class="layout">
    <div id="header">头部</div>
    <div id="content">
      <div class="aside">aside</div>
      <div class="main">main</div>
    </div>
    <div id="footer">尾部</div>
  </div>
</body>

如果我们觉得多了一个div,嵌套比较麻烦,我们也可以用这个方法:

<title>单列布局2</title>
  <style>
    .layout{
      width: 960px;
      margin: 0 auto;
    }
    #header{
      height: 60px;
      background: red;
    }
    #content{
      height: 400px;
      background: blue;
    }
    #footer{
      height: 50px;
      background: yellow;
    }
  </style>
</head>
<body>
  <div id="header"  >头部</div>
  <div id="content" class="layout">内容</div>
  <div id="footer" class="layout">尾部</div>
</body>
  • 一栏布局(通栏)
    • 实现方式:在头部和尾部元素加一个父元素div,设置div的颜色和尺寸来达到目的
 <title>单列布局-通栏</title>
  <style>
    body{
      /* min-width: 960px; 设置body最小宽度可以去掉滚动条*/
    }
    .layout{
      width: 600px;/* 头部定宽 居中*/
      margin: 0 auto;
      border: 1px solid;
    }
    #header{
      height: 60px;  /* 父元素是块级元素,充满一行 */
      background: red;
    }
    #content{
      height: 400px;
      background: blue;
    }
    #footer{
      height: 50px;
      background: yellow;
    }
  </style>
</head>
<body>
  <div id="header">
    <div class="layout">头部</div>
  </div>
  <div id="content" class="layout">内容</div>
  <div id="footer">
    <div class="layout">尾部</div>
  </div>
</body>

多列布局


等分布局

定宽+自适应

  • float+margin
    • 优点:结构简单,容易懂
    • 缺点:有一点兼容性问题
	<title>定宽加自适应</title>
	<style>
		*{margin: 0;padding: 0; }
		body{border: 2px solid #ccc;}
		.left{
			background: red;
			float: left;    /*别忘了清除浮动哦*/
			width: 300px;
		}
		.right{
			background: blue;
			margin-left: 310px;/*因为left浮动,right: 会环绕着left,所以给个大于或者等于宽度的margin值*/
		}
	</style>
</head>
<body>
	<div class="left">
		<p>left</p>
	</div>
	<div class="right">
		<p>right</p>
		<p>right</p>
	</div>
</body>
  • float + margin + (fix)
    • 优点:兼容性特别好
    • 缺点:样式比较麻烦
<title>多列布局</title>
<style type="text/css">
	body{margin:20px;}
	.parent{
		border: 2px solid #ccc;
	}
	.clearfix:after{content:'';clear:both;display:block;height:0;overflow:hidden;visibility:hidden;}
	.left{
		float: left; width: 100px;
		position: relative;  /*提升层级*/
		background: red;
	}
	.right-fix{    /*解决IE6不兼容的问题产生的bug问题*/
		float: right; width: 100%;   /*右浮动因为宽度100%,所以会掉下去*/
		margin-left: -100px;    /*设置margin负边距,右浮动元素会上去*/

	}
	.right{
		margin-left: 120px;
		background: blue;
	}
</style>
</head>
<body>
<div class="parent  clearfix">
	<div class="left"><p>left</p></div>
	<div class="right-fix">
		<div class="right">
			<p>right</p>
			<p>right</p>
		</div>
	</div>
</div>
</body>
  • float + overflow
    • 优点:样式简单
    • 缺点:IE6不支持
<title>多列布局</title>
<style type="text/css">
	body{margin:20px;}
	
	.parent{
		border: 5px solid #ccc;
	}
	.left{
		float: left;
		width: 100px;
		margin-right: 20px;
		background: red;
	}
	.right{
		overflow: hidden;   会触发BFC(块级格式化文本)模式,bfc里面的容器跟外面隔离,外面的浮动不会影响里面的内容
		background: blue;
	}
</style>
</head>
<body>
<div class="parent">
	<div class="left">
		<p>left</p>
	</div>
	<div class="right">
		<p>right</p>
		<p>right</p>
	</div>
</div>
</body>
  • table
    • 缺点:代码较多
<title>多列布局</title>
<style type="text/css">
	body{margin:20px;}
	*{margin: 0;padding: 0; }
	.parent{
		display: table; width: 100%;    /*display:table;变成表格结构,设置成100%,是因为table宽度默认跟着内容走*/
		table-layout: fixed;   /* 1. 加速table的渲染 2. 实现了布局优先,要写上*/
		border: 5px solid #ccc;
	}
	.left,.right{
		display: table-cell; /*  变成水平排列单元格*/
	}
	.left{
		width: 100px;   /* table里每列的宽度之和等于表格,所以right是剩余的宽度*/
		padding-right: 20px;
		background: red;
	}
	.right{background: blue;}
</style>
</head>
<body>
<div class="parent">
	<div class="left">
		<p>left</p>
	</div>
	<div class="right">
		<p>right</p>
		<p>right</p>
	</div>
</div>
</body>
  • flex
    • 缺点:兼容性问题,性能可能有问题,做一些小范围布局
<title>多列布局</title>
<style type="text/css">
	body{margin:20px;}
	
	.parent{
		display: flex; /* 弹性布局*/
	}
	.left{
		width: 100px;
		margin-right: 20px;
		background: red;
	}
	.right{
		flex: 1;   /*分配剩余宽度*/
		background: blue
	}
</style>
</head>
<body>
<div class="parent">
	<div class="left">
		<p>left</p>
	</div>
	<div class="right">
		<p>right</p>
		<p>right</p>
	</div>
</div>
</body>

不定宽加自适应

  • float + margin做不到
    • width变化,margin值也需要变化,所以不能跟着内容走
  • float + margin +(fix)做不到
    • 同上,width变化,margin也需要重新设置变化
  • float + overflow
    • 可以实现跟着内容走
<title>多列布局</title>
<style type="text/css">
	body{margin:20px;}
	
	.parent{
		
	}
	.left{
		float: left;
		margin-right: 20px;
		background: red;
	}
	.right{
		overflow: hidden;
		background: blue;
	}
	.left p{width: 300px;}  /* 不管宽度怎么变,右边的元素始终距离它20px自适应*/
</style>
</head>
<body>
<div class="parent">
	<div class="left">
		<p>left</p>
	</div>
	<div class="right">
		<p>right</p>
		<p>right</p>
	</div>
</div>
</body>
  • table可以
<style type="text/css">
	body{margin:20px;}
	
	.parent{
		display: table; width: 100%;
		/*table-layout: fixed;*/       /*这句话需要去掉,因为它是布局优先,现在我们是内容优先*/
	}
	.left,.right{
		display: table-cell;
	}
	.left{
		width: 0.1%;   /*宽度由内容决定,left单元格宽度设置非常小,0.1%兼容性考虑,*/
		padding-right: 20px;
	}
	.left p{
		width:200px;   /*由内容撑开left*/
	}
</style>
</head>
<body>
<div class="parent">
	<div class="left">
		<p>left</p>
	</div>
	<div class="right">
		<p>right</p>
		<p>right</p>
	</div>
</div>
</body>
  • flex当然可以,就是有点兼容性问题

等分布局

我们先看一下原理
c是父容器宽度,w每一列宽度,g是每列中的宽度
)

我们来转化一下公式:
C = W * N + G * N -G 
C = (W + G) * N - G
C + G =  (W + G) * N,如果父元素增加一个G的宽度,等于后边的
  • float怎么弄?
    • 缺点:结构和样式有点耦合性, 兼容性有点问题
<title>等分布局</title>
<style type="text/css">
	body{margin:20px;}
	.parent{background:#ddd;color:#fff;}
	.clearfix:after{content:'';clear:both;display:block;height:0;overflow:hidden;visibility:hidden;}
	p{background:#666;}
	.parent{
		margin-left: -20px;
	}
	.column{
		float: left;
		width: 25%;
		padding-left: 20px;
		box-sizing: border-box;
	}
</style>
</head>
<body>
<div class="parent clearfix">
	<div class="column"><p>1</p></div>
	<div class="column"><p>2</p></div>
	<div class="column"><p>3</p></div>
	<div class="column"><p>4</p></div>
</div>
</body>
  • table怎么弄?
<title>等分布局</title>
<style type="text/css">
	body{margin:20px;}
	/*.parent{background:#ddd;color:#fff;}*/
	.clearfix:after{content:'';clear:both;display:block;height:0;overflow:hidden;visibility:hidden;}
	p{background:#666;color: #fff;}
	.parent-fix{ /*增加父容器的宽度*/
		margin-left: -20px;
	}
	.parent{
		display: table;
		width:100%;
		table-layout: fixed;
	}
	.column{
		display: table-cell;
		padding-left: 20px;
	}
</style>
</head>
<body>
<div class="parent-fix">
	<div class="parent">
		<div class="column"><p>1</p></div>
		<div class="column"><p>2</p></div>
		<div class="column"><p>3</p></div>
		<div class="column"><p>4</p></div>
	</div>
</div>
</body>
  • flex怎么做?
<title>等分布局</title>
<style type="text/css">
	body{margin:20px;}
	.parent{background:#ddd;color:#fff;}
	.clearfix:after{content:'';clear:both;display:block;height:0;overflow:hidden;visibility:hidden;}
	p{background:#666;}
	.parent{
		display: flex;
	}
	.column{
		flex: 1;
	}
	.column+.column{
		margin-left:20px;
	}
</style>
</head>
<body>
<div class="parent">
	<div class="column"><p>1</p></div>
	<div class="column"><p>2</p></div>
	<div class="column"><p>3</p></div>
	<div class="column"><p>4</p></div>
</div>
</body>

最后来个DEMO

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>DEMO</title>
</head>
<body>
<style>
ul,li{
  margin: 0;
  padding: 0;
  list-style: none;
}
.ct{
    overflow:hidden;
    width: 640px;
    border:dashed 1px orange;
    margin: 0 auto;
}

.ct .item{
    float: left;
    width:200px;
    height:200px;
    margin-right: 20px;
    margin-top: 10px;
    background: red;
}
.ct>ul{
  margin-right: -20px;
}

</style>
<div class="ct">
  <ul>
    <li class="item">1</li>
    <li class="item">2</li>
    <li class="item">3</li>
    <li class="item">4</li>
    <li class="item">5</li>
    <li class="item">6</li>
    <li class="item">7</li>
    <li class="item">8</li>
  </ul>
</div>
</body>
</html>

有些内容借鉴,不过每个内容我都在浏览器上跑了一遍,自己亲自用代码实现了一遍,如果有侵权的,请联系删除

定时器API

定时器

JavaScript提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()setInterval()这两个函数来完成。

setTimeout()

setTimeout函数用来指定某个函数或某段代码,在多少毫秒之后执行。它返回一个整数,表示定时器的编号,以后可以用来取消这个定时器。

  • delay是推迟执行的毫秒数,默认为0
  • 异步的过程
  • 间隔只执行一次
var timeoutId = setTimeout(func,delay)

clearTimeout(timeoutId) 清除定时器

setInterval()

  • func 执行改变属性的操作
  • delay触发的时间间隔
  • 一直执行
var intervalId = setInterval(func,delay)

clearInterval(intervalId) 清除定时器

requestAnimationFrame

  • 浏览器自己控制频率
  • 用户不用关心间隔时间
  • 动画更流畅
var requestId =  requestAnimationFrame(func)

cancelAnimationFrame(requestId)

clearTimeout()取消定时器

clearInterval()取消定时器

cancelAnimationFrame


运行机制

setTimeout和setInterval的运行机制是,将指定的代码移出本次执行,等到下一轮Event Loop时,再检查是否到了指定时间。如果到了,就执行对应的代码;如果不到,就等到再下一轮Event Loop时重新判断。这意味着,setTimeout指定的代码,必须等到本次执行的所有代码都执行完,才会执行。

setTimeout的作用是将代码推迟到指定时间执行,如果指定时间为0,即setTimeout(f,0),那么不会立刻执行setTimeout(f,0)将第二个参数设为0,作用是让f在现有的任务(脚本的同步任务和“任务队列”中已有的事件)一结束就立刻执行。也就是说,setTimeout(f,0)的作用是,尽可能早地执行指定的任务。

单线程模型

console.log(1);
setTimeout('console.log(2)',1000);
console.log(3);
// 1
// 3
// 2
依次输出1,3,2,因为setTimeout是异步的,所以浏览器会吧代码放在callbackqueue中,
等待stack中的任务运行完,在运行,所以结果是这个
    for(var i=0; i<10; i++){
      setTimeout(function(){
          console.log(i)
      }, 1000)
    }
    //结果是10个10
for循环完成i变为10,过了一秒以后才执行定时器,相当于创建了10个定时器
var t = true;  
setTimeout(function(){ 
  t = false; 
}, 1000);  

while(t){ }  
console.log('end')
//结果是无限循环
因为setTimeout会被放在任务队列中,然后执行while,因为t= true,
所以一直执行while(t){}

异步和回调

function f1(callback){
    setTimeout(function(){
        //做某件事,可能很久
        console.log('别急,开始执行f1')
        for(var i=0;i< 100000;i++){

        }
        console.log('f1执行完了')

        callback()  // 回调函数
    }, 0);

}
function f2(){
    console.log('执行f2');
}
function f3(){
    console.log('执行f3');
}
f1(f2) //当f1执行完之后再执行 f2
f3()

函数节流

用户执行一个事件过多次,我们只取最后一次的结果

var timer    //开始是undefined
function hiFrequency(){    //hiFrequency用户快速执行的事件
  if(timer){    
      clearTimeout(timer)    //开始是不执行的
  }
    timer = setTimeout(function(){
         console.log('do something')
    }, 300)    //在300ms后执行,如果在300ms以内再次执行hiFrequency,clear
}

hiFrequency()
hiFrequency()
hiFrequency()  //do somthing 只执行最后一次
封装成函数
function throttle(fn, delay) {
    var timer = null
    return function(){
        clearTimeout(timer)
        timer = setTimeout(function(){ 
            fn(arguments)
        }, delay)
    }
}

function fn(){
    console.log('hello ')
}

var fn2 = throttle(fn, 1000)
fn2()
fn2()
fn2()

对象和JSON

对象

所谓对象,就是一种无序的数据集合,由若干个“键值对”(key-value)构成

创建对象

var obj = new Object()
var obj = {}  //字面量

属性和方法

  • 对象.属性
  • 对象["属性"]
  • 增加属性和方法
    • car.type = "suv"(直接赋值)
    • car.stop = function(){alert("stop")}
  • 修改属性和方法
    • car.color= "white"
    • car.run = function(){alert(run2)}
  • 删除属性和方法
    • delete car.color
  • 查看所有属性
    • 查看一个对象本身的所有属性,可以使用Object.keys方法。
var car = {
  color: "red",
  run: function(){alert("run")}
}
car.color  //"red"
car.run  //ƒ (){alert("run")}
car["color"]  //"red"

var o = {
  key1: 1,
  key2: 2
};

Object.keys(o);
// ['key1', 'key2']

obj.constructor

  • 获取某个对象的构造函数
var car = {
  color: "red",
  run: function(){alert("run")}
}
car.constructor  //ƒ Object() { [native code] }

var num = new Number(123)
num.constructor  //ƒ Number() { [native code] }

obj.toString()

  • 转换为字符串
var num = new Number(123)
num.toString()  //"123"

obj.valueOf()

  • 获取对象的原始值
var num = new Number(123)
num.valueOf()  //123

obj.hasOwnProperty()

  • 自己所拥有的属性,返回true或者false
var car = {
  color: "red",
  run: function(){alert("run")}
}
car.hasOwnProperty("color")  //true
car.hasOwnProperty("logo")  //false

JSON

JSON 格式(JavaScript Object Notation 的缩写)是一种用于数据交换的文本格式

JSON 对值的类型和格式有严格的规定。

  • 复合类型的值只能是数组或对象,不能是函数、正则表达式对象、日期对象。
  • 简单类型的值只有四种:字符串、数值(必须以十进制表示)、布尔值和null(不能使用NaN, Infinity, -Infinity和undefined)。
  • 字符串必须使用双引号表示,不能使用单引号。
  • 对象的键名必须放在双引号里面。
  • 数组或对象最后一个成员的后面,不能加逗号。
以下是合格的 JSON 值。

["one", "two", "three"]
{ "one": 1, "two": 2, "three": 3 }
{"names": ["张三", "李四"] }
[ { "name": "张三"}, {"name": "李四"} ]

以下是不合格的 JSON 值。

{ name: "张三", 'age': 32 }  // 属性名必须使用双引号
[32, 64, 128, 0xFFF] // 不能使用十六进制值
{ "name": "张三", "age": undefined } // 不能使用undefined
{ "name": "张三",
  "birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'),
  "getName": function() {
      return this.name;
  }
} // 不能使用函数和日期对象

JSON.parse()

  • JSON.parse方法用于将JSON字符串转化成对象。
  • JSON --> JS
var userJson = '{\
            "id": 1,\
            "nick": "春鸟秋虫",\
            "avatar": "1.jpg",\
            "tags": null,\
            "authed": false\
        }';
var user = JSON.parse(userJson);

JSON.stringify()

  • JSON.stringify方法用于将一个值转为字符串。该字符串符合 JSON 格式,并且可以被JSON.parse方法还原
JSON.stringify('abc') // ""abc""
JSON.stringify(1) // "1"
JSON.stringify(false) // "false"
JSON.stringify([]) // "[]"
JSON.stringify({}) // "{}"

JSON.stringify([1, "false", false])
// '[1,"false",false]'

JSON.stringify({ name: "张三" })
// '{"name":"张三"}'

使用node.js实现一个简单的静态服务器

在这之前,我对node.js是只闻其名,未见其身啊,学习了ajax,老师说用node.js搭建一个自己的服务器,老师也讲了实现原理,但还是一知半解,怎么办?只好去看看node.js教程了

好了,话不多说,先了解一个node.js应用由哪几部分组成

  • 引入 required 模块:我们可以使用 require 指令来载入 Node.js 模块。
  • 创建服务器:服务器可以监听客户端的请求,类似于 Apache 、NginxHTTP 服务器。
  • 接收请求与响应请求 服务器很容易创建,客户端可以使用浏览器或终端发送HTTP请求,服务器接收请求后返回响应数据。
步骤一:引入 required 模块

我们使用 require 指令来载入 http 模块,并将实例化的 HTTP 赋值给变量http

var http = requier("http")
步骤二、创建服务器

使用http.createServer()方法创建服务器,并使用 listen 方法绑定 8888 端口。 函数通过request, response参数来接收和响应数据。

http.createServer(function (request, response) {

    // 发送 HTTP 头部 
    // HTTP 状态值: 200 : OK
    // 内容类型: text/plain
    response.writeHead(200, {'Content-Type': 'text/plain'});

    // 发送响应数据 "Hello World"
    response.end('Hello World\n');
}).listen(8080);

把代码总结起来就是

var http = require('http')

var server = http.createServer(function(request, response){

    //.setheader设置响应头 text/plain当成字符串去渲染
    response.setHeader("Content-Type","text/plain; charset=utf-8")

    response.setHeader('Content-Type','text/html')
    //状态码,以及状态码解释
    response.writeHead(202, 'haha')
    response.write('<html><head><meta charset="utf-8" /></head>')
    response.write('<body>')
    response.write('<h1>你好</h1>')
    response.write('</body>')
    
    response.end()
})

console.log('open http://localhost:8080')
server.listen(8080)

设置响应头
状态码

node执行一下

命令执行

服务器监听8080端口


上面我们了解了node.js怎么使用,下面我们来看看真正写一个静态服务器怎么写?

创建server.js是如何把我们写的东西展现在服务器上的?

先来了解几个模块

  • Path模块
    Node.js path 模块提供了一些用于处理文件路径的小工具,我们可以通过以下方式引入该模块,有一些方法和属性可以查看文档
var path = require("path")
path.join([path1][, path2][, ...])

用于连接路径。该方法的主要用途在于,会正确使用当前系统的路径分隔符,Unix系统是"/"Windows系统是"\"

  • Node.js 文件系统
    Node.js 提供一组类似 UNIX(POSIX)标准的文件操作APINode 导入文件系统模块(fs)语法如下所示:
var fs = require("fs")

Node.js 文件系统(fs 模块)模块中的方法均有异步和同步版本,例如读取文件内容的函数有异步的fs.readFile()和同步的 fs.readFileSync()

我们看一下静态服务器的原理

  • 当用户访问一个地址为localhost:8080/index.html,我们怎么样才能让用户看到我们的文件呢?
  • 我们可以通过函数参数request得到这个url
  • 得到url以后,我们只要在本地找到对应的文件就可以了

过程

静态服务

var http = require('http')
var path = require('path')  //处理路径url
var fs = require('fs')
var url = require('url')

//staticRoot静态路径
function staticRoot(staticPath, req, res){
  //解析url路径,包括文件名
  var pathObj = url.parse(req.url, true)
  //默认读index.html
  if(pathObj.pathname === '/'){
    pathObj.pathname += 'index.html'
  }
  //请求文件的具体路径
  var filePath = path.join(staticPath, pathObj.pathname)
  //异步读文件  fs.readFile   
  //binary 二进制读文件
  fs.readFile(filePath, 'binary', function(err, fileContent){
    //判断是否读到
    if(err){
      console.log('404')
      res.writeHead(404, 'not found')
      res.end('<h1>404 Not Found</h1>')
    }else{
      console.log('ok')
      res.write(fileContent, 'binary')
      res.end()      
    }
  })
  

}
//创建服务器
var server = http.createServer(function(req, res){
  staticRoot(path.resolve(__dirname, 'static'), req, res)
})

server.listen(8080)
console.log('visit http://localhost:8080' )
//一个最基本的 HTTP 服务器架构(使用8081端口),创建 server.js 文件

var http = require('http');
var fs = require('fs');
var url = require('url');


// 创建服务器
http.createServer( function (request, response) {  
   // 解析请求,包括文件名
   var pathname = url.parse(request.url).pathname;
   
   // 输出请求的文件名
   console.log("Request for " + pathname + " received.");
   
   // 从文件系统中读取请求的文件内容
   fs.readFile(pathname.substr(1), function (err, data) {
      if (err) {
         console.log(err);
         // HTTP 状态码: 404 : NOT FOUND
         // Content Type: text/plain
         response.writeHead(404, {'Content-Type': 'text/html'});
      }else{             
         // HTTP 状态码: 200 : OK
         // Content Type: text/plain
         response.writeHead(200, {'Content-Type': 'text/html'});    
         
         // 响应文件内容
         response.write(data.toString());        
      }
      //  发送响应数据
      response.end();
   });   
}).listen(8081);

// 控制台会输出以下信息
console.log('Server running at http://127.0.0.1:8081/');

上面只是实现了一个简单的静态服务器,只能定位文件夹,我想mock数据,和前端交互怎么弄?

  • 看一个简单的例子,请求到达8080端口的服务器,我处理对应的路由,域名后面的就是路由
 url.parse(string).query
                                           |
           url.parse(string).pathname      |
                       |                   |
                       |                   |
                     ------ -------------------
http://localhost:8888/start?foo=bar&hello=world
                                ---       -----
                                 |          |
                                 |          |
              querystring.parse(queryString)["foo"]    |
                                            |
                         querystring.parse(queryString)["hello"]
var http = require('http')
var fs = require('fs')
http.createServer(function(req, res){
  //如果解析的路由是/getWeather,To-do
  switch (req.url) {
    //相当于ajax mock数据
    case '/getWeather':
      res.end(JSON.stringify({a:1, b:2}))
      break;
    case '/user/123':
      res.end( fs.readFileSync(__dirname + '/static/user' ))
      break;
    default:
      //都没有匹配,是一个静态文件
      res.end( fs.readFileSync(__dirname + '/static' + req.url) )
  }
}).listen(8080)

第一次短时间接触node.js,对后台知识,以及一些模块什么的理解不太清楚,所以还是有点不足,和面再对这个服务器补充一下

jQuery动画与ajax

jQuery函数方法

<div class="box">
  <ul>
    <li>1</li>
    <li>2</li>
    <li class="active">3</li>
    <li>4</li>
  </ul>
</div>
//元素遍历 .each()
$("ul>li").each(function(index,node){  //node是原生js对象,需转化
  var str = $(node).text()
  $(node).text(str + str)
})

//.map()
var arr = $(".box>ul>li").map(function(){
  return $(this).text()
})
console.log(arr)  // ["1", "2", "3", "4"]

//.index()
$(".active").index()  //2

jQuery 中, $(document).ready()是什么意思?

  • 当DOM准备就绪时,指定一个函数来执行。
  • 大多数情况下,只要DOM结构已完全加载时,脚本就可以运行。传递处理函数给.ready()方法,能保证DOM准备好后就执行这个函数

如果执行的代码需要在元素被加载之后才能使用时,(例如,取得图片的大小需要在图片被加载完后才能知道),就需要将这样的代码放到 load 事件中。

$(document).ready(handler)
$(handler)

$(function(){
    console.log('ready');
});

$node.html()和$node.text()的区别?

  • $node.html(),返回所选择元素内的html内容,包含html标签和文本内容
  • $node.text(),返回所选择元素内的文本内容,不包含html标签,只包含文本内容

$.extend 的作用和用法?

  • 当我们提供两个或多个对象给$.extend(),对象的所有属性都添加到目标对象(target参数)
  • 如果只有一个参数提供给$.extend(),这意味着目标参数被省略。在这种情况下,jQuery对象本身被默认为目标对象。
var obj1 = {a:1}
var obj2 = {b:2,c:3}
var obj3 = {b:3,d:5} 
var obj4 = {}

$.extend(obj1,obj2)  //obj1 == {a: 1, b: 2, c: 3}
$.extend(obj1,obj2,obj3)  //obj1 == {a: 1, b: 3, c: 3, d: 5}
$.extend(obj4,obj1,obj2,obj3)  //obj4 == {a: 1, b: 3, c: 3, d: 5}
//写法同上
var obj5 = $.extend({},obj1,obj2,obj3)  //obj5 == {a: 1, b: 3, c: 3, d: 5}

jQuery 的链式调用是什么?

  • 可以连续的使用 jQuery 方法的过程叫做 链式调用。
  • jQuery是通过在调用方法后返回这个调用对象来实现链式调用的。

Query 中 data 函数的作用

  • .data()
    • 在匹配元素上存储任意相关数据 或 返回匹配的元素集合中的第一个元素的给定名称的数据存储的值。

.data() 方法允许我们在DOM元素上绑定任意类型的数据,避免了循环引用的内存泄漏风险。

.data( key, value ) 在匹配元素上存储任意相关数据.

  • key:一个字符串,用户存储数据的名称。
  • value:新的数据值;它可以是任意的Javascript数据类型,包括Array 或者 Object。
我们可以在一个元素上设置不同的值,之后获取这些值:
$("body").data("foo", 52);
$("body").data("bar", { myType: "test", count: 40 });
$("body").data({ baz: [ 1, 2, 3 ] });
 
$("body").data("foo"); // 52
$("body").data(); // { foo: 52, bar: { myType: "test", count: 40 }, baz: [ 1, 2, 3 ] }

写出以下功能对应的 jQuery 方法:

  • 给元素 $node 添加 class active,给元素$noed删除 class active
$node.addClass('active')  //添加
$node.removeClass('active')  //删除
  • 展示元素$node, 隐藏元素$node
$node.show()  //展示
$node.hide()  //隐藏
  • 获取元素$node 的 属性: id、src、title, 修改以上属性
$node.attr('id','value')  //获取并赋值
$node.attr('src','value')
$node.attr('title','value')
  • $node 添加自定义属性data-src
$node.attr("data-src","value")
  • $ct 内部最开头添加元素$node,在$ct 内部最末尾添加元素$node
//结尾添加
$ct.append($node) 
$node.appendTo($ct)  
//开头添加
$ct.prepend($node)
$node.prependTo($ct)
  • 删除$node$ct里内容清空
// 事件之类的删除后不保存
$node.remove()
// 事件之类的删除后保存
$node.detach()

$ct.empty()  //清空
  • $ct 里设置 <div class="btn"></div>
$ct.html('<div class="btn"></div>')
  • 获取、设置$node 的宽度、高度(分别不包括内边距、包括内边距、包括边框、包括外边距)
$node.width();//不包括内边距宽度,仅包括内容
$node.height();//不包括内边距高度,仅包括内容
$node.innerWidth();//包括内容和内边距宽度
$node.innerHeight();//包括内容和内边距高度
$node.outerWidth();//包括内容,内边距,边框宽度
$node.outerHeight();//包括内容,内边距,边框高度
$node.outerWidth(true);//包括内容,内边距,边框,外边距高度
$node.outerHeight(true);//包括内容,内边距,边框,外边距宽度

宽高

  • 获取窗口滚动条垂直滚动距离
$(window).scrollTop()
  • 获取$node 到根节点水平、垂直偏移距离
$node.offset()  //{top: 16, left: 48}
  • 修改$node 的样式,字体颜色设置红色,字体大小设置14px
$node.css({"color": "red", "font-size": "14px"})
  • 遍历节点,把每个节点里面的文本内容重复一遍
<div class="box">
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
  </ul>
</div>
$("ul>li").each(function(index,node){  //node是原生js对象,需转化
  var str = $(node).text()
  $(node).text(str + str)
})
  • $ct 里查找 class 为 .item的子元素
$ct.find('.item')
  • 获取$ct 里面的所有孩子
$ct.children()
  • 对于$node,向上找到 class 为'.ct'的父亲,在从该父亲找到'.panel'的孩子
//找父亲
$node.parents('.ct')
//从父亲找儿子
$node.parents('.ct').find('.panel')
  • 获取选择元素的数量
$node.length
  • 获取当前元素在兄弟中的排行
$node.index()

用jQuery实现以下操作

  • 当点击$btn 时,让 $btn 的背景色变为红色再变为蓝色
<button id="btn" type="button">变色</button>

$("#btn").on("click",function(){
  $(this).css({"background-color":"red"})
//设置定时
  setTimeout(function(){
    $("#btn").css({"background-color":"blue"})
  },1000)
})
  • 当窗口滚动时,获取垂直滚动距离
$(window).on("scroll",function(){
    $("node").text($(window).scrollTop()+"px");
});
  • 当鼠标放置到$div 上,把$div 背景色改为红色,移出鼠标背景色变为白色
<div class="bg"></div>

$(".bg").on("mouseenter",function(){
  $(this).css({"background-color":"red"})
})
$(".bg").on("mouseleave",function(){
  $(this).css({"background-color":"white"})
})
  • 当鼠标激活 input 输入框时让输入框边框变为蓝色,当输入框内容改变时把输入框里的文字小写变为大写,当输入框失去焦点时去掉边框蓝色,控制台展示输入框里的文字
<input id="ipt" type="text">

$("#ipt").on("focus",function(){
  $(this).css({"outlineColor":"blue"})
})
//键盘事件
$("#ipt").on("keydown",function(){
  $(this).val($(this).val().toUpperCase())
})
$("#ipt").on("blur",function(){
  $(this).css({"outlineColor":"none"})
  console.log($(this).val())
})

  • 当选择 select 后,获取用户选择的内容
<select name="" class="sports">
  <option value="篮球">篮球</option>
  <option value="排球">排球</option>
  <option value="足球">足球</option>
  <option value="乒乓球">乒乓球</option>
</select>
<p>用户选择的内容是:<span></span></p>

$(".sports").on("change",function(){
  $("p>span").text($("option:selected").val())
})

用 jQuery ajax 实现如下效果。`当点击加载更多会加载数据展示到页面效果预览

  • 启用server-mock
  • 需开启 mock start
  • 代码地址

效果预览

函数调用和函数传参

函数声明定义函数特点

  • 和变量的声明会前置一样,函数声明同样会前置,如果我们使用函数表达式那么规则和变量一样
  • 用函数声明的方式,重复定义函数,最后一次定义有效

函数实例化定义函数特点

  • 定义的函数只能访问本地作用域和全局作用域

变量前置

console.log(a)   //undefined
var a = 3    

==>等同于

var a
console.log(a)
a = 3

函数声明

console.log(sum(3,5))

function sum(a,b){
  return a + b
}

==>等同于
  

function sum(a,b){
  return a + b
}

console.log(sum(3,5))

函数表达式声明前置

fn()  //"TypeError: fn is not a function(不是一个函数)

var fn = function(){
  console.log('fn...')
}

==>


var fn
fn()

fn = function(){
  console.log('fn...')
}

立即执行函数

立即执行函数可以形成一个作用域,和全局隔开,不会污染全局,另一方面也是防止命名冲突的影响

(function(){
  console.log('我是立即执行函数')
})()

==>
  
var fn = function(){
  console.log('我是立即执行函数')
}
fn()

命名冲突

当在同一个作用域内定义了名字相同的变量和方法的话,会根据前置顺序产生覆盖

var fn = 3;
function fn(){}

console.log(fn); // 3

==>

var fn
function fn(){}  //覆盖上面的

fn = 3  //重新赋值
console.log(fn)

console.log(fn); // 3

function fn(){}
var fn = 3;

==>
function fn(){}  
var fn  //已经声明的值不会变

console.log(fn)  //fn(){}
fn = 3  

递归

简单来说就是自己调用自己

function factorial(n){
  if(n === 1){
    return 1
  }
  return n * factorial(n-1) 
}
alert(factorial(3))

//缺点:效率低

函数调用

  • 函数调用模式
    • 函数名()
  • 方法调用模式
var myNumber = {
 value: 1,
 add: function(i){
  console.log(this);
  this.value += i;
  }
}
myNumber.add(1);
  • 构造函数调用模式
    • new Function(...)首字母大写
  • apply(call)调用模式
    • apply是function构造函数原型上的构造方法
      • 实现函数借用的功能,把函数借用给对象

函数调用模式的区别-this

  • 函数调用模式
    • this指向window的全局对象
//例子:
function add(i,j){
  console.log(this);  //Window
  // console.log(arguments);
  var sum = i+j;
  console.log(sum);
  (function(){
  	console.log(this);  //Window
  })()
  return sum;
}
add(1,2);
  • 方法调用模式
    • this指向调用者
//例子:
var myNumber = {
  value: 1,
  add: function(i){
  	console.log(this);  //Object{value: 1, add: ƒ}
  	this.value += i;
  }
}
myNumber.add(1);
  • 构造函数调用模式
    • this指向被构造的函数
//例子:
function Car(type,color){
  this.type = type;
  this.color = color;
  this.status = "stop";
  this.light = "off";
  console.log(this);  //打印结果是我们创建的对象
}
Car.prototype.start = function(){
  this.status = "driving";
  this.light = "on";
  console.log(this.type + " is " + this.status);
}
Car.prototype.stop = function(){
  this.status = "stop";
  this.light = "off";
  console.log(this.type + " is " + this.status);
}
var benz = new Car("benz", "black");  //Car {type: "benz", color: "black", status: "stop", light: "off"}
  • apply(call)调用模式
    • this指向第一个参数

函数传参

  • 原始类型按值传递-call by value
var count = 1;
var addOne = function(num) {
	num += 1;
	return num;
}
var ret = addOne(count);
console.log(ret);  //2
console.log(count);  //1结果没有受到影响
  • 对象类型按共享传递-call by sharing
//例子一:
var count = {a:1,b:1};
var addOne = function(obj) {
	obj.a += 1;
	obj.b += 1;
	return obj;
}
var ret = addOne(count);
console.log(ret);  //{a: 2, b: 2}
console.log(count);  //{a: 2, b: 2}

//例子二:
var count = {a:1,b:1};
var addOne = function(obj) {
	obj = {a:2, b:2};
	return obj;
}
var ret = addOne(count);
console.log(ret);  //{a: 2, b: 2} 
console.log(count);  //{a: 1, b: 1}

函数传参

JS基本语法和基本类型

基本语法

直接量

var number = 1;    //1 是直接量
直接量也可以是其他类型: 
1.2  "Hello World"    true    false    null    []    {name:"js"} ...

变量

var number = 1;    //mumber 是变量
我们可以把变量看做一个个的盒子,我们可以在盒子里放各种不同的东西,然后给盒子命名不同的名称.

命名盒子的过程叫做:声明变量   (语法: var 变量名; )  
例如 var age; var name; var sex; 
或者 var age,name,sex;

标识符

标识符就是指变量、函数、属性的名字,或者函数的参数,最好采用驼峰大小写格式,也就是第一个字母小写,剩下每个单词首字母大写。

  • 命名要求
    • 以字母 下划线 或者美元符号($)开头
    • 由字母 下划线 或者美元符号($)和数字组成
  • 范例
    • var abc; var _abc; var $abc; var _abc1$; 都是合法的;
    • var 1abc; var *abc; var abc&; var #abc1$; 都是不合法的
  • 关键字和保留字不能做标识符
  • 大小写敏感 var age; var Age;是不同的.

语句

  • 每个语句都以分号结尾,虽不是必须的,但强烈建议加上,以面不必要错误
  • 语句是可以嵌套的
  • 把多条语句组合到一个代码块中,用 {} 包括;而且在控制语句中使用代码块可以让编码意图更清晰,降低修改代码出错的概率。

注释

单行注释
    以//开头       
        //我被注释了
块级注释
    以/*开头,以*/结尾
    不可嵌套
        /*
         * 这是一个多行
         * (块级)注释
         */

基本类型

基本数据类型:Number String Boolean Null Undefined Object

Number

整数

  • 十进制 var intNum = 55; //整数

  • 八进制字面值第一位必须是零(0),然后八进制数字序列(0-7)). 如果字面值数值超出范围,前导零忽略,和面当做十进制解析

var octalNum1 = 070;        //八进制56
var octalNum2 = 079;        //无效的八进制数值---解析为79
var octalNum3 = 08;          //无效的八进制数值---解析为8
八进制字面量在严格模式下无效,会导致支持该模式的js引擎抛出错误
  • 十六进制字面量前两位必须是0x,后跟任何十六进制数字(0-9及A-F)
var hexNum1 = 0xA;        //十六进制的10
var hexNum2 =0x1f;        //十六进制31

所有以八进制和十六进制表示的数值都将被装换成十进制数值。

浮点数值

浮点数就是该数值中必须包含一个小数点.

保存浮点数值需要的内存空间是保存整数值的两倍所以,ECMAScript会不失时机的将浮点数值转换为整数值

var floatNum1 = 1.;        //小数点后面没有数字--解析为1
var floatNum2 = 10.0;        //整数--解析为10

对于极大或极小的数值,用科学计数法(e)表示,等于e前面的数值乘以10的指数次幂。

var floatNum =3.125e7;        //等于31250000

浮点的最高精度是17位小数。 

数值范围

Infinitiy(正无穷) -Infinnity(负无穷)

  • 确定一个数值是不是有穷的(是不是位于最大与最小之间),可
    以使用 isFinite() 函数,位于其中,返回true。
var result = Number.Max_VALUE + Number.Max_VALUE;
alert(isFinite(result));        //false

NaN

NaN即非数值(Not a Number)是一个特殊的数值,表示一个本来要返回数值的操作数未返回数值的情况

  1. 任何涉及NaN的操作都会返回NaN
  2. NaN与任何值都不相等,包括NAN本身
alert(NaN == NaN);        //false

定义了isNaN()的函数,函数接受一个参数,该参数可以使任何类型,帮我们确定这个参数是否不是数值

alert(isNaN(NaN));        //true
alert(isNaN(10));        //false(10是一个整数)
alert(isNaN(“10”));        //false(可以被转换成10)
alert(isNaN(“blue”));        //false(不能转换成数值)
alert(isNaN(“true”));        //false(可以被转换成1)

数值转换

有三个函数可以把非数值转换为数值:Number() parseInt() parseFloat()

  1. Number()函数转换规则
    • 如果是Boolean值,true和false将分别被转换为1和0
    • 如果是数字值,简单的传入和返回
    • 如果是null值,返回0
    • 如果是undefined,返回NaN
    • 如果是字符串,遵循以下:
      • 如果字符串中只包含数字(包括前面带正号和负号),将其转换为十进制数值
      • 如果字符串中包含有效的浮点格式,则将其转换为对应的浮点数值
      • 如果字符串是空的(不包含任何字符),转换为0
      • 如果字符串中包含除上述格式之外的字符,则转换为NaN
    • 如果是对象,调用对象的valueOf()方法,按照前面的规则返回相应的值.如果结果是NaN,调用toString()方法,按照前面的返回字符串值
    var num1 = Number('Hello World')  //NaN
    var num2 = Number('')  //0
    var num3 = Number('000011')  //11
    var num4 = Number(true)  //1
    
  2. parseInt()函数转换
    • parseInt()函数在转化字符串时,更多的看是否符合数值模式
    • 它会忽略字符串前面的空格,直至找到第一个非空字符串.
    • 如果第一个字符不是数字字符或者负号,会返回NaN
    var number1 = parseInt('123456')//123456
    var number2 = parseInt('')    //NaN
    var number3 = parseInt('22.5')  //22
    var number4 = parseInt('070')  //56(八进制)
    
  3. parseFloat()函数转换规则
    • parseFloat()只解析十进制
    var number1 = parseFloat('1234blue')  //1234(整数)
    var number2 = parseFloat('22.5')  //22.5
    var number3 = parseFloat('22.34.5')  //22.34
    var number4 = parseFloat('0908.5')  //908.5
    

String

String即字符串类型,只要是被单引号(‘’)或者双引号(“”)引起来的类型就是String类型

var firstname = "Yangyumeng";
var lastNmae = '123';

字符串的特点

字符串是不可变的,字符串一旦创立,它们的值不能改变,要改变某个变量保存的字符串,首先销毁原来的字符串,然后在用另一个包含新值的字符串填充该变量

var lang = "Java"
lang = lang + "Script" 

转换成字符串

要把一个值转换成字符串有两种方式。第一种使用几乎所有值都有的toString()方法,返回的是相应值字符串的表现

var age = 11;
var ageAsString = age.toString();        // 字符串“11”

var found = true;
var foundAsString = found.toString();        // 字符串“true”

但是null、undefined值没有toString()方法。

一般情况下,调用toString()方法不必传参数,但在调用数值toString()方法时,可以传递一个参数:输出数值的基数。

var num = 10;
alert(num.toString());        //"10" 默认10进制
alert(num.toString(2));        //"1010"
alert(num.toString(8));        //"12"
alert(num.toString(16));        //"a"

在不知道转换的值是不是nullundefined,使用转型函数String(),这个函数能将任何值转换为字符串,String()遵循以下规则

  • 如果值有**toString()**方法,则调用该方法(没有参数)并返回相应结果
  • 如果值是null,则返回"null"
  • 如果值是undefined,则返回"undefined".

Boolean

Boolean类型只有两个字面值:true和false,虽然Boolean类型字面值只有两个,但ECMAScript中所有类型都有与这两个Boolean值等价的值。要将一个值转换为其对应的Boolean值,可以调用函数Boolean() 转换规则

数据类型 转换为true的值 转换为false的值
Boolean true false
String 任何非空字符串 ""(空字符串)
Number 任何非零数字值 0和NaN
Object 任何对象 null
Undefined n/a(不适用) undefined

Object

Object是一组数据和功能的集合,对象可以通过执行new操作符后跟要创建的对象类型的名称来创建

创建对象

var o = new Object();
Object类型所具有的任何属性和方法也同样存在于更具体的对象中
  • Object的每个实例都具有下列属性和方法:
    • constructor:保存着用于创建当前对象的函数,对前面而言,构造函数(constructor)就是Object()
    • hasOwnProperty:用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。其中,作为参数的属性(*propertyNmae*)必须以字符串形式指定(例:o.hasownProperty(“name”))。
    • isprototypeof(object):用于检查传入的对象是否是当前对象的原型
    • propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用for-in语句来枚举,参数的属性名必须是字符串。
    • toLocalString():返回对象的字符串表示,该字符串与执行环境的地区对应
    • toString():返回对象的字符串表示。
    • valueOf():返回对象的字符串、数值或布尔值表示。

Null

Null类型只有一个值:null

  • 表示对象不存在
var car = null; 

如果定义的变量准备在将来用于 保存对象 ,那么最好将该变量初始化为null而不是其他值。这样,只要检查null值可以知道相应的变量是否已经保存了一个对象的引用

if(car != null){
   //对car对象执行某种操作 
 }

Undefined

Undefined类型只有一个值:undefined。在使用var声明变量但为对其加以初始化时,变量值就是undefined

例如:
        var message;
        alert(message == undefined);        //true
  • 使用场景:
未初始化的值(已声明未赋值的变量)默认是undefined值
var a;
console.log(a);        //undefined

获取对象中不存在的属性
var obj = {a:1,b:2}
console.log(obj.c);        //undefined

类型识别

typeof操作符

var num;
typeof num;        //undefined

var num = 1;
typeof num;        //number

var num = "1";
typeof num;        //string

var flag = true;
typeof flag;        //boolean

var cat = null;
typeof cat;        //object

原始类型和引用类型

  • 原始类型
    • Number
    • String
    • Boolean
    • Null
    • Undefined
  • 引用类型
    • Object

原始类型和引用类型 区别

image.png

今天先把javascript的基本语法和六大基本类型做个了解,后面继续学习知识点,并做笔记

Git小应用

git是什么?

Git是一个“分布式版本管理工具”,简单的理解版本管理工具:大家在写东西的时候都用过“回撤”这个功能,但是回撤只能回撤几步,假如想要找回我三天之前的修改,光用“回撤”是找不回来的。而“版本管理工具”能记录每次的修改,只要提交到版本仓库,你就可以找到之前任何时刻的状态(文本状态)。

Git小白教程入门

一步步走进git的世界,学习命令

  • 先理解几个概念:
    • 工作区:改动(增删文件和内容)
    • 暂存区:输入命令:git add 改动的文件名,此次改动就放到了‘暂存区’
    • 本地仓库(简称:本地):输入命令:git commit 此次修改的描述,此次改动就放到了’本地仓库’,每个commit,我叫它为一个‘版本’。
    • 远程仓库(简称:远程):输入命令:git push 远程仓库,此次改动就放到了‘远程仓库’(GitHub等)
    • commit-id:输出命令:git log,最上面那行commit xxxxxx,后面的字符串就是commit-id

ES6快速使用

Babel-webpack的配置

前段项目我想使用ES6的语法我应该怎么做呢?我们可以查看Babel的官方文档,就简单用webpack如何配置
所以我们就可以先用ES6语言来写代码,然后用webpack打包生成ES5的文件,下面只是简单介绍一下,详细的可以查看官方文档,当然了这只是一种工具,我们只需要看官网怎么做的就可以

1. Shell
npm install --save-dev babel-loader babel-core

2. webpack.config.js
module: {
  rules: [
    { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }
  ]
}

3. create .babelrc
npm install babel-preset-env --save-dev
//JSON
{
  "presets": ["env"]
}

var let const

  • var 可声明前置
var a
a = 1
var a = 2

ES6 新增了let命令,用来声明变量。它的用法类似于var,但也有区别:

  • let 不存在变量提升
console.log(bar); // 报错ReferenceError
let bar = 2;

a = 1  //报错
let a
  • let不允许在相同作用域内,重复声明同一个变量。
// 报错
function func() {
  let a = 10;
  var a = 1;
}

// 报错
function func() {
  let a = 10;
  let a = 1;
}

let a = 3
var a =4  //报错
let a =5  //报错
  • 存在块级作用域
for(let i =0;i<3;i++){
  console.log(i)
}
console.log(i)  //报错

块级作用域的出现,实际上使得获得广泛应用的立即执行函数表达式(IIFE)不再必要了。

(function(){
  var a = 1
})()

==>

{
  let a = 1
}

ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。

  1. 内层变量可能会覆盖外层变量。
var tmp = new Date();

function f() {
  console.log(tmp);
  if (false) {
    var tmp = 'hello world';  // var tmp 变量提升
  }
}

f(); // undefined
  1. 用来计数的循环变量泄露为全局变量。
var s = 'hello';

for (var i = 0; i < s.length; i++) {
  console.log(s[i]);  // i泄露为全局变量
}

console.log(i); // 5
  • 暂时性死区(TDZ)
var tmp = 123;

if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}

只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。

  • const

const声明一个只读的常量。一旦声明,常量的值就不能改变。
const一旦声明变量,就必须立即初始化,不能留到以后赋值。

//基本类型
const PI = 3.1415;
PI // 3.1415
PI = 3;  // TypeError: Assignment to constant variable.

//引用类型
const foo = {};
// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop // 123
// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only

适用let的也适用const


解构赋值

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

  • 数组的解构赋值
let [a,b,c] = [1,2,3]
console.log(a,b,c)  // 1 2 3

let [a, [b], c] = [1, [2], 3]
a // 1
b // 2
c // 3

let [x, , y] = [1, 2, 3] // x=1  y=3

let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]

如果解构不成功,变量的值就等于undefined。

let [foo] = [];
let [bar, foo] = [1];
// 报错
let [foo] = 1;

默认值
解构赋值允许指定默认值。
数组对应值有没有?如果没有(没有指undefined),使用默认值,有就使用对应值

let [foo = true] = [];
foo // true

let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'

let [a=2,b=3] = [undefined, null]
a  //2
b  //null
  • 对象的解构赋值
    实际上说明,对象的解构赋值是下面形式的简写
let { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };
let { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"

对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

let { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"

let { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined  没有同名的

对象解构的默认值
默认值生效的条件是,对象的属性值严格等于undefined。

var {x = 3} = {};
x // 3

var {x, y = 5} = {x: 1};
x // 1
y // 5

var {x: y = 3} = {};
y // 3

var {x: y = 3} = {x: 5};
y // 5

var { message: msg = 'Something went wrong' } = {};
msg // "Something went wrong"
  • 字符串的解构赋值
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。

let {length : len} = 'hello';
len // 5
  • 数值和布尔值的解构赋值

解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。

let {toString: s} = 123;
s === Number.prototype.toString // true

let {toString: s} = true;
s === Boolean.prototype.toString // true

解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。

let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError
  • 函数参数的解构赋值
function add([x, y] = [1,1]){
  return x + y;
}
add()  // 2
add([2])  // 3 
add([1, 2]); // 3

function sum({x,y} = {x:0, y:0},{a=1,b=1}){
  return [x+a,y+b]
}
console.log(sum({x:1,y:2},{a:2}))  //[3,3]
  • 解构赋值的作用
  1. 交换变量的值
let x = 1;
let y = 2;

[x, y] = [y, x];  // [2,1]
  1. 函数参数默认值
function ajax(url , type='GET'){
  
}
ajax(url:'http://localhost')

字符串常用

  • 字符串模板
// ES5字符串拼接
$('#result').append(
  'There are <b>' + basket.count + '</b> ' +
  'items in your basket, ' +
  '<em>' + basket.onSale +
  '</em> are on sale!'
);

模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。

$('#result').append(`
  There are <b>${basket.count}</b> items
   in your basket, <em>${basket.onSale}</em>
  are on sale!
`);

模板字符串中嵌入变量,需要将变量名写在${}之中

function authorize(user, action) {
  if (!user.hasPrivilege(action)) {
    throw new Error(
      // 传统写法为
      // 'User '
      // + user.name
      // + ' is not authorized to do '
      // + action
      // + '.'
      `User ${user.name} is not authorized to do ${action}.`);
  }
}

数组扩展常用

  • 扩展运算符
    扩展运算符(spread)是三个点(...)
var a = [1,2]
console.log(...a)  // 1,2
var b = [...a,3]
b  // [1,2,3]

function add(x, y) {
  return x + y;
}
const numbers = [4, 38];
add(...numbers) // 42
... 应用替代apply用法
// ES5 的写法
Math.max.apply(null, [14, 3, 77])
// ES6 的写法
Math.max(...[14, 3, 77])

// ES5的 写法
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
Array.prototype.push.apply(arr1, arr2);
// ES6 的写法
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
arr1.push(...arr2);

函数参数的扩展
function sort(...arr){
  console.log(arr.sort())
}
sort(3,1,5)  //[1,3,5]
  • Array.form()
    • Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。
// NodeList对象
let ps = document.querySelectorAll('p');
Array.from(ps).forEach(function (p) {
  console.log(p);
});

// arguments对象
function foo() {
  var args = Array.from(arguments);
  // ...
}
//  类数组对象
let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
};
// ES5的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']

// ES6的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']

函数扩展

  • 可以给参数添加默认值
function log(x, y = 'World') {
  console.log(x, y);
}
log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello
//练习,区别?
// 写法一
function m1({x = 0, y = 0} = {}) {
  return [x, y];
}
// 写法二
function m2({x, y} = { x: 0, y: 0 }) {
  return [x, y];
}


// 函数没有参数的情况
m1() // [0, 0]
m2() // [0, 0]

// x 和 y 都有值的情况
m1({x: 3, y: 8}) // [3, 8]
m2({x: 3, y: 8}) // [3, 8]

// x 有值,y 无值的情况
m1({x: 3}) // [3, 0]
m2({x: 3}) // [3, undefined]

// x 和 y 都无值的情况
m1({}) // [0, 0];
m2({}) // [undefined, undefined]

m1({z: 3}) // [0, 0]
m2({z: 3}) // [undefined, undefined]

//总结
ex1: 调用函数需要你传递一个对象,如果你没传对象就用默认值对象{},默认值对象里面都是 undefined, 所以属性使用初始值

ex2:参数需要是一个对象,如果没传对象,就用默认值对象{ x: 0, y: 0 }如果传了对象,就使用你传递的对象
  • 箭头函数
    • ES6 允许使用“箭头”(=>)定义函数。
var f = v => v;
//等价于
var f = function(v) {
  return v;
};

var f = () => 5;
// 等同于
var f = function () { return 5 };

var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
  return num1 + num2;
};

如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。

var sum = (num1, num2) => { return num1 + num2; }
  • 箭头函数的this

函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。this对象的指向是可变的,但是在箭头函数中,它是固定的。

function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

foo.call({ id: 42 });
// id: 42

setTimeout的参数是一个箭头函数,这个箭头函数的定义生效是在foo函数生成时,而它的真正执行要等到 100 毫秒后。如果是普通函数,执行时this应该指向全局对象window,这时应该输出21。但是,箭头函数导致this总是指向函数定义生效时所在的对象(本例是{id: 42}),所以输出的是42

对象扩展

  • 属性的简洁表示法
    ES6 允许直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。
const foo = 'bar';
const baz = {foo};
baz // {foo: "bar"}

// 等同于
const baz = {foo: foo};
function f(x, y) {
  return {x, y};
}
// 等同于
function f(x, y) {
  return {x: x, y: y};
}
f(1, 2) // Object {x: 1, y: 2}
//方法简写
const o = {
  method() {
    return "Hello!";
  }
};

// 等同于

const o = {
  method: function() {
    return "Hello!";
  }
};

Module的语法 模块化

模块功能主要由两个命令构成:export和importexport命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。

一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量。下面是一个 JS 文件,里面使用export命令输出变量。

// profile.js
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;

// profile.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
export {firstName, lastName, year};

//usage.js
import {firstName, lastName, year} from './profile';

export命令除了输出变量,还可以输出函数或类(class)。

export function multiply(x, y) {
  return x * y;
};
  • export default 命令
    使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载,为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。
// export-default.js
export default function () {
  console.log('foo');
}

其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。

// import-default.js
import customName from './export-default';
customName(); // 'foo'

Class和继承

ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以
做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。上面的代码用 ES6 的class改写,就是下面这样。

//定义类
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

//等价于

function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};

var p = new Point(1, 2);

ES6 的类,完全可以看作构造函数的另一种写法。

class Point {
  // ...
}

typeof Point // "function"
Point === Point.prototype.constructor // true

构造函数的prototype属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面。

class Point {
  constructor() {
    // ...
  }

  toString() {
    // ...
  }

  toValue() {
    // ...
  }
}

// 等同于

Point.prototype = {
  constructor() {},
  toString() {},
  toValue() {},
};

constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。

class Point {
}

// 等同于
class Point {
  constructor() {}
}
  • Class静态方法
    类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
class Foo {  //类
  static classMethod() {
    return 'hello';
  }
}

Foo.classMethod() // 'hello'

var foo = new Foo();
foo.classMethod()
// TypeError: foo.classMethod is not a function

上面代码中,Foo类的classMethod方法前有static关键字,表明该方法是一个静态方法,可以直接在Foo类上调用(Foo.classMethod()),而不是在Foo类的实例上调用。如果在实例上调用静态方法,会抛出一个错误,表示不存在该方法。

  • 继承
    Class 可以通过**extends**关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。
class Point {
}

class ColorPoint extends Point {
}

super 关键字

super这个关键字,既可以当作函数使用,也可以当作对象使用。在这两种情况下,它的用法完全不同。

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  sayHello() {
    console.log( `hello, ${this.name}, i am ${this.age} years old`);
  }
}
class Student extends Person {
  constructor(name, age, score) {
    super(name, age); 
    this.score = score;
  }

  sayScore() {
     console.log(  `hello, ${this.name}, i am ${this.age} years old, i get ${this.score}`);
  }
}

详解float

浮动的定义

一个浮动盒会向左或向右移动,直到其外边(outer edge)挨到包含块边沿或者另一个浮动盒的外边。如果存在行盒,浮动盒的外top(边)会与当前行盒的top(边)对齐 如果没有足够的水平空间来浮动,它会向下移动,直到空间合适或者不会再出现其它浮动了

因为浮动(盒)不在普通流内,在浮动盒之前或者之后创建的未定位的(non-positioned)块盒会竖直排列,就像浮动不存在一样。然而,接着(next to)浮动(盒)创建的当前及后续行盒会进行必要的缩短,为了给浮动(盒)的margin box让出空间

W3.org MDN


我们看几个例子,来理解上面你的定义

  • 我们看一下浮动出现的根源:

float的作用

浮动布局希望布局仅仅是盒模型上下排版,还需要左右排版,于是出现了float


  • 例2:放不下换行(看一下定义)

一个浮动盒会向左或向右移动,直到其外边(outer edge)挨到包含块边沿或者另一个浮动盒的外边。

float


  • 高度不同,被卡住

如果存在行盒,浮动盒的外top(边)会与当前行盒的top(边)对齐 如果没有足够的水平空间来浮动,它会向下移动,直到空间合适或者不会再出现其它浮动了

高度不同时


  • 文本被缩短下移动(文本遇见浮动元素)

因为浮动(盒)不在普通流内,在浮动盒之前或者之后创建的未定位的(non-positioned)块盒会竖直排列,就像浮动不存在一样。然而,接着(next to)浮动(盒)创建的当前及后续行盒会进行必要的缩短,为了给浮动(盒)的margin box让出空间

文本在文档流中


浮动产生的问题

  • 脱离普通流?!
    • 和position:absolute;不一样
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <style>
    .ct{
      width: 280px;
      height: 300px;
      border: 1px solid;
      margin: 100px;
    }

    .box{
      width: 100px;
      height: 100px;
      background: red;
    }
    .box1{
      background: blue;
      float: left;
      opacity: 0.6;
    }
    .box2{
      background: pink;
      height: 110px;
      width: 110px;
    }
</style>
</head>
<body>
<div class="ct">
  <div class="box box1">1</div>
  <div class="box box2">2块盒看不见浮动的 box1,但我是文本我能看见</div>

</div>

</body>
</html>

image

  • 块级元素浮动宽度收缩

image

image


浮动总结

语法:float : left | right | none(默认) | inherit

float基本特征:

  • 默认宽度为内容宽度
  • 脱离文档流(不占有原来的位置,后续元素会占有它的位置)
  • 向指定方向一直移动(不能移动为止)

float其他特征:

  • float元素在同一文档流中

  • float元素半脱离文档流

image

对元素,脱离文档流; 对内容,在文档流

  • 看一个demo

image


clear清除浮动

语法:clear: both | left | right | none | inherit

  • 应用于浮动元素的后续元素
  • 应用于块级元素

clear

  • 空白元素
  • clearfix
空白元素

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <style>
    .sample{
       float: left;
       width: 100px;
       line-height: 100px;
       text-align: center;
       background-color: pink;}
    .parent{
       padding: 5px 0;
       margin-bottom: 10px;
       outline: 1px dashed blue;
      }
    .sample{
       margin: auto 5px;
        }
    /* 清除浮动 */
    .cb{
      clear: both;
      height: 0;
      overflow: hidden;
      visibility: hidden;
    }

  </style>
</head>
<body>
  <div class="parent">
	  <div class="sample">
	  	float: left
	  </div>
	  <div class="sample">
	  	float: left
	  </div>
	  <div class="sample">
	  	float: left
	  </div>
    <!-- 空白符 -->
	 <br class="cb">
	</div>
</body>
</html>
clearfix

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>float obscure</title>
	<style>
		body{width: 400px;line-height: 1.6;}
		.sample{width: 100px;line-height: 100px;margin: 3px;text-align: center;background-color: pink;}
		.sb{margin: 10px auto;padding: 5px;border: 1px dashed #0f00fa;}

		.sample{float: left;}
         /*  清除浮动 */
		.clearfix:after{content:'.';display: block;clear: both;height: 0;overflow: hidden;visibility: hidden;}
		/* IE低版本 */
		.clearfix{zoom:1;}
			</style>
</head>
<body>
      <!-- 在父元素上增加了一个clearfix类 -->
	<div class="sb clearfix">
		<div class="sample">float: left;</div>
		第12届ChinaJoy动漫游戏展7月31日在上海新国际博览中心开幕,到处是站台表演的帅哥美女。
	</div>
	<div class="sb">
		有些游戏商为了吸引人气,还请来了著名的演员、模特前来助阵。以下是一批漂亮的Show Girl现场照片。
	</div>
</body>
</html>

由float弄一个简单的两列布局

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>两列布局</title>
	<style>
		html, body, .body, .main, .side{margin: 0;padding: 0;height: 100%;}
		.body{width: 960px;margin: 0 auto;}
		.main{background-color: pink;}
		.side{background-color: #eee;}

		.main{float: left;width: 660px;}
		.side{float: right;width: 300px;}
		.clearfix:after{content:'.';display: block;clear: both;height: 0;overflow: hidden;visibility: hidden;}
	</style>
</head>
<body>
	<div class="body clearfix">
		<div class="main">main</div>
		<div class="side">side</div>
	</div>
</body>
</html>

这是我理解的float

js小知识点串讲

变量的生命周期

  • 看几个小例子
//问题一: a什么时候被赋值,或者a什么时候出现在内存中?什么时候消失?

<script>
  var a = 1  //当代码执行到这一行时才有1
  // => window.a = 1   所以当页面关闭时a消失,或者刷新又有了新的a
</script>
//问题二:  a什么时候被赋值,或者a什么时候出现在内存中?什么时候消失?

<script>
  function fn(){
    var a = 1    //当函数调用后a才出现
  }
  //浏览器执行到这一行
  fn()  //执行完成以后a消失
  // fn() 重新调用,重新赋值a
</script>
//问题三: 如果a被引用者,a什么时候被赋值,或者a什么时候出现在内存中?什么时候消失?

<script>
  function fn(){
    var a = {name : 2}   //执行完不会消失,因为被引用,当window页面关闭,消失
    var b = 2  // 执行完就消失了,因为没有东西引用它
    window.f = a
  }
  fn()  
  console.log(window.f)  //1
  window.f = {name : 3}  //a没有被引用,消失
</script>

总结一下:

  • 默认作用域消失时,内存就被回收
  • 如果内存被引用着,则不能回收

var 作用域

  • 就近原则
  • 词法作用域
  • 同名的不同变量

一直觉得看例子最直接

//问题一: a=1,指的是哪个a

<script>
  var a
  function f1(){
    var a 
    function f2(){
      var a  //同一作用域级的a 就近原则
      a = 1
    }
  }
//函数同理
  function f2(){}
  function f1(){
    function f2(){
      f2()  //指向父级f2
    }
  }
</script>
<script>
//词法作用域 ,不同作用域的a是不同的变量
  var a
  function f1(){
    var a 
    function f2(){
      var a 
      f3()
      a = 1
    }
  }
  function f3(){
    a = 2 //指向第一个a
  }

立即执行函数

-想得到一个独立的作用域.声明一个函数

fucntion f1(){
  var a
  a = 1
  console.log(a)
}
f1()
=>
//但是我想不想要全局变量f1怎么办啊,改一下
function (){
  var a
  a = 1
}()   //语法会报错?怎么办呢
=>
(function (){
  var a
  a = 1
})()   
或者
!function (){
  var a
  a = 1
}()   //需要的是一个独立的作用域

函数前面可以加 + - ~ 都可以成为立即执行函数
//立即执行函数可以加参数
var a = 100
!function (a){  //形参声明的变量,值是第一个参数
  var a = arguments[0]
  var a
  a = 1
console.log(a)   //1
}(/*没有参数*/)
console.log(a)  //100 

var a = 100
!function (a){
  console.log(a)  //99 新的作用域
}(99)
//问题: 实参a 和形参a 是同一个a 吗?
var a = 100
!function (a){  //新声明的a,只是恰好名字相同,a可以是b,c,i,h不同的名字
  console.log(a) //100 赋值时var a =100
}(a)  //这个a是var a = 100

变量(声明)提升

  • 浏览器在执行代码之前,会先把所有声明提升到作用域的顶部
  • 你却从来不知道去提升一下变量
  • 只要你提升变量,面试题就是小 case

就喜欢例子

// 问题: a 的值是多少
var a = 100
function a(){}
==>
var a
function a(){}
a = 100
console.log(a)  // 100
//问题: a 的值是什么
var a = 100
var a = function (){}
function a(){}

console.log(a)
// 以下代码执行时,三次打印分别输出什么?为什么?手动提升作用域
 
function add1(i){
  console.log("函数声明:"+(i+1));
}
add1(1);  // 101
 
var add1 = function(i){
  console.log("函数表达式:"+(i+10));
}
add1(1);  // 11
 
function add1(i) {
    console.log("函数声明:"+(i+100));
}
add1(1);  // 11

时机(异步)

button.onclick = function(){
  console.log("A") //当用户操作,才打印
}
console.log("B")  //先打印

还有setTimeout

复习了上面那么多只是,就是为了做一些面试题目:

<ul>
  <li>选项1</li>
  <li>选项2</li>
  <li>选项3</li>
  <li>选项4</li>
  <li>选项5</li>
  <li>选项6</li>
</ul>

var items = document.querySelectorAll('li')

for(var i=0; i<items.length; i++){
   items[i].onclick = function(){
     console.log(i)  //每次结果都是li的长度,为什么呢??
   }
}

==>
//提升一下变量,在观察
var items
var i
items = document.querySelectorAll('li')
for(i=0; i<items.length; i++){
  //i = 0,1,2,3,4,5,6
  items[i].onclick = function(){
    console.log(i)  //点击每一次打印都是6 怎么解决这个问题呢?
  }
}
console.log(i)  //6
var items
var i
items = document.querySelectorAll('li')
for(i=0; i<items.length; i++){
  //创建一个函数作用域
  var temp = function(j){
    console.log(j)
  }
  //把函数i作为参数传进去,得到的是6个不同的值
  temp(i)   //i = 0,1,2,3,4,5

  items[i].onclick = function(){
    console.log(i)
  }
}

==> 再改一下
var items
var i
items = document.querySelectorAll('li')
for(i=0; i<items.length; i++){
  //创建一个函数作用域
  var temp = function(j){
    // j1 = 0, j2 = 1 ...
    console.log(j)
    items[j].onclick = function(){
      // 每点击一次,出现的值不同
      console.log(j)
    }
  }
  //把函数i作为参数传进去
  temp(i) 
}

==>

var items
var i
items = document.querySelectorAll('li')
for(i=0; i<items.length; i++){
  //立即执行函数
 !function(j){
    items[j].onclick = function(){
      // 每点击一次,出现的值不同
      console.log(j)
    }
  //i作为参数传进去
  }(i)
}

另一种方法

//修改一下上面
var items
var i
items = document.querySelectorAll('li')
for(i=0; i<items.length; i++){
  function temp(j){
    //return一个函数
    return function(){
      console.log(j)
    }
  }
  var fn = temp(i)  //创建一个新的作用域
  items[i].onclick = fn  //等于一个函数
}

==>

var items
var i
items = document.querySelectorAll('li')
for(i=0; i<items.length; i++){
  items[i].onclick = function(i){
    //return一个函数
    return function(){
      console.log(i)
    }
  }(i)
}

又一个题目

var fnArr = [];
for (var i = 0; i < 10; i ++) {
  fnArr[i] =  function(){
    return i
  };
}
//var fn = fnArr[3]
//fn()  调用时才有i,先执行for循环

console.log( fnArr[3]() ) // 10,怎么输出1,2,3...,9
var fnArr = []
for (var i = 0; i < 10; i ++) {
  fnArr[i] =  (function(j){
    return function(){
      return j
    } 
  })(i)
}
console.log( fnArr[3]() ) // 3

var fnArr = []
for (var i = 0; i < 10; i ++) {
  (function(i){
    fnArr[i] =  function(){
      return i
    } 
  })(i)
}
console.log( fnArr[3]() ) // 3

//使用ES6语法let,创建一个作用域
var fnArr = []
for (let i = 0; i < 10; i ++) {
  fnArr[i] =  function(){
    return i
  } 
}
console.log( fnArr[3]() ) // 3

我们做了两个面试题目,发现在ES5中使用立即执行函数就可以打印出我们需要的东西

  • 立即执行函数创造了新的作用域
  • 造成上面的原因是闭包
  • 闭包作用暴露局部变量

webpack简介

webpack 是一个现代 JavaScript 应用程序的模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

我们为什么要学习webpack呢?它的动机是什么?

现在的网站都向webapp进化:

  • 页面中使用越来越多的js
  • 现在浏览器提供更多接口
  • 更少的页面重载刷新,页面中有更多的代码
  • 导致浏览器端存在大量的代码。

大量代码需要被重新组织,于是出现了模块系统,用来代码分割成模块。


在有webpack之前,我们都是使用那些模块系统呢?

  • <script>标签风格
  • Commonjs
  • AMD规范以及对应实现
  • ES6模块
  • 其他

<script>标签风格

如果没有使用模块系统,我们一般都是用<Script>标签引入js

<script src="module1.js"></script>
<script src="module2.js"></script>
<script src="libraryA.js"></script>
<script src="module3.js"></script>

存在的问题:

  • 全局对象的冲突
  • 加载的顺序是重要的
  • 开发者需要解决模块的依赖问题
  • 在大项目中引入的数目将会非常长且难以维护

Commonjs:同步的require

这种风格使用同步的require方法来加载依赖和返回暴露的接口。一个模块可以通过给exports对象添加属性,或者设置module.exports的值来描述暴露对象。

require("module");
require("../file.js");
exports.doStuff = function() {};
module.exports = someValue;

存在的问题以及优缺点:

优点:

  • 服务端代码可以被重写
  • npm中有大量模块
  • 用起来简单方便

缺点:

  • 阻塞调用无法再网络环境中应用,网络请求是异步的
  • 不能并行require多个模块

AMD: 异步的require

其他一些模块系统(针对浏览器)对同步的require(CommonJS 规范)有问题,于是引出了异步的版本(以及一种定义模块和导出值的方式)

require(["module", "../file"], function(module, file) { /* ... */ });
define("mymodule", ["dep1", "dep2"], function(d1, d2) {
  return someExportedValue;
});

优点:

  • 符合在网络中异步请求的风格
  • 可以并行加载多个模块

缺点:

  • 编码成本增加,可读性不好写起来麻烦
  • 更像是一种临时修补方案

ES6模块

CMAScript 2015 (6th Edition) 给 JavaScript添加了一些语法结构,用来实现另外一种模块系统

import "jquery";
export function doStuff() {}
module "localModule" {}

优点:

  • 静态分析方便
  • 作为ES的标准前途是光明

缺点:

  • 浏览器支持还需要很长时间
  • 这种风格的模块不多

无偏见的解决方案

开发者可以选择自己的模块风格,现存的代码库和包能正常工作,添加定制的模块风格也很方便。


但是上面的都不是最佳方案:

  • 一个模块对应一个请求
    • 优点:只有需要的模块被传输
    • 缺点:多个请求意味着更多的额外的开销
    • 缺点:请求的延迟导致你的应用启动很慢
  • 一个请求包含所有模块
    • 优点:更少的请求开销,更少的延迟
    • 缺点:不需要的模块也会被传输

除了JavaScript 能模块化,其它资源行不行?

  • 不仅 JavaScript 需要模块化,许多其他的资源同样需要被处理:
    • stylesheets
    • images
    • webfonts
    • html模板
    • 等等
  • 或者需要被编译:
    • coffeescript -> javascript
    • elm -> javascript
    • less -> css
    • jade templates -> 生成html的js
    • i118n 文件 -> something
    • 等等

所以我们就需要更加强大的工具webpack

webpack中文文档

安装

建议本地安装
npm install --save-dev webpack

CSS语法

什么是 CSS?

  • CSS 指层叠样式表 (Cascading Style Sheets)
  • 样式定义如何显示 HTML 元素
  • 样式通常存储在样式表中
  • 把样式添加到 HTML 4.0 中,是为了解决内容与表现分离的问题
  • 外部样式表可以极大提高工作效率
  • 外部样式表通常存储在 CSS 文件中
  • 多个样式定义可层叠为一

css如何引入

  • 外部样式表(推荐)
    • 通过<link>引入css
    • 通过 @import 引入样式,放入 css 中
<head>
  <meta charset="UTF-8" />
  <title>CSS</title>
  <link rel="stylesheet" href="index.css">
</head>

<style>
@import url("index.css");
@import url('index.css');
@import url(index.css);
@import 'custom.css';
@import "common.css";
@import url('landscape.css') screen and (orientation:landscape);
</style>
  • 内部样式表
    • 将 CSS 放在页面的 <style>元素中。
 <style>
    h1 { background: orange; }
 </style>
  • 内嵌样式(不推荐)
<p style="background: orange; font-size: 24px;">CSS 很 👍<p>

css语法

selector{
	property1:value;
	property2:value;
	....
}
选择器
属性声明 = 属性名:属性值
注释  /*  */


浏览器私有属性

  • chrome safari
    • -weikit -
  • firefox
    • -moz-
  • IE
    • -ms-
  • opera
    • -o-

为了兼容不同的浏览器,我们需要用到这些私有属性

.pic{
	-weikit-transform:rotate(45deg);
	-moz-transform:rotate(45deg);
	-ms-transform:rotate(45deg);
	-o-transform:rotate(45deg);
	transform:rotate(45deg);
}

属性值语法

例:
margin:[<length>|<percentage>|auto]{1,4}
基本元素      组合符号             数量符号
组合符号
  1. 组合符号 - 空格
  • <'font-size'> <'font-family'>空格隔开的两个基本属性
    • 必须出现,顺序不能错
    • 合法值: 12px arial
    • 不合法值: 2em 或者 arial 14px
  1. 组合符号 - &&
  • <length>&&<color> &&连接的基本属性
    • 必须出现但顺序没有关系
    • 合法值:green 2px 或者 10px red
  1. 组合符号 - ||
  • underline || overline || line-through || bink
    • 至少出现一个,顺序无关
    • 合法值: underline 或者 overline underline
  1. 组合符号 - |
  • <color> | transparent
    • 只能出现一个
    • 合法值 orange 或者 transparent
  1. 组合符号 - []
  • bold [ thin || <length>]
    • 主要是分组的作用, []里可以看做一个整体,再和外面属性计算
    • 合法值: bold thin 或者 bold 2em
数量符号
  1. 数量符号 -
  • <length>
    • 基本元素只能出现一次
    • 合法值:1px
  1. 数量符号 - +
  • <color-stop> [,<color-stop>]+
    • +加号可以出现一次或者多次
    • 合法值:#fff , red或者blue, green 50%,gray
  1. 数量符号 - ?
  • insert?&&<color>
    • ?可以出现也可以不出现
    • 合法值:red 或者insert blue
  1. 数量符号 - {}
  • <length>{2,4}
    • 最少出现几次,最多出现几次,上例说最少出现2次,最多4次
  1. 数量符号 - *
  • <time> [.<time>]*
    • *表示可以出现0次,1次或者多次
  1. 数量符号 - #
  • <time>#
    • 出现一次或多次,中间用逗号隔开
    • 合法值: 2s,4s
属性值例子
padding-top:<length>|<percentage>
  padding-top:1px;
  padding-top:1em 5%;  (错)
border-width:[<length> |thick|medium|thin]{1,4} 
  border-width:2px;
  border-width:2px small;   (错)
box-shadow:[inset? &&[<length>{2,4}&&<dolor>?]]#|none
  box-shadow:3px 3px rgb(50%,50%,50%),red 0 0 4px inset; 
  box-shadow:inset 2px 4px,2px blue;    (错)

@规则语法
  • @ 标识符 xxx;
  • @ 标识符 xxx {};
  1. @media 做一些响应式布局,媒体查询条件
  2. @keyframes描述css动画的中间步骤
  3. @font-face引入外部字体
  4. @charset
  5. @import
  6. @support
  7. @document

参考:

css语法

HTTP,Ajax实践

在了解ajax之前,我们先粗略的了解一下http协议

HTTP协议

http事务

  • 一个完整的http请求是怎样的呢?
    1. 浏览器端会向服务器端发送一个包含命令和url的http请求报文
    2. 服务器端接收到请求,会进行一系列的计算,向浏览器返回一个包含事务结果的http响应报文

请求报文格式

格式

  • 第一部分
    • get:http方法
    • music.com主机地址
    • http/1.1http版本
  • 第二部分
    • Accept:浏览器接收的媒体类型
    • Accept-Encoding:浏览器接收的媒体类型的编码方式
    • Accept-Language浏览器端接收的语言方式
    • Cache-Control:缓存策略
    • Cookie:发送cookie值
    • User- Agent浏览器的版本
  • Get方法请求体为空

响应报文格式

响应格式
常用HTTP方法

方法 描述 是否包含主体
GET 从服务器获取一份文档
POST 向服务器发送需要处理的数据
PUT 将请求的主体部分存储在服务器上
DELETE 从服务器删除一份文档

URL构成

url

常见http状态码

状态码


ajax 是什么?有什么作用?

  • Ajax(Asynchronous JavaScript and Xml)
    • 能够向服务器请求额外的数据而无需卸载整个页面,会带来良好的用户体验
    • Ajax是一种技术的泛称,可以和后端交换数据,不用刷新页面

优点:

  • 更新数据而不需要刷新页面: 它能在不刷新整个页面的前提下与服务器通信维护数据,由于ajax是按照需求请求数据,避免发送那些没有改变的数据。
  • 异步通信: 它与服务器使用异步的方式通信,不会打断用户的操作(卡死页面)。
  • 前后端负载平衡: 可以将后端服务器的一些工作转移给客户端,利用客户端限制的能力来处理,减轻了服务器的负担。
  • 数据与呈现分离: 利于分工,降低前后耦合。

缺点:

  • 浏览器历史记录的遗失: 在使用AJAX对页面进行改变后,由于并没有刷新页面,没有改变页面的访问历史,当用户想要回到上一个状态时,无法使用浏览器提供的后退。
  • AJAX的安全问题: AJAX的出现就像建立起了一直通服务器的另一条通道,容易遭受到一些攻击。

一个ajax调用示例

ajax API

  • open开启一个请求
xhr.open('method',url[,async = true])

参数:
method:  //  GET/POST/DELETE/HEAD...
url:  // 我要请求的资源相对当前文档的路径
默认为true异步求情  :  //false同步
  • setRequestHeader(非必须)
xhr.setRequestHeader(header,value)
参数:
header:  //Content-type
  • send正式向服务端发请求
xhr.send([data = null])

我们注意到前面的url都是相对当前文档的相对路径,是受ajax的同源策略影响的

  • 什么是同源策略呢?

两个页面拥有相同的协议(protocol),端口(port),主机(host),那么这两个页面你属于同一个源(origin)

  • 不是同一个地址,我们就需要跨域资源访问
    • 跨域后面再说

可参考:跨域Frame代理


前后端开发联调需要注意哪些事情?后端接口完成前如何 mock 数据?

  1. 前后端联调是一种 真实业务数据和 本地mock数据之间来回切换以达到前后端分离架构下的不同开发速度时数据交换的一种方式方法,需要注意
  • 接口是get还是post
  • 接口的名字
  • 参数是什么?我发给后端的参数
  • 我要的是什么?后端发送给我,服务器?端口?方法?请求数据的一些限制?
  1. mock数据
  • 使用 nodejs 搭建服务器
  • anywhere
  • server-mock
    mock数据

点击按钮,使用 ajax 获取数据,如何在数据到来之前防止重复点击?

//弄一个状态锁
var AjaxLock = false;
//事件触发下面代码
// ******start*****
if (!AjaxLock){
	AjaxLock = true;
	xhr.onreadystatechange = function(){
		if( xhr.readyState == 4) {
			//do sth
			AjaxLock = false; 
			//当接受完毕请求数据后将锁打开
		}
	}
	//ajax配置
	xhr.send();
} else {
	return;
}

**题目4:**实现加载更多的功能,效果范例415后端在本地使用server-mock来模拟数据

加载更多

代码预览,需要开启mock-server数据

JS语句

条件语句

if 条件语句

语法: if ( condition ) statement1 else statement2
语法: if ( 条件 ) { 语句1 } else { 语句2 }

其中condition(条件)可以是任意表达式,求值结果不一定是布尔值,ECMAScript会自动调用Boolean()转换函数将结果转换为一个布尔值,如果结果是true,执行statement1;如果是false,执行statemen2,两个语句可以是代码,也可以代码块(以一对花括号括起来的多行代码),

demo1 :
if( i > 25 )
  alert ( " Greater than 25 . ");        //单行语句
else {
  alert ( " Less than  or equal to 25 .");        //代码块中的语句
}

demo2 :
var isMale = false;
  if(isMale){
    document.write('男');
  } else {
    document.write('女');  //上面是false,打印为女
  }

不过if语句也可以扩展为嵌套if

if(condition) statement1 else if (condition2) statement2 else statement3
if( 条件 ) { 语句1 } else if (条件2) { 语句2 } else { 语句3 }

demo:
var score = 85;
  if(score > 80){
    document.write('A');
  } else if(score > 60){
    document.write('B');
  } else {
    document.write('C');
  }

switch语句

switch语句if语句关系密切

语法:switch (expression) {  //表达式
           case value : statement  //值1:语句
               break;  //跳出
           case value : statement
               break;
           case value : statement
               break;
           case value : statement
               break;
           default : statement
       }

demo:
var degree = 'A';
  switch(degree){
    case 'A':
      document.write('优秀');
      break;
    case 'B':
      document.write('良好');
      break;
    default:
      document.write('合格');
  }

switch语句中每一个情形(case)的含义:"如果表达式等于这个值(value),则执行后面的语句(statement)".而break关键字会导致代码执行流跳出switch语句.如果省略break,会导致执行完当前case,继续执行下一个case.default关键字用于在表达式不匹配前面任何一种情况时候,执行机动代码.


循环语句

do-while 循环语句

do-while 语句是一种后测试循环语句,即在对表达式求值之前,循环体内的代码至少会被执行一次.

语法:  do {
          statement
       } while ( expression )

var i = 11 ;
do {
    document.write(i);
    i++;
} while ( i <= 10 )    //11

while 循环语句

while语句属于前测试循环语句,在循环体内的代码被执行之前,就会对出口条件求值,循环体内的代码可能永远不会被执行.

语法: while ( expression ) statement
      while( 表达式 ){ 语句 }
示例:
var i = 1 ;
while ( i <= 10 ) {
   document.write(i);
   i++;
}    //12345678910

for循环语句

for语句也是一种前测试循环语句,但它具有在执行循环之前初始化变量和定义循环后要执行的代码

语法:for( initialization; expression; post-loop-expression)statement
     for(初始化; 循环条件; 更新表达式){语句}    //中文解释
示例:
var count = 10 ;
  for(var i = 0; i<count; i++){
  alert(i);
}

另外,for语句中的初始化表达式 控制表达式 循环后表达式都是可选的,这三个表达式全部省略,就会创建一个无限循环,

for( ; ;){        //无限循环
  dosomething();
}

break和continue语句

break和continue语句用于循环中准确控制代码的执行.其中,break语句会立即退出循环,强制执行循环后面的语句.而continue语句虽然也是立即退出循环,但退出循环后会从循环的顶部继续执行.

var num = 0 ;
for(var i =0; i<10; i++){
  if(i%5 == 0) {
    break;
  }
  num++;
}
alert(num);    //4

结果4是次数,break语句的执行,导致了循环在num再次递增之前就退出了了.(跳出整个循环体)

var num = 0 ;
for(var i =0; i<10; i++){
  if(i%5 == 0) {
    continue;
  }
  num++;
}
alert(num);    //8

结果为8,说明执行了8次,当变量i=5时,循环会在num再次递增之前退出,但接下来执行下一次循环,即i=6的循环,于是,循环再次执行了(跳出一次循环体)


for - in语句

for-in语句是一种精准的迭代语句,可以用来枚举对象的属性.

语法:for(property in expression) statement
     for(属性名 in 对象) {语句}     //中文解释
示例:
var cat = {
  name:'kitty',
  age:2,
  mew : function () {
    console.log("喵喵喵")
   }
}
如果我们想把上面的对象的属性名都打印出来,可以用for-in语句:
for(var p in cat){
  document.write(p);
}        //name age mew

如果表示要迭代的对象的变量值为null和undefined,for-in会抛出错误,不过ECMAScript5更改了这一行为,不在抛出错误,只是不执行循环体,,所以建议使用for-in之前,确认对象的值是不是null或undefined


with语句

with语句的作用是将代码的作用域设置到一个特定的对象中.

语法:with(expression) statement
     with(表达式) {语句}     //中文解释

with语句

定义with语句的目的是为了简化多次编写同一个对象的工作,严格模式下不允许使用with语句

由于大量使用with语句会导致性能下降,同时也会给调试代码造成困难,因此开发大型应用程序时,不建议使用with语句


异常捕获语句

try{
  语句
} catch (exception){
  语句
} finally{
  语句
}
demo:
 try{
    document.write(notDefined);
  }catch(error){
    console.log(error);
    alert(error);
  }finally{
    alert('finally');
  }  //notDefined变量未定义的,是错误的,会执行catch里面的语句.

如果try里语句执行出错的话,会到catch语句中在语句中可以对错误执行一些操作,不管try语句是否出错,都会执行finally语句.一般用于我们执行的代码不知道它是否出错,把它放到try catch语句中


语句的学习很简单,难得是实际应用,所以多练

正则表达式总结

什么是正则表达式

  • 正则表达式(Regular Expression)是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。

正则表达式

  • 描述字符串规则的表达式
    • 直接量
      • /12345/
      • /yym/i
    • var reg = new RegExp
  • RegExp实例对象有五个属性
    • g:global:是否全局搜索,默认是false
    • i:ignoreCase:是否大小写敏感,默认是false
    • m:multiline:多行搜索,默认值是false
    • lastIndex:是当前表达式模式首次匹配内容中最后一个字符的下一个位置,每次正则表达式成功匹配时,lastIndex属性值都会随之改变
    • source:正则表达式的文本字符串

regexObj.test(str)

  • 测试字符串参数中是否存正则表达式模式,如果存在则返回true,否则返回false
var reg = /\d+\.\d{1,2}$/g;

reg.test('123.45'); //true
reg.test('0.2'); //true

reg.test('a.34'); //false
reg.test('34.5678'); //false

/1352648/.test('1352648')  //true
/1352648/.test('13526478')  //false
/1352648/.test('x1352648y')  //true 为什么是true呢?
/^1352648$/.test('x1352648y')   //false

看一个示例:

//获取焦点
<input type="text" onblur="check(this)" onfocus="reset(this)">
<script>
	function check(mobileInput){
        //用户输入的值
		var value = mobileInput.value;
        //判断是否等于用户输入的值
		if(!/13566668888/.test(value)){
			mobileInput.style.borderColor = 'red';
		}
	}

	function reset(mobileInput){
		mobileInput.style.borderColor = '';
	}
</script>

锚点(边界)

  • 匹配一个位置
    • ^ : 起始位置
    • $ :结尾位置
    • \b :单词边界
    • \B :非单词边界
/^http:/.test("http://www.163.com")  //true
/^http:/.test("ahttp://www.163.com")  //false
/^http:/.test("ht//www.163.com")  //false
/\.jpg$/.test('a.jpg')  //true
/\.jpg$/.test('a.jpg abc')  //false
  //单词边界就是看起来像一个独立的单词
/\bis\b/.test('this')  //false is没有边界
/\bis\b/.test('that is yym')  //true is有单词边界
('that is yym').match(/\bis\b/)  //["is", index: 5, input: "that is yym"]
('this').match(/\bis\b/)  //null

question:
var str = 'header clearfix active header-fixed'
str.match(/(^|\s)header($|\s)/g)    //["header "]

看一个示例

<input type="text" id="mobile" onblur="check(this)" onfocus="reset(this)">
<script>
	function check(mobileInput){
		var value = mobileInput.value;
        //和上面示例的区别多了锚点^ $,测试开头和结尾
		if(!/^13566668888$/.test(value)){
			mobileInput.style.borderColor = 'red';
		}
	}

	function reset(mobileInput){
		mobileInput.style.borderColor = '';
	}
</script>

字符类

  • 匹配一类字符中的一个
    • [abc]: a或b或c
    • [0-9]: 一个数字
      • [^0-9]:非数字的一个字符,^写在[]表示非
    • [a-z]: 一个字母
    • . : 点号任一字符(换行除外)
  • 使用元字符[]来构建一个简单的类
/[0-9]/.test('123')  //true
/[0-9]/.test('123ab')  //true
/[0-9]/.test('abc')  //false
/[^0-9]/.test('abc')  //true
/[a-z]/.test("abc")  //true
/[a-z]/.test("123")  //false
/./.test("123abc")  //true
/./.test("%%$$&&**")  //true

学了字符类,我们看看我们上面你的例子怎么写

<input type="text" id="mobile" onblur="check(this)" onfocus="reset(this)">
<script>
	function check(mobileInput){
		var value = mobileInput.value;
        //这样我们就可以测试用户输入的任意数字了,但是是不是太多了?
		if(!/^1[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$/.test(value)){
			mobileInput.style.borderColor = 'red';
		}
	}

	function reset(mobileInput){
		mobileInput.style.borderColor = '';
	}
</script>

元字符

  • ^ $ .
字符 等价类 含义
\d [0-9] 数字字符
\D [^0-9] 非数字字符
\s [\t\n\x0B\f\r] 空白符
\S [^\t\n\x0B\f\r] 非空白符
\w [a-zA-Z_0-9] 单词字符,字母、数字下划线
\W [^a-zA-Z_0-9] 非单词字符
/\d/.test("123")  //true
/\d/.test("123abc")  //true
/\D/.test("123abc")  //true
/\D/.test("123")  //false
/\s/.test('\t')  //true
/\s/.test('   ')  //true
/\s/.test('123abc')  //false
/\S/.test('\t')  //false
/\S/.test('abc123')  //true
/\S/.test('$%^&')  //true
/\w/.test('$%^')  //false
/\w/.test('ABaz')  //true
/\w/.test('123')  //true
/\W/.test('123')  //false
/\W/.test('$%^')  //true

看上一个例子,又可以变成下面这样:

<input type="text" id="mobile" onblur="check(this)" onfocus="reset(this)">
<script>
	function check(mobileInput){
		var value = mobileInput.value;
        //用元字符/\d/来表示数字,简单了一些
		if(!/^1\d\d\d\d\d\d\d\d\d\d$/.test(value)){
			mobileInput.style.borderColor = 'red';
		}
	}

	function reset(mobileInput){
		mobileInput.style.borderColor = '';
	}
</script>

量词

  • 出现的次数
字符 含义
? 出现零次或一次(最多出现一次)
+ 出现一次或多次(至少出现一次)
* 出现零次或多次(任意次)
{n} 出现n次
{n,m} 出现n到m次
{n,} 至少出现n次
/\d*/.test("abc")  //true
/\d+/.test("abc")  //false
/\d+/.test("abc1")  //true
/https?:/.test("http://www.163.com")  //true
/https?:/.test("https://www.163.com")  //true
/https?:/.test("httpsss://www.163.com")  //false

上面那个例子,学了量词,又能写成什么样子呢?

<input type="text" id="mobile" onblur="check(this)" onfocus="reset(this)">
<script>
	function check(mobileInput){
		var value = mobileInput.value;
        //使用量词,代码少了
		if(!/^1\d{10}$/.test(value)){
			mobileInput.style.borderColor = 'red';
		}
	}

	function reset(mobileInput){
		mobileInput.style.borderColor = '';
	}
</script>

chrome测试
chrome测试
chrome测试


global(全局)

/./g

转义符

  • \

多选分支(或)

  • |
/thi(c|n)k/   ===   /thi[cn]k/
/\.jpg|png|jpeg|gif/    //可选jpg结尾的图片格式,也可以是png和其它两种
/(.+)@(163|126|188)\.com$/    //网易邮箱163或126或188都可以

捕获(分组)

  • 保存匹配到的字符串,日后再用
  • () : 捕获
  • (?:) : 不捕获

我们希望使用量词的时候匹配多个字符,而不是像上面例子只是匹配一个,比如希望匹配Byron出现20次的字符串,我们如果写成 Byron{20} 的话匹配的是Byro+n出现20次

Byron{20}

怎么把Byron作为一个整体呢?使用()就可以达到此目的,我们称为分组

(Byron){20}

str.search(reg)

  • search() 方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串
  • search() 方法不执行全局匹配,它将忽略标志g,它同时忽略正则表达式对象的lastIndex属性,并且总是从字符串的开始进行检索,这意味着它总是返回字符串的第一个匹配的位置
'a1b2c3'.search(/\d/g); //1
'a1b2c3'.search(/\d/); //1

str.match(RegExp)

  • 获取匹配的字符串
var url = 'http://blog.163.com/album?id=1#comment';
	var arr = url.match(/(https?:)\/\/([^\/]+)(\/[^\?]*)?(\?[^#]*)?(#.*)?/);
	// var arr = url.match(/(https?:)\/\/([^\/]+)([^\?]*)([^#]*)(.*)/);
	console.log(arr);

str.replace(regexp,replacement)

  • 替换一个字符串
'abcabcabc'.replace('bc','X'); //aXabcabc
'abcabcabc'.replace(/bc/g,'X'); //aXaXaX
'abcaBcabC'.replace(/bc/gi,'X'); //aXaXaX

str.split(reg)

  • 使用split方法把字符串分割为字符数组
'a,b,c,d'.split(','); //["a", "b", "c", "d"]
'a1b2c3d'.split(/\d/); //["a", "b", "c", "d"]

form表单

form

  • 所有表单控件(文本框、文本域、按钮、单选框、复选框等)都必须放在 <form></form> 标签之间(否则用户输入的信息可提交不到服务器上哦!)。
<form   method="传送方式"   action="服务器文件">
  1. <form> :<form>标签是成对出现的,以<form>开始,以</form>结束。

  2. action :浏览者输入的数据被传送到的地方,比如一个PHP页面(save.php)。

  3. method : 数据传送的方式(get/post)。

文本输入框,密码输入框

<form>
   <input type="text/password" name="名称" value="文本" />
</form>

1、type: 当type="text"时,输入框为文本输入框; 当type="password"时, 输入框为密码输入框。

2、name:为文本框命名,以备后台程序ASP 、PHP使用。

3、value:为文本输入框设置默认值。(一般起到提示作用)

文本域,支持多行文本输入

<textarea  rows="行数" cols="列数">文本</textarea>

1、<textarea>标签是成对出现的,以<textarea>开始,以</textarea>结束。
2、cols :多行输入域的列数。
3、rows :多行输入域的行数。
4、在<textarea></textarea>标签之间可以输入默认值。

  • 注意:这两个属性可用css样式的width和height来代替:col用width、row用height来代替。

使用单选框、复选框

使用表单设计调查表时,为了减少用户的操作,使用选择框是一个好主意,html中有两种选择框,即单选框和复选框,两者的区别是单选框中的选项用户只能选择一项,而复选框中用户可以任意选择多项,甚至全选。

<input   type="radio/checkbox"   value="值"    name="名称"   checked="checked"/>

1、type:
当 type="radio" 时,控件为单选框
当 type="checkbox" 时,控件为复选框
2、value:提交数据到服务器的值(后台程序PHP使用)
3、name:为控件命名,以备后台程序 ASP、PHP 使用
4、checked:当设置 checked="checked" 时,该选项被默认选中

  • 注意:同一组的单选按钮,name 取值一定要一致,比如上面例子为同一个名称“radioLove”,这样同一组的单选按钮才可以起到单选的作用。

使用下拉列表框


  • selected="selected":
    设置selected="selected"属性,则该选项就被默认选中。

类型识别

类型识别方法

  • typeof
  • instanceof
  • Object.prototype.toString.call
  • constructor

typeof操作符

  • 可以识别标准类型(Null除外)
typeof 'yym'  //"string"
typeof 23  //"number"
typeof true  //"boolean"
typeof undefined  //"undefined"
typeof null  //"object"    没有识别的正确
typeof {name:'yym'}  //"object"

标准类型识别

  • 不能识别具体的对象类型(Function除外)
typeof function(){}  //"function"  这个识别是function
typeof []  //"object"
typeof new Date  //"object"
typeof /\d/  //"object"

function Person(){}
typeof new Person  //"object"

具体对象类型

instanceof

  • 能够判别内置对象类型
  • 不能判别原始类型
  • 能够判别自定义对象类型和父子类型
    • 识别所有的对象类型
能够判别内置对象类型
[] instanceof Array  //true
/\d/ instanceof RegExp  //true
new Date instanceof Date  //true

不能判别原始类型
1 instanceof Number  //false
'yym' instanceof String  //false

Object.prototype.toString.call方法

  • 可以识别标准类型以及内置对象类型
  • 不能识别自定义对象类型
Object.prototype.toString.call(123)  //"[object Number]"
Object.prototype.toString.call('yym')  //"[object String]"
Object.prototype.toString.call(true)  //"[object Boolean]"

从上面的代码中我们可以看到返回值是一个字符串当中的子字符串,我们来封装一个方法

function type(obj){
  return Object.prototype.toString.call(obj).slice(8, -1)
}
type(1)  //"Number"
type('1')  //"String"
type(true)  //"Boolean"
type(undefined)  //"Undefined"
type(null)  //"Null"

constructor 构造函数

  • 判别标准类型(Undefined/Null除外)
  • 判别内置对象类型
  • 判别自定义对象类型
判别标准类型(Undefined/Null除外)
'yym'.constructor === String  //true
(1).constructor === Number  //true
true.constructor === Boolean  //true
({}).constructor === Object  //true

判别内置对象类型
new Date().constructor === Date  //true
[].constructor === Array  //true

封装一下获取构造函数的名称

/*
* 1. 入参obj如果是undefined和null,则返回其自身;
* 2. 入参obj如果是其他值,则返回obj.constructor&&obj.constructor.toString().match(/function\s*([^(]*)/)[1]的结果;
*/
function getConstructorName(obj){
    return (obj===undefined||obj===null)?obj:(obj.constructor&&obj.constructor.toString().match(/function\s*([^(]*)/)[1]);
}

看一个类型识别的题目

/*
* 输入格式:
* '2015-08-05'
* 1438744815232
* {y:2015,m:8,d:5}
* [2015,8,5]
* 返回格式:Date
*/
function toDate(param){
  if (typeof(param) == 'string' || 
      typeof(param) == 'number' ){
    return new Date(param);
  } 
  if (param instanceof Array){
    var date = new Date(0);
    date.setYear(param[0]);
    date.setMonth(param[1]-1);
    date.setDate(param[2]);
    return date;
  }
  if (typeof(param) == 'object') {
    var date = new Date(0);
    date.setYear(param.y);
    date.setMonth(param.m-1);
    date.setDate(param.d);
    return date;
  }
  return -1;
}

文本属性都在这了

字体属性

font-size

  • 语法:font-size:<length> | <percentage> | <absolute-size> | <relative-size>
    • 后面两个值不常用有small,middle ,large
font-size:12px;
  font-size:16px;
  font-size:2em;(24px)
  font-size:200%;

font-family

  • 语法:font-family:[<family-name> | <generic-family>]#
    • <generic-family>=serif | sans-sarif
font-family:arial;
font-family:arial,Verdana,sans-sarif;
font-family:Verdana,"微软雅黑";

font-weight

  • 语法:font-weight:normal|bold|bolder|lighter|100|200|..|900
    • font-weight:normal默认
font-weight;bold;

font-style

  • 语法:font-style:normal|italic|oblique
    • oblique:倾斜
    • italic: 斜体
font-style:italic;

line-height

  • 语法:line-height:normal|<number>|<length>|<percentage>
    • normal不是固定的,由浏览器决定
line-height:40px;
  line-height:3em;
  line-height:300%;
  line-height:3;
300%和3显示是一样的,有哪些区别呢?
  修改里面某一段文字大小时;
line-height为number时,继承为直接继承,所以如果给下面的元素设置行高,等于字体大小乘以number值(不计算,直接继承)

而line-height:百分比;先计算,在继承,

结合上面五个属性:

font

  • 语法:font:[[<font-size>||<font-weight>]?<font-size>[/<line-height>]?<font-family>]
    • 语法可以看出:font-style font-weight可选,font-size必填项,font-family也是必填项,line-height可选,但有的时候前面有/
缩写:
font:30px/2 "Consolas",monospace;
font:20px arial,serif;
font:italic bold 20px/2 arial,serif

color

  • color:red;
  • color:#ffffff;
  • color:rgb(255,0,0);
  • color:rgba(255,0,0,1);
  • color: transparent;

对齐方式

text-align

  • 语法:text-align:left|right|center|justify
    • justify:两端对齐

vertical-align

  • 语法:vertical-align:baseline|sub|super|top"text-top|middle|bottom|text-bottom|<percentage>|<length>
    • baseline:基线
    • sub:下标
    • suoer:上标
    • middle:垂直居中

vertical-align

text-indent 首行缩进

  • text-indent:<length>|<percentage>
text-indent:2em;首行缩进两个字

text-indent


格式处理

white-space设置换行是否保留,空格是否合并等

  • white-space:normal|nowrap|pre|pre-wrap"pre-line
    • nowrap不换行,字强制一行
    • pre 换行保留 空格和Tab保留 不换行 完整保留代码格式
    • pre-wrap 在pre的基础上允许换行
    • pre-line 只保留换行,空格合并掉

word-wrap 单词换行

  • word-wrap:normal|break-word
    • break-word 把一个长单词允许自动换行

word-break

  • word-break:normal|leep-all|break-all
    • break-all 任意字母都可以换行

文本修饰

text-shadow 文字阴影

  • text-shadow:none|[<length>{2,3}&&<color>?]#
    • color可不写,颜色为文字颜色
    • #代表可写多个shadow,逗号分开
    • 2到3个length值

image.png

text-decoration下划线

  • 语法:text-decoration:none | [underline||overline||line-through]
    • 语法可以知道,可以写多条线
    • underline:下划线
    • overline;上划线

高级设置

css ...的实现

  • text-overflow:clip | ellipsis
text-overflow:ellipsis;
overflow:hidden; 文字超出隐藏,溢出截掉
white-space:nowrap;不换行

鼠标形状的设置 Cursor

cursor

  • url()自定义
  • auto:自动处理
  • default 普通光标
  • none 消失
  • help 带问号的
  • pointer手型
  • zoom-in放大镜类似的
  • move 十字移动鼠标

inherit 强制继承

很多文本类型都可以继承

杂谈css高度技巧

不学习具体的知识点,只了解一下

文档流(Normal flow)

块级元素的宽高,
  • 以div里只有行内元素举例
  • 字和字之间用基线对齐
  • 行和行之间是有建议行高的,字体设计师设计师给的行高
  • div高度由line-height决定
  • 空格宽度 也是由设计师决定
<div></div>  // height:0
//中间加文字,height高度是多少呢?

<div>你好</div>  //随字体变化,height也在变化  字体*建议行高
  1. display:inline-block空隙问题,可以用float
  2. div里行内元素足够多的话,一行容纳不下,自动换行,就是文档流
  3. 遇到一个足够长的单词,超出了文档流,用word-break:break-alll
多行文字溢出

单行文本溢出

多行文本溢出

文字垂直居中
  • 写一个div高为40px
//小白
div{
  height:40px;  //千万不要写死  
  line-height:40px;
}
//怎么改?
div{
  line-height:40px;
  padding:8px 0;  //文字很多,不会出现bug
}
margin合并 div高度
//只需要一个东西挡住margin,就不会合并
div.child{
  border:10px solid red; 
  padding:10px;
  margin:10px;
}
div.parent{
  outline:2px solid green;

  // overflow:hidden 也可以去除margin合并,不过不推荐
}

<div class="parent">  //div 里 div 外面的div 高度由谁决定
  <div class="child">
    111
  </div>
</div>

margin合并

字体两边对齐(技巧)

该怎么实现对齐呢?小技巧

对齐了,用了什么方法

/* css */
    div{
      border:1px solid red;
      font-size:20px;
    }
    span{
      display: inline-block;
      width:5em;
      border:1px solid green;
      text-align: justify;
      height:20px;
      line-height:20px;
      overflow: hidden;
    }
    span:after{
      content:'';
      display:inline-block;
      width:100%;
    }

/* html*/
<div>
  <span>姓名</span><br>
  <span>联系方式</span>
</div>
  <p style="text-align: justify;">
    我是文字,我想换行对齐.我是文字,我想换行对齐.我是文字,我想换行对齐.我是文字,我想换行对齐.我是文字,我想换行对齐.我是文字,我想换行对齐.我是文字,我想换行对齐.我是文字,我想换行对齐.我是文字,我想换行对齐.我是文字,我想换行对齐.我是文字,我想换行对齐.我是文字,我想换行对齐.我是文字,我想换行对齐.我是文字,我想换行对齐.我是文字,我想换行对齐.我是文字,我想换行对齐.我是文字,我想换行对齐.
  </p>

div中的div垂直居中

  1. padding
  2. display:flex
  3. transform:translate

div的高度是由内部文档流中元素的总和决定,行内元素从左到右,块级元素从上到下,脱离文档流中的不算,float position:absolute position:fixed

CSS : border调试大发

写的比较乱,凑合看看吧,♫♫∵

元素居中方法总结

水平居中

<1>行内元素的居中

被设置元素为文本、图片等行内元素时,水平居中是通过给父元素设置 text-align:center 来实现的。

  • text-align
<title>行内元素水平居中</title>
<style>
div{
    border:1px solid red;
    margin:20px;
}
.txtCenter{text-align:center;}
.imgCenter{text-align:center;}
</style>
</head>
<body>
<div class="txtCenter">我想要在父容器中水平居中显示。</div>
<div class="imgCenter">![](http://upload-images.jianshu.io/upload_images/5983146-dec4b8fafded5d82.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</div>
</body>

<2>块状元素的居中

当被设置元素为 块状元素 时用 text-align:center 就不起作用了,这时也分两种情况:定宽块状元素和不定宽块状元素。

定宽块状元素

  • margin: value auto;
<title>定宽块状元素水平居中</title>
<style>
    div{
        border:1px solid red;
	    width:200px;
	    margin:20px auto;
    }
</style>
<body>
    <div>我是定宽块状元素,我要水平居中显示。</div>
</body>

不定宽块状元素

  • table + margin

table标签的长度自适应性---即不定义其长度也不默认父元素body的长度(table其长度根据其内文本长度决定),因此可以看做一个定宽度块元素,然后再利用定宽度块状居中的margin的方法,使其水平居中。

优点:只需在子元素child上设置css样式,不用关心父元素的
缺点:兼容性较差,如果需要兼容,更改html样式,改为table样式

<-- css -->
<style type="text/css">
	body{margin:20px;}
	.parent{background: red;}
	.child{
		display: table;
		margin: 0 auto;
		background: blue;
		opacity: .5;
	}
</style>
<-- html -->
<div class="parent">
	<div class="child">DEMO</div>
</div>
  • inline-block + text-align

初始DEMO是块级元素,会充满父元素;inline-block默认宽度为内容宽度,然后给父元素设置text-align

优点:兼容性较好,甚至可以兼容IE6
缺点:子元素会继承父元素的text-align,使子元素里的内容也水平居中

<style type="text/css">
	body{margin:20px;}
	.parent{
		background: red;
		text-align: center;
	}
	.child{
		display: inline-block;
		background: blue;
	}
</style>
<body>
<div class="parent">
	<div class="child">DEMO</div>
</div>
</body>
  • absolute + transform

利用绝对定位和偏移解决居中问题,left:50%; 将子元素距离左边50%,translateX是将自身宽度往左偏移50%;结果是水平居中

优点:因为position:absolute;脱离文档流,所以不会影响其他的子元素;
缺点:transform是css3的内容,所以兼容性较差;

<style type="text/css">
	body{margin:20px;}
	.parent{background:#ddd;}
	.child{background:#666;color:#fff;}
	.parent{height:1.5em;}
	.parent{
		position: relative;
	}
	.child{
		position: absolute;
		left: 50%;
		transform: translateX(-50%);
	}
</style>
</head>
<body>
<div class="parent">
	<div class="child">DEMO</div>
</div>
  • float + relative

通过给父元素设置 float,然后给父元素设置 position:relative 和 left:50%,子元素设置 position:relative 和 left: -50% 来实现水平居中。

<style>
.wrap{
    clear:both;
    float:left;
    position:relative;
    left:50%
    }
.wrap-center{
    background:#ccc;
    position:relative;
    left:-50%;
}
</style>
</head>
<body>
<div class="wrap">
    <div class="wrap-center">我们来学习一下这种方法。</div>
</div>
  • flex + justify-content

flex是弹性布局,有自己的居中属性,水平居中justify-content:center

优点:只需设置父元素,不用设置子元素
缺点:flex也是css3的,兼容性较差

<style type="text/css">
	body{margin:20px;}
	.parent{background:#ddd;}
	.child{background:#666;color:#fff;}
	.parent{
		display: flex;
		justify-content: center;
	}
	.child{
		margin: 0 auto;
	}
</style>
</head>
<body>
<div class="parent">
	<div class="child">DEMO</div>
</div>

垂直居中

<1>父元素高度确定的单行文本

通过设置父元素的 height 和line-height 高度一致来实现的。(height: 该元素的高度,line-height: 顾名思义,行高(行间距),指在文本中,行与行之间的 基线间的距离 )。

缺点:当文字内容的长度大于块的宽时,就有内容脱离了块。

<title>垂直居中</title>
<style>
.wrap h2{
    margin:0;
    height:100px;
    line-height:100px;
    background:#ccc;
}
</style>
</head>
<body>
<div class="wrap">
    <h2>hello world!</h2>
</div>
</body>

<2>父元素高度不确定的多行文本

  • table-cell + vertical-align

竖直居中的属性 vertical-align,在父元素设置此样式时,会对inline-block类型的子元素都有用。
display:table-cell属性指让标签元素以表格单元格的形式呈现,类似于td标签。我们都知道,单元格有一些比较特别的属性,例如元素的垂直居中对齐,关联伸缩等,所以可以设置垂直居中

优点:不用添加无意义的标签
缺点:兼容性有问题

<title>垂直居中</title>
<style type="text/css">
	body{margin:20px;}
	.parent{background:#ddd;}
	.child{background:#666;color:#fff;}
	.parent{width:4em;height:500px;}
	.child{width:100%;}
	.parent{
		display: table-cell;
		vertical-align: middle;
	}
</style>
</head>
<body>
<div class="parent">
	<div class="child">DEMO</div>
</div>

下面的代码直接在div外面机加一个table tbody tr td,又因为td 标签默认情况下就默认设置了 vertical-alignmiddle,所以我们不需要显式地设置了。

<style>
  .wrap{height:300px;background:#ccc}
</style>
</head>
<body>
<table><tbody><tr><td class="wrap">
<div>
    <p>看我是否可以居中。</p>
    <p>看我是否可以居中。</p>
    <p>看我是否可以居中。</p>
    <p>看我是否可以居中。</p>
    <p>看我是否可以居中。</p>
</div>
</td></tr></tbody></table>

<table><tbody><tr><td class="wrap">
<div>
    ![害羞的小女生](http://upload-images.jianshu.io/upload_images/5983146-1a12aeadf25d2b5f.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
</div>
</td></tr></tbody></table>
</body>
  • absolute + transform

这个方法和水平居中的方法类似,唯一的区别是top:50%;,transform:translateY(-50%);

  • flex + align-items

与水平居中justify-content对应的属性align-items值为center,也可以实现垂直居中
设置display:flex;会使子元素充满父元素。因为align-items的值默认为stretch


水平垂直居中

综合水平居中和垂直居中一起

  • inline-block + text-align +table-cell +vertical-align
<title>居中</title>
<style type="text/css">
	body{margin:20px;}
	.parent{width:200px;height:300px;}
	.parent{background:#ddd;}
	.child{background:#666;color:#fff;}
	.parent{
		text-align: center;
		display: table-cell;
		vertical-align: middle;
	}
	.child{
		display: inline-block;
	}
</style>
</head>
<body>
<div class="parent">
	<div class="child">DEMO</div>
</div>
</body>
  • absolute + transform
<title>居中</title>
<style type="text/css">
	body{margin:20px;}
	.parent{width:200px;height:300px;}
	.parent{background:#ddd;}
	.child{background:#666;color:#fff;}
	.parent{
		position: relative;
	}
	.child{
		position: absolute;
		left: 50%;
		top: 50%;
		transform: translate(-50%,-50%);
	}
</style>
</head>
<body>
<div class="parent">
	<div class="child">DEMO</div>
</div>
  • flex + justify-content + align-items
<title>居中</title>
<style type="text/css">
	body{margin:20px;}
	.parent{width:200px;height:300px;}
	.parent{background:#ddd;}
	.child{background:#666;color:#fff;}
	.parent{
		display: flex;
		justify-content: center;
		align-items: center;
	}
</style>
</head>
<body>
<div class="parent">
	<div class="child">DEMO</div>
</div>
</body>
垂直居中的搭配有很多,我们可以根据实际情况做出一个判断,然后充分了解一些居中的属性以及属性值

总结:解决此类问题,我们需要了解css属性的值和特性,了解属性以后,对问题进行分解,把特性和分解的问题进行一些联系,问题可以用那些特性实现,综合解决

后面如果在遇到不同的居中方式,会补充在这里

css样式层叠与继承

层叠与继承

css样式来源

  • 使用不同的选择器设置的样式
  • 浏览器默认样式 (user agent stylesheet)
  • 继承的样式 (Inherited from xxx) 权重小

选择器样式权重

!important

例:
<div class="success no-background-color" id="box">
  Hello World
</div>

给几个样式

#box {
  background-color: blue;
}

.success {
  background-color: green;
}

.no-background-color {
  background-color: transparent !important; 
}
我们看到最后一个class选择器后面有 !important  所以最后的样式是transparent
!important权重比较大

如果没有!important我们怎么判断样式的优先级和权重,如果有行内样式,那么行内样式最高,没有,我们继续判断:

Specificity 特异性

分数 条件
1000 + 1 / 在 style 属性内或在 <style>标签内
100 + 1 / 每个出现的 ID 选择器
10 + 1 / 每个出现的 类,伪类或 属性选择器
1 + 1 / 每个元素选择器或伪元素
注意 通用选择器(*), 组合选择器 (+, >, ~, ' ') 和 (:not) 对特异性没有影响
选择器 1000 100 10 1 总分
body 0 0 0 1 1
#flash 0 1 0 0 100
h1 + p::after 0 0 0 3 3
li > a[download] > .warning 0 0 2 2 22
#notice a:hover 在 <style> 里 1 1 1 1 1111
继承
  • 会继承 - color font-size 等
  • 不继承 - padding margin border background-image 等

问题

样式问题

h1的文字大小不是没有变成12px,而是变的不对

image

a链接和h1一样,都是浏览器默认样式大于继承的样式


标签在浏览器里有一些默认样式会让我们对某些css样式判断失误,所以一般我们都会写一个reset.css来重置样式

JS字符串方法的应用

想要去除一个字符串的第一个字符,有哪些方法可以实现

1. "string".replace("s","")  //替换
2. "string".substring(1)   //截取
3. "string".slice(1)      //截取
4. "string".substr(1)    //截取

看一个例子,字符串在一些表单验证方面的应用

string字符串的应用

字符串方法

DEMO1

字符串长度

  • str.length 获取字符串长度
var userName = input.value
if(userName.length > 6){
  alert(要求大于等于六个字符)
}
DEMO2

不能以"-"开头

  • str.charAt(index)
    • index索引值
"yangyumeng".charAt(0)  //"y"
应用:
var userName = input.value;
if(userName.charAt(0) == "-"){
	alert("不能以“-”开头");
}
DEMO3

必须包含"-"

  • str.indexOf(searchValue)
    • 返回值是索引位置
"yymyang-yumeng".indexOf("-")   //7
"yang-yu-meng".indexOf("-")  //4   只匹配一次
"yang-yumeng".indexOf("yumeng")  //5  按照第一个字符所在位置
"yangyumeng".indexOf("-")  //-1  没有会返回-1,可以利用-1做一些判断
DEMO4

不能含有数字

  • str.search(regexp)
    • regexp(正则)
"yangyumeng123".search(/[0-9]/)  //10,返回数字索引位置
"yang123yumeng".search(/[0-9]/)  //4
"yangyumeng123".search(/[A-Z]/)  //-1,找不到数字-1
  • str.match(regexp)
    • regexp(正则)
    • g全局
"yang123yumeng".match(/[0-9]/)  //["1"] 返回数组
"yang123yumeng".match(/[0-9]/g)  // ["1", "2", "3"]
"yangyumeng123".match(/[A-Z]/)  //没有数字,返回null

以上代码均经过chrome验证

验证

其他的字符串方法

替换

  • str.replace(regexp|substr,newSubstr|function)
    • 参数可以是正则,也可以是某一字符串
"yangyumeng123".replace("123","###") //"yangyumeng###"
"yangyumeng123".replace(/[0-9]/,"###")  //"yangyumeng###23"只替换了一个
"yangyumeng123".replace(/[0-9]/g,"#") //"yangyumeng###" 全局参数g
"yangyumeng123".replace(/[0-9]/g,"")  //"yangyumeng" 去掉数字
  • str.substring(indexA[,indexB])
    • 截取字符串
    • indexA,indexB 索引
    • 返回的是从A索引值到B索引值的字符串
    • 包含A不包含B

其实substring可以传入负数,但是负数对substring是没有任何意义的,都会处理成0,所以我们可以理解为substring其实不支持负数。

"yangyumeng".substring(2,5)  //"ngy"
"yangyumeng".substring(2)  //"ngyumeng"  从2后面所有字符串
  • str.slice(beginSlice[,endSlice])
    • 大多数和str.substring一样
    • str.slice可传入负数,倒数,
    • 后面的值取不到
"yangyumeng".slice(1,-1)  //"angyumen"
"yangyumeng".slice(-3)  //"eng"
  • str.substr(start[,length])
    • start 索引
    • length 取多少长度
"yangyumeng".substr(2,5)  //"ngyum"
"yangyumeng".substr(2)  //"ngyumeng"

看一个需求

分割

  • str.split([separator][,limit])
    • separator用什么分隔符分开
    • limit不常用,输出几个
"yagn yumeng".split(" ")  //["yagn", "yumeng"] 返回数组
"yagn yumeng".split(" " , 1)  //["yagn"]
"yagn5yumeng".split(/[0-9]/)  //["yagn", "yumeng"] 用数字分割

验证

  • str.toLowerCase()
    • 变小写字符串
"YanYUmeng".toLowerCase()  //"yanyumeng"
  • str.toUpperCase()
    • 大写
"yanguyemng".toUpperCase()  //"YANGUYEMNG"

需求

demo

  • 连接+
"0571" + "-" + "1234565"  //"0571-1234565"

var area = input.value
var tel = input.value
var num = area + "-" + tel
  • String()
    • 转字符串`
String(123)  //"123"
String(null)  //"null"
  • 转义\
"yang\"yumeng"  //"yang"yumeng"
"yang\\yumeng"  //"yang\yumeng"
"yang\tyumeng"  //"yang	  yumeng"
"yang\nyumeng"   //"yang
                    yumeng"

JS初识函数

函数

我们再看函数前,先来看一个demo,看看如果没有函数我们的代码量

 var students1 = [{
        name: '张',
        gender: 1
    }, {
        name: '一',
        gender: 1
    }, {
        name: '二',
        gender: 0
    }];
    var students2 = [{
        name: '三',
        gender: 0
    }, {
        name: '四',
        gender: 1
    }, {
        name: '五',
        gender: 1
    }, {
        name: '六',
        gender: 1
    }];

    // 求1班的男女比率
    var maleCount1 = 0,
        femaleCount1 = 0,
        length1 = students1.length,
        student1,
        ratio1;
    for (var i = 0; i < length1; i++) {
        student1 = students1[i];
        if (student1.gender === 1) {
            maleCount1++;
        } else {
            femaleCount1++;
        }
    }
    ratio1 = maleCount1 / femaleCount1;
    alert('1班的男女比率为:' + ratio1);
    // 求2班的男女比率
    var maleCount2 = 0,
        femaleCount2 = 0,
        length2 = students2.length,
        student2,
        ratio2;
    for (var i = 0; i < length2; i++) {
        student2 = students2[i];
        if (student2.gender === 1) {
            maleCount2++;
        } else {
            femaleCount2++;
        }
    }
    ratio2 = maleCount2 / femaleCount2;
    alert('2班的男女比率为:' + ratio2);

这是两个班级的,如果我们有十个班级,就需要写十个这么长的代码,怎么解决的,我们就用到函数了,我们再来看看函数怎么写

/**
 * 求学生的男女比率
 * @param  {Array} students 学生列表
 * @return {Number}          男女比率
 */
function ratio(students) {
    var maleCount = 0,
        femaleCount = 0,
        length = students.length,
        student,
        ratio;
    for (var i = 0; i < length; i++) {
        student = students[i];
        if (student.gender === 1) {
            maleCount++;
        } else {
            femaleCount++;
        }
    }
    ratio = maleCount / femaleCount;
    return ratio;
}

alert('1班的男女比率为:' + ratio(students1));
alert('2班的男女比率为:' + ratio(students2));

我们需要哪个班级调用就可以了


函数语法

ECMAScript中的函数使用关键字function关键字来声明,后跟一组参数以及函数体

语法:
function functionName(arg0, arg1,...,argn){
		statements
}

function 函数名([形参列表]){
         执行代码
}
函数名([实参列表])      //函数调用

示例:
function sayHi(name, message){
	alert("Hello" + name + "," + message);
}
sayHi("yym" ,"how are you today");
//这个函数可以通过其函数名来调用,后面加上一对圆括号和参数(参数如果多个,用逗号隔开)

ECMAScript中的函数在定义时不必指定是否具有返回值.实际上,任何函数在任何时候都可以通过return语句后跟要返回的值来实现返回值

function sum(num1, num2){
	return num1 + num2;
}
//这个函数会在执行完return语句后停止并立即退出,因此,位于return之后的任何代码都不会执行.

function sum(number1, number2){
	return number1 + number2;
    alert("Hello World");        //永远不会执行
}

另外,return语句也可以不带有任何返回值,在这种情况下,函数停止执行后返回undefined,一般用在需要提前停止函数执行而又不需要返回值的情况下


函数定义的方式

  • 函数声明
function add(number0, number1){
	var sum = number0 + number1;
	return sum;
}    //函数声明
  • 函数表达式
var add = function(number0, number1){
	var sum = number0 + number1;
	return sum;
}    //函数表达式(把匿名函数赋值给变量)  
  • 函数调用的过程
function add(number0, number1){  //number0 = 2, number1 = 3 
	var sum = number0 + number1;  //sum = 5
	return sum;  //返回sum
}
var x = add(2, 3); //x = 5
alert(x);  // 弹出5

函数参数

ECMAScript函数的参数与大多数其他语言的参数不同.ECMAScript函数不介意传递进来多少参数,也不在乎什么数据类型,既是你定义的函数只接收两个参数,你也可以传递一个 三个甚至不传参数,解析器永远不会有怨言.之所以这样,js中的参数在内部用一个数组表示.函数接收的始终都是数组,而不关心数组中包含哪些参数.实际上,在函数体内可以通过arguments来访问这个参数数组,从而获取传递给函数的每一个参数.

  • 实参数量少于形参
function add(number0, number1){  //number0 = 2, number1 = undefined
	var sum = number0 + number1;
	return sum;
}
var x = add(2);
alert(x)  //NaN
  • 实参数量多于形参
function add(number0, number1){  //number0=2, number1=3, 4=?
	debugger;
	var sum = number0 + number1;
	return sum;
}
var x = add(2, 3, 4);  //5

arguments

  • 实参不定时(arguments)
function add() {
    var length = arguments.length,
        sum = 0,
        parameter;
    for (var i = 0; i < length; i++) {
        parameter = arguments[i];
        sum = sum + parameter;
    }
    return sum;
}

alert(add(2, 3)); // 5
alert(add(2, 3, 4)); // 9
alert(add(2, 3, 4, 5)); // 14

函数参数传递方式

ECMAScript中所有函数都是按值传递,也就是说,把函数外部的值赋值给函数内部的参数,就和把值从一个变量复制到另一个变量一样

  • 参数为原始类型:值传递
function increment(number){
	number = number + 1;
	return number;
}
var a = 10;
var x = increment(a); //11
a;  // 10

函数increment()有一个参数number,参数实际上是局部变量,调用时,变量a作为参数传递给函数,a的值被加1,这个变化不会影响函数外部的a变量,参数number与变量a互不相识,仅具有相同的值

  • 参数为对象类型:值传递
function setName(obj){
	obj.name = "yym";
}
var person = new Object();
setNmae(person);
alert(person.name);    //"yym"     

代码创建了对象,保存在变量person中,,这个变量被传递给setName()函数中复制给了obj,在函数内部,obj和person引用同一个对象,换句话说,既使这个变量按值传递,obj也会被引用来访问同一个对象,于是,在函数内部为obj添加name属性,外部person也有所反应;因为person指向的对象在堆内存中只有一个,而且是全局对象,有些人会认为是参数按照引用传递,让我们看修改的例子:

function setName(obj){
	obj.name = "yym";
	obj = new Object();
	obj.name = "Greg";
}

var person = new Object();
setName(person);
alert(person.name);     //"yym"

和上面的例子区别,我们可以看到,如果person是引用传递,那么person会被修改为"Greg",但结果仍是"yym",说明即使在函数内部修改了参数的值,原始的引用仍然保持不变,实际上,在函数内部重写obj时,这个变量引用的就是一个局部对象了,而这个局部对象会在函数执行完毕后立即被销毁


执行环境及作用域

  • 执行环境(execution content)定义了变量或函数有权访问的其他数据.每个执行环境都有一个与之关联的变量对象(variable object)
var zhoujielun = {
    name: "周杰伦",
    gender: 1
};

function class1() {
    var zhoujielun = {
        name: "周杰伦",
        gender: 0
    };
    zhoujielun.name = "周杰";
    zhoujielun.gender = 1;
}
class1();

console.log(zhoujielun);   //访问不到内部的zhoujielun

再来看一个demo

var color = "blue";

function changeColor(){
   var anotherColor = "red";

   function swapColors(){
   	var tempColor = anotherColor;
   	anotherColor = color;
   	color = tempColor;

   		//这里可以访问color anotherColor和tempColor
   	}

   	//这里可以访问color和anotherColor,不能访问tempColor   
     swapColors();
}

//这里只能访问color
changeColor();
  • 涉及了3个执行环境:全局环境,changeColor()的局部环境和swapColors()的局部环境.
  • 全局环境中有一个变量color和一个函数changeColor()
  • changeColor()的局部环境中有一个anotherColor变量和一个名为swapColors()的函数,但它也可以访问全局变量中的color
  • swapColors()的局部环境中有一个变量tempColor,该变量只能在这个环境中访问到

下图中的矩形代表特定执行环境内部环境可以通过作用域链访问所有外部环境,但外部环境不能访问内部环境任何变量和函数,这些环境之间的联系是线性 有次序的.每个环境都可以向上搜索作用域链,以查询变量和函数名.任何环境都不能通过向下搜索作用域链而进入另一个执行环境

image.png


函数作为对象属性

对象属性
看上图,如果我们修改变量point是不是也要把函数里的point修改一下,不然的话无法运行,那我们又没有简单的方法呢?

可以把point修改为this
var point = {
	x: 1,
	y: 1,
	move: function(stepX, stepY){
		 this.x += stepX;
		 this.y += stepY;
	}
};
point.move(2, 1);
console.log(point);

其实,今天所写的这些都是对函数一个简单的介绍,并不是很深入,只需要理解就好了,后面我会整理一下,函数进阶的东西

常见设计模式

常见设计模式

构造函数模式、混合模式、模块模式、工厂模式、单例模式、发布订阅模式的范例。
  • 工厂模式 factory
// 抽象了创建具体对象的过程
function createPerson(name){
  var person = {
    name : name
  };
  person.sayName : function(){
    console.log(this.name)  // this指向调用的方法
  }
  return person
}
createPerson("yym")  // 创建一个新的引用
createPerson("yangyu")

// 工厂模式

function createPerson(name, age, job){
  var o = new Object()
  o.name = name
  o.age = age
  o.job = job
  o.sayName = function(){
    console.log(this.name)
  } 
  return o
}

var person1 = createPerson("yym", 15, "work")
var person2 = createPerson("yym三国杀", 15, "wo是rk")
console.log(person1)

// 根据接受的参数构建一个包含所有必要信息的对象,无数次调用这个函数
  • 构造函数模式 constructor

与工厂模式的区别

  • 没有显式的创建对象
  • 直接将属性和方法赋给了this对象
  • 没有return语句

new操作符经历的步骤

  1. 创建一个新对象
  2. 将构造函数的作用域赋给新对象(this只想这个新对象)
  3. 执行构造函数中的代码
  4. 返回新对象
function Person(name, age){  //创建对象
  this.name = name
  this.age = age
  this.sayname = function(){    // 问题: 每个方法在实例时都要重新一遍
    return this.name
  }
// this.sayName = new Function("alert(this.name)")
}

var student = new Person('yym',  24)  // new 一个新对象
console.log(students)

alert(student.constructor === Person)  // true
alert(student instanceof Object)  // true
  • 原型模式
    无论何时,只要创建了一个新函数,会根据一组特定的规则为该函数创建一个prototype属性,属性指向函数的原型对象,默认情况下,所有原型对象会自动获得一个constructor(构造函数)属性,是一个指向prototype属性所在函数的指针
function Person(){
}
Person.prototype.name = "yym"
Person.prototype.age = 24
Person.prototype.job = "work"
Person.prototype.sayName = function(){
  console.log(this.name)
}

var person1 = new Person()
console.log(person1.sayName())
var person2 = new Person()
console.log(person2.sayName())
console.log(person1.sayName == person2.sayName)  // true

//isPrototypeOf() 确定是否__proto__指向调用对象(Person.prototype)
alert(Person.prototype.isPrototypeOf(person1))  // true

// ES5新方法: Object.getPrototypeOf()
alert(Object.getPrototypeOf(person1) == Person.prototype)  // true

// hasOwnProperty() 检查一个属性是存在于实例中,还是原型中
alert(person1.hasOwnProperty("name"))  // false

// in操作符会在通过对象能够访问给定属性时返回true,无论实例
// 还是原型中
console.log("name" in person1)  // true
person1.name = "yangyu"
console.log("name" in person1)  // true

//使用for-in循环,返回的所有能够通过对象访问的,可枚举的属性
//既包括实例中的属性,也包括原型中的属性

// 要取得对象上所有的可枚举实例属性,可用ES5中的 Object.keys()
// 接受一个对象作为参数,返回一个字符串数组
var a = Object.keys(Person.prototype)
console.log(a) // ["name", "age", "job", "sayName"]

//想要得到所有实例属性,无论是否可枚举. Object.getOwnPropertyNames()
var key = Object.getOwnPropertyNames(Person.prototype)
console.log(key)  //["constructor", "name", "age", "job", "sayName"]
  • 混合模式 mixin
// 混合它的原型
//Person 构造函数
var Person = function(name, age){
  this.name = name;
  this.age = age;
}
Person.prototype.sayName = function(){
  console.log(this.name)
}
// Student 构造函数
var Student = function(name, age, score){
  Person.call(this, name, age)  // 继承
  this.score = score
}
// 原型式继承
// Student.prototype = Object.create(Person.prototype)
Student.prototype = create(Person.prototype)

function create(parentObj){
  function F(){}  // 空对象 构造函数
  F.prototype = parentObj  // 原型链上是传进来的对象
  return new F()  //  实例化构造函数
}

Student.prototype.sayScore = function(){
  console.log(this.score);
}

var student = new Student("yym", 22, 100)
console.log(student)

// 原型式继承
// 函数内部创造一个临时构造函数,传入对象作为构造函数原型,返回实例
function object(o){
  function F(){}
  F.prototype = o
  return new F()
}
  • 单例模式 singleton
// 匿名函数
var People = (function(){  // 闭包
  var instance;
  function init(name){
    return {
      name: name
    };
  };
  return {
    createPeople : function(name){
      if(!instance){
        instance = init(name)
      }
      return instance;
    }
  };
}())
console.log(People.createPeople("yym"))  // { name: "yym"}
console.log(People.createPeople("hello"))  // { name: "yym"}
  • 模块模式 module
// 通过闭包实现一个模块
var Person = (function(){
  var name = "yym"
  function sayName(){
    console.log(name)
  };  // 词法作用域
  return {
    name: name,
    sayName: sayName
  }
}())
  • 发布订阅模式 publish / subscibe
var EventCenter = (function(){
  var events = {};  // 存储所有的key/value  事件映射表
  // 事件 回调函数
  // 1. on做了什么  ('hello',function(){})
  function on(evt,handler){
    // events['hello'] = []
    events[evt] = events[evt] || [];
    /* events['hello'] = [{
         handler: handler
       }]
    */
    events[evt].push({
      handler: handler
    });
  }
  //事件 所有的参数
  // 2. fire怎么做 ('hello')
  function fire(evt,args){
    // hello 有的 不执行
    if(!events[evt]){
      return;
    }
    // 触发 handler
    for(var i=0; i<events[evt].length; i++){
      events[evt][i].handler(args);
    }
  }
  function off(evt){
    delete events[evt]
  }
  return {
    on: on,
    fire: fire,
    off : off  // 取消订阅
  }
})()

EventCenter.on('hello', function(data){
  console.log('Hello World');
});
EventCenter.fire('hello');
使用发布订阅模式写一个事件管理器,可以实现如下方式调用
Event.on('change', function(val){
 console.log('change...  now val is ' + val);  
});
Event.fire('change', '饥人谷');
Event.off('changer');
var Event = (function (){
        var events = {};

        function on(evt, handle){
            events[evt] = events[evt] || [];
            events[evt].push({
                handle:handle
            });
        };

        function fire(evt,args){
            if(!events[evt]){
                return
            }

            for(var i=0; i<events[evt].length; i++){
                events[evt][i].handle(args);
            }
        };

        function off(evt){
            delete events[evt]
        };

        return {
            on: on,
            fire: fire,
            off: off
        }

    })()

    Event.on('change', function(val){
        console.log('change…… now val is' + val);
    });
    Event.fire('change', '饥人谷');
}

jQuery初识

jQuery 能做什么?

jQuery是一款快速而简洁的javascript的库,核心是构建与css选择器上,用来操作DOM元素,通过链式调用,兼容性好,API 友好,功能强大,与时俱进

  • 选择网页元素
  • 改变结果集
  • 元素的操作:取值和赋值
  • 元素的操作:移动
  • 元素的操作:复制、删除和创建
  • 工具方法
  • 事件操作
  • 特殊效果
  • AJAX

jQuery 对象和 DOM 原生对象有什么区别?如何转化?

  • 对于jQuery对象只能使用jQuery对象的API
  • 对于原生对象只能使用原生对象的 API

如何转化?

  • 对于原生转化为jQuery,只需在外面加上一层$符号
$(document.querySelector("#box"))
就可以变为jQuery对象,就可以使用jQuery对象的API了
  • 对于jQuery对象转换为原生对象,只需要加个[下标]
$("#box .box")[0]
,就可以使用j原生对象的API了

问题是:那我们又不想变成原生对象,又想取值怎么办呢?
$("#box .box").eq(0)  //.eq(index)

jQuery DOM操作,如何设置和获取元素内部 HTML 内容?如何设置和获取元素内部文本?

<div class="container">
  <ul class="wrap">
    <li>1</li>
    <li class = "active">2</li>
    <li>3</li>
  </ul>
</div>
//创建元素
$("<div class="box"><h1>创建html元素</h1></div>")
//添加元素append
var $li = $("<li>4</li>")
$(".wrap").append($li)   //添加到元素的后面
$li.appendTo($(".container .wrap"))  //把对象插入到目标元素尾部

var $li1 = $("<li>0</li>")
$(".wrap").prepend($li1)  // 向对象头部追加内容,用法和append类似,内容添加到最开始

$li.before($li1)  //翻译就是:4的前面是0
$li.before($("<li>5</li>"))  //翻译:4的前面新建了5

$li.after($li1)  //翻译就是:4的后面是0
$li.after($("<li>5</li>"))  //翻译:4的后面新建了5

//删除元素.remove()
$(".wrap li").eq(3).remove()  //删除第三个li

$(".wrap").empty()  //清空ul下所有的li  .empty()清空被选择元素内所有子元素


// $(selector).html()用于获取/修改元素的innerHTML
     当没有传递参数的时候,返回元素的innerHTML
     当传递了一个string参数的时候,修改元素的innerHTML为参数值
// $(selector).text()设置文本内容

jQuery中如何绑定事件?bind、unbind、delegate、live、on、off都有什么作用?推荐使用哪种?使用on绑定事件使用事件代理的写法?

//html demo点击在div里显示增加
<div class="box">
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
  </ul>
</div>
<input id="ipt" type="text">
<button id="btn">添加</button>

<div class="wrap">


</div>
//jQuery
$(".box>ul>li").on("click",function(){
  var str = $(this).text()
  $(".wrap").text(str)  //text() == innerText
})

$("#btn").on("click",function(){
  var value = $("#ipt").val()
  $(".box>ul").append('<li>'+value+'</li>')  //添加value
})

事件效果

那使用事件代理呢?

//事件代理
$(".box>ul").on("click","li",function(){
  var str = $(this).text()
  $(".wrap").text(str)
})

$("#btn").on("click",function(){
  var value = $("#ipt").val()
  $(".box>ul").append('<li>'+value+'</li>')
})

事件代理

  • .trigger( eventType [, extraParameters ] )根据绑定到匹配元素的给定的事件类型执行所有的处理程序和行为

  • bind为一个元素绑定一个事件处理程序 ,适用于早期jQuery版本(1.7以前)

  • unbind从元素上删除一个以前附加事件处理程序。

  • delegate为所有匹配选择器(selector参数)的元素绑定一个或多个事件处理函数,基于一个指定的根元素的子集,匹配的元素包括那些目前已经匹配到的元素,也包括那些今后可能匹配到的元素。

  • live附加一个事件处理器到匹配目前选择器的所有元素,现在和未来。

  • on在选定的元素上绑定一个或多个事件处理函数。

  • off移除一个事件处理函数

现在推荐使用on(),off()来绑定/解除事件。


如何设置和获取表单用户输入或者选择的内容?如何设置和获取元素属性?

// .val() 读写双用的方法,用来处理input的value
<input id="ipt" type="text" value="hello">
$("#ipt").val() //"hello"
$("#ipt").val("hello World")  //"hello World"

// .attr(attributeName) 获取元素特定属性的值
$("#ipt").attr("type")  //查看属性值  "text"
$("#ipt").attr("type","checkbox")  //设置属性  变为了多选框

// .removeAttr()  移除属性
$('div').removeAttr('id') //移除id属性

// .css() 类似于 style
<div class="box"></div>
$(".box").css({"width":"200px",   //设置css样式
               "backgroundColor":"yellow",
               "height":"30px"})
// .addClass()
// .removeClass()
// .hasClass()
// .toggleClass(className) toggle是切换的意思,方法用于切换

// .hasClass(className) 检查元素是否包含某个class,返回true/false
$( "#mydiv" ).hasClass( "foo" )

jQuery属性 如何展示/隐藏元素? jQuery 动画如何使用?

//展示
.show( [duration ] [, easing ] [, complete ] )
  duration:动画持续多久
  easing:表示过渡使用哪种缓动函数,jQuery自身提供"linear" 和 "swing"
  complete:在动画完成时执行的函数

//隐藏
.hide([duration ] [,easing ] [,complete ])
  duration:动画持续多久
  easing:表示过渡使用哪种缓动函数,jQuery自身提供"linear" 和 "swing"
  complete:在动画完成时执行的函数

//切换
.toggle( [duration ] [, easing ] [, complete ] ) 用法同上

// 渐变
.fadeIn( [duration ] [, easing ] [, complete ] )通过淡入的方式显示匹配元素,参数含义和上面相同
.fadeOut( [duration ] [, easing ] [, complete ] )通过淡出的方式隐藏匹配元素
.fadeTo( duration, opacity [, easing ] [, complete ] )调整匹配元素的透明度,方法通过匹配元素的不透明度做动画效果
.fadeToggle( [duration ] [, easing ] [, complete ] )

//滑动
.slideDown( [duration ] [, easing ] [, complete ] )用滑动动画显示一
个匹配元素,方法将给匹配元素的高度的动画,这会导致页面的下面部分滑下去,弥补了显示的方式

.slideUp( [duration ] [, easing ] [, complete ] )用滑动动画隐藏一个匹配
元素,方法将给匹配元素的高度的动画,这会导致页面的下面部分
滑上去,当一个隐藏动画后,高度值达到0的时候,display 样式属性
被设置为none,以确保该元素不再影响页面布局。 display 样式属性将
被设置为none,以确保该元素不再影响页面布局。

//自定义
.animate( properties [, duration ] [, easing ] [, complete ] )  
//properties是一个CSS属性和值的对象,动画将根据这组对象移动。

.stop( [clearQueue ] [, jumpToEnd ] )
//停止匹配元素当前正在运行的动画。

展示,隐藏
渐变
滑动
动画

练习DEMO

预览地址

解密类型转换

解密类型转换

if的判断

if(xxx){
}

js 是如何处理的?做几道测试题看一看

题目

// 题目1:如下代码输出什么?
if ("hello") {
    console.log("hello")  //任何非空字符串都转换为boolean是true
}

// 题目2:如下代码输出什么?
if ("") {
    console.log('empty')  //空字符串转换boolean值为false
}

// 题目3:如下代码输出什么?
if (" ") {
    console.log('blank')  //任何非空字符串都转换为boolean是true
}

题目

// 题目4:如下代码输出什么?
if ([0]) {
    console.log('array')  //任何对象除null转换为boolean值为true
}

if('0.00'){
  console.log('0.00')  //任何非空字符串都转换为boolean是true
}

原理

类型 结果
Undefined false
Null false
Boolean 直接判断
Number +0, −0, 或者 NaN 为 false, 其他为 true
String 空字符串为 false,其他都为 true
Object true

== 的判断

对于==的判断,js是怎么处理的?做几道题看看

题目

"" == 0  //题目1 true
" " == 0  //题目2  true 
"" == true  //题目3 false
"" == false  //题目4
" " == true  //题目5

题目

!" " == true  //题目6 false
!" " == false  //题目7 true
"hello" == true  //题目8 false
"hello" == false //题目9 false
"0" == true  //题目10 false
"0" == false  //题目11 true
"00" == false  //题目12 true
"0.00" == false  //题目13  true

题目

undefined == null  //题目14 true
{} == true  //题目15 false
[] == true  //题目16 false
var obj = { 
  a: 0, 
  valueOf: function(){return 1} 
} 
obj == "[object Object]"  //题目17 false
obj == 1  //题目18 true
obj == true  //题目19 true

解密

x y 结果
null undefined true
Number String x == toNumber(y)
Boolean (any) toNumber(x) == y
Object String or Number toPrimitive(x) == y
otherwise otherwise false

toNumber

type Result
Undefined NaN
Null 0
Boolean ture -> 1, false -> 0
String “abc” -> NaN, “123” -> 123

toPrimitive

对于 Object 类型,先尝试调用 .valueOf 方法获取结果。
如果没定义,再尝试调用 .toString方法获取结果

相等判断为数字,if(XXX)里转换为boolean

文本属性都在这了

字体属性

font-size

  • 语法:font-size:<length> | <percentage> | <absolute-size> | <relative-size>
    • 后面两个值不常用有small,middle ,large
font-size:12px;
  font-size:16px;
  font-size:2em;(24px)
  font-size:200%;

font-family

  • 语法:font-family:[<family-name> | <generic-family>]#
    • <generic-family>=serif | sans-sarif
font-family:arial;
font-family:arial,Verdana,sans-sarif;
font-family:Verdana,"微软雅黑";

font-weight

  • 语法:font-weight:normal|bold|bolder|lighter|100|200|..|900
    • font-weight:normal默认
font-weight;bold;

font-style

  • 语法:font-style:normal|italic|oblique
    • oblique:倾斜
    • italic: 斜体
font-style:italic;

line-height

  • 语法:line-height:normal|<number>|<length>|<percentage>
    • normal不是固定的,由浏览器决定
line-height:40px;
  line-height:3em;
  line-height:300%;
  line-height:3;
300%和3显示是一样的,有哪些区别呢?
  修改里面某一段文字大小时;
line-height为number时,继承为直接继承,所以如果给下面的元素设置行高,等于字体大小乘以number值(不计算,直接继承)

而line-height:百分比;先计算,在继承,

结合上面五个属性:

font

  • 语法:font:[[<font-size>||<font-weight>]?<font-size>[/<line-height>]?<font-family>]
    • 语法可以看出:font-style font-weight可选,font-size必填项,font-family也是必填项,line-height可选,但有的时候前面有/
缩写:
font:30px/2 "Consolas",monospace;
font:20px arial,serif;
font:italic bold 20px/2 arial,serif

color

  • color:red;
  • color:#ffffff;
  • color:rgb(255,0,0);
  • color:rgba(255,0,0,1);
  • color: transparent;

对齐方式

text-align

  • 语法:text-align:left|right|center|justify
    • justify:两端对齐

vertical-align

  • 语法:vertical-align:baseline|sub|super|top"text-top|middle|bottom|text-bottom|<percentage>|<length>
    • baseline:基线
    • sub:下标
    • suoer:上标
    • middle:垂直居中

vertical-align

text-indent 首行缩进

  • text-indent:<length>|<percentage>
text-indent:2em;首行缩进两个字

text-indent


格式处理

white-space设置换行是否保留,空格是否合并等

  • white-space:normal|nowrap|pre|pre-wrap"pre-line
    • nowrap不换行,字强制一行
    • pre 换行保留 空格和Tab保留 不换行 完整保留代码格式
    • pre-wrap 在pre的基础上允许换行
    • pre-line 只保留换行,空格合并掉

word-wrap 单词换行

  • word-wrap:normal|break-word
    • break-word 把一个长单词允许自动换行

word-break

  • word-break:normal|leep-all|break-all
    • break-all 任意字母都可以换行

文本修饰

text-shadow 文字阴影

  • text-shadow:none|[<length>{2,3}&&<color>?]#
    • color可不写,颜色为文字颜色
    • #代表可写多个shadow,逗号分开
    • 2到3个length值

image.png

text-decoration下划线

  • 语法:text-decoration:none | [underline||overline||line-through]
    • 语法可以知道,可以写多条线
    • underline:下划线
    • overline;上划线

高级设置

css ...的实现

  • text-overflow:clip | ellipsis
text-overflow:ellipsis;
overflow:hidden; 文字超出隐藏,溢出截掉
white-space:nowrap;不换行

鼠标形状的设置 Cursor

cursor

  • url()自定义
  • auto:自动处理
  • default 普通光标
  • none 消失
  • help 带问号的
  • pointer手型
  • zoom-in放大镜类似的
  • move 十字移动鼠标

inherit 强制继承

很多文本类型都可以继承

Date

创建日期

  • 表示当前时间
new Date()
  • 表示2017年9月1日
new Date(2017,8)  //月份从零开始,小一月
new Date(2017,4)  //2017-5

date.getXXX()

  • 获取时间
var date = new Date(2017,9,3,14,57,18)  //2017-10-3 14:57:18
date.getFullYear()  //2017
date.getMouth()  //9
date.getDate()  //3
date.getHours()  //14
date.getMinutes  //57
date.getSeconds()  //18

var date = new Date();
alert('今天是' + date.getFullYear() + '年' + (date.getMonth() + 1) + '月' + date.getDate() + '日');
alert('现在是北京时间' + date.getHours() + '点' + date.getMinutes() + '分' + date.getSeconds() + '秒');

我们希望得到的时间是看的简单的,这样的(2017-10-3 14:57:18)但是在浏览器上的到的结果是这样的

var date = new Date(2017,9,3,14,57,18)
date
Tue Oct 03 2017 14:57:18 GMT+0800 (**标准时间)

格式化

function padding(number){
  return number < 10 ? '0' + number : '' + number;
}
function format(date) {
  return date.getFullYear() + '-' 
  + padding(date.getMonth() + 1) + '-' 
  + padding(date.getHours()) + ':' 
  + padding(date.getMinutes()) + ':' 
  + padding(date.getSeconds());
}
var date = new Date();  
alert(date);  //Fri Sep 01 2017 11:24:40 GMT+0800 (**标准时间)
alert(format(date));  //2017-09-01 11:24:40

date.setXXX()

  • 设置日期
var date = new Date(2017,9,3,14,57,18)  //2017-10-3 14:57:18
date.setFullYear(2050)  //2050-10-3 14:57:18
date.setMouth(11)  //2050-12-3 14:57:18
date.setDate(16)  ///2050-12-16 14:57:18

如果是

date.setDate(35)  //2017-11-4,自动计算

求天数?

function getDays(year, month){
	var date = new Date(year, month, 0);
	return date.getDate();
}

alert('2001年2月有' + getDays(2001, 2) + '天。');
alert('2001年3月有' + getDays(2001, 3) + '天。');

Date -> Number

var date = new Date(2017,9,3,14,57,18)
date.getTime()  //1507013838000 距1970-1-1 00:00:00的毫秒数

Number -> Date

new Date(1507013838000)
date.getTime(1507013838000)

JS数值(Math)

数值

  • 100 整型
  • 3.14 浮点型
  • 3.14e7 科学计数法
  • 0xfa1b 16进制

在数值中除了加减乘除求余外,还有一些四舍五入,绝对值等在Js中是怎样运算的呢?我们来看一下

先看一个问题?

如何获取一个大于等于0且小于等于9的随机整数?

Math.floor(Math.random()*10)

下面是一些数学数值方法

绝对值

  • Math.abs(x)
Math.abs(5)   // 5
Math.abs(-5)  // 5

四舍五入

  • Math.round(x)
Math.round(1.1)   // 1
Math.round(1.9)   // 2

向上取整

  • Math.ceil(x)
Math.ceil(1.1)   // 2
Math.ceil(1.9)   // 2

向下取整

  • Math.floor(x)
Math.floor(1.1)   // 1
Math.floor(1.9)   // 1

获取最大的值

  • Math.max([value1[,value2[,...]]])
Math.max(1,2)      // 2
Math.max(-1,-2,-3) // -1

获取最小的值

  • Math.min([value1[,value2[,...]]])
Math.min(1,2)      // 1
Math.min(-1,-2,-3) // -3

随机数

  • Math.random()
    • 0=<随机数<1
Math.random()  // 大于等于0且小于1的随机数

其他的

求值方法

下面看几个实际应用,我们应该怎么用JS解决

用户输入小数点怎么处理

parseInt(string,radit)

  • 输入一个字符串
  • radit进制
parseInt('1.1')    // 1  字符串转换为数值
parseInt('1.9')    // 1
parseInt('1b2.4')  // 1   非数字后面会忽略
parseInt('www')    // NaN  不能识别

如何保留小数点

从上图我们可以看出,如果继续使用parseInt(string)肯定是不行的,它会舍去小数点,那我们应该用什么呢?

###parseFloat(string)

  • 输出浮点型
parseFloat('100.1')  // 100.1
parseFloat('12.4b5') // 12.4
parseFloat('www')    // NaN

对于上面的需求,我们会有一些疑惑,像12.4b5这样的数值,肯定是用户输入错误,那我们怎么样识别出来它不是数值呢?

Number(value)

Number('100.1')    // 100.1 转换为数值
Number('12.4b5')   // NaN 一个不能识别,就不能识别了
Number('www')      // NaN

区别

保留两位小数点

上面我们只需要两个小数点就可以了,该怎么做呢?

num.toFixed(digits)

  • digits保留几位小数点?
(100.123).toFixed(2)   //  "100.12"
(100.123).toFixed(0)   //  "100"

盒模型汇总

盒模型其实就是一个个的生活中盒子类似的东西,比方我们拿快递的盒子,那是什么样的呢?

快递小哥的盒子

那我们再来看一下CSS盒模型是什么样子的?

css盒模型


是不是非常的相似,那我们就来来学习一下css中的盒模型

盒模型概念、width、 height、 padding、 margin(水平居中)、 border、 border-radius、 overflow、 box-sizing、 box-shadow、 outline

width

  • 语法:width: <length> | <percentage> | auto | inherit
    • length:长度,单位有px em rem...等
    • percentage: 百分比 %
    • auto width默认值
  • min-width
    • min-width属性为给定元素设置最小宽度。它可以阻止 width属性的应用值小于 min-width的值。
  • max-width
    • max-width 属性用来给元素设置最大宽度值. 定义了max-width的元素会在达到max-width值之后避免进一步按照width属性设置变大.

height

  • 语法:height: <length> | <percentage> | auto | inherit
    • length:长度,单位有px em rem...等
    • percentage: 百分比 %
    • auto height默认值
  • min-height
    • min-height 通常用来设置一个元素的最小高度。这个属性(min-height)不允许一个元素的高度(height)小于这个元素指定的最小高度(min-height)。
    • min-height的值会覆盖max-height 和height(译者:这句话我的理解是,当该元素的高度小到最小高度的时候,最大高度和高度值将不会有效。)
  • max-height
    • max-height这个属性会阻止 height属性的设置值变得比 max-height
       更大。
    • max-height 属性用来设置给定元素的最大高度. 如果height
       属性设置的高度比该属性设置的高度还大,则height 属性会失效.
    • max-height 重载(覆盖掉) 但是min-height又会重载(覆盖掉max-height)

参考:box-Model


在介绍padding margin border等属性之前,我们来了解几个知识,以padding为例,margin border也适合以下规则

Top Left Bottom Right

上右下左顺时针

值缩写

值缩写


padding

  • 语法:padding: [<length> | <percentage>]{1,4} | inherit

image.png

margin

  • 语法:padding: [<length> | <percentage> | auto]{1,4} | inherit

image.png

  • margin合并

    • 毗邻元素,外边距会合并,取较大值
    • 父元素与第一个/最后一个子元素也会合并(不是所有的情况)
    • margin合并问题,详见 MDN 外边距合并
      image.png
  • 水平居中

    • margin:0 auto;

border

说明: ... 代表不常用的

  • 语法:border: [<border-width>||<border-style>||<border-color>] | inherit
  1. 语法:border-width:[<length>|...]{1,4} | inherit
  2. 语法:border-style:[solid | dashed | dotted | ...]{1,4} | inherit
  3. 语法:border-color:[<color>| transparent]{1,4} |inherit

border


border-radius

圆角

  • 语法:border-radius:[<length>|<percentage>]{1,4}[/<length>|<percentage>]{1,4}]?
    • 语法代表一个是水平半径,一个是垂直半径,可以最多有八个值,中间用/分开

image.png

overflow

  • overflow;visible| hidden | scroll |auto
    • overflow:visible默认值
    • overflow:hidden 超出隐藏
    • overflow:scroll一直显示滚动条,不管又没有超出
    • overflow:auto 内容少的时候没有滚动条,多了就有
  • overflow-x
  • overflow-y

box-sizing

  • box-sizing:content-box| border-box | inherit

box-sizing

  • content-box 是默认值。如果你设置一个元素的宽为100px,那么这个元素的内容区会有100px宽,并且任何边框和内边距的宽度都会被增加到最后绘制出来的元素宽度中。
    • 尺寸计算公式:width = 内容的宽度,height = 内容的高度。宽度和高度都不包含内容的边框(border)和内边距(padding)。
  • border-box 告诉浏览器去理解你设置的边框和内边距的值是包含在width内的。也就是说,如果你将一个元素的width设为100px,那么这100px会包含其它的border和padding,内容区的实际宽度会是width减去border + padding的计算值。大多数情况下这使得我们更容易的去设定一个元素的宽高。
    • width = border + padding + 内容的 width,
      height = border + padding + 内容的 height。

box-shadow(阴影)

  • box-shadow:none| <shadow>[,<shadow>]*
  • <shadow>:inset?&&<length>{2,4}&&<color>?
    • inset 内阴影
    • color可写可不写,不写就是字体的颜色
    • 阴影不占空间

值的意思

阴影用法

outline(轮廓)

  • outline:[<outline-width>||<outline-style>||<outline-color>]
    • 不占空间
    • borde外

image.png


关于CSS属性的浏览器兼容性,可以通过 caniuse 查询。

  • border-radius ie8及以下不支持

  • box-sizing ie7及以下不支持

  • box-shadow ie8及以下不支持

  • outline ie7及以下不支持

display的用法及特性

什么是布局?

  • 将元素以正确大小摆放在正确的位置上
  • 元素的摆放模式

display

  • 设置元素的显示方式
  • display: block | inline | inline-block | none

display:block

  • 默认宽度为父元素宽度(影响大小)
  • 可设置宽高(影响大小)
  • 换行显示(影响位置)

默认块级元素:div p h1-h6 ul form...

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>display block</title>
	<style>
		.sample{background-color: pink}
		
		.sample{width: 200px;height: 200px;}  /*可设置宽高*/
	</style>
</head>
<body>
	<span>before block</span>
	<div class="sample">display:block;</div>
	<div>after block</div>
</body>
</html>

display:inline

  • 默认宽度为内容宽度
  • 不可设置宽高
  • 同行显示

默认行内元素: span a label cite em...

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>display inline</title>
	<style>
		.sample{background-color: pink}
			
	 	.sample{width: 200px;height: 200px;} 
		em{display: block;}
	</style>
</head>
<body>
	<span>before inline</span>
	<span class="sample">display:inline;</span>
	<em>after inline</em>
</body>
</html>

display:inline-block

  • 默认宽度为内容宽度
  • 可以设置宽高
  • 同行显示
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>display inline-block</title>
	<style>
		.sample{background-color: pink}
			
		.sample{display: inline-block;}
		.sample{width: 200px;height: 200px;}
		.sample{vertical-align: middle;}
	</style>
</head>
<body>
	<span>before inline-block</span>
	<span class="sample">display:inline-block;</span>
	<em>after inline-block</em>
</body>
</html>

display:none

  • 设置元素不显示

display:none vs visibility:hidden

  • display:none 不显示也不再原来的位置
  • visibility:hidden 只是隐藏还在原来的位置
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>display none demo</title>
	<style>
		.parent{margin: 30px;border: 1px solid pink;}
			
		/*.dn{display: none;}*/
		/*.vh{visibility: hidden;}*/
	</style>
</head>
<body>
	<div class="parent">
		<div class="dn">display: none</div>
	</div>
	<div class="parent">
		<div class="vh">visibility: hidden</div>
	</div>
</body>
</html>

布局-块级元素水平居中

margin:auto;

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>块级元素的水平居中</title>
	<style>
		.content{width: 300px;height: 300px;background-color: pink;}

		.content{margin:0 auto;}
	</style>
</head>
<body>
	<div>
	  <div class="content">content area</div>
	</div>
</body>
</html>

布局-居中导航

display:inline-block

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>居中导航</title>
	<style>
		ul{text-align: center;height: 30px;line-height: 30px;background-color: #f00;}
		li, a{display: inline-block;width: 80px;height: 100%;}
		li{margin: 0 5px;list-style: none;}
		a, a:hover, li.cur a{color: #fff;text-decoration: none;}
		a:hover, li.cur a{background-color: #c00}
	</style>
</head>
<body>
	<ul class="m-nav">
	  <li><a href="#">推荐</a></li>
	  <li class="cur"><a href="#">歌单</a></li>
	  <li><a href="#">大牌DJ</a></li>
	  <li><a href="#">歌手</a></li>
	  <li><a href="#">新碟上架</a></li>
	</ul> 
</body>
</html>

居中导航


如何实现浏览器兼容版的inline-block显示
display:inline-block;ie6、ie7下只有设置在默认显示方式为inline的元素上才会生效,请实现兼容ie6、ie7的通用的方式。

1、先使用display:inline-block,再使用display:inline;
div {
  display:inline-block;
}
div {
  display:inline;
}

2、先让块元素变为内联,再使用(zoom:1 或float属性等)触发块元素layout;
div{  
    display:inline-block; 
    *display:inline;
    *zoom:1;
}

从onClick谈事件代理和了解事件传播机制

javasriptdelegate这个词经常出现,看字面的意思,代理、委托。

要搞懂事件代理,我们先来看看什么是代理,相信我们生活中现在还有朋友在做微商的,而微商的产品就是一级一级代理,下家找上家拿货这样子,你卖了东西从上家拿货,这个过程相当于你也有了货

我们怎么从字面上来了解事件的代理呢?慢慢来,我们先来看一个需求,有这样一个列表,当我们每次点击的时候,就在控制台打印列表里的内容

作为一名新手,我经常这样绑定onclick事件

我会循环每一个li当我点击一个在控制台显示打印结果,全部绑定click事件,于是,我的代码是这样的

 <ul class="ct">
    <li>我是一号</li>
    <li>我是二号</li>
    <li>我是三号</li>
    <li>我是四号</li>
    <li>我是五号</li>
  </ul>
  <button type = "button" id="btn">增加</button>

var ul = document.querySelector(".ct")
for(var i=0;i<ul.children.length;i++){
  ul.children[i].onclick = function(){
    console.log(this.innerText)
  } 
}

代码没有问题
我觉得这样写的挺好的,可是有人说这样会耗费性能,那我就不管了,可是当我改了一下需求,我发现这个代码用的没那么舒服了

我在代码中通过js加入新的li,当我点击新的li时,控制台没有打印我的代码?怎么回事?

我加入了几这样的代码

var btn =document.querySelector("#btn")
var i =6
btn.addEventListener("click",function(){
  var node = document.createElement("li")
  node.innerText = "我是" + i++ + "号"
  ul.appendChild(node)
})

后面增加的li没有在控制台打印

这是为什么?因为原有的li跟我后面生成的li根本不是同时发生的,在创建新的li元素之前,已经给存在的li加事件了,好吧,那我怎么修改呢?难道要重新循环遍历,太麻烦了,

有人告诉我可以用代理,代理是什么,看了文章,好吧,修改一下代码

ul.addEventListener("click",function(e){
 // 检查事件源e.targe是否为Li
  if(e.target.nodeName.toLowerCase() == 'li'){
    console.log(e.target.innerText)
  }
})

成功了
新增新的点击li也会再控制台打印,解决了,于是耐心翻资料看了一下什么是事件代理:

定义:事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

那什么是冒泡呢?

  • 当一个元素上的事件被触发的时候,比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发。这一过程被称为事件冒泡

回到我们本文的这个例子,看看改动后的代码,我把onlick事件绑定到了ul标签上面,而不是li标签。于是,当我点击任何一个li标签(不管是动态生成的还是之前就有的)是,这个事件就开始冒泡,寻找父元素。由于我这里给ul绑定了onlick,那么这时,ul会捕获冒泡上来的onclick事件。

接着,如果,这个target刚刚好就是li标if(target.nodeName.toLowerCase() == 'li'),那么执行函数。

简单介绍一下事件传播机制,主要介绍DOM2.0

  • DOM2.0模型将事件处理流程分为三个阶段:一、事件捕获阶段,二、事件目标阶段,三、事件起泡阶段。如图:

事件传播

  • 事件捕获:当某个元素触发某个事件(如onclick),顶层对象document就会发出一个事件流,随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。在这个过程中,事件相应的监听函数是不会被触发的。

  • 事件目标:当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。

  • 事件起泡:从目标元素开始,往顶层元素传播。途中如果有节点绑定了相应的事件处理函数,这些函数都会被一次触发。如果想阻止事件起泡,可以使用e.stopPropagation()(Firefox)或者e.cancelBubble=true(IE)来组织事件的冒泡传播。

几个css的单位你需要了解一下

css长度单位

css 长度单位一般我们分为绝对长度单位相对长度单位

绝对长度单位

绝对长度单位是一个固定的值,它反应一个真实的物理尺寸。那么,常见的绝对长度单位有哪些呢?

  • in,英寸
  • cm,厘米
  • mm,毫米
  • pt,points
  • pc,Picas

这些单位都是拥有真实的物理尺寸的以及确定的换算关系,比如,1in = 2.54cm。我们平时在书写css代码时,当然也可以直接使用这些单位,并且也能够在屏幕上表现。不过由于这些单位都是绝对长度单位,往往不利于页面屏幕的渲染,这些绝对长度单位更多的使用场景往往是被用在印刷、打印等方向。

相对长度单位

CSS相对长度单位中的相对二字,表明了其长度单位会随着它的参考值的变化而变化,不是固定的。下面是常用的一些相对长度单位:

  • px,Pixels像素
  • em,元素的字体高度
  • ex,x-height,字母x的高度
  • %,百分比
  • ch,字符0的宽度
  • rem,根元素(html)的font-size
  • vw,viewpoint width,视窗宽度,1vw=视窗宽度的1%
  • vh,viewpoint height,视窗高度,1vh=视窗高度的1%
  • vminvmax

今天我们了解几个我们比较常用而且不容易记得几个css的单位:px em rem vw vh vmin vmax

px

px像素单位其实是和设备屏幕的分辨率是直接相关的。

在web开发中,像素现在仍然是典型(主流的)度量单位。当然,你可以在web开发的过程中采用其他的单位,但是往往这些单位在渲染时都被映射换算成像素。是我们最常使用的单位:

header{
    width: 100px;
    height: 100px;
    border: 1px solid #fff;
}
em

em的含义最初是指基于当前字体大写字母”M”的尺寸。所以当改变font-size的大小时,这个长度单位将会发生变化。

现代所有的浏览器中,都会有这样的一个默认值,即1em = 16px,所以即使你忘记了设置font-size也不要紧。

对于em我们需要注意:

基于当前元素的(如果没设置就是继承其父元素的)font-size
<div style="font-size: 12px;">
    <span style="font-size: 2em">em单位</span>
</div>

如上代码中,span标签中设置了font-size: 2em,因为其父标签设置了font-size: 12px,所以span标签的结果就是font-size: 24px

rem

rem单位是相对于字体大小的html元素,也称为根元素。
1rem = 根元素(html 节点)字体大小的倍数。根元素(html)的 font-size:16px

html {
  font-size: 10px; /* 不建议设置 font-size: 62.5%; 在 IE 9-11 上有偏差,具体表现为 1rem = 9.93px。 */
}

.sqaure {
  width: 5rem;  /* 50px */
  height: 5rem; /* 50px */
}

注意 中文版的 Chrome 不支持把 font-size 设置到到 12px 以下,因此可以考虑给根元素设置 font-size: 125%

px em rem 转换工具


rem与em的区别:

rem是相对于根元素(html)的字体大小,而em是相对于其父元素的字体大小
em最多取到小数点的后三位

<style>
  html{ font-size: 20px; }
  body{ 
    font-size: 1.4rem;  /* 1rem = 28px */
    padding: 0.7rem;  /* 0.7rem = 14px */
  } 
  div{
    padding: 1em;  /* 1em = 28px */
  }
  span{
    font-size:1rem;  /* 1rem = 20px */
    padding: 0.9em;  /* 1em = 18px */
  }
</style>

<html>
  <body>
    <div>   
      <span></span>  
    </div>
  </body>
</html>

在上面的代码中,我们将根元素(html)的字体大小font-size设为20px,
body的字体大小设为1rem,那么转换为像素就是28px(20 × 1.4),
接着我们又将div的padding设为1em,由于其基于父元素,所以转换为像素是28px ( 28 × 1),
然后我们又将span的字体大小设为1rem,也就是20px,由于其自身设置了字体大小,所以padding设为1em,转换为像素是20px(20 × 1),而不是乘以其父元素的字体大小28px(28 × 1)。

注意:当元素自身设置了字体大小,那么如果它的其他css属性也使用em单位,则会基于它自身的字体大小。(就像上面例子的span的padding一样)

基于上面这些原因,个人更倾向于使用rem,因为em使用不当的话,当出现多层继承时,会很容易混淆,比如:
<style>
  html{ font-size: 20px; }
  body{ 
    font-size: 0.9em;  /* 18px */
  } 
  div{
    font-size: 0.8em;  /* 14.4px */
  }
  span{
    font-size: 0.9em;  /*  12.96px */
  }
</style>

<html>
  <body>
    <div>   
      <span></span>  
    </div>
  </body>
</html>
使用em时,如果其祖先元素都是用了em,那么就会像上面一样,body继
承其父元素html的字体大小,而div又继承其父元素body的字体大小
,而span又继承其父元素div的字体大小,
最终span的字体大小最终是12.96px(20 × 0.9 ×0.8 × 0.9)。

vw、 vh

vw viewpoint width,视窗宽度,1vw=视窗宽度的1%
vh viewpoint height,视窗高度,1vh=视窗高度的1%

vh等于viewport高度的1/100.例如,如果浏览器的高是900px,1vh求得的值为9px。同理,如果显示窗口宽度为750px,1vw求得的值为7.5px

做一个占满高度的或者接近占满高度的幻灯片,可以用一个非常简单的方法实现,只要用一行CSS:
.cover{
    width: 100vw;
    height: 100vh;
}
vmin、vmax

vminvmax是相对于视口的高度和宽度两者之间的最小值最大值

如果浏览器的高为1100px、宽为700px,那么1vmin就是7px,1vmax就是11px;如果浏览器的高为800px,宽为1080px,那么1vmin也是8px,1vmax也是10.8px。

兼容性

注意: 选择使用什么字体单位主要由你的项目来决定,如果你的用户群都使用最新版的浏览器,那推荐使用rem,如果要考虑兼容性,那就使用px,或者两者同时使用。当然了,最好根据实际应用来使用相应的字体单位


参考博客:

博客来源
W3C
饥人谷
感谢各位所写的博客作为了参考,也使用了部分代码来加深印象,如果有侵权,请联系删除,谢谢

事件总结

DOM事件主要内容

  • 事件流
  • 事件注册
  • 事件对象
  • 事件分类
  • 事件代理

什么是DOM事件?

  • 事件是某个行为或者触发,比如点击、鼠标移动
  • 当用户点击鼠标时
  • 当网页已加载时
  • 当图像已加载时
  • 当鼠标移动到元素上时
  • 当用户触发按键时...

事件流

事件流

  • capture phase捕获事件
    • 事件对象通过目标的祖先从传播窗口到目标的父。这个阶段也被称为捕获阶段
  • target phase
    • DOM2级事件规定事件流包括三个阶段,事件捕获阶段,处于目标阶段,事件冒泡阶段,首先发生的是事件捕获,为截取事件提供机会,然后是实际目标接收事件,最后是冒泡阶段
  • bubble phase 冒泡
    • IE的事件冒泡:事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的元素

参考资料: 事件流


事件注册与触发

在讲述事件注册之前,讲一下前面的事件处理程序

  • HTML内联方式
    • 存在加载顺序问题,如果事件处理程序在html代码之后加载,用户可能在事件处理程序还未加载完成时就点击按钮之类的触发事件,存在时间差问题
    • 这样书写html代码和JavaScript代码紧密耦合,维护不方便
<input type="button" value="Click Here" onclick="alert('Clicked!');" />
  • JavaScript指定事件处理程序
    • 把一个方法赋值给一个元素的事件处理程序属性。
    • 可以删除事件处理程序,只需把元素的onclick属性赋为null即可
<input id="btnClick" type="button" value="Click Here" />

<script type="text/javascript">
    var btnClick = document.getElementById('btnClick');
    btnClick.onclick = function showMessage() {
        alert(this.id);
    };
</script>

事件注册(DOM2事件处理程序)

  • eventTarget.addEventListener(type,listener[,useCapture])
    • 事件类型
    • 事件处理方法
    • 布尔参数,如果是true表示在捕获阶段调用事件处理程序,如果是false,则是在事件冒泡阶段处理
var elem = document.getElementById("div1")
var clickHandler = function(){
  //to do
}
elem.addEventListener('click',clickHandler,false)

取消事件注册

  • eventTarget.removeEventListener(type,listener[,useCapture])
    • 事件类型
    • 事件处理方法
    • 布尔参数,如果是true表示在捕获阶段调用事件处理程序,如果是
elem.removeEventListener('click',clickHandler,false)
elem.onclick = null

事件触发

  • eventTarget.dispatchEvent(type)
elem.dispatch("click")
浏览器兼容性(IE6 7 8)

事件注册与取消

IE并不支持addEventListener和removeEventListener方法,而是实现了两个类似的方法

  • attachEvent
  • detachEvent
    这两个方法都接收两个相同的参数
    • 事件处理程序名称
    • 事件处理程序方法

事件触发

  • fireEvent(e)

no capture没有捕获

兼容性

事件对象(共有的)

当事件被触发的时候,会调用事件处理函数,在调用时间处理函数中,有一些信息,这些信息代表着事件的状态,这个就是事件对象

click为例

  • 属性
    • type类型:例如点击什么的...
    • target(srcElement IE低版本)目标元素,点击哪个就是那个
    • currentTarget:事件处理程序当前处理元素
  • 方法
    • stopPropagation()取消事件进一步捕获或冒泡
    • preventDefault()取消事件默认行为

阻止事件传播(冒泡)

  • event.stopPropagation()W3C
  • event.cancelBubble=trueIE

默认行为

  • event.preventDefault()W3C
  • event.returnValue = false IE

事件分类

事件种类

MouseEvent

事件类型 是否冒泡 元素 默认事件 元素例子
click(点击) Yes element focus/activation div
dbclick(双击) Yes element focus/activation div
mousedown Yes element drag/scroll text selection div
mousemove Yes element None div
mouseout鼠标离开 Yes element None div
mouseover鼠标移上去,进入子元素也会触发 Yes element None div
mouseup Yes element context menu div
mouseenter鼠标移上去 No element None div
mouseleave鼠标离开 No element None div

MouseEvent对象

  • 属性
    • clientX, clientY位置
    • screenX, screenY
    • ctrlKey,shiftKey,altKey,metaKey
    • button(0,1,2)鼠标左键还是右键还是滚轮

MouseEvent事件顺序

顺序

WheelEvent滚轮事件

事件类型 是否冒泡 元素 默认事件 元素例子
wheel Yes element scroll or zoom document div

FocusEvent 元素获得焦点和失去焦点

事件类型 是否冒泡 元素 默认事件 元素例子
blur(失去焦点) No Window,element None window,input
focus(获得焦点) No Window,element None window,input
focusin(即将获得焦点) No Window,element None window,input
focunsout(即将失去焦点) No Window,element None window,input
  • 属性
    • relatedTarget当一个元素失去焦点,另一个元素就会获得焦点

InputEvent 输入事件(W3C)

事件类型 是否冒泡 元素 默认事件 元素例子
beforeinput Yes Element Update DOM Element input
input Yes element None input
  • onpropertychange(ie)

KeyboardEvent键盘事件

事件类型 是否冒泡 元素 默认事件 元素例子
keydown Yes Element input bulr/focus input
keyup按下去松开触发 Yes element None input
  • 属性
    • key按下什么键,值是字符串
    • code
    • ctrlKey,shiftKey,altKey,metaKey
    • repeat持续按一个键

Event

事件类型 是否冒泡 元素 默认事件 元素例子
load(事件加载) NO Window,document,element None window,image,iframe
unload(类似页面退出) No Window,document,element None window
error(加载错误) NO Window,element None window,image
select(input被选择..) NO element None input,textarea
abort(esc) NO window,element None window,image
window对象 Image
load load
unload error
error abort
abort
<image alt = "photo" src = "www.baidu.com" onerror = "this.src = 'www.wangyi.com'"/>

UIEvent

事件类型 是否冒泡 元素 默认事件 元素例子
resize(窗体大小) NO Window,element None window,iframe
scroll(页面滚从) NO/Yes Document,element None document,div

事件代理

参考我写的另一片文章 从onClick谈事件代理和了解事件传播机制

总结一下不能冒泡的事件:

  • mouseenter
  • mouseleave
  • blur
  • focus
  • focusin
  • focusout
  • load
  • unload
  • error
  • select
  • abort
  • resize

CSS选择器汇总

对很多人来说都比较熟悉CSS选择器,对于我们在html里的各种标签,class类名,ID类名都非常熟悉,怎么选择他们来设置样式通过练习也早已熟记于心,今天我们就简单的把选择器做一个总结,方便以后使用

  • 元素选择器
  • 类选择器
  • id选择器
  • 通配符选择器
  • 属性选择器
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<style>
	/*通配符选择器*/
	*{
		color: green;
	}
	
	/*标签选择器*/
	p{
		color:blue;
	}
	
	/*类选择器*/
	.special{
		color: red;
	}
	.sterss{
		font-weight: bold;
		font-size: 20px;
	}
	
	/*ID选择器*/
	#hello{
		color: gray;
	}

	/*属性选择器-[att]*/
	[disabled]{
		background-color: #eee;
	}

	/* 属性选择器-[att=val]*/
	/*#nav{} == [id=nav]{}*/
	[type=button]{
		color: red;
	}

    /*属性选择器-[att~=val]*/
    /*选中所有class属性值为sports的元素*/
    /*.sports{}==[class~=sports]{}*/
    [class~=sports]{
    	color: orange;
    }

    /*属性选择器-[att|=val]*/
    [lang|=en]{
    	color: red;
    }

    /*属性选择器-[att^=val]*/
    [href^="#"]{
    	color: yellow;
    }

    /*属性选择器-[att$=val]*/
    [href$=pdf]{
    	color: red;
    }

    /*属性选择器-[att*=val]*/
    [href*="lady.163.com"]{
    	color: pink;
    }

</style>
<body>
	
<div>
	<!--  .classNmae
           - .号开头
           - classNmae必须以字母开头
           - 后跟字母, 数字, - , _
           - 区分大小写
           - 可以出现多个类名 -->
	<p>段落一</p>
	<p class="special">段落二</p>
	<p class="special sterss">段落三</p>
</div>
    <!--  #id
          - #
          - 字母, 数字, -, _
          - id必须以字母开头
          - 区分大小写
          - 只出现一次 -->
<div id="hello">
	Hello World
</div>
<div>
	I Love China
</div>

<!-- 属性选择器-[att] -->
<from action="">
	<div>
		<input disabled type="text" value="张三">
	</div>
	<div>
		<input type="password" placeholder="密码">
	</div>
</from>

<!-- 属性选择器-[att=val] -->

<from action="">
	<div>
		<input type="text" value="文本框">
	</div>
	<div>
		<input type="button" value="按钮">
	</div>
</from>

 <!-- 属性选择器-[att~=val] -->
 <h2 class="title sports">标题</h2>
 <p class="sports">内容...</p>

 <!-- 属性选择器-[att|=val] -->
 <p lang="en">Hello!</p>
 <p lang="en-us">Greetings</p>
 <p lang="en-au">Goods</p>
 <p lang="enfr">Bon</p>
 <p lang="cy-en">Gr</p>

 <!-- 属性选择器-[att^=val] -->
 <div>
 	<a href="http://www.w3.org">W3C</a>
 	<a href="#HTML">HTML</a>
 	<a href="#CSS">CSS</a>
 </div>

  <!-- 属性选择器-[att$=val]以什么结尾 -->
  <a href="http://xxx.doc">word文档.doc</a>
  <a href="http://xxx.pdf">pdf文件.pdf</a>

  <!-- 属性选择器-[att*=val]包含了某些值 -->
  <a href="http://lady.163.com/15.html">女性</a>
  <a href="http://lady.163.com/10.html">男性</a>
  <a href="http://sports.163.com/12.html">篮球</a>
  <a href="http://sports.163.com/16.html">足球</a>
</body>
</html>

选择器效果图

  • 伪类选择器
a:link{color:gray}    所有的链接变成灰色(只用于链接)
a:visited{color:red}    访问过的链接样式(只用于链接)
a:hover{color:green}    鼠标滑过链接时的样式
a:active{color:orange}    用户鼠标点击时的样式

:enabled
- input:enabled{}  元素可用的状态
:disabled
- input:disabled{}  元素不可用的状态
:checked
- input:checked{}  单选,复选框

:first-child   第一项
:last-child   最后一个
:nth-child(even)    偶数
:nth-child(3n+1)   表达式选择


:only-child  只有一个子元素

:first-of-type
:lat-of-type
:nth-of-type(even)

:only-of-type


:empty 选中没有子元素的标签
:root  html根标签
:target 
:lang()
  • 伪元素选择器
::first-letter   选中第一个字母

::first-line    选中第一行

::before{content:"before";}   在某个元素之前插入一些内容(当前插入了after)

::after{content:"after";}   在某个元素之后插入一些内容

::selection  应用于被用户选中的内容
  • 后代选择器和子选择器
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style>
		/*后代选择器*/
		.main h2{
			color: red;
		}
		/*子选择器*/
		.main>h2{
			color: green;
		}
	</style>
</head>
<body>
	<div class="main">
		<h2>标题一</h2>
		<div>
			<h2>标题二</h2>
			<p>段落一</p>
		</div>
	</div>
</body>
</html>
  • 相邻兄弟选择器和通用兄弟选择器
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style>
	/*相邻兄弟选择器,选择了h2后面面第一个p标签*/
		h2+p{
			color: red;
		}
		/*通用兄弟选择器*/
		/*选择的是h2后面所有的兄弟节点p标签*/
		h2~p{
			color: orange;
		}
	</style>
</head>
<body>
	<div>
		<p>段落一</p>
		<h2>标题</h2>
		<p>段落二</p>
		<p>段落三</p>
	</div>
</body>
</html>

动态REM

动态REM是手机专用的自适应方案

REM是什么

我们常用的单位有(有问题看MDN)

  • px
  • em (一个汉字M的宽度,对面试官说)
  • rem (root em根元素的font-size)
    • 根元素就是html 的 font-size 16px
  • vh viewport 的height高度 视口高度 100vh == 视口高度
  • vw viewport 的width 跨度 视口宽度 100vw == 视口宽度
  • 页面默认font-size:16px
  • chrome 默认最小12px,字体大小不要小于12px
  • REM就是根元素(html)的font-size大小

rem 和 em区别

css单位个人博客

  • 1em == 16px默认值
  • em自己的font-size
  • rem 根元素的font-size

动态REM

如果没有设计图,就不做响应式

给这些图再做响应式

  • 所有手机显示的界面都是一样的,只是大小不同

响应式需做不同的适配,例如:

  • 0~320px 一套css ?
  • 320px~375px 一套css ?
  • 375~414px 一套css ?
  1. 百分比布局
    • 缺点: 高度不能和宽度做配合,不知道宽度的大小
  2. 整体缩放
    • 一切单位以宽度为标准
// html的font-size宽度 等于 页面宽度
// 1 rem == html font-size == viewport width

 <script>
     var pageWidth = window.innerWidth
     document.write('<style>html{font-size:'+pageWidth+'px;}</style>')
 </script>
// 动态REM示例
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <script>
    var pageWidth = window.innerWidth;
    document.write("<style>html{font-size:"+ pageWidth +"px;}</style>")
  </script>
  <style>
    *{margin:0;padding:0;}
    .child{
      float:left;
      width:0.4rem;
      height:0.2rem;
      margin:0.05rem 0.05rem;
      background:#ddd;
    }
    body{
      font-size:16px;
    }
    .clearfix::after{
      content:'';
      display:block;
      clear:both;
    }
  </style>
</head>
<body>
  <div class="parent clearfix">
    <div class="child">box</div>
    <div class="child">box</div>
    <div class="child">box</div>
    <div class="child">box</div>
  </div>
</body>
</html>
// 重要的
 <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

// 可以调节宽度

 <script>
     var pageWidth = window.innerWidth
     document.write('<style>html{font-size:'+ pageWidth/10 +'px;}</style>')
 </script>
  • border怎么办?
    • 太小的直接用px,和rem混用
REM 可以与其他单位同时存在
 font-size: 16px;
 border: 1px solid red;
 width: 0.5rem;

上面的这些可以解决我们在移动端是配上的单位动态rem,但是对于我们来说,还是有一个痛点.单位的换算特别麻烦,先px,再rem,该怎么解决呢???

px自动变为rem

给自己一个警告!!!!

  • 为什么你学不好 LESS/SASS/Webpack/SCSS
    • 你不会命令行,你非要用 Windows (卸载windows)
    • 你不会英语(有些内容可以看中文翻译)
    • 你不会看文档(很重要的能力)

rem自动化转px 就用scss呗

  • 先自己尝试使用scss

轮播实现原理

无缝轮播

  • css需要让图片或者文本水平排列,overflow:hidden隐藏其他图片
  • 整体图片向左/右偏移,就会出现不同的照片

		/*设置父容器宽高,隐藏后面的元素*/
		.carousel{
			width: 320px;
			height: 180px;
			overflow: hidden;

		}

		/*特别重要的一步,不管容器有多宽,元素排成一列*/
		.carousel .img-ct{
			width: 1280px;
			overflow: hidden;
		}

轮播示意图
元素排成一列,设置总宽度

  • 但是当我们到最后一张照片时,后面就没有了,怎么循环轮播呢?
    • 可以clone头位元素和末尾元素
    • 可以改变dom的顺序
  • 立刻整体移位,由clone的3,移位到真正的3
    clone元素

把css样式写好,我们就用jQuery把逻辑写一下

  • 克隆第一个元素
//图片容器
var $imgCt = $("img-ct")
//获取图片的数量
var $imgs = $(".carousel .img-ct>li")
var imgCount = $imgs.length
//图片的宽度
var imgWidth = $imgs.width()
//把第一个图片clone到最后
$imgCt.append($imgs.first().clone())

注意有一点区别

jQuery区别

当我门克隆元素完成的时候,需要注意一点的是图片的总宽度
clone元素跑下面了
我们可以看到多出来两个克隆的元素,超出ul的长度,不水平排列了,所以我们应该设置长度在js中,而不是css里,不然一旦是其他数量的图片修改特别麻烦

//计算父容器总宽度
$imgCt.width((imgCount +2)*imgWidth)

下面就是写两个函数,一个往左点击偏移,一个往右点击偏移

//函数展示上一页
$nextBtn.click(function(){
	playNext()
})
//展示下一页
$preBtn.click(function(){
	playPre()
})
//点击下一页图片往左偏移
function playNext(){
	$imgCt.animate({
		//原来基础上在减小宽度
		left: "-=" +imgWidth
}
function playPre(){
	$imgCt.animate({
		//原来基础上在减小宽度
		left: "+=" +imgWidth
    })
}

但是有出先了一个问题,当我一直往一边点击时,当图片偏移完了.结果出现了空白,该怎么解决呢?我们需要让点击到最后一张图片时,立即回到第一张,循环,该怎么做呢?

//把上面的函数改一下
var pageIndex = 0
//点击下一页图片往左偏移
function playNext(){
	$imgCt.animate({
		//原来基础上在减小宽度
		left: "-=" +imgWidth
	},function(){
		//点击一次pageIndex加一次
		pageIndex++
		//如果pageindex的值等于了图片的数量
		if (pageIndex === imgCount) {
			//pageindex立刻回到第一张图片
			pageIndex = 0
			//容器初始化值为图片宽度
			$imgCt.css({left: -imgWidth})
		}
	})
}

打印pageIndex

大家看上面的动图,会发现,pageIndex,一直在0123循环,因为图片数量为4,所以判断当pageIndex为图片的数量时,使pageindex值返回去做判断,设置偏移量就可以了

  • 那怎么配合下面的选项卡点击呢?
//把这个函数调用放在左右点击click事件中
function setBullet(){
	//获取li,然后移除所有的active,并给下标添加class为actie
	$bullets.removeClass("active").eq(pageIndex).addClass("active")
}

圆点的样式跟着点击

  • 现在可以写当点击下面圆点图片动画的函数
//点击选项卡
$bullets.click(function(){
	// 获取下标
	var index = $(this).index()
	console.log(index)
	//如果点击的下标比轮播图片的下标大
	if (index > pageIndex) {
		//执行next函数,往左偏移,到达对应位置
		playNext(index - pageIndex)
	}else if (index < pageIndex) {
		playPre(pageIndex-index)
	}
})

当然还需要修改一下其他函数的参数
  • 最后再添加一个定时器,就可以自动轮播了
setInterval(function(){
	playNext(1)
},2000)

好了,到了这里,一个轮播图就完成了
看到这个轮播,我们可以抽离出一些函数:

playNext()
playPre()

渐变轮播

JS类型和隐式类型转换

##类型

  • 原始(值)类型:Undefined Null Number String Boolean
  • 对象(引用)类型:Object

对象类型

原始类型和对象类型的区别

区别

区别

隐式类型转换

  • 数字运算符
    • 数字 + 字符串 数字隐式转换为字符串
  • .
    • 所有的直接量用点号调用某个方法时,JS运行环境会转化会成对应的对象类型用console.dir可以打印看出
  • if语句
  • ==

隐式类型转换结果

##显式类型转换方法

  • Number(), String(), Boolean()
  • parseInt(),parseFloat()
  • !, !!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.