WEB前端学习笔记_js link 属性-程序员宅基地

技术标签: css  html  javascript  

目录

一、结构(HTML)

1.HTML的语法规范

        1.1 基本语法概述

        1.2 标签关系

2.HTML的基本结构

3.HTML常用标签

3.1 标题标签

3.2 段落标签&换行标签

3.3 div和span标签

3.4 图像标签

3.5 链接标签

3.6 表格标签

3.7 列表标签

4.标签的分类

4.1 块元素标签

4.2 行内标签

4.3 行内块标签

二、表现(CSS)

1.css基础选择器

1.1 标签选择器

1.2 类选择器

1.3 id选择器

1.4 通配符选择器

2.复合选择器

2.1 后代选择器

2.2 子选择器

2.3 并集选择器

2.4伪类选择器

3.css的三大特性

3.1 层叠性

3.2 继承性

3.3 优先级

4.浮动

4.1 浮动的特性(重难点)

4.2 浮动元素经常和标准流父级搭配使用

5.清除浮动

5.1 清除浮动的本质

5.2 清除浮动的方法

6.定位

6.1 静态定位 static

6.2 相对定位 relative

6.3 绝对定位 absolute

6.4 固定定位 fixed

6.5 粘性定位 sticky

6.6 定位的叠放顺序 z-index

7.flex布局

7.1 flex布局父项常见属性

7.2 flex布局子项常见属性

三、行为(JS)

1. 数据类型

1.1 数值型 number

1.2 字符串 String

1.3 布尔值 boolean

1.4 逻辑运算符

1.5 比较运算符

1.6 null & undefined

1.7 数组

1.8 函数

1.9 对象

2. 作用域

2.1 js的作用域(es6)

2.2 变量的作用域

2.3 作用域链

 3. 预解析

3.1 预解析

3.2 代码执行

4.构造函数

4.1 语法格式

4.2 new关键字的执行过程

4.3 遍历对象

5. 内置对象

5.1 查文档(MDN)

5.2 日期对象

5.3 数组对象

5.4 字符串对象

6.简单数据类型和复杂数据类型总结

6.1 数据类型内存分配

6.2 数据类型的传参

四、Web APIs(DOM+BOM)

1. DOM 简介

1.1 DOM树

 1.2 获取元素

2. 事件基础

2.1 事件的三要素:

2.2 执行事件的步骤:

3. 操作元素

3.1 改变元素内容

3.2 改变元素属性

3.3 操作表单元素的属性

3.4 操作样式属性

3.5 操作自定义属性

3.6 操作节点

4. DOM重点核心

4.1 创建

4.2 增

4.3 删

4.4 改

4.5 查

4.6 属性操作

4.7 事件操作

5. 高级事件

5.1 注册事件

5.2 删除事件(解绑事件)

5.3 DOM 事件流

5.4 事件对象 

5.5 事件委托(代理、委派)

5.6 常用的鼠标事件

5.7 常用的键盘事件

6. BOM

6.1 window对象常见的事件

6.2 定时器

6.3 JS执行机制

6.4 location对象

6.5 navigator对象

6.6 history对象


web标准的构成

主要包括结构、表现、行为三个方面,三者之中结构最重要。

  • 结构:结构用于对网页元素进行整理和分类,主要指的是HTML。
  • 表现:表现用于设置网页元素的版式、颜色、大小等外观样式,主要指的是CSS。
  • 行为:行为是指网页模型的定义及交互的编写,主要指的是Javascript。

一、结构(HTML)

1.HTML的语法规范

        1.1 基本语法概述

                1.HTML标签是由尖括号包围的关键词,例如<html>

                2.<html></html>这类我们称为双标签

                3.<br />这类我们称为单标签

        1.2 标签关系

                1.包含关系:例如<html>包含<head>

<html>
    <head>
    </head>
</html>

                2.并列关系:例如<head>和<body>为并列关系

<html>
    <head></head>
    <body></body>
</html>

2.HTML的基本结构

<!DOCTYPE html>声明文档
<html>是网页当中最大的标签,所有的内容都要写在此标签内,我们称为跟标签
<head>文档的头部,主要用于书写网页设置。如:字符编码,网页的标题,引入外部的CSS文件,引入外部的JavaScript文件等。其中必须要设置的标签是<title>
<body>文档的主体部分,元素包含的文档的所有内容,页面内容基本都放在body标签中
其中<head><body>都是<html>的子标签

文档的基本结构如下:
<!DOCTYPE html> <!--声明此文档为html文档-->

<!--跟标签-->
<html lang="en"> <!--lang用于定义当前文档显示的语言-->
	<!--字符编码的设置和网页的标题都是写在<head>标签里-->
	<head> <!--文档的头部-->
		<meta charset="UTF-8"> <!--字符集声明-->
		<title>Title</title> <!--文档的标题-->
	</head>
	<body>
		<!-- 文档的内容 -->
	</body>
</html>

3.HTML常用标签

3.1 标题标签

        <h1>~<h6> 双标签,有默认样式

        标题标签为块标签,会自动换行

3.2 段落标签&换行标签

        <p></p>为段落标签,双标签

        段落标签为块标签,会自动换行

        <br />为换行标签,单标签,用于强制换行,将段落中的内容另起一行展示

        两个段落中间的间距较大,而在同一个段落内通过换行标签换行后的两行内容间距较小

3.3 div和span标签

        div和span就是一个盒子,用来装内容布局页面的

        <div>为块标签,独占一行,自动换行

        <span>为行内标签,一行可以放多个

3.4 图像标签

        <img> 标签用于定义HTML页面中的图像

        常用属性:

属性 属性值 说明
src 图片路径 src用于指定图像文件的路径,是<img>标签的必须属性
alt 文本 图片加载失败时使用其他内容替代图片
title 文本 鼠标移入图像时出现的提示文本
height 像素 设置图像的高度
width 像素 设置图像的宽度

3.5 链接标签

        <a>标签用于定义超链接,作用是从一个页面链接到另一个页面

                常用属性:

                href:用于指定链接目标的url地址,是<a>标签的必须属性

                target:用于指定链接页面的打开方式,其中“_self ”为默认值,“_blank”为打开新窗口

        <a>标签跳转到当前页面的指定位置

<!--跳转到当前页面的指定位置 锚点-->    
<html>
    <head>
        <title>Title<title>
    </head>
    
    <body>
        <div>
            <a href="#jump">第一章</a> <!--2.a标签的href属性的值为#指定元素id属性的值-->
        </div>
        <div>第二章</div>

        <div id="jump">这里是第二章的内容</div> <!--1.给指定标签添加id属性-->
    </body>
</html>

        <link>标签定义文档与外部资源的关系

                常用属性:

                href:用于指定被链接文档的url地址,是link标签的必须属性

                rel:规定当前文档与被链接文档之间的关系

3.6 表格标签

        <table></table>是用于定义表格的标签

        <th></th>标签用于定义表格中的表头单元格

        <tr></tr>标签用于定义表格中的行

        <td></td>标签用于定义表格中的单元格

        结构标签:

                <thead></thead>用于定义表格中的表头内容

                <tbody></tbody>用于定义表格中的主体内容

<table>
    <thead> <!--<thead>标签定义表格的表头内容-->
        <tr> <!--<tr>标签定义表格的行-->
            <th>一</th> <!--<th>标签定义表头单元格-->
            <th>二</th>
        </tr>
    </thead>

    <tbody> <!--<tbody>标签定义表格的主体内容-->
        <tr>
            <td>1</td> <!--<td>标签定义表格的单元格-->
            <td>2</td>
        </tr>
        <tr>
            <td>3</td>
            <td>4</td>
        </tr>
    </tbody>
</table>

        合并单元格

                1.合并单元格的方式

                  跨行合并:rowspan=“合并单元格的数量”

                  跨列合并:colspan=“合并单元格的数量”

                2.目标单元格(写合并代码)

                  跨行:最上侧的单元格为目标单元格,写合并代码 <td rowspan="2"></td>

                  跨列:最左侧的单元格为目标单元格,写合并代码 <td colspan="2"></td>

                3.合并后需要删除多余的单元格

3.7 列表标签

        无序列表

