yym-yumeng123 / blog Goto Github PK
View Code? Open in Web Editor NEWyym写博客的地方,见证自己一步步的进步
yym写博客的地方,见证自己一步步的进步
命令行对我们来说一直是一个很高深的东西,今天让我们进入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! 不保存强制退出
1.命令格式:
pwd [选项]
2.命令功能:
查看”当前工作目录“的完整路径
3.常用参数:
一般情况下不带任何参数
如果目录是链接时:
格式:pwd -P 显示出实际路径,而非使用连接(link)路径。
Position
-设置定位方式top
,right
,bottom
,left
,z-index
--设置位置top right bottom left
元素边缘距参照物的边缘的距离
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
z轴上的排序:默认为z-index:0; 正值越大,在z轴上越在上面,在下面的会被覆盖.
z-index:-value;值可为负值,在z-index:0;
是不是值越大约在上面呢?不一定
z-index栈
上图有两个定位元素,如果给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: static | relative | absolute | fixed
position:relative
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>
三行自适应布局
<!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
说起兼容性,我们先用can I Use
看看flex
兼容性如何
CSS 3
部分,IE9
以下不支持,现代浏览器指的就是IE9
及以上的浏览器那什么是flex弹性布局
呢?
MDN flex
给出了这样的定义:弹性布局是指通过调整其内元素的宽高
,从而在任何显示设备上实现对可用显示空间最佳填充的能力
。弹性容器扩展其内元素来填充可用空间,或将其收缩来避免溢出。在学习flex
弹性布局之前,我们先看几个名词flex Terms
flex container弹性容器:
包含着弹性项目的父元素。flex item弹性元素:
弹性容器的每个子元素都称为弹性元素。main axis主轴:
弹性项目沿其依次排列的那根轴称为主轴(main axis)cross axis辅轴:
垂直于主轴的那根轴称为侧轴(cross axis)。我们知道了flex弹性布局
,如何在css中创建弹性容器
flex container
display:flex :
我们之前创建块级元素,行内元素,块级行内元素
,都是用display
来创建的,那我们的弹性布局就可以用display:flex
弹性元素flex item
在flex弹性容器
中的元素都是弹性元素
文档流中
的子元素<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>
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-flow: <'flex-direction'> || <'flex-wrap'>
flex-flow
属性是 flex-direction
和 flex-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>
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)的拉伸因子。弹性布局元素宽度 = 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-shrink:<number>
flex
元素的收缩规则。flex
元素仅在默认宽度之和大于容器的时候才会发生收缩,其收缩的大小是依据 flex-shrink
的值。正常布局空间超出分配超出的负值空间
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: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>
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-self:auto | flex-start | flex-end | center | baseline | stretch
flex-item
在cross-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>
参考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']
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 修改
var tel = [110,114,120]
tel.indexOf(110) //0 索引位置
tel.indexOf(119) //-1 没有返回-1
当前元素
当前元素索引值
整个数组
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)
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}]
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}
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]
var a=new Array(1,2,3);
a.unshift(4);
console.log(a);//[4, 1, 2, 3]
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]
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]
splice方法
返回一个由删除元素组成的新数组,没有删除则返回空数组替换
删除
添加
var num = [1,2,3,4,5,6]
num.slice(1,4) // [2, 3, 4]
num // [1, 2, 3, 4, 5, 6]
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]
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
var scores = [60,70,80,90]
var addScore = function(item,index,array){
return item+5
}
scores.map(addScore)
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
只能操作一个值的操作符叫做一元操作符。
有递增(++)
和递减(--)
操作符,有两个版本:
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
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
乘法
乘法操作符是由一个(*)表示,用于表示两个数值的乘积处理特殊值,遵循以下规则:
除法
除法操作符有一个(/)表示,
例:var result = 66/11;
处理特殊值,遵循以下规则:
求模
求模(余数)操作符有一个(%)表示,
例:var result = 26 % 5; //等于1
,处理特殊值,遵循以下规则:
加性操作符
加法操作符用(+)表示。
例: var result = 1 + 2;
处理特殊值,遵循以下规则:
toString()
方法取得相应的字符串值,然后再应用前面的关于字符串的规则,对于undefined和null
,则调用String()
函数取得字符串.var result = 5 + 5;
alert(result); // 10
var result1 = 5 + "5";
alert(result1); // "55"
减法
减法操作符用(-)表示,
var result = 2 - 1;
处理特殊值,遵循以下规则:
var result1 = 5 - true ; // 4 ,因为true转换为1
var result2 = NaN - 1 ; // NaN
var result3 = 5 - "" ; // 5, 因为""被转换为0
var result4 = 5 - null ; // 5,因为null转换为0
关系操作符用于对两个值得比较,返回时布尔值。包括:
小于(<)、大于(>)、大于等于(>=)、小于等于(<=)
当关系操作数使用了非数值,遵循以下规则:
ECMAScript提供两组操作符:
相等 和 不相等
----先转换再比较,全等 和 不全等
----仅比较而不转换
相等和不相等
相等操作符有
==
两个等号表示,返回布尔值,不相等操作符由!=
叹号后跟等号组成,这两个操作符先转换再比较(强制转换)
转换遵循基本原则:
全等和不全等
全等操作符由
===
三个等于号表示,只在两个操作数未经转换就相等的情况下返回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).
逻辑非
逻辑非由一个感叹号
!
表示,返回布尔值,逻辑非操作先将其转化为布尔值,然后取非对其求反.
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 |
逻辑与操作可以应用于任何类型的操作数,不仅仅布尔值,其他数值类型,遵循以下规则:
逻辑与操作属于短路操作,即如果第一个操作数能够决定结果,不会对第二个操作数求值.
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 |
与逻辑与操作相似,也遵循类似规则:
逻辑或操作也属于短路操作,即如果第一个操作数为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
虽然不常见,但是这个例子可以理解逗号的这种行为
.
这些都是一些常见的操作符,好好掌握,嘿嘿,还有 位操作符 还没太熟练,在研究一下,继续努力
每个载入浏览器的HTML文档都会成为document对象。document对象包含了文档的基本信息,我们可以通过JavaScript对HTML页面中的所有元素进行访问、修改。
document.doctype //获取格式
document.title //获取标题
document.characterSet
document.head
document.body
document.images
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
方法用于新建一个文档,供write方法写入内容。它实际上等于清除当前文档,重新写入内容document.close
方法用于关闭open方法所新建的文档。一旦关闭,write方法就无法写入内容了。document.write
方法用于向当前文档写入内容。只要当前文档还没有用close方法关闭,它所写入的内容就会追加在已有内容的后面。document.open();
document.write("hello");
document.write("world");
document.close();
Element 对象可以拥有类型为元素节点、文本节点、注释节点的子节点,DOM提供了一系列的方法可以进行元素的增、删、改、查操作
nodeName
:元素标签名,还有个类似的tagNamenodeType
:元素类型className
:类名id
:元素idchildren
:子元素列表(HTMLCollection)childNodes
:子元素列表(NodeList)firstChild
:第一个子元素lastChild
:最后一个子元素nextSibling
:下一个兄弟元素previousSibling
:上一个兄弟元素parentNode、parentElement
:父元素getElementById
方法返回匹配指定ID属性的元素节点。如果没有发现匹配的节点,则返回nullelement = document.getElementById(id)
==>
var elem = document.getElementById("test");
getElementsByTagName
方法返回所有指定标签的元素(搜索范围包括本身)。返回值是一个HTMLCollection对象
,也就是说,搜索结果是一个动态集合,任何元素的变化都会实时反映在返回的集合中。这个方法不仅可以在document
对象上调用,也可以在任何元素节点上调用。collection = element.getElementsByTagName(tagname)
collection = element.getElementsByTagName(tagname)[index]
collection = element.getElementsByTagName("*")//通配符
==>
var paras = document.getElementsByTagName("p");
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
方法用于选择拥有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属性最好设为不一样的值。
querySelector
方法返回匹配指定的CSS选择器的元素节点。如果有多个节点满足匹配条件,则返回第一个匹配的节点
。如果没有发现匹配的节点,则返回null。list = element.querySelector(selector)
==>
var el1 = document.querySelector(".myclass");
var el2 = document.querySelector('#myParent > [ng-click]');
querySelector方法无法选中CSS伪元素。
querySelectorAll
方法返回匹配指定的CSS选择器的所有节点
,返回的是NodeList
类型的对象。NodeList
对象不是动态集合,所以元素节点的变化无法实时反映在返回结果中。elementList = document.querySelectorAll(selectors);
querySelectorAll方法的参数,可以是逗号分隔的多个CSS选择器
返回所有匹配其中一个选择器的元素。
var matches = document.querySelectorAll("div.note, div.alert");
createElement
方法用来生成HTML元素节点。element = document.createElement(tagName)
==>
var newDiv = document.createElement("div");
createTextNode
方法用来生成文本节点,参数为所要生成的文本节点的内容。var newDiv = document.createElement("div");
var newContent = document.createTextNode("Hello");
createDocumentFragment
方法生成一个DocumentFragment对象。var docFragment = document.createDocumentFragment();
DocumentFragment
对象是一个存在于内存的DOM片段,但是不属于当前文档,常常用来生成较复杂的DOM结构,然后插入当前文档。这样做的好处在于,因为DocumentFragment不属于当前文档,对它的任何改动,都不会引发网页的重新渲染,比直接修改当前文档的DOM有更好的性能表现。
<li class="user">我是li元素</li>
user.textContent //我是li元素
user.textContent = "yym"
==>
<li class="user">yym</li>
var achild = element.appendChild(achild)
==>
var newDiv = document.createElement("div");
var newContent = document.createTextNode("Hello");
newDiv.appendChild(newContent);
var achild = element.insertBefore(achild,referenceChild)
==>
var newDiv = document.createElement("div");
var newContent = document.createTextNode("Hello");
newDiv.insertBefore(newContent, newDiv.firstChild);
newDiv.replaceChild(newElement, oldElement);
child = element.removeChild(child)
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>
自己以前的命名规范,以及编码规范比较乱,现在准备用这些,让代码变得干净
(大声叫出它的名字,翻译成英文)
<!-- 不好 -->
<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 -- 弹窗
tab
用两个空格表示css的
:后加个空格, {前加个空格#fff
0.5s -> .5s
;0不用加单位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;
}
曾经有一段时间,XML是互联网上传输结构化数据的事实标准,但很多人认为XML过于繁琐,冗长.为了解决这一问题,2006年Duglas Crockford把JSON(javaScript Object Notation,对象表示法)作为IETFRFC4627提交给IETF,而JSON的应用早在2001年就开始了,JSON是javascript的严格的子集,表示结构化数据
关于JSON,它是一种数据结构,不是一种编程语言
最简单的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解析器基本上使用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()
第三个参数用于控制结果中的缩进和空白符,如果参数是一个数值,表示每个级别缩进的空格数 数值和字符串都不能超过10var 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
}
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)
序列化对象顺序
toJSON()
方法而且能通过它取得的有效值,则调用该方法,否则,返回对象本身.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.stringify() JSON.parse()
使用CSS更改非inline-block水平元素为inline-block水平,元素之间会出现缝隙,应该怎么去除缝隙
.space a {
display: inline-block;
margin-right: -3px;
}
<div class="space">
<a href="##">惆怅
<a href="##">淡定
<a href="##">热血</a>
</div>
.space {
font-size: 0;
}
.space a {
font-size: 12px;
}
.space {
letter-spacing: -3px;
}
.space a {
letter-spacing: 0;
}
.space {
word-spacing: -6px;
}
.space a {
word-spacing: 0;
}
vertical-align:top
HTML 是用来描述网页的一种语言。
Hyper Text Markup Language
HTML 标记标签通常被称为 HTML 标签 (HTML tag)。
<!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 html>
<!DOCTYPE HTML>
<!doctype html>
<!Doctype 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>
body
呈现给用户header
头部nav
导航aside
和主要内容不相关的区域article
相邻独立可重复主体section
文档中的区域footer
尾部hx
h1-h6 标题<a></a>
超链接
em
strong
strong比em更强调span
无语义br
换行 单闭合标签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属性
<script>document.createElement("header");</script>,也可以使用shiv来解决兼容性问题,详情可参考[HTML5 Shiv](https://github.com/afarkas/html5shiv)。主流浏览器都兼容HTML5的新标签,对于 IE8 及以下版本不认识 HTML5的新元素,可以使用 JavaScript 创建一个没用的元素来解决,例如:
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>
所有标签(包括 ) 都有的属性,请自行学习此教程
 
"
"
>
>
<
<
©
©
&
&
声明:本文章版权归本人所有,转载需经作者同意
先做个题目:
<!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
<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
做不到
float + margin +(fix)
做不到
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 * 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>
<!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>
有些内容借鉴,不过每个内容我都在浏览器上跑了一遍,自己亲自用代码实现了一遍,如果有侵权的,请联系删除
JavaScript提供定时执行代码的功能,叫做
定时器(timer)
,主要由setTimeout()
和setInterval()
这两个函数来完成。
setTimeout函数
用来指定某个函数或某段代码,在多少毫秒之后执行。它返回一个整数,表示定时器的编号,以后可以用来取消这个定时器。
delay
是推迟执行的毫秒数,默认为0var timeoutId = setTimeout(func,delay)
clearTimeout(timeoutId) 清除定时器
func
执行改变属性的操作delay
触发的时间间隔var intervalId = setInterval(func,delay)
clearInterval(intervalId) 清除定时器
var requestId = requestAnimationFrame(func)
cancelAnimationFrame(requestId)
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()
所谓对象,就是一种无序的数据集合,由若干个“键值对”(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']
var car = {
color: "red",
run: function(){alert("run")}
}
car.constructor //ƒ Object() { [native code] }
var num = new Number(123)
num.constructor //ƒ Number() { [native code] }
var num = new Number(123)
num.toString() //"123"
var num = new Number(123)
num.valueOf() //123
var car = {
color: "red",
run: function(){alert("run")}
}
car.hasOwnProperty("color") //true
car.hasOwnProperty("logo") //false
JSON 格式(JavaScript Object Notation 的缩写)
是一种用于数据交换的文本格式
JSON 对值的类型和格式有严格的规定。
以下是合格的 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字符串转化成对象。var userJson = '{\
"id": 1,\
"nick": "春鸟秋虫",\
"avatar": "1.jpg",\
"tags": null,\
"authed": false\
}';
var user = JSON.parse(userJson);
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
是只闻其名,未见其身啊,学习了ajax
,老师说用node.js
搭建一个自己的服务器,老师也讲了实现原理,但还是一知半解,怎么办?只好去看看node.js教程了
好了,话不多说,先了解一个node.js应用由哪几部分组成
require
指令来载入 Node.js
模块。 Apache 、Nginx
等 HTTP
服务器。HTTP
请求,服务器接收请求后返回响应数据。我们使用 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执行一下
创建server.js
是如何把我们写的东西展现在服务器上的?
先来了解几个模块
Path
模块Node.js path
模块提供了一些用于处理文件路径的小工具,我们可以通过以下方式引入该模块,有一些方法和属性可以查看文档var path = require("path")
path.join([path1][, path2][, ...])
用于连接路径。该方法的主要用途在于,会正确使用当前系统的路径分隔符,Unix系统是"/"
,Windows系统是"\"
。
Node.js
文件系统Node.js
提供一组类似 UNIX(POSIX)
标准的文件操作API
。 Node
导入文件系统模块(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/');
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,对后台知识,以及一些模块什么的理解不太清楚,所以还是有点不足,和面再对这个服务器补充一下
<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
.ready()
方法,能保证DOM准备好后就执行这个函数如果执行的代码需要在元素被加载之后才能使用时,(例如,取得图片的大小需要在图片被加载完后才能知道),就需要将这样的代码放到 load 事件中。
$(document).ready(handler)
$(handler)
$(function(){
console.log('ready');
});
$node.html()
,返回所选择元素内的html内容,包含html标签和文本内容$node.text()
,返回所选择元素内的文本内容,不包含html标签,只包含文本内容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}
.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 ] }
$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()
<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 class="bg"></div>
$(".bg").on("mouseenter",function(){
$(this).css({"background-color":"red"})
})
$(".bg").on("mouseleave",function(){
$(this).css({"background-color":"white"})
})
<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 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())
})
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
//例子:
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);
//例子:
var myNumber = {
value: 1,
add: function(i){
console.log(this); //Object{value: 1, add: ƒ}
this.value += i;
}
}
myNumber.add(1);
//例子:
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)
调用模式
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结果没有受到影响
//例子一:
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}
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
整数
十进制 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)
是一个特殊的数值,表示一个本来要返回数值的操作数未返回数值的情况
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()
Number()
函数转换规则
Boolean
值,true和false
将分别被转换为1和0
null
值,返回0
undefined,
返回NaN
valueOf()
方法,按照前面的规则返回相应的值.如果结果是NaN,调用toString()
方法,按照前面的返回字符串值var num1 = Number('Hello World') //NaN
var num2 = Number('') //0
var num3 = Number('000011') //11
var num4 = Number(true) //1
parseInt()
函数转换
parseInt()
函数在转化字符串时,更多的看是否符合数值模式忽略字符串前面的空格
,直至找到第一个非空字符串
.不是数字字符或者负号
,会返回NaN
var number1 = parseInt('123456')//123456
var number2 = parseInt('') //NaN
var number3 = parseInt('22.5') //22
var number4 = parseInt('070') //56(八进制)
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类型
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"
在不知道转换的值是不是
null
或undefined
,使用转型函数String()
,这个函数能将任何值转换为字符串,String()
遵循以下规则
Boolean
类型只有两个字面值:true和false
,虽然Boolean
类型字面值只有两个,但ECMAScript
中所有类型都有与这两个Boolean
值等价的值。要将一个值转换为其对应的Boolean
值,可以调用函数Boolean() 转换规则
数据类型 | 转换为true的值 | 转换为false的值 |
---|---|---|
Boolean | true | false |
String | 任何非空字符串 | ""(空字符串) |
Number | 任何非零数字值 | 0和NaN |
Object | 任何对象 | null |
Undefined | n/a(不适用) | undefined |
Object
是一组数据和功能的集合,对象可以通过执行new操作符后跟要创建的对象类型的名称来创建
var o = new Object();
Object类型所具有的任何属性和方法也同样存在于更具体的对象中
constructor
:保存着用于创建当前对象的函数,对前面而言,构造函数(constructor)
就是Object()
。hasOwnProperty
:用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。其中,作为参数的属性(*propertyNmae*)
必须以字符串形式指定(例:o.hasownProperty(“name”)
)。isprototypeof(object)
:用于检查传入的对象是否是当前对象的原型propertyIsEnumerable(propertyName)
:用于检查给定的属性是否能够使用for-in
语句来枚举,参数的属性名必须是字符串。toLocalString()
:返回对象的字符串表示,该字符串与执行环境的地区对应toString()
:返回对象的字符串表示。valueOf()
:返回对象的字符串、数值或布尔值表示。Null类型只有一个值:null
var car = null;
如果定义的变量准备在将来用于 保存对象 ,那么最好将该变量初始化为
null
而不是其他值。这样,只要检查null值可以知道相应的变量是否已经保存了一个对象的引用
if(car != null){
//对car对象执行某种操作
}
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
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
原始类型和引用类型 区别
今天先把javascript的基本语法和六大基本类型做个了解,后面继续学习知识点,并做笔记
Git是一个“分布式版本管理工具”,简单的理解版本管理工具:大家在写东西的时候都用过“回撤”这个功能,但是回撤只能回撤几步,假如想要找回我三天之前的修改,光用“回撤”是找不回来的。而“版本管理工具”能记录每次的修改,只要提交到版本仓库,你就可以找到之前任何时刻的状态(文本状态)。
Git小白教程入门
git add 改动的文件名
,此次改动就放到了‘暂存区’git commit 此次修改的描述
,此次改动就放到了’本地仓库’,每个commit,我叫它为一个‘版本’。git push 远程仓库
,此次改动就放到了‘远程仓库’(GitHub等)git log
,最上面那行commit xxxxxx
,后面的字符串就是commit-id前段项目我想使用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 a
a = 1
var a = 2
ES6 新增了let
命令,用来声明变量。它的用法类似于var
,但也有区别:
console.log(bar); // 报错ReferenceError
let bar = 2;
a = 1 //报错
let a
// 报错
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 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。
var tmp = new Date();
function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world'; // var tmp 变量提升
}
}
f(); // undefined
var s = 'hello';
for (var i = 0; i < s.length; i++) {
console.log(s[i]); // i泄露为全局变量
}
console.log(i); // 5
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
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]
let x = 1;
let y = 2;
[x, y] = [y, x]; // [2,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()
// 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 }如果传了对象,就使用你传递的对象
“箭头”(=>)
定义函数。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对象的指向是可变的,但是在箭头函数中,它是固定的。
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
。
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!";
}
};
模块功能主要由两个命令构成:export和import
。export
命令用于规定模块的对外接口,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;
};
import
命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载,为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default
命令,为模块指定默认输出。// export-default.js
export default function () {
console.log('foo');
}
其他模块加载该模块时,import
命令可以为该匿名函数指定任意名字。
// import-default.js
import customName from './export-default';
customName(); // 'foo'
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() {}
}
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类的实例上调用。如果在实例上调用静态方法,会抛出一个错误,表示不存在该方法。
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}`);
}
}
一个浮动盒会向左或向右移动,直到其外边(outer edge)挨到包含块边沿或者另一个浮动盒的外边。如果存在行盒,浮动盒的外top(边)会与当前行盒的top(边)对齐 如果没有足够的水平空间来浮动,它会向下移动,直到空间合适或者不会再出现其它浮动了
因为浮动(盒)不在普通流内,在浮动盒之前或者之后创建的未定位的(non-positioned)块盒会竖直排列,就像浮动不存在一样。然而,接着(next to)浮动(盒)创建的当前及后续行盒会进行必要的缩短,为了给浮动(盒)的margin box让出空间
我们看几个例子,来理解上面你的定义
浮动布局希望布局仅仅是盒模型上下排版,还需要左右排版,于是出现了float
一个浮动盒会向左或向右移动,直到其外边(outer edge)挨到包含块边沿或者另一个浮动盒的外边。
如果存在行盒,浮动盒的外top(边)会与当前行盒的top(边)对齐 如果没有足够的水平空间来浮动,它会向下移动,直到空间合适或者不会再出现其它浮动了
因为浮动(盒)不在普通流内,在浮动盒之前或者之后创建的未定位的(non-positioned)块盒会竖直排列,就像浮动不存在一样。然而,接着(next to)浮动(盒)创建的当前及后续行盒会进行必要的缩短,为了给浮动(盒)的margin box让出空间
<!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>
float : left | right | none(默认) | inherit
对元素,脱离文档流; 对内容,在文档流
clear: both | left | right | none | inherit
clear
空白元素
<!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>
<!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
//问题一: 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>
总结一下:
一直觉得看例子最直接
//问题一: 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
就喜欢例子
// 问题: 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 是一个现代 JavaScript 应用程序的模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
我们为什么要学习webpack呢?它的动机是什么?
现在的网站都向webapp进化:
大量代码需要被重新组织,于是出现了模块系统,用来代码分割成模块。
在有webpack之前,我们都是使用那些模块系统呢?
<script>
标签风格<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;
存在的问题以及优缺点:
优点:
缺点:
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" {}
优点:
缺点:
无偏见的解决方案
开发者可以选择自己的模块风格,现存的代码库和包能正常工作,添加定制的模块风格也很方便。
但是上面的都不是最佳方案:
除了JavaScript 能模块化,其它资源行不行?
所以我们就需要更加强大的工具webpack
安装
建议本地安装
npm install --save-dev webpack
<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>
<style>
元素中。 <style>
h1 { background: orange; }
</style>
<p style="background: orange; font-size: 24px;">CSS 很 👍<p>
selector{
property1:value;
property2:value;
....
}
选择器
属性声明 = 属性名:属性值
注释 /* */
chrome
safari
firefox
IE
opera
为了兼容不同的浏览器,我们需要用到这些私有属性
.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}
基本元素 组合符号 数量符号
空格
<'font-size'>
<'font-family'>
空格隔开的两个基本属性
&&
<length>
&&<color>
&&连接的基本属性
||
underline
|| overline
|| line-through
|| bink
|
<color>
| transparent
[]
bold
[ thin
|| <length>
]
无
<length>
+
<color-stop>
[,<color-stop>
]+
?
insert
?&&<color>
?
可以出现也可以不出现{}
<length>
{2,4}
*
<time>
[.<time>
]*
#
<time>
#
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; (错)
在了解ajax之前,我们先粗略的了解一下http协议
http事务
请求报文格式
get:
http方法music.com
主机地址http/1.1
http版本Accept:
浏览器接收的媒体类型Accept-Encoding:
浏览器接收的媒体类型的编码方式Accept-Language
浏览器端接收的语言方式Cache-Control:
缓存策略Cookie:
发送cookie值User- Agent
浏览器的版本Get方法
请求体为空响应报文格式
方法 | 描述 | 是否包含主体 |
---|---|---|
GET |
从服务器获取一份文档 | 否 |
POST |
向服务器发送需要处理的数据 | 是 |
PUT |
将请求的主体部分存储在服务器上 | 是 |
DELETE |
从服务器删除一份文档 | 否 |
URL构成
常见http状态码
Ajax(Asynchronous JavaScript and Xml)
优点:
缺点:
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代理
//弄一个状态锁
var AjaxLock = false;
//事件触发下面代码
// ******start*****
if (!AjaxLock){
AjaxLock = true;
xhr.onreadystatechange = function(){
if( xhr.readyState == 4) {
//do sth
AjaxLock = false;
//当接受完毕请求数据后将锁打开
}
}
//ajax配置
xhr.send();
} else {
return;
}
代码预览,需要开启mock-server数据
语法: 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语句
与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 {
statement
} while ( expression )
var i = 11 ;
do {
document.write(i);
i++;
} while ( i <= 10 ) //11
while语句
属于前测试循环语句,在循环体内的代码被执行之前,就会对出口条件求值,循环体内的代码可能永远不会被执行.
语法: while ( expression ) statement
while( 表达式 ){ 语句 }
示例:
var i = 1 ;
while ( i <= 10 ) {
document.write(i);
i++;
} //12345678910
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语句虽然也是立即退出循环,但退出循环后会从循环的顶部继续执行.
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(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(expression) statement
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语句中
语句的学习很简单,难得是实际应用,所以多练
什么是正则表达式
/12345/
/yym/i
var reg = new RegExp
g:global
:是否全局搜索,默认是falsei:ignoreCase
:是否大小写敏感,默认是falsem:multiline
:多行搜索,默认值是falselastIndex
:是当前表达式模式首次匹配内容中最后一个字符的下一个位置,每次正则表达式成功匹配时,lastIndex属性值都会随之改变source
:正则表达式的文本字符串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>
/./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}
search()
方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串'a1b2c3'.search(/\d/g); //1
'a1b2c3'.search(/\d/); //1
var url = 'http://blog.163.com/album?id=1#comment';
var arr = url.match(/(https?:)\/\/([^\/]+)(\/[^\?]*)?(\?[^#]*)?(#.*)?/);
// var arr = url.match(/(https?:)\/\/([^\/]+)([^\?]*)([^#]*)(.*)/);
console.log(arr);
'abcabcabc'.replace('bc','X'); //aXabcabc
'abcabcabc'.replace(/bc/g,'X'); //aXaXaX
'abcaBcabC'.replace(/bc/gi,'X'); //aXaXaX
'a,b,c,d'.split(','); //["a", "b", "c", "d"]
'a1b2c3d'.split(/\d/); //["a", "b", "c", "d"]
<form></form>
标签之间(否则用户输入的信息可提交不到服务器上哦!)。<form method="传送方式" action="服务器文件">
<form> :<form>
标签是成对出现的,以<form>
开始,以</form>
结束。
action :
浏览者输入的数据被传送到的地方,比如一个PHP页面(save.php)。
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>
标签之间可以输入默认值。
使用表单设计调查表时,为了减少用户的操作,使用选择框是一个好主意,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" 时,该选项被默认选中
typeof
instanceof
Object.prototype.toString.call
constructor
可以识别标准类型(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 Array //true
/\d/ instanceof RegExp //true
new Date instanceof Date //true
不能判别原始类型
1 instanceof Number //false
'yym' instanceof String //false
可以识别标准类型以及内置对象类型
不能识别自定义对象类型
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"
判别标准类型(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:<length> | <percentage> | <absolute-size> | <relative-size>
small,middle ,large
等font-size:12px;
font-size:16px;
font-size:2em;(24px)
font-size:200%;
语法: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:normal|bold|bolder|lighter|100|200|..|900
font-weight:normal默认
font-weight;bold;
语法:font-style:normal|italic|oblique
font-style:italic;
语法:line-height:normal|<number>|<length>|<percentage>
line-height:40px;
line-height:3em;
line-height:300%;
line-height:3;
300%和3显示是一样的,有哪些区别呢?
修改里面某一段文字大小时;
line-height为number时,继承为直接继承,所以如果给下面的元素设置行高,等于字体大小乘以number值(不计算,直接继承)
而line-height:百分比;先计算,在继承,
结合上面五个属性:
语法: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:red;
color:#ffffff;
color:rgb(255,0,0);
color:rgba(255,0,0,1);
color: transparent;
语法:text-align:left|right|center|justify
语法:vertical-align:baseline|sub|super|top"text-top|middle|bottom|text-bottom|<percentage>|<length>
text-indent:<length>|<percentage>
text-indent:2em;首行缩进两个字
white-space:normal|nowrap|pre|pre-wrap"pre-line
word-wrap:normal|break-word
word-break:normal|leep-all|break-all
text-shadow:none|[<length>{2,3}&&<color>?]#
#
代表可写多个shadow,逗号分开语法:text-decoration:none | [underline||overline||line-through]
text-overflow:clip | ellipsis
text-overflow:ellipsis;
overflow:hidden; 文字超出隐藏,溢出截掉
white-space:nowrap;不换行
很多文本类型都可以继承
不学习具体的知识点,只了解一下
div
高度由line-height
决定
也是由设计师决定<div></div> // height:0
//中间加文字,height高度是多少呢?
<div>你好</div> //随字体变化,height也在变化 字体*建议行高
display:inline-block
空隙问题,可以用float
- div里行内元素足够多的话,一行容纳不下,自动换行,就是文档流
- 遇到一个足够长的单词,超出了文档流,用
word-break:break-alll
div高为40px
//小白
div{
height:40px; //千万不要写死
line-height:40px;
}
//怎么改?
div{
line-height:40px;
padding:8px 0; //文字很多,不会出现bug
}
//只需要一个东西挡住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>
/* 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>
padding
display:flex
transform:translate
div的高度是由内部文档流中元素的总和决定,行内元素从左到右,块级元素从上到下,脱离文档流中的不算,
float
position:absolute
position:fixed
CSS : border调试大发
写的比较乱,凑合看看吧,♫♫∵
被设置元素为文本、图片等行内元素时,水平居中是通过给父元素设置 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>
当被设置元素为 块状元素 时用 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标签的长度自适应性---即不定义其长度也不默认父元素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>
初始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>
利用绝对定位和偏移解决居中问题,
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,然后给父元素设置 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: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>
通过设置父元素的
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>
竖直居中的属性
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-align
为middle
,所以我们不需要显式地设置了。
<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>
这个方法和水平居中的方法类似,唯一的区别是
top:50%;
,transform:translateY(-50%);
与水平居中
justify-content
对应的属性align-items
值为center
,也可以实现垂直居中
设置display:flex;
会使子元素充满父元素。因为align-items
的值默认为stretch
。
综合水平居中和垂直居中一起
<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>
<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>
<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>
后面如果在遇到不同的居中方式,会补充在这里
!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 |
h1的文字大小不是没有变成12px,而是变的不对
a链接和h1一样,都是浏览器默认样式大于继承的样式
标签在浏览器里有一些默认样式会让我们对某些css样式判断失误,所以一般我们都会写一个reset.css
来重置样式
想要去除一个字符串的第一个字符,有哪些方法可以实现
1. "string".replace("s","") //替换
2. "string".substring(1) //截取
3. "string".slice(1) //截取
4. "string".substr(1) //截取
看一个例子,字符串在一些表单验证方面的应用
str.length 获取字符串长度
var userName = input.value
if(userName.length > 6){
alert(要求大于等于六个字符)
}
str.charAt(index)
index索引值
"yangyumeng".charAt(0) //"y"
应用:
var userName = input.value;
if(userName.charAt(0) == "-"){
alert("不能以“-”开头");
}
str.indexOf(searchValue)
"yymyang-yumeng".indexOf("-") //7
"yang-yu-meng".indexOf("-") //4 只匹配一次
"yang-yumeng".indexOf("yumeng") //5 按照第一个字符所在位置
"yangyumeng".indexOf("-") //-1 没有会返回-1,可以利用-1做一些判断
str.search(regexp)
"yangyumeng123".search(/[0-9]/) //10,返回数字索引位置
"yang123yumeng".search(/[0-9]/) //4
"yangyumeng123".search(/[A-Z]/) //-1,找不到数字-1
str.match(regexp)
"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])
其实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])
"yangyumeng".substr(2,5) //"ngyum"
"yangyumeng".substr(2) //"ngyumeng"
看一个需求
str.split([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"
需求
连接+
"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"
我们再看函数前,先来看一个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
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();
下图中的矩形代表特定执行环境内部环境可以通过作用域链访问所有外部环境,但外部环境不能访问内部环境任何变量和函数,这些环境之间的联系是线性 有次序的.每个环境都可以向上搜索作用域链,以查询变量和函数名.任何环境都不能通过向下搜索作用域链而进入另一个执行环境
看上图,如果我们修改变量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
与工厂模式的区别
new操作符经历的步骤
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是一款快速而简洁的javascript的库,核心是构建与css选择器上,用来操作DOM元素,通过链式调用,兼容性好,API 友好,功能强大,与时俱进
如何转化?
$符号
$(document.querySelector("#box"))
就可以变为jQuery对象,就可以使用jQuery对象的API了
[下标]
$("#box .box")[0]
,就可以使用j原生对象的API了
问题是:那我们又不想变成原生对象,又想取值怎么办呢?
$("#box .box").eq(0) //.eq(index)
<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()设置文本内容
//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" )
//展示
.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 ] )
//停止匹配元素当前正在运行的动画。
预览地址
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 |
type | Result |
---|---|
Undefined | NaN |
Null | 0 |
Boolean | ture -> 1, false -> 0 |
String | “abc” -> NaN, “123” -> 123 |
对于 Object 类型,先尝试调用 .valueOf 方法获取结果。
如果没定义,再尝试调用 .toString方法获取结果
语法: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:[<family-name> | <generic-family>]#
<generic-family>=serif | sans-sarif
font-family:arial;
font-family:arial,Verdana,sans-sarif;
font-family:Verdana,"微软雅黑";
语法:font-weight:normal|bold|bolder|lighter|100|200|..|900
font-weight:normal默认
font-weight;bold;
语法:font-style:normal|italic|oblique
font-style:italic;
语法:line-height:normal|<number>|<length>|<percentage>
line-height:40px;
line-height:3em;
line-height:300%;
line-height:3;
300%和3显示是一样的,有哪些区别呢?
修改里面某一段文字大小时;
line-height为number时,继承为直接继承,所以如果给下面的元素设置行高,等于字体大小乘以number值(不计算,直接继承)
而line-height:百分比;先计算,在继承,
结合上面五个属性:
语法: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:red;
color:#ffffff;
color:rgb(255,0,0);
color:rgba(255,0,0,1);
color: transparent;
语法:text-align:left|right|center|justify
语法:vertical-align:baseline|sub|super|top"text-top|middle|bottom|text-bottom|<percentage>|<length>
text-indent:<length>|<percentage>
text-indent:2em;首行缩进两个字
white-space:normal|nowrap|pre|pre-wrap"pre-line
word-wrap:normal|break-word
word-break:normal|leep-all|break-all
text-shadow:none|[<length>{2,3}&&<color>?]#
#
代表可写多个shadow,逗号分开语法:text-decoration:none | [underline||overline||line-through]
text-overflow:clip | ellipsis
text-overflow:ellipsis;
overflow:hidden; 文字超出隐藏,溢出截掉
white-space:nowrap;不换行
很多文本类型都可以继承
new Date()
new Date(2017,8) //月份从零开始,小一月
new Date(2017,4) //2017-5
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
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) + '天。');
var date = new Date(2017,9,3,14,57,18)
date.getTime() //1507013838000 距1970-1-1 00:00:00的毫秒数
new Date(1507013838000)
date.getTime(1507013838000)
在数值中除了
加减乘除求余
外,还有一些四舍五入,绝对值
等在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()
Math.random() // 大于等于0且小于1的随机数
下面看几个实际应用,我们应该怎么用JS解决
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('100.1') // 100.1 转换为数值
Number('12.4b5') // NaN 一个不能识别,就不能识别了
Number('www') // NaN
上面我们只需要两个小数点就可以了,该怎么做呢?
digits
保留几位小数点?(100.123).toFixed(2) // "100.12"
(100.123).toFixed(0) // "100"
盒模型其实就是一个个的生活中盒子类似的东西,比方我们拿快递的盒子,那是什么样的呢?
那我们再来看一下CSS盒模型是什么样子的?
是不是非常的相似,那我们就来来学习一下css中的盒模型
盒模型概念、
width、
height、
padding、
margin(水平居中)、
border、
border-radius、
overflow、
box-sizing、
box-shadow、
outline
语法:width: <length> | <percentage> | auto | inherit
length:
长度,单位有px em rem...等percentage:
百分比 %auto
width默认值min-width
max-width
语法:height: <length> | <percentage> | auto | inherit
length:
长度,单位有px em rem...等percentage:
百分比 %auto
height默认值min-height
max-height
参考:box-Model
在介绍
padding margin border
等属性之前,我们来了解几个知识,以padding
为例,margin border
也适合以下规则
语法:padding: [<length> | <percentage>]{1,4} | inherit
语法:padding: [<length> | <percentage> | auto]{1,4} | inherit
margin
合并
水平居中
margin:0 auto;
说明:
...
代表不常用的
语法:border: [<border-width>||<border-style>||<border-color>] | inherit
语法:border-width:[<length>|...]{1,4} | inherit
语法:border-style:[solid | dashed | dotted | ...]{1,4} | inherit
语法:border-color:[<color>| transparent]{1,4} |inherit
语法:border-radius:[<length>|<percentage>]{1,4}[/<length>|<percentage>]{1,4}]?
水平半径
,一个是垂直半径
,可以最多有八个值,中间用/
分开overflow;visible| hidden | scroll |auto
overflow-x
overflow-y
box-sizing:content-box| border-box | inherit
box-shadow:none| <shadow>[,<shadow>]*
<shadow>:inset?&&<length>{2,4}&&<color>?
outline:[<outline-width>||<outline-style>||<outline-color>]
关于CSS属性的浏览器兼容性,可以通过 caniuse 查询。
border-radius ie8及以下不支持
box-sizing ie7及以下不支持
box-shadow ie8及以下不支持
outline ie7及以下不支持
什么是布局?
设置元素的显示方式
display: block | inline | inline-block | none
默认块级元素:
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>
默认行内元素:
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>
<!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>
<!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;
}
在javasript
中delegate
这个词经常出现,看字面的意思,代理、委托。
要搞懂事件代理,我们先来看看什么是代理,相信我们生活中现在还有朋友在做微商的,而微商的产品就是一级一级代理,下家找上家拿货这样子,你卖了东西从上家拿货,这个过程相当于你也有了货
我们怎么从字面上来了解事件的代理呢?慢慢来,我们先来看一个需求,有这样一个列表,当我们每次点击的时候,就在控制台打印列表里的内容
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)
}
}
我觉得这样写的挺好的,可是有人说这样会耗费性能,那我就不管了,可是当我改了一下需求,我发现这个代码用的没那么舒服了
我加入了几这样的代码
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加事件了,好吧,那我怎么修改呢?难道要重新循环遍历,太麻烦了,
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')
,那么执行函数。
事件捕获:当某个元素触发某个事件(如onclick),顶层对象document就会发出一个事件流,随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。在这个过程中,事件相应的监听函数是不会被触发的。
事件目标:当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。
事件起泡:从目标元素开始,往顶层元素传播。途中如果有节点绑定了相应的事件处理函数,这些函数都会被一次触发。如果想阻止事件起泡,可以使用e.stopPropagation()(Firefox)或者e.cancelBubble=true(IE)来组织事件的冒泡传播。
css 长度单位一般我们分为绝对长度单位和相对长度单位
绝对长度单位是一个固定的值,它反应一个真实的物理尺寸。那么,常见的绝对长度单位有哪些呢?
in
,英寸cm
,厘米mm
,毫米pt
,pointspc
,Picas这些单位都是拥有真实的物理尺寸的以及确定的换算关系,比如,1in = 2.54cm。我们平时在书写css代码时,当然也可以直接使用这些单位,并且也能够在屏幕上表现。不过由于这些单位都是绝对长度单位,往往不利于页面屏幕的渲染,这些绝对长度单位更多的使用场景往往是被用在印刷、打印等方向。
CSS相对长度单位中的相对二字,表明了其长度单位会随着它的参考值的变化而变化,不是固定的。下面是常用的一些相对长度单位:
px
,Pixels像素em
,元素的字体高度ex
,x-height,字母x的高度%
,百分比ch
,字符0的宽度rem
,根元素(html)的font-sizevw
,viewpoint width,视窗宽度,1vw=视窗宽度的1%vh
,viewpoint height,视窗高度,1vh=视窗高度的1%vmin
,vmax
等今天我们了解几个我们比较常用而且不容易记得几个css的单位:
px
em
rem
vw
vh
vmin
vmax
px
像素单位其实是和设备屏幕的分辨率是直接相关的。
在web开发中,像素现在仍然是典型(主流的)度量单位。当然,你可以在web开发的过程中采用其他的单位,但是往往这些单位在渲染时都被映射换算成像素。是我们最常使用的单位:
header{
width: 100px;
height: 100px;
border: 1px solid #fff;
}
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
单位是相对于字体大小的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%
。
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
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
是相对于视口的高度和宽度两者之间的最小值或最大值。
如果浏览器的高为1100px、宽为700px,那么1vmin就是7px,1vmax就是11px;如果浏览器的高为800px,宽为1080px,那么1vmin也是8px,1vmax也是10.8px。
注意: 选择使用什么字体单位主要由你的项目来决定,如果你的用户群都使用最新版的浏览器,那推荐使用rem,如果要考虑兼容性,那就使用px,或者两者同时使用。当然了,最好根据实际应用来使用相应的字体单位
窗口
到目标的父。这个阶段也被称为捕获阶段参考资料: 事件流
在讲述事件注册之前,讲一下前面的事件处理程序
<input type="button" value="Click Here" onclick="alert('Clicked!');" />
<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])
var elem = document.getElementById("div1")
var clickHandler = function(){
//to do
}
elem.addEventListener('click',clickHandler,false)
取消事件注册
eventTarget.removeEventListener(type,listener[,useCapture])
elem.removeEventListener('click',clickHandler,false)
elem.onclick = null
事件触发
eventTarget.dispatchEvent(type)
elem.dispatch("click")
事件注册与取消
IE并不支持addEventListener和removeEventListener方法,而是实现了两个类似的方法
attachEvent
detachEvent
事件触发
fireEvent(e)
no capture没有捕获
当事件被触发的时候,会调用事件处理函数,在调用时间处理函数中,有一些信息,这些信息代表着事件的状态,这个就是事件对象
以click
为例
type类型:
例如点击什么的...target(srcElement IE低版本)
目标元素,点击哪个就是那个currentTarget:
事件处理程序当前处理元素stopPropagation()
取消事件进一步捕获或冒泡preventDefault()
取消事件默认行为阻止事件传播(冒泡)
event.stopPropagation()
W3Cevent.cancelBubble=true
IE默认行为
event.preventDefault()
W3Cevent.returnValue = false
IE事件类型 | 是否冒泡 | 元素 | 默认事件 | 元素例子 |
---|---|---|---|---|
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选择器,对于我们在html里的各种标签,class类名,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是手机专用的自适应方案
我们常用的单位有(有问题看MDN)
px
em
(一个汉字M的宽度,对面试官说)vh
viewport 的height高度 视口高度 100vh == 视口高度vw
viewport 的width 跨度 视口宽度 100vw == 视口宽度font-size:16px
1em == 16px默认值
em
自己的font-sizerem
根元素的font-size如果没有设计图,就不做响应式
响应式需做不同的适配,例如:
// 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>
REM 可以与其他单位同时存在
font-size: 16px;
border: 1px solid red;
width: 0.5rem;
上面的这些可以解决我们在移动端是配上的单位动态rem,但是对于我们来说,还是有一个痛点.单位的换算特别麻烦,先px,再rem,该怎么解决呢???
给自己一个警告!!!!
rem自动化转px 就用scss呗
文本水平排列
,overflow:hidden
隐藏其他图片
/*设置父容器宽高,隐藏后面的元素*/
.carousel{
width: 320px;
height: 180px;
overflow: hidden;
}
/*特别重要的一步,不管容器有多宽,元素排成一列*/
.carousel .img-ct{
width: 1280px;
overflow: hidden;
}
把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())
注意有一点区别
当我门克隆元素完成的时候,需要注意一点的是图片的总宽度
我们可以看到多出来两个克隆的元素,超出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,一直在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()
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.