<ul> <!--<ul>中只能嵌套<li>标签,不允许输入其他标签或直接输入文字-->
    <!--无序列表各个列表项是并列的,没有顺序-->
    <li>列表项1</li> <!--<li>标签中可以放其他标签-->
    <li>列表项2</li>
    <li>列表项3</li>
</ul>

        有序列表

<ol> <!--<ol>中只能嵌套<li>标签,不允许输入其他标签或直接输入文字-->
    <!--有序列表中各个列表会按照一定顺序排列-->
    <li>列表项1</li> <!--<li>标签中可以放其他标签-->
    <li>列表项2</li>
    <li>列表项3</li>
</ol>

        自定义列表

<dl> <!--<dl>中只能嵌套<dt>和<dd>标签,不允许输入其他标签或直接输入文字-->
    <!--一个dt标签可以对应多个dd标签-->
    <dt>列表1</dt>
    <dd>列表1的描述1</dd>
    <dd>列表1的描述2</dd>
</dl>

4.标签的分类

按照标签效果进行分类可以分为块标签、行内标签和行内块标签。

4.1 块元素标签

常见块标签:<h1>、<p>、<div>、<ul>、<ol>、<li>、<dl>、<hr>

块级元素的特点:

        1.自己独占一行

        2.高度、宽度、外边距以及内边距都可以控制

        3.宽高是默认容器(或父级容器)的100%

        4.是一个容器及盒子,里面可以放块级元素或行内元素

4.2 行内标签

常见的行内标签:<a>、<span>、<i>、<em>、<b>、<strong>、<u>

行内标签的特点:

        1.相邻行内元素在一行上,一行可以显示多个行内元素

        2.直接对标签进行设置高和宽是无效的

        3.默认宽度就是它本身内容的宽度

        4.行内元素只能容纳文本或其他行内元素

注意:a标签内不能放a标签;a标签里可以放块级元素,但将a转换为块级模式最安全

4.3 行内块标签

常见的行内块标签:<img>、<input>

行内块元素的特点:

        1.和相邻行内元素或行内快元素在一行显示,但是他们之间有空白缝隙,并且以行内可以显示多个

        2.默认宽度就是他本身内容的宽度

        3.高度、行高、外边距以及内边距都可以控制

二、表现(CSS)

1.css基础选择器

1.1 标签选择器

标签选择器(元素选择器)是指用HTML标签作为选择器,按标签名称分类,为页面中某一标签指定统一的CSS样式。

<head>
    <style>
        div {
            color:red;
        }
    </style>
</head>
<body>
    <div>这是一个div盒子</div>
</body>

1.2 类选择器

如果想要差异化选择不同标签,单独选一个或某几个标签,可以使用类选择器

类选择器在HTML中以class属性表示,在css中类选择器以一个点号“.”来定义

<head>
    <style>
        .red {
            color:red;
        }
    </style>
</head>
<body>
    <div class="red">变红色</div>
    <div class="red">这里也变红色</div>
</body>

类选择器-多类名:

<head>
    <style>
        .red {
            color:red;
        }
        .font20 {
            font-size:20px;
        }
    </style>
</head>
<body>
    <div class="red font20">变红色</div>
</body>

1.3 id选择器

id选择器可以为表用特定id的HTML元素指定特定的css样式

HTML元素以id属性来设置id选择器,css中id选择器以“#”来定义

注意:id属性唯一,一个页面中不能同时存在两个相同的id

<head>
    <style>
        #red {
            color:red;
        }
    </style>
</head>
<body>
    <div id="red">变红色</div>
</body>

1.4 通配符选择器

在css中,通配符选择器使用“*”来定义,它表示选取页面中的所有元素(标签)

2.复合选择器

复合选择器是建立在基础选择器之上的,由两个或多个基础选择器通过不同的方式组合而成

2.1 后代选择器

后代选择器又称包含选择器,可以选择父元素里面的子元素,其写法就是把外层标签写在前面,内层标签写在后面,中间用空格分隔。当标签发生嵌套时,内层标签就成为外层标签的后代。

<head>
    <style>
        ol li {
            color:red; <!--改变ol中li标签内容的字体颜色-->
        }
    </style>
</head>
<body>
    <ol>
        <li>猪头</li>
        <li>猪蹄</li>
    </ol>
</body>

2.2 子选择器

子选择器只能选择作为某元素的最近一级子元素

<head>
    <style>
         div>a {
            color:red; <!--改变div下第一个a标签中内容的字体颜色-->
        }
    </style>
</head>
<body>
    <div>
        <a href="#">肥猪</a>
        <ol>
            <li><a href="#">猪头</a></li>
            <li><a href="#">猪蹄</a></li>
        </ol>
    </div>
</body>

2.3 并集选择器

并集选择器可以选择多组标签,同时为他们定义相同的样式,通常用于集体声明。

并集选择器是各选择器通过英文逗号“,”连接而成,任何形式的选择器都可以作为并集选择器的一部分。

<head>
    <style>
         div a,
         span {
            color:red; <!--改变div中a标签和span中内容的字体颜色-->
        }
    </style>
</head>
<body>
    <div><a href="#">肥猪</a></div>
    <span>猪仔</span>
    <ol>
        <li><a href="#">猪头</a></li>
        <li><a href="#">猪蹄</a></li>
    </ol>
</body>

2.4伪类选择器

伪类选择器用于向某些选择器添加特殊的效果,比如给链接添加特殊效果,或者选择第一个,第n个元素。伪类选择器书写最大的特点是用冒号(:)表示。

伪类选择器有很多,如:链接伪类,结构伪类

链接伪类

注意事项 :为了确保生效,必须按照:link -- :visited -- :hover -- :active 的顺序声明

<!--链接伪类-->
<style>
    <!--选择所有未被访问的链接-->
    a:link {
        color:red;
    }

    <!--选择所有已被访问过的链接-->
    a:visited {
        color:red;
    }

    <!--选择鼠标指针位于其上的链接-->
    a:hover {
        color:red;
    }

    <!--选择活动链接(鼠标单击按下但未弹起的链接)-->
    a:active {
        color:red;
    }
</style>

3.css的三大特性

3.1 层叠性

为同一个选择器设置相同的样式,此时后运行到的样式会覆盖先运行的样式。层叠性主要是为了解决样式冲突的问题

3.2 继承性

子标签会继承父标签的某些样式,如:文本、字体、颜色等和文字相关的属性

3.3 优先级

当一个元素指定多个选择器,就会有优先级的产生,选择器不同则根据选择器权重执行

选择器 选择器权重
继承或* 0,0,0,0
元素选择器 0,0,0,1
类选择器,伪类选择器 0,0,1,0
id选择器 0,1,0,0
行内样式(元素内写style="") 1,0,0,0
!important 无穷大

4.浮动

4.1 浮动的特性(重难点)

  1. 脱离标准普通流的控制(浮),移动到指定位置(动),俗称脱标
  2. 浮动的盒子不再保留原先位置
  3. 如果多个盒子都设置了浮动,则他们会按照属性值一行内显示并且顶端对其排列
  4. 浮动的元素是互相贴靠在一起的(不会有缝隙),如果父级宽度装不下这些浮动的盒子,多出的盒子会另起一行对其。
  5. 浮动元素会具有行内块元素特性啊

任何元素都可以浮动,不管原先是什么模式的元素,添加浮动后具有行内块元素相似的特性

  • 如果块级盒子没有设置宽度,默认宽度和父级一样宽,但是添加浮动后,它的大小根据内容来决定
  • 浮动的盒子中间是没有间隙的,是紧挨在一起的
  • 行内元素添加浮动后,它的大小根据内容来决定

4.2 浮动元素经常和标准流父级搭配使用

为了约束浮动元素位置,我们页面布局一般采取的策略是:先用标准流的父级元素排列上下位置,之后内部子元素采取浮动排列左右位置,符合网页布局第一准则。

5.清除浮动

5.1 清除浮动的本质

  • 清除浮动元素造成的影响
  • 如果父盒子本身有高度,则不需要清除浮动
  • 清除浮动之后,父级元素就会根据浮动的子盒子自动检测高度。当父级元素有了高度,就不会影响到下方的标准流元素了

5.2 清除浮动的方法

  • 额外标签法(也称隔墙法)
    • 在浮动元素末尾新添加一个空的标签,例如:<div style="clear: both" ></div>,或者其他块级元素标签
    • 优点:通俗易懂,书写方便
    • 缺点:会添加许多无意义的标签,结构较差
  • 在父级元素添加overflow属性
    • 给父级元素添加overflow属性,属性值有hidden、auto或scroll
    • 优点:代码简洁
    • 缺点:无法现实溢出部分
  • 在父级元素添加after伪元素
    • 该方法是额外标签法的升级版本

      先在父元素添加一个clearfix类,<div class="clearfix"><div>

      然后指定css样式:

      .clearfix:after {

              content: "";

              display: block;

              height: 0;

              clear: both;

              visibility: hidden;

      }

      .clearfix {

              /* 这里是用来兼容IE6、IE7的 */

              *zoom: 1;

      }

    • 优点:没有增加新标签,结构上比较简单
    • 缺点:需要照顾低版本浏览器
  • 父级添加双伪元素
    • 该方法也是额外标签法的升级版本

      先在父元素添加一个clearfix类,<div class="clearfix"><div>

      然后指定css样式:

      .clearfix:before,

      .clearfix:after {

              content: "";

              display: table;

      }

      .clearfix:after {

             clear: both;

      }

      .clearfix {

              /* 这里是用来兼容IE6、IE7的 */

              *zoom: 1;

      }

    • 优点:没有增加新标签,结构上比较简单
    • 缺点:需要照顾低版本浏览器

6.定位

6.1 静态定位 static

静态定位是元素默认的定位方式,意思是无定位

选择器 { position: static; }

6.2 相对定位 relative

相对定位是元素在移动位置的时候,是相对于它原来的位置来说的

选择器 { position: relative; }

相对定位的特点:

1. 它是相对于自己原来的位置移动的

2. 移动后原来的位置继续占有,后面的盒子仍然以标准流的方式对待它(不脱标,继续保留原来位置)

6.3 绝对定位 absolute

绝对定位是元素在移动位置的时候,是相对于它的祖先元素来说的

选择器 { position: absolute; }

绝对定位的特点:

1. 如果没有祖先元素或者祖先元素没有定位,则会以浏览器为准定位(Document文档)

2. 如果祖先元素有定位,则以最近一级的有定位的祖先元素为参考点移动位置。(若父级元素无定位,但父级的父级元素有定位,则参考点位父级的父级)

3. 绝对定位不再占有原先的位置(脱标)

6.4 固定定位 fixed

固定定位是元素固定在浏览器可视区域的位置。主要场景:可以在浏览器页面滚动时,固定定位的元素位置不改变。

选择器 { position: fixed; }

固定定位的特点:

1. 以浏览器的可视窗口为参照点移动元素

  • 跟父元素没有任何关系
  • 不随滚动条滚动

2. 固定定位不再占有原先的位置(脱标)

固定定位也是脱标的,可以看作是一种特殊的绝对定位

6.5 粘性定位 sticky

粘性定位可以认为是相对定位和固定定位的混合

选择器 { position: sticky;  top: 10px; }

粘性定位的特点:

1. 以浏览器的可视窗口为参照点移动元素

2. 粘性定位会占有原先的位置(相对定位特性)

3. 必须添加top、right、bottom、left其中一个才会生效

4. 兼容性较差

6.6 定位的叠放顺序 z-index

在使用定位布局时,可能会出现盒子重叠的情况。此时可以是使用z-index来控制盒子的前后顺序

选择器 { z-index: 1; }

  • 数值可以是正整数、负整数或0,默认是auto,数值越大则盒子越靠上
  • 如果属性值相同,则按照书写顺序排序,后来居上
  • 数字后面不能加单位
  • 只有定位的盒子才有z-index属性

7.flex布局

7.1 flex布局父项常见属性

  • flex-direction设置主轴的方向
属性值 说明
row 默认值,从左到右
row-reverse 从右到左
column 从上到下
column-reverse 从下到上
  • justify-content设置主轴上子元素的排列方式
属性值 说明
flex-start 默认值,从头部开始(如果主轴是x轴,则从左到右)
flex-end 从尾部开始排列

center

在主轴居中对齐
space-around 平分剩余空间
space-between 先两边贴边,再平分剩余空间
  • flex-wrap设置子元素是否换行
属性值 说明
nowrap 默认值,不换行
wrap 换行
  • align-item设置侧轴上子元素的排列方式(单行)
属性值 说明
flex-start 默认值,从上到下
flex-end 从下到上
center 垂直居中
stretch 拉伸(使用该属性时,子元素没有高度才会看到效果)
  • align-content设置侧轴上子元素的排列方式(多行)
属性值 说明
flex-start 默认值,从侧轴的头部开始排列
flex-end 从侧轴的底部开始排列
center 在侧轴的中间显示
space-around 子项在侧轴平分剩余空间
space-between 子项在侧轴贴两边,再平分剩余空间
stretch 设置子项高度平方父元素高度
  • flex-flow是flex-direction和flex-wrap的整合,设置主轴方向和是否换行

7.2 flex布局子项常见属性

  • flex属性:定义子项目分配剩余空间,用flex来表示占多少份数
  • align-self:控制子项自己在侧轴上的排列方式
  • order属性:定义项目的排列顺序

三、行为(JS)

1. 数据类型

变量的数据类型:变量是用来存储值的所在处,他们有名字和数据类型。变量的数据类型决定了如何将代表这些值的位存储到计算机的内存中。JavaScript是一种弱类型或者说动态语言。这意味着不用提前声明变量的类型,在程序运行过程中,类型会被自动确定

1.1 数值型 number

  • 123 整型
  • 123.1 浮点型
  • 1.123e3 科学计数法
  • NaN (not a number)
  • Infinity 无限大

1.2 字符串 String

  • ‘ABC’(js中建议使用单引号)
  • “abc”

1.3 布尔值 boolean

  • true
  • false

1.4 逻辑运算符

  • && 两个都为真,结果为真
  • || 只要一个为真,结果为真
  • !真即假,假即真

1.5 比较运算符

  • = 赋值
  • == 等于(类型不一样,值一样,也会判断为true)
  • === 完全等于(类型一样,值一样,结果为true)

js中不要使用==来进行比较

须知:

  • NaN === NaN为false,NaN与所有数值都不相等,包括自己
  • 1/3 === 1-2/3为false,尽量避免浮点数进行运算,因为会存在精度问题

1.6 null & undefined

  • null 空值
  • undefined 未定义值

1.7 数组

var arr = [1,2,3,4,5,'hello',null,true];

  • 访问数组:console.log(arr[i])。i(索引)取数组下标,如果越界了则输出undefined
  • 遍历数组:for循环+索引解决,for(i=0;i<=arr.length-1;i++) { console.log(arr[i]); }
  • 修改数组长度:arr.length = X(数字)。若x小于当前长度,删除超出部分;若x大于当前长度,则插入empty元素
  • 修改数组元素:arr[i] = 'xxx'。若i小于当前数组长度,替换arr[i]的值;若i大于当前数组长度,则新增arr[i]的值
  • 注意:不要直接给数组名赋值,否则会直接覆盖掉数组

1.8 函数

  • 形参数量大于实参,多出来的形参为undefined;形参数量小于实参,多出来的实参没有用
  • 一个函数中,return返回值后面的语句不会执行
  • 函数如果有return,则返回return后面的值;如果没有return,则返回的是undefined
  • arguments:里面存储了所有传递过来的实参,是一个伪数组(有length,可遍历)
  • 函数的两种声明方式:1. 命名函数 function fn() { ... }   2. 匿名函数 var fun() = function() { ... }

1.9 对象

在JavaScript中,对象时一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。

  • 对象是由属性和方法组成
    • 属性:事物的特征,在对象中用属性来表示(常用名词)
    • 方法:事物的行为,在对象中用方法来表示(常用动词)
  • 每个属性中间用逗号分隔,最后一个不需要添加逗号
    var person = {
    
        userName: "zhangsan",
    
        age: 3,
    
        tags: ['js','java','web','...'],
    
        sayHi: function(){ console.log('hi~'); }
    
    }
  • 使用对象

    • 调用对象的属性 对象名.属性名:person.userName

    • 调用属性的另一种方法 对象名[ '属性名' ]:person[ 'age' ]

2. 作用域

就是变量在某个范围内起作用和效果,目的是为了提高程序的可靠性,更重要的是减少命名冲突

2.1 js的作用域(es6)

  • 全局作用域:整个script标签,或者是一个单独的js文件
  • 局部作用域:在函数内部的就是局部作用域,这个变量只在函数内部起作用和效果
  • 块级作用域:{ }包围的变量,如if { },for{ }。但js中只有在es6才新增了块级作用域

2.2 变量的作用域

  • 全局变量:在全局作用域下的变量。如果在函数内部没有声明就直接赋值的变量也是全局变量
  • 局部变量:在局部作用域下的变量(在函数内部的变量)
  • 区别:全局变量只有在浏览器关闭时才会销毁,比较占用内存;局部变量在函数调用后就会销毁,消耗资源更少

2.3 作用域链

内部函数访问外部函数的变量,采取的是链式查找的方式来决定取哪个值,这种结构我们称为作用域链

<script>
    let num = 456; //全局变量
    function f1(){
        let num = 123; //局部变量
        function f2(){
            console.log(num); // 123 ,一层一层向上查找
        }
        f2();
    }
    f1();
</script>

 3. 预解析

JavaScript代码是由浏览器中的JavaScript解析器来执行的。JavaScript解析器在运行JavaScript代码的时候分为两步:1.预解析  2.代码执行。

3.1 预解析

js引擎会把js里面所有的声明变量和function提升到当前作用域的最前面

  • 变量预解析:就是把所有的变量声明提升到当前作用域的最前面,赋值不提升
    案例1: 最终输出为undefined
    //预解析前
    console.log(num);
    let num = 20;
    
    //预解析后
    let num; //只声明了变量但没有复制,num的值为undefined
    console.log(num); //输出undefined
    num = 20;
    
    
    案例2: 报错,变量不是函数
    //预解析前
    fn();
    var fn = function(){
        console.log(10);
    }
    
    //预解析后
    var fn; //只声明了变量但没有复制,fn的值为undefined
    fn(); //fn并非函数
    fn = function(){
        console.log(10);
    }
  • 函数预解析:把所有的函数声明提升到当前作用域的最前面,不调用函数
    案例:
    //预解析前
    fun();
    function fun(){
        console.log(11);
    }
    
    //预解析后
    function fun(){
        console.log(11);
    }
    fun();

3.2 代码执行

按照代码书写的顺序从上往下执行

4.构造函数

构造函数就是把对象中的一些相同的属性和方法抽象出来封装到函数里面,方便多次重复调用

4.1 语法格式

function 构造函数名(){
    this.属性 = 值
    this.方法 = function(){}
}
new 构造函数名()

//例子
function Star(uname,age,sex){
    this.name = uname;
    this.age = age;
    this.sex = sex;
}
let ldh = new Star('刘德华',18,'男');
let zxy = new Star('张学友',17,'男');
  • 构造函数名字首字母要大写
  • 构造函数不需要return就可以返回结果
  • 调用构造函数时必须要用new,例如:new Star() 调用构造函数创建一个对象“ldh”
  • 构造函数的属性和方法前面必须添加this

4.2 new关键字的执行过程

  1. new 构造函数可以在内存中创建一个空的对象
  2. this 就会指向刚才创建的空对象
  3. 执行构造函数里面的代码,给这个空对象添加属性和方法
  4. 返回这个对象

4.3 遍历对象

for...in 用于对数组或者对象的属性进行循环操作

// obj对象
let obj = {
    name:'菜虚鲲',
    age : 18,
    sex : '男',
    hobby: function(){
        console.log('唱跳rap篮球');
    }
}

//for in 循环遍历对象
for(let key in obj){
    console.log(key);  // key变量输出得到的是 属性名
    console.log(obj[key]);  //obj[key]输出得到的是 属性值
}

5. 内置对象

  • JavaScript中的对象分为三种:自定义对象、内置对象、浏览器对象。前两种对象是JS基础内容,属于ECMAScript;第三个浏览器对象属于JS独有的
  • 内置对象就是指JS语言自带的一些对象,这些对象提供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)
  • 内置对象最大的优点就是帮助我们快速开发
  • JavaScript提供了多个内置对象:Math、Date、Array、String等

5.1 查文档(MDN)

5.2 日期对象

let date = new Date();

5.3 数组对象

let arr = new Array();

  • 检测是否为数组:Array.isArray(arr)
  • 添加数组元素
    • 在数组末尾追加一个值:arr.push()
    • 在数组头部追加一个值:arr.unshift()
  • 删除数组元素
    • 删除数组的最后一个值:arr.pop()
    • 删除数组的第一个值:arr.shift()
  • 数组排序
    • 翻转数组:
      • arr.reverse();
      • for循环一个个交换
    • 冒泡排序:
      • 从小到大排序:arr.sort(function(a, b){return a-b});
      • 从大到小排序:arr1.sort(function(a, b){return b-a});
      • 双重for循环,替换数值
  • 数组索引方法
    方法名 说明 返回值
    indexOf('要查找的元素',起始的位置) 数组中查找给定义元素的第一个索引 如果存在则返回索引号,如果不存在则返回-1
    lastIndexOf() 数组中查找给定义元素的最后一个索引 如果存在则返回索引号,如果不存在则返回-1
  • 数组转换为字符串

    • arr.toString() 以逗号分隔

    • arr.join('分隔符') 自己选择分隔符

5.4 字符串对象

  • 基本包装类型:把简单数据类型包装成为了复杂数据类型

    let str = 'andy';

    console.log(str.length);

    按道理来说,基本数据类型是没有属性和方法的,而对象才有属性和方法,但上面的代码却可以执行,这是因为js会把一些基本数据类型包装为复杂数据类型。三个特殊的引用类型:String、Number、Boolean

    //1.生成临时变量,把简单数据类型包装为复杂数据类型
    let temp = new String('andy');
    //2.赋值给我们声明的字符串变量
    str = temp;
    //3.销毁临时变量
    temp = null;

  • 字符串不可变
    let str = 'andy';
    str = 'red';
    console.log(str); //结果为red

    字符串不可变指的是里面的值不可变,虽然上方的代码看上去改变了str里的内容,但其实是在内存中新开辟了一个内存空间(red),str的地址指向了新的空间,而andy仍然占用着它自己的内存空间。

  • 根据字符返回位置
    • str.indexOf('要查找的字符',起始的位置)
      let str = '改革春风吹满地,春天来了';
      console.log(str.indexOf('春')); //输出为2
      console.log(str.indexOf('春',3)); //从索引号为3的位置开始往后查找,所以输出为8
    • str.lastIndexOf('要查找的字符',起始的位置)
  • 根据位置返回字符
    • 返回指定位置的字符:charAt(index);
    • 获取指定位置处字符的ASCII码:charCodeAt(index);
    • 获取指定位置处的字符:str[index];(兼容性:HTML5,IE8+支持)
  • 字符串的拼接以及截取
    • 拼接:concat(str1,str2,str3...);concat()方法用于连接两个或多个字符串,等效于str1+str2+str3,但更多用+来拼接
    • 截取:substr(start,length);从start位置开始,length为取的个数
    • 截取:slice(start,end);从start位置开始,截取到end位置(不包括end),可以是负值(负值就是从尾部开始截取)
    • 截取:substring(start,end);从start位置开始,截取到end位置(不包括end),但是不接受负值
  • 替换字符:replace('被替换的字符','替换为的字符'); 如果有多个相同的字符,该方法只会替换第一个字符。
  • 字符转换为数组:split('分隔符');
    let str1 = 'red,orange,blue';
    console.log(str1.split(','));
    //输出['red','orange','blue']
    
    let str2 = 'red&orange&blue';
    console.log(str1.split('&'));
    //输出['red','orange','blue']

6.简单数据类型和复杂数据类型总结

6.1 数据类型内存分配

  • 栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的等。其操作方式类似于数据结构中的栈。简单数据类型会存放到栈里面,存放的是值,修改也是直接修改值。
  • 堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。复杂数据类型存放到堆里面,先在栈里存放了地址,栈里的地址指向堆中的值。所以在修改复杂数据类型时, 

6.2 数据类型的传参

  • 简单数据类型传参:函数的形参也可以看做是一个变量,当我们把一个值类型变量作为参数传给函数的形参时,其实是把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到外部变量。
    function func(a){ //调用func(x)后,a的值就是10
        a++; //a的值变为了11
        console.log(a);//a打印出来值为11
    }
    
    let x = 10;//外部变量x 值为10
    func(x); //将变量x作为参数传递给func函数,形参a的值改变不影响这里x的值
    console.log(x);//x打印出来值为10
    
    
  • 复杂数据类型传参:函数的形参也可以看做是一个变量,当我们把引用类型变量传给形参时,其实是把变量在栈空间里保存的地址复制给了形参,形参和实参保存的是同一个地址,所以操作的也是同一个对象。
    function Person(name){
        this.name = name;
    }
    
    // x=p,p在栈中存的是地址,复制了一份地址给x,所以x和p的地址相同,指向了堆里同一个对象
    function fn(x){ 
        console.log(x.name); //第二次输出:因为x和p指向了同一个对象,所以x的name也是‘刘德华’
        x.name = '张学友'; //x将该对象的name改成了‘张学友’
        console.log(x.name); //第三次输出:name为‘张学友’,因为x把对象的name改了
    }
    
    let p = new Person('刘德华'); //先执行构造函数,在栈中生成一个地址,地址指向堆里的对象
    console.log(p.name); //第一次输出:name为‘刘德华’
    
    fn(p); //再执行方法,p作为参数传递给方法fn
    console.log(p.name);//第四次输出:name为‘张学友’,因为调用fn方法时x将对象的name改掉了

四、Web APIs(DOM+BOM)

1. DOM 简介

文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口

W3C已经定于了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、接口和样式。

1.1 DOM树

  • 文档:一个页面就是一个文档,DOM中使用document来表示
  • 元素:页面中所有的标签都是元素,DOM中使用element来表示
  • 节点:网页中所有的内容都是节点(标签、属性、文本、注释),DOM中使用node来表示

DOM把以上内容都看作是对象

 1.2 获取元素

  • 根据ID获取:使用getElementById()可以获取带有ID的元素对象
  • 根据标签名获取:使用getElementsByTagName()可以返回带有指定标签名的对象的集合
    • document.getElementsByTagName() 页面上所有的指定标签名
    • element.getElementsByTagName() 指定元素下的指定标签名
  • HTML5 新增的方法(不兼容低版本ie)
    • document.getElementsByClassName('类名')  //根据类名返回元素对象的集合
    • document.querySelector('选择器'); //根据指定选择器返回第一个元素对象
    • document.querySelectorAll('选择器'); //根据指定选择器返回所有元素对象
  • 获取body和html元素
    • document.body;//获取body元素对象
    • document.documentElement; //获取html元素对象

2. 事件基础

JavaScript使我们有能力创建动态页面,而事件是可以被JavaScript侦测到的行为(触发响应机制)。网页中的每个元素都可以产生某些可以触发JS的事件,例如我们可以在用户点击某按钮时产生一个事件,然后去执行某些操作。

2.1 事件的三要素:

  1. 事件源
  2. 事件类型
  3. 事件处理程序
//1.事件源:事件被触发的对象(谁)
let btn = document.getElementById('btn');
//2.事件类型:如何触发(鼠标点击onclick)
//3.事件处理程序:触发后做了什么事
btn.onclick = function() {
    alert('点秋香');
}

2.2 执行事件的步骤:

  1. 获取事件源
  2. 注册事件(绑定事件)
  3. 添加事件处理程序(采取函数赋值的形式)
常见的鼠标事件 触发条件
onclick 鼠标点击左键触发
onmouseover 鼠标经过触发
onmouseout 鼠标离开触发
onfocus 获得鼠标焦点触发
onblur 失去鼠标焦点触发
onmousemove 鼠标移动触发
onmouseup 鼠标弹起触发
onmousedown 鼠标按下触发

3. 操作元素

3.1 改变元素内容

  • element.innerText  从起始位置到终止位置的内容,但它去除html标签,同时空格和换行也会去掉
  • element.innerHTML 从起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行

innerText和innerHTML的区别

  1. innerText不识别html标签,innerHTML识别html标签
    <body>
        <div id="innertext"></div>
        <div id="innerhtml"></div>
    </body>
    <script>
        //是否识别HTML标签
        let div1 = document.querySelector('#innertext');
        div1.innerText = '<strong>今天是:</strong> 2021年05月20日';
        let div2 = document.querySelector('#innerhtml');
        div2.innerHTML = '<strong>今天是:</strong> 2021年05月20日';
    </script>

    结果:

  2. innerText会自动去除空格和换行,innerHTML保留空格和换行(这两个属性是可读写的,这里做读取使用,获取元素里面的内容)
    <body>
        <p>
            吧啦吧啦吧啦
            <span>嘤嘤嘤</span>
        </p>
    </body>
    <script>
        //是否保留空格
        let p = document.querySelector('p');
        console.log('innerText:' + p.innerText);
        console.log('');
        console.log('innerHTML:' + p.innerHTML);
    </script>

    结果:

3.2 改变元素属性

常用元素的属性操作

  1. innerText、innerHTML 改变元素内容
  2. src、href 链接
    <body>
        <img src="" alt="">
    </body>
    <script>
        let img = document.querySelector('img');
        img.src = "images/xxx.jpg"
    </script>
  3. id、alt、title
    <body>
        <img src="" alt="">
    </body>
    <script>
        let img = document.querySelector('img');
        img.title = "乌拉!!"
    </script>

3.3 操作表单元素的属性

type、value、checked、selected、disabled

用法:ducument.type = xxxx;

3.4 操作样式属性

我们可以通过js修改元素的大小、颜色、位置等样式

  • 行内样式操作:element.style   这个方法用于修改样式较少或较简单的情况
    <style>
        .box {
            width: 100px;
            height: 100px;
            background-color: red;
        }
    </style>
    <body>
        <div class="box">文本</div>
    </body>
    <script>
        let box = document.querySelector('.box');
        box.onclick = function(){
            this.style.backgroundColor = 'blue';
        }
    </script>
  • 类名样式操作:element.className
    <style>
        .box {
            width: 100px;
            height: 100px;
            background-color: red;
        }
        .change {
            width: 200px;
            height: 100px;
            background-color: blue;
        }
    </style>
    <body>
        <div class="box">文本</div>
    </body>
    <script>
        let box = document.querySelector('.box');
        box.onclick = function(){
            this.className = 'change';
        }
    </script>

注意:

  1. 如果样式修改较多,可以采取操作类名的方式来修改元素样式
  2. class因为是个保留字,因此使用className来操作元素类名属性
  3. className会直接更改元素的类名,会覆盖原先的类名

3.5 操作自定义属性

  • 获取属性值
    • element.属性名;  获取内置属性值(元素本身自带的属性)
    • element.getAttribute('属性名');  主要用于获取自定义的属性(程序员自定义的属性)
  • 设置元素属性值
    • element.属性名 = '值';  修改内置属性值(元素本身自带的属性)
    • element.setAttribute('属性名', 属性值);  主要用于修改自定义的属性,也可修改内置属性
  • 移除属性 element.removeAttribute('属性名');

3.6 操作节点

节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。

1. 父级节点 node.parentNode

  • parentNode属性可返回某节点的父节点,注意是最近的一个父节点
  • 如果指定的节点没有父节点则返回null

2. 子节点 node.childNodes

  • 返回值里包含了所有的子节点,包括元素节点和文本节点等
  • 如果只想要获得里面的元素节点,则需要做专门处理。所以一般不提倡使用childNodes

3. 子元素节点 node.children

  • node.children是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其余的节点不返回
  • 虽然chlidren是一个非标准,但是得到了各个浏览器的支持,因此可以放心使用

4. 获取第一个子元素节点和最后一个元素节点

  • node.firstChild 获取第一个子节点,这个方法会获取文字节点
  • node.firstElementChild 获取第一个子元素节点,这个方法只支持ie9以上版本
  • node.lastChild 获取最后一个子节点,这个方法会获取文字节点
  • node.lastElementChild 获取最后一个子元素节点,这个方法只支持ie9以上版本
  • 实际开发中也可以使用node.children方法获取所有的子元素节点,然后通过list[0]和 list[length-1]来获取第一个和最后一个子元素节点

5. 获取兄弟节点

  • node.nextSibling和node.previousSibling 下一个或上一个兄弟节点,包括元素节点和文本节点等
  • node.nextElementSibling和node.previousElementSibling 得到下一个兄弟元素节点,但支持ie9以上的版本

6. 创建和添加节点

第一步:创建节点 document.createElement('tagName')

document.createElement() 方法创建由tagName指定的HTML元素,因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称之为动态创建元素节点

第二步:添加节点 node.appendChild(child) / node.insertBefore(child, 指定元素)                    node是父级 child是子级

  • node.appendChild() 方法将一个节点添加到指定父节点的子节点列表末尾,类似于css里面的after伪元素
  • node.insertBefore() 方法将一个节点添加到父节点的前面,类似于css里的before伪元素
<body>
    <ul>
        <li>123</li>
    </ul>
</body>
<script>
    let ul = document.querySelector('ul');
    //1.创建节点
    let li1 = document.createElement('li');
    let li2 = document.createElement('li');
    //2.添加节点
    ul.appendChild(li1);
    ul.insertBefore(li2,ul.children[0]);
    console.log(ul);
</script>

7. 删除节点 node.removeChild(child)

  • node是父级 child是子级
  • node.removeChild() 方法从DOM中删除一个子节点,返回删除的节点

8. 克隆节点 node.cloneNode()

node.cloneNode() 方法返回调用该方法的节点的一个副本。也称为克隆节点/拷贝节点

注意:

  • 如果括号参数为空或者false,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点
  • 如果括号参数为true,则是深度拷贝,会复制节点本身以及里面所有的子节点

9. 三种动态创建元素的区别

  • document.write()
  • element.innerHTML
  • document.createElement()

区别:

  1. document.write() 是直接将内容写入页面的内容流,但是当文档流执行完毕时触发该方法,它会导致页面全部重绘
  2. innerHTML是将内容写入某个DOM节点,不会导致页面全部重绘
  3. innerHTML创建多个元素的效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
  4. createElement()创建多个元素的效率稍微低一点点,但是结构更清晰

4. DOM重点核心

4.1 创建

  • document.write
  • innerHTML
  • createElement

4.2 增

  • appendChild
  • insertBefore

4.3 删

  • removeChild

4.4 改

  • 修改元素属性:src、href、title
  • 修改普通元素内容:innerHTML、innerText
  • 修改表单元素:value、type、disabled等
  • 修改元素样式:style、className

4.5 查

  • DOM提供的API方法:getElementById、getElementsByTagName 古老用法、不太推荐
  • H5提供的新方法:querySelector、querySelectorAll  提倡
  • 利用节点操作获取元素:父(parentNode)、子(children)、兄(nextElementSibling、previousElementSibling) 提倡

4.6 属性操作

  • setAttribute:设置dom的属性值
  • getAttribute:得到dom的属性值
  • removeAttribute:移除属性

4.7 事件操作

给元素注册事件:事件源.事件类型 = 事件处理程序

5. 高级事件

5.1 注册事件

给元素添加事件,称为注册事件或者绑定事件

注册事件有两种方式:传统方式方法监听注册方式

  • 传统注册方式
    • 利用on开头的鼠标事件
    • 特点:注册事件的唯一性
    • 同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数会覆盖前面注册的处理函数
  • 事件监听注册方式
    • addEventListener() 它是一个方法
    • IE9之前的版本不支持此方法,可食用attachEvent() 代替
    • 特点:同一个元素同一个事件可以注册多个监听器,按注册顺序依次执行

eventTarget.addEventListener(type, listener [, useCapture])

该方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数

该方法接收三个参数:

  • type:事件类型字符串,比如click、mouseover等,注意这里不要带on
  • listener:事件处理函数,事件发生时,会调用该监听函数
  • useCapture:可选参数,是一个布尔值,默认是false。
<body>
    <button>事件1</button>
    <button>事件2</button>
</body>
<script>
    let btns = document.querySelectorAll('button');
    btns[0].addEventListener('click',function (){
        alert(1);
    })
    btns[0].addEventListener('click',function (){
        alert(2);
    })

    // attachEvent ie9以前的浏览器支持(不建议使用)
    btns[1].attachEvent('click',function (){
        alert(3);
    })
</script>

5.2 删除事件(解绑事件)

  • 传统注册方式 eventTarget.onclick = null;
  • 方法监听注册方式 eventTarget.removeEventListener(type,listener[, useCapture]); 注意:这里括号中的事件处理函数不能使用匿名函数
    <body>
        <button>事件1</button>
        <button>事件2</button>
    </body>
    <script>
        let btns = document.querySelectorAll('button');
        //1.传统方式
        btns[0].onclick = function(){
            alert(1);
            btns[0].onclick = null; //传统方式删除事件
        }
        //2.方法监听
        btns[1].addEventListener('click', fn)
        function fn(){
            alert(2);
            btns[1].removeEventListener('click', fn);
        }
    </script>

5.3 DOM 事件流

事件流描述的是从页面中接收事件的顺序

事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程DOM事件流

注意:

  • JS代码中只能执行捕获或者冒泡其中一个阶段
  • onclick和attachEvent只能得到冒泡阶段
  • addEventListener(type, listener[, useCapture])第三个参数为true,表示在事件捕获阶段调用事件处理程序;如果是false(不写默认就是false),表示在事件冒泡阶段调用事件处理函数
  • 实际开发中我们很少使用事件捕获,更关注事件冒泡
  • 有些事件是没有冒泡的,如:onblur、onfocus、onmouseenter、onmouseleave

mouseenter和mouseover的区别:

  • 当鼠标移动到元素上时就会触发mouseenter事件,类似于mouseover
  • mouseover鼠标经过自身盒子会触发,经过子盒子还会触发,因为鼠标经过子盒子时没有注册事件,就向上冒泡到了父盒子,于是触发了第二次
  • mouseenter不会冒泡

m5.4 事件对象 

什么是事件对象

let btn = document.querySelector('button');
btn.onclick = function(event){
    console.log(event);
}
  • event 就是一个时间对象,写到侦听函数的小括号里,当作形参
  • 事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要传递参数
  • 事件对象是事件的一系列相关数据的集合,跟事件相关,例如鼠标点击里面就包含了鼠标的相关信息:鼠标点击坐标等等
  • 这个事件对象也可以自己命名,比如event、evt、e
  • 事件对象也有兼容性问题,ie678通过window.event来获取事件对象

事件对象的常见属性和方法

事件对象属性方法 说明
e.target 返回触发事件的对象
e.srcElement 返回触发事件的对象(ie6-8使用)
e.type 返回事件的类型(click、mouseover等,不带on)
e.cancelBubble 阻止冒泡(ie6-8使用)
e.returnValue 阻止默认事件(比如不让链接跳转,ie6-8使用)
e.preventDefault() 阻止默认事件(比如不让链接跳转)
e.stopPropagation() 阻止冒泡
  • e.target和this的区别:e.target点击了哪个元素就返回那个元素,this是哪个元素绑定了这个点击事件就返回谁
    <body>
        <div>
            <button>按钮</button> //点击div中的btn按钮
        </div>
    </body>
    <script>
        let div = document.querySelector('div');
        let btn = document.querySelector('button');
        div.addEventListener('click', function (e){
            console.log(this); //this返回的是绑定了事件的div
            console.log(e.target); //e.target返回的是点击的button
        })
    </script>
  •  阻止默认行为

    <body>
        <a href="https://www.baidu.com">baidu</a>
        <br>
        <a href="https://www.baidu.com">baidu(阻止跳转)</a>
    </body>
    <script>
        let aa = document.querySelectorAll('a');
        aa[1].addEventListener('click', function (e){
            e.preventDefault(); //dom的标准写法
        })
        //传统的注册方式
        aa[1].onclick = function(e){
            //1.普通浏览器
            e.preventDefault();
            //2.低版本ie
            e.returnValue;
            //3.也可以利用return false来阻止默认行为,没有兼容性问题
            //注意:return后面的代码不执行,且只限于传统注册事件方法
            return false;
        }
    </script>
  • 阻止事件冒泡

    <body>
        <div class="father">
            <div class="son"></div>
        </div>
    </body>
    <script>
        let son = document.querySelector('.son');
        son.addEventListener('click', function (e){
            alert('son');
            e.stopPropagation(); //dom标准方式
            e.cancelBubble = true; //非标准,低版本ie使用
        })
    </script>

5.5 事件委托(代理、委派)

事件委托也称为事件代理,在jQuery里面称为事件委派

  • 原理:不是给每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点
  • 作用:只操作了一次DOM,提高了程序的性能
    <body>
        <div>
            <button>按钮1</button>
            <button>按钮2</button>
            <button>按钮3</button>
        </div>
    </body>
    <script>
        let div = document.querySelector('div');
        //给div设置事件监听器,每次点击按钮时,因为冒泡原理,div的子节点也会执行div的事件
        div.addEventListener('click',function (){
            alert('呀呼~!');
        })
    </script>

5.6 常用的鼠标事件

1. 禁止鼠标右键菜单 contextmenu

<body>
    <div>这是一段无法鼠标右击的文字</div>
</body>
<script>
    let div = document.querySelector('div');
    div.addEventListener('contextmenu', function(e){
        e.preventDefault();
    })
</script>

2. 禁止鼠标选中 selectstart

<body>
    <div>这是一段你选不中的文字</div>
</body>
<script>
    let div = document.querySelector('div');
    div.addEventListener('selectstart', function(e){
        e.preventDefault();
    })
</script>

3. 获得鼠标在页面中的坐标

鼠标事件对象 说明
e.clientX 返回鼠标相对于浏览器窗口可视区的X坐标
e.clientY 返回鼠标相对于浏览器窗口可视区的Y坐标
e.pageX 返回鼠标相对于文档页面的X坐标,IE9+支持,重点
e.pageY 返回鼠标相对于文档页面的Y坐标,IE9+支持,重点
e.screenX 返回鼠标相对于电脑屏幕的X坐标
e.screenY 返回鼠标相对于电脑屏幕的Y坐标

5.7 常用的键盘事件

事件

  1. onkeyup 按键弹起的时候触发
  2. onkeydown 按键按下的时候触发,识别功能键
  3. onkeypress 按键按下的时候触发,但不识别功能键

注意:

  • 如果使用addEventListener,不需要加on
  • onkeypress不识别功能键,如左右箭头、ctrl、shift等
  • 以上三个事件的执行顺序是:keydown -- keypress -- keyup

键盘事件对象

1. e.keyCode 判断用户按下了哪个键,返回对应的ASCII码

注意:

  • onkeydown和onkeyup不区分字母大小写,onkeypress区分字母大小写
  • 在我们实际开发中,更多的是使用keydown和keyup,它能识别所有的键
  • keypress不识别功能键,但是其keyCode属性能区分大小写,返回不同的ASCII码

2. e.key 判断用户按下了哪个键,返回对应的键(推荐使用,keyCode后续可能会被淘汰)

6. BOM

BOM(Browser Object Model)即浏览器对象模型,它提供了独立与内容而与浏览器窗口进行交互的对象,其核心对象是windows。

BOM由一系列相关的对象构成,并且每个对象都提供了很多的方法和属性。

6.1 window对象常见的事件

窗口加载事件:

1. window.onload = function(){ } 或者 window.addEventListener('load', function(){ })

当文档内容完全加载完成后才会触发该事件(包括图像、脚本文件、CSS文件等)

注意:

  • 有了window.onload就可以把JS代码写到页面元素的上方,因为onload是等页面内容全部加载完毕后再去执行处理函数的。
  • window.onload传统注册事件方式只能写一次,如果有多个,会以最后一个为准。使用addEventListener则没有该问题

2. document.addEventListener('DOMContentLoaded',function(){ })

DOMContentLoaded事件触发时,仅当DOM加载完成,不包括样式表,图片,flash等等。

DOMContentLoaded和load的区别:

  • DOMContentLoaded仅 ie9以上支持
  • 如果页面的图片很多的话,从用户访问到onload触发可能需要较长的时间,交互效果就不能实现,必然影响用户的体验,此时用DOMContentLoaded事件比较合适。

调整窗口大小事件

window.onresize = function(){ } 或者 window.addEventListener('resize',function(){ });

window.onresize是调整窗口大小加载事件,当出发时就调用的处理函数

注意:

  • 只要窗口大小发生像素变化,就会触发这个事件
  • 我们经常利用这个事件完成响应式布局,window.innerWidth返回当前屏幕的宽度

6.2 定时器

setTimeout() 定时器

1、window.setTimeout(调用函数,延迟的毫秒数) 该方法用于设置一个定时器,该定时器在定时器到期后执行调用函数

注意:

  • window可以省略
  • 这个调用函数可以直接写函数,或者写函数名或者采取字符串‘函数名()’的形式。第三种形式不推荐
  • 延迟的毫秒数可省略,省略则默认为0
  • 因为定时器可能有很多,所以我们经常给定时器赋值一个标识符

2、回调函数:需要等待时间,时间到了才会去调用这个函数,因此称为回调函数。普通函数则是按照代码顺序直接调用。setTimeout()和element.onclick = function(){ } 或者 element.addEventListener('click', function(){ })里面的函数也都是回调函数。

3、停止setTimeout() 定时器

window.clearTimeout(timeoutID) 该方法用于取消先前通过调用setTimeout() 建立的定时器

注意:

  • window可以省略
  • 里面的参数就是定时器的标识符

setInterval() 定时器

1、window.setInterval(调用函数,延迟的毫秒数) 该方法用于重复调用一个函数,每隔这个时间就去执行一次调用函数

注意:

  • window可以省略
  • 这个调用函数可以直接写函数,或者写函数名或者采取字符串‘函数名()’的形式。第三种形式不推荐
  • 延迟的毫秒数可省略,省略则默认为0
  • 因为定时器可能有很多,所以我们经常给定时器赋值一个标识符

2、停止setTimeout() 定时器

window.clearInterval(timeoutID) 该方法用于取消先前通过调用setTimeout() 建立的定时器

注意:

  • window可以省略
  • 里面的参数就是定时器的标识符

6.3 JS执行机制

JavaScript语言一大特点就是单线程同一个时间只能做一件事。所有的任务都需要排队,前一个任务结束后才会执行后一个任务。如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。

同步和异步

  • 同步:前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的
    • 同步任务都在主线程上执行,形成一个执行线
  • 异步:等待某个任务执行的过程中,可同时执行其他的任务
    • 异步任务是通过回调函数实现的,一般来说异步任务有以下三种类型
    • 普通事件:click、resize等
    • 资源加载:load、error等
    • 定时器:包括setInterval、setTimeout等

JS执行机制

  1. 先执行执行栈中的同步任务
  2. 异步任务(回调函数)放入任务队列
  3. 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行

由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环(event loop)

6.4 location对象

window对象给我们提供了一个location属性,用于获取或设置窗体的URL,并且可以用于解析URL。因为这个属性返回的是一个对象,所以我们将这个属性也称为location对象

URL:统一资源定位符(Uniform Resource Locator,URL)是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置,以及浏览器应该怎么处理它。

URL的一般语法格式为:protocol://host[:port]/path/[?query]#fragment

  • https://blog.csdn.net/weixin_48009833/article/details/120365994
  • https://www.bilibili.com/video/BV1Sy4y1C7ha?p=281
组成 说明
protocol 通信协议,常用的http,https,ftp,maito等
host 主机:就是指域名
port 端口号(选填,不填时使用方案的默认端口,如http的默认端口是80)
path 路径:由零或多个‘/’符号隔开的字符串,一般用来表示一个目录或文件地址
query 参数:以键值对的形式,通过&符号隔开
fragment 片段:#后面内容常见于锚点链接

location对象的属性:

  • location.href: 获取或者设置整个URL
  • location.host:返回主机域名
  • location.port:返回端口号,如果没有填写则返回空字符串
  • location.pathname:返回路径
  • location.search:返回参数
  • location.hash:返回片段 #后面内容常见于锚点链接

localtion对象的方法:

  • location.assign():跟href一样,可以跳转页面(也称为重定向页面)
  • location.replace():替换当前页面,因为不记录历史,所以不能后退页面
  • location.reload():重新加载页面,相当于刷新按钮或者f5;如果参数为true强制刷新ctrl+f5,强制刷新可清除缓存

6.5 navigator对象

navigator 对象包含有关浏览器的信息,它有很多属性,我们最常用的是userAgent,该属性可以返回由客户主机发送服务器的user-agent头部的值,从而判断用户使用的是哪个终端打开的页面,实现跳转。

if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPad|ios|iPod|Android|
Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS
|Symbian|Windows Phone)/i))) {
    window.location.href = ''; //手机
} else {
    window.location.href = ''; //电脑
}

6.6 history对象

window对象给我们提供了一个history对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中)访问过的URL。

history对象的方法:

  • back():后退功能
  • forward():前进功能
  • go(参数):前进或后退功能(参数如果是1则前进一个页面,如果是-1则后退一个页面)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_48009833/article/details/120365994

智能推荐

【史上最易懂】马尔科夫链-蒙特卡洛方法:基于马尔科夫链的采样方法,从概率分布中随机抽取样本,从而得到分布的近似_马尔科夫链期望怎么求-程序员宅基地

文章浏览阅读1.3k次,点赞40次,收藏19次。虽然你不能直接计算每个房间的人数,但通过马尔科夫链的蒙特卡洛方法,你可以从任意状态(房间)开始采样,并最终收敛到目标分布(人数分布)。然后,根据一个规则(假设转移概率是基于房间的人数,人数较多的房间具有较高的转移概率),你随机选择一个相邻的房间作为下一个状态。比如在巨大城堡,里面有很多房间,找到每个房间里的人数分布情况(每个房间被访问的次数),但是你不能一次进入所有的房间并计数。但是,当你重复这个过程很多次时,你会发现你更有可能停留在人数更多的房间,而在人数较少的房间停留的次数较少。_马尔科夫链期望怎么求

linux以root登陆命令,su命令和sudo命令,以及限制root用户登录-程序员宅基地

文章浏览阅读3.9k次。一、su命令su命令用于切换当前用户身份到其他用户身份,变更时须输入所要变更的用户帐号与密码。命令su的格式为:su [-] username1、后面可以跟 ‘-‘ 也可以不跟,普通用户su不加username时就是切换到root用户,当然root用户同样可以su到普通用户。 ‘-‘ 这个字符的作用是,加上后会初始化当前用户的各种环境变量。下面看下加‘-’和不加‘-’的区别:root用户切换到普通..._限制su root登陆

精通VC与Matlab联合编程(六)_精通vc和matlab联合编程 六-程序员宅基地

文章浏览阅读1.2k次。精通VC与Matlab联合编程(六)作者:邓科下载源代码浅析VC与MATLAB联合编程浅析VC与MATLAB联合编程浅析VC与MATLAB联合编程浅析VC与MATLAB联合编程浅析VC与MATLAB联合编程  Matlab C/C++函数库是Matlab扩展功能重要的组成部分,包含了大量的用C/C++语言重新编写的Matlab函数,主要包括初等数学函数、线形代数函数、矩阵操作函数、数值计算函数_精通vc和matlab联合编程 六

Asp.Net MVC2中扩展ModelMetadata的DescriptionAttribute。-程序员宅基地

文章浏览阅读128次。在MVC2中默认并没有实现DescriptionAttribute(虽然可以找到这个属性,通过阅读MVC源码,发现并没有实现方法),这很不方便,特别是我们使用EditorForModel的时候,我们需要对字段进行简要的介绍,下面来扩展这个属性。新建类 DescriptionMetadataProvider然后重写DataAnnotationsModelMetadataPro..._asp.net mvc 模型description

领域模型架构 eShopOnWeb项目分析 上-程序员宅基地

文章浏览阅读1.3k次。一.概述  本篇继续探讨web应用架构,讲基于DDD风格下最初的领域模型架构,不同于DDD风格下CQRS架构,二者架构主要区别是领域层的变化。 架构的演变是从领域模型到C..._eshoponweb

Springboot中使用kafka_springboot kafka-程序员宅基地

文章浏览阅读2.6w次,点赞23次,收藏85次。首先说明,本人之前没用过zookeeper、kafka等,尚硅谷十几个小时的教程实在没有耐心看,现在我也不知道分区、副本之类的概念。用kafka只是听说他比RabbitMQ快,我也是昨天晚上刚使用,下文中若有讲错的地方或者我的理解与它的本质有偏差的地方请包涵。此文背景的环境是windows,linux流程也差不多。 官网下载kafka,选择Binary downloads Apache Kafka 解压在D盘下或者什么地方,注意不要放在桌面等绝对路径太长的地方 打开conf_springboot kafka

随便推点

VS2008+水晶报表 发布后可能无法打印的解决办法_水晶报表 不能打印-程序员宅基地

文章浏览阅读1k次。编好水晶报表代码,用的是ActiveX模式,在本机运行,第一次运行提示安装ActiveX控件,安装后,一切正常,能正常打印,但发布到网站那边运行,可能是一闪而过,连提示安装ActiveX控件也没有,甚至相关的功能图标都不能正常显示,再点"打印图标"也是没反应解决方法是: 1.先下载"PrintControl.cab" http://support.businessobjects.c_水晶报表 不能打印

一. UC/OS-Ⅱ简介_ucos-程序员宅基地

文章浏览阅读1.3k次。绝大部分UC/OS-II的源码是用移植性很强的ANSI C写的。也就是说某产品可以只使用很少几个UC/OS-II调用,而另一个产品则使用了几乎所有UC/OS-II的功能,这样可以减少产品中的UC/OS-II所需的存储器空间(RAM和ROM)。UC/OS-II是为嵌入式应用而设计的,这就意味着,只要用户有固化手段(C编译、连接、下载和固化), UC/OS-II可以嵌入到用户的产品中成为产品的一部分。1998年uC/OS-II,目前的版本uC/OS -II V2.61,2.72。1.UC/OS-Ⅱ简介。_ucos

python自动化运维要学什么,python自动化运维项目_运维学python该学些什么-程序员宅基地

文章浏览阅读614次,点赞22次,收藏11次。大家好,本文将围绕python自动化运维需要掌握的技能展开说明,python自动化运维从入门到精通是一个很多人都想弄明白的事情,想搞清楚python自动化运维快速入门 pdf需要先了解以下几个事情。这篇文章主要介绍了一个有趣的事情,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获,下面让小编带着大家一起了解一下。_运维学python该学些什么

解决IISASP调用XmlHTTP出现msxml3.dll (0x80070005) 拒绝访问的错误-程序员宅基地

文章浏览阅读524次。2019独角兽企业重金招聘Python工程师标准>>> ..._hotfix for msxml 4.0 service pack 2 - kb832414

python和易语言的脚本哪门更实用?_易语言还是python适合辅助-程序员宅基地

文章浏览阅读546次。python和易语言的脚本哪门更实用?_易语言还是python适合辅助

redis watch使用场景_详解redis中的锁以及使用场景-程序员宅基地

文章浏览阅读134次。详解redis中的锁以及使用场景,指令,事务,分布式,命令,时间详解redis中的锁以及使用场景易采站长站,站长之家为您整理了详解redis中的锁以及使用场景的相关内容。分布式锁什么是分布式锁?分布式锁是控制分布式系统之间同步访问共享资源的一种方式。为什么要使用分布式锁?​ 为了保证共享资源的数据一致性。什么场景下使用分布式锁?​ 数据重要且要保证一致性如何实现分布式锁?主要介绍使用redis来实..._redis setnx watch

推荐文章

热门文章

相关标签