JavaScript
JavaScript
JavaScript简介
Web前端有三层:
- HTML:从语义的角度,描述页面结构
- CSS:从审美的角度,描述样式(美化页面)
- JavaScript:从交互的角度,描述行为(提升用户体验)
JavaScript历史背景介绍
布兰登 • 艾奇(Brendan Eich,1961年~),1995年在网景公司,发明的JavaScript。
JavaScript与Java的关系,一开始JavaScript叫做LiveScript,但是由于当时Java这个语言特别火,所以为了傍大牌,就改名为JavaScript。如同“北大”和“北大青鸟”的关系。“北大青鸟”就是傍“北大”大牌。
JavaScript和ECMAScript的关系
CMAScript是一种由Ecma国际(前身为欧洲计算机制造商协会,英文名称是European Computer Manufacturers Association)制定的标准。
JavaScript是由公司开发而成的,问题是不便于其他的公司拓展和使用。所以欧洲的这个ECMA的组织,牵头制定JavaScript的标准,取名为ECMAScript。
简单来说,ECMAScript不是一门语言,而是一个标准。符合这个标准的比较常见的有:JavaScript、Action Script(Flash中用的语言)。就是说,你JavaScript学完了,Flash中的程序也就轻而易举了。
ECMAScript在2015年6月,发布了ECMAScript 6版本,语言的能力更强(也包含了很多新特性)。但是,浏览器的厂商不能那么快去追上这个标准。
JavaScript的组成
JavaScript基础分为三个部分:
- ECMAScript:JavaScript的语法标准。包括变量、表达式、运算符、函数、if语句、for语句等。
- DOM:操作网页上的元素的API。比如让盒子移动、变色、轮播图等。
- BOM:操作浏览器部分功能的API。比如让浏览器自动滚动。
JavaScript的特点
- 简单易用:可以使用任何文本编辑工具编写,只需要浏览器就可以执行程序。
- 解释执行(解释语言):事先不编译、逐行执行、无需进行严格的变量声明。
- 基于对象:内置大量现成对象,编写少量程序可以完成目标
Hello World
jS代码形式
- 行内式,在标签内写
- 内接式,在script便签内写
- 外联式,引入外部JS代码
语法规则
- JS代码对换行、缩进、空格不敏感,大小写敏感,每行代码后必须加英文分号“;”
- 所有符号都是半角的,英语的
- 注释,单行//,多行/**/
交互
- alert(),弹出警告框
- console.log(),在控制台输出
- prompt(),弹出能够让用户输入的对话框
常量与变量
常量
- 数字
- 字符串
变量定义与赋值
var a = 111
var是英语“variant”变量的缩写。后面要加一个空格,空格后面的东西就是“变量名”.
PS:在JavaScript中,永远都是用var来定义变量,这和C、Java等语言不同(有兴趣的同学可以看一下es6)
变量命名规范
变量名有命名规范:只能由英语字母、数字、下划线、美元符号$构成,且不能以数字开头,并且不能是JavaScript保留字。
驼峰法就可以
变量类型 - 数值型,number
- 字符串型,string
typeof()表示“获取变量的类型”,语法为:
typeof 变量
在JavaScript中,只要是数,就是数值型(number)的。无论整浮、浮点数(即小数)、无论大小、无论正负,都是number类型的。
连字符和加号的区别
键盘上的+可能是连字符,也可能是数字的加号
如果加号两边都是数值,此时是加。否则,就是连字符(用来连接字符串)。
number与string类型转换
- parseInt():字符串转数字,只保留字符串中的数字,小数取整,不四舍五入
数据类型
数据类型包括:基本数据类型和引用数据类型
基本数据类型
- number,Infinity(无限大,6/0)也是number类型
- string
- boolean
- null,空的,空对象
- undefined,表示变量未定义
引用数据类型
- Function
- Object
- Array
- String
- Date
运算符
- 赋值运算符,=、+=、-=、*=、/=、%=
- 算数运算符,=、-、*、/、%、++、--
- 比较运算符,、=、!=、!==、<、>、<=、>=
- 特殊情况
- 字符串拼接,+、ES6模板模板字符串
- NaN是number类型
ES6模板模板字符串,用(反引号)标识,用${}将变量括起来。
He is <b>${person.name}</b>and we wish to know his${person.age}.that is all
数据类型转换
- 将数值类型转换成字符串类型
- 隐式转换,字符串与数值类型拼接,自动转化为字符串类型
- 显式转换,String(),toString()
- 将字符串类型转换成数值类型,Number,parseInt,parseFloat
- 任何数据类型都可以转换为boolean类型,Boolean
常用内置对象
数组Array
- 数组的创建方式
字面量方式创建
var a = [1,2,3,4];
使用构造函数
var b = new Array();
- 数组赋值
var a = []; a[1] = 233
- 数组常用方法
- contact(),把几个数组合并到一个数组,返回
- join(),返回字符串,其中包含了连接到一起的数组中的所有元素,元素由指定分隔符开头
- pop(),移除数组最后一个元素
- push(),往数组尾添加一个元素,返回数组长度
- shift(),移除数组第一个元素
- unshift(),往数组头添加一个元素,并返回数组长度
- slice(start,end),返回数组的一部分
- sort(),对数组进行排序,按照ascii码
- reverse(),对数组进行反转
- length,属性,获取数组长度
字符串String
字符串方法
- charAt(),返回指定索引位置的字符
- concat(),返回字符串值,表示为多个字符的拼接
- match(),返回正则表达式模式对字符串进行查找,并将查找结果作为结果返回
- replace(old,new),用new替换old
- search(stringObject),知名是否存在响应匹配。如果找到匹配,search方法将返回一个整数值,指明这个匹配距离字符串开始的偏移位置;没有找到,返回-1.
- slice(start,end),返回start到end-1的字符串
- split(arg,length),返回将字符串以arg拆分,最大长度为length的数组
- toUpperCase(),返回一个新的字符串,此字符串全大写
- toLowerCase(),返回一个新的字符串,此字符串全小写
- trim(),去除字符串两边的空白
- substring(start,end),字符串截取,左闭右开
- 如果 indexStart 等于 indexEnd,substring 返回一个空字符串。
- 如果省略 indexEnd,substring 提取字符一直到字符串末尾。
- 如果任一参数小于 0 或为 NaN,则被当作 0。
- 如果任一参数大于 stringName.length,则被当作 stringName.length。
- 如果 indexStart 大于 indexEnd,则 substring 的执行效果就像两个参数调换了一样
- array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
- splice()方法通过删除现有元素和/或添加新元素来修改数组,并以数组返回原数组中被修改的内容。
- start指定修改的开始位置(从0计数),如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位(从-1计数);如果负数的绝对值大于数组的长度,则表示开始位置为第0位。
- deleteCount 可选,整数,表示要移除的数组元素的个数。如果 deleteCount 是 0或者负数,则不移除元素。这种情况下,至少应添加一个新元素。如果 deleteCount 大于start 之后的元素的总数,则从 start 后面的元素都将被删除(含第 start 位)。如果deleteCount被省略,则其相当于(arr.length - start)。
- item1, item2, ... 可选,要添加进数组的元素,从start 位置开始。如果不指定,则 splice() 将只删除数组元素。
- 详情请跳转
日期对象Date
创建日期对象只有构造函数一种方式,使用new关键字
//创建了一个date对象 var myDate = new Date();
日期对象方法
- getDate(),根据本地时间返回指定日期对象的月份中的第几天(1-31)
- get(),根据本地时间返回当天的日期和时间
- getMonth(),根据本地时间返回指定日期对象的月份(0-11)
- getFullYear(),根据本地时间返回指定日期对象的年份(四位数年份时返回四位数字)
- getDay(),根据本地时间返回指定日期对象的星期中的第几天(0-6)
- getHours(),根据本地时间返回指定日期对象的小时(0-23)
- getMinutes(),根据本地时间返回指定日期对象的分钟(0-59)
- getSeconds(),根据本地时间返回指定日期对象的秒数(0-59)
Math内置对象
Math常用方法
- Math.floor(),向下取整,称为“地板函数”
- Math.ceil(),向上取整,称为“天花板函数”
- Math.max(a,b),求a、b中的最大值
- Math.min(a,b),求a、b中的最小值
- Math.random(),随机数,默认0-1之间的随机数,公式 min+Math.random()*(max-min),求min~max之间的数
函数
函数:就是将一些语句进行封装,然后通过调用的形式,执行这些语句。
函数的作用:
- 将大量重复的语句写在函数里,以后需要这些语句的时候,可以直接调用函数,避免重复劳动。
- 简化编程,让编程模块化。
定义函数
function functionName(){}
function是一个关键字,functionName是函数名,小括号内放形参,大括号内放函数的语句
函数的调用
functionName();
形参与实参
形参与实参要匹配,个数要相同
函数返回值
看 return
伪数组arguments
arguments代表的是实参。有个讲究的地方是:arguments只在函数中使用。
- 获取函数实参的个数:arguments.length
- 获取函数形参的个数:functionName.length
- 之所以说arguments是伪数组,是因为:arguments可以修改元素,但不能改变数组的长短。
function functionName(a,b) {
arguments[0] = 99; //将实参的第一个数改为99
arguments.push(8); //此方法不通过,因为无法增加元素
}
清空数组的几种方式:
var array = [1,2,3,4,5,6];
array.splice(0); //方式1:删除数组中所有项目
array.length = 0; //方式1:length属性可以赋值,在其它语言中length是只读
array = []; //方式3:推荐
DOM事件操作
JavaScript的组成
JavaScript基础分为三个部分:
- ECMAScript:JavaScript的语法标准。包括变量、表达式、运算符、函数、if语句、for语句等。
- DOM:文档对象模型,操作网页上的元素的API。比如让盒子移动、变色、轮播图等。
- BOM:浏览器对象模型,操作浏览器部分功能的API。比如让浏览器自动滚动。
事件
JS是以事件驱动为核心的一门语言。
事件的三要素:事件源、事件、事件驱动程序。
总结如下:
- 事件源:引发后续事件的html标签。
- 事件:js已经定义好了
- 事件驱动程序:对样式和html的操作。也就是DOM。
<body>
<div id="box1"></div>
<script type="text/javascript">
// 1、获取事件源
var div = document.getElementById("box1");
// 2、绑定事件
div.onclick = function () {
// 3、书写事件驱动程序
alert("我是弹出的内容");
}
</script>
</body>
常见事件
获取事件源
- 通过id获取
var oDiv = document.getElementById('app');//单个对象
- 通过类名获取
var oActive = document.getElementsByClassName('active');//多个对象
- 通过标签名获取
var oLis = document.getElementsByTagName('li');//多个对象
- 救命稻草
document.querySelectorAll('css所学的所有选择器') //不管获取单个还是多个元素,获取的是NodeList对象
绑定事件的方式
- 直接绑定匿名函数
- 先单独定义函数,再绑定
- 行内绑定
<div id="box" class="box" onmouseover="func()">233</div>
<script type="text/javascript">
var oDiv = document.getElementById("box");
// 一、直接绑定匿名函数
oDiv.onclick = function () {
alert("匿名函数绑定方式");
};
// 二、先定义函数,再绑定
function fn() {
alert('第二种绑定方式'); //注意,这里是fn,不是fn()。fn()指的是返回值。
}
oDiv.onmouseout = fn;
// 三、行内绑定,在div标签中直接绑定
function func() {
alert("行内绑定方式");
}
</script>
事件驱动程序
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.box {
width: 200px;
height: 200px;
background-color: red;
}
</style>
</head>
<body>
<div class="box" id="box"></div>
<script>
var oDiv = document.getElementById("box");
oDiv.onmouseover = function () {
this.style.backgroundColor = "blue";
};
oDiv.onmouseout = function () {
this.style.backgroundColor= "red";
}
</script>
</body>
</html>
onload事件
当页面加载(文本和图片)完毕的时候,触发onload事件。
有一点我们要知道:js的加载是和html同步加载的。因此,如果使用元素在定义元素之前,容易报错。这个时候,onload事件就能派上用场了,我们可以把使用元素的代码放在onload里,就能保证这段代码是最后执行。
window.onload可以预防使用标签在定义标签之前。
<script type="text/javascript">
window.onload = function () {
console.log('233');
// 当页面加载完毕时,打印字符串
}
</script>
DOM
DOM介绍
什么是DOM
DOM:文档对象模型。DOM 为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构。目的其实就是为了能让js操作html元素而制定的一个规范。
解析过程
HTML加载完毕,渲染引擎会在内存中把HTML文档,生成一个DOM树,getElementById是获取内中DOM上的元素节点。然后操作的时候修改的是该元素的属性。
DOM树(一切都是节点)
上图可知,在HTML当中,一切都是节点:(非常重要)
- 元素节点:HMTL标签。
- 文本节点:标签中的文字(比如标签之间的空格、换行)
- 属性节点::标签的属性。
整个html文档就是一个文档节点。所有的节点都是Object。
DOM可以做什么 - 找对象(元素节点)
- 设置元素的属性值
- 设置元素的样式
- 动态创建和删除元素
- 事件的触发响应:事件源、事件、事件的驱动程序
DOM节点的获取
- 通过id获取单个标签
- 通过标签名获得标签数组
- 通过类名获得标签数组
DOM访问关系的获取
DOM的节点并不是孤立的,因此可以通过DOM节点之间的相对关系对它们进行访问。
可以通过一个节点访问它的父节点、兄弟节点、孩子节点。
- 访问父节点,parentNode
- 访问兄弟节点,nextElementSibling,nextSibling,previousElementSibling,previousSibling
- 访问孩子节点,firstElementChild,firstChild,lastElementChild,lastChild,childNodes,children
nextElementSibling与nextSibling
nextSibling指的是下一个节点(包括标签、空文档和换行节点)
- 火狐、谷歌、IE9+版本:都指的是下一个节点(包括标签、空文档和换行节点)。
- IE678版本:指下一个元素节点(标签)。
nextElementSibling - 火狐、谷歌、IE9+版本:都指的是下一个元素节点(标签)。
总结:为了获取下一个元素节点。我们可以这样做:在IE678中用nextSibling,在火狐谷歌IE9+以后用nextElementSibling,于是,综合这两个属性,可以这样写:
下一个兄弟节点 = 节点.nextElementSibling || 节点.nextSibling
previousElementSibling与previousSibling、firstChild与firstElementChild、lastElementChild与lastChild、childNodes与children都是一样的
获取任意一个兄弟节点:
节点自己.parentNode.children[index]; //随意得到兄弟节点
<div class="father">
<div class="child1">
<p>233</p>
<p>666</p>
</div>
<div class="child2"></div>
<div class="child3"></div>
</div>
<script>
var oChild1 = document.getElementsByClassName('child1')[0];
// 获取父亲节点
var father = oChild1.parentNode;
console.log(father);
// 获取兄弟节点
var brother = oChild1.nextElementSibling || oChild1.nextSibling;
// 获取孩子节点
var child = oChild1.children;
</script>
nodeType
- nodeType == 1 表示的是元素节点(标签) 。记住:元素就是标签。
- nodeType == 2 表示是属性节点
- nodeType == 3 是文本节点
DOM节点的操作(增删)
上一段的内容:节点的访问关系都是属性。
节点的操作都是函数(方法)
- 创建节点
新的标签(元素节点) = document.createElement("标签名");
- 插入节点
方式一
父节点.appendChild(新的子节点); //父节点的最后插入一个新的子节点
方式二
父节点.insertBefore(新的子节点,作为参考的子节点);
在参考节点前插入一个新的节点。
如果参考节点为null,那么他将在父节点最后插入一个子节点。 - 删除节点
父节点.removeChild(子节点);
自己删除自己
node1.parentNode.removeChild(node1);
- 复制节点(克隆节点)
要复制的节点.cloneNode(); //括号里不带参数和带参数false,效果是一样的。
要复制的节点.cloneNode(true);
括号里带不带参数,效果是不同的。解释如下:
- 不带参数/带参数false:只复制节点本身,不复制子节点。
- 带参数true:既复制节点本身,也复制其所有的子节点。
网页中显示隐藏性能消耗问题
- 可以通过控制元素的类名或者是style属性,对元素进行显示隐藏
好处:可以在网页中频繁性的切换,主要控制的是display:none|block;
坏处:文档初始化会有渲染开销,但是这点开销不算什么. - 通过DOM操作 appendChild和removeChild 对元素显示隐藏
好处:文档初始化的时候不会产生渲染开销
坏处:不要在网页中做频繁性的切换,会产生性能消耗
<div id="box">
<p></p>
<p id="pp">pp</p>
<p></p>
</div>
<script>
// 创建新节点
var newNode = document.createElement('div');
newNode.innerText = "新标签";
// 追加到id='pp'的标签前
var pp = document.getElementById('pp');
var box = document.getElementById('box');
box.insertBefore(newNode,pp);
// 删除id='pp'的节点
pp.parentNode.removeChild(pp);
// 复制新节点,并追加到页面中
var copyNode = newNode.cloneNode(true);
box.appendChild(copyNode);
</script>
设置节点的属性
- 获取节点属性
方式一
元素节点.属性; 元素节点[属性];
方式二
素节点.getAttribute("属性名称");
- 设置节点属性
方式一
myNode.src = "images/2.jpg" //修改src的属性值
方式二
元素节点.setAttribute(属性名, 新的属性值);
- 删除节点属性
元素节点.removeAttribute(属性名);
对标签值的操作
- 只设置文本
var oDiv = document.getElementById('box'); oDiv.innerText= '哈哈哈哈';
- 获取标签的内容值
//只获取所有(当前标签和子标签)文本内容
console.log(oDiv.innerText);
//获取父标签中所有的标签元素 (子标签,空格,换行,文本)
console.log(oDiv.innerHTML);
- 对表单控件value的操作
//设置value值 只适应于表单控件元素
document.getElementById('user').value = '233';
console.log(document.getElementById('user').value);
- img标签设置src属性来设置图片内容,a标签设置href属性来设置超链接的内容
对标签的css操作(样式操作)
xxx.style.css的属性key = '值'
对标签属性的操作
对id属性操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.box{
width: 200px;
height: 200px;
background-color: red;
}
.active{
background-color: black;
}
</style>
</head>
<body>
<input type="button" value="切换" id="btn">
<div class="box" id="box" title="显示的标题" ></div>
<img src="1.png" alt="图片加载失败显示的文本">
<a href="" title="" id class="" target="_blank"></a>
<script>
var oDiv = document.getElementById('box');
var oBtn = document.getElementById('btn');
oBtn.onclick = function () {
oDiv.id = 'box';
oDiv.title = '23333333333';
oDiv.className += ' active';
}
</script>
</body>
</html>
对img属性操作
- src 链接图片地址
- alt 图片加载失败的时候显示的文本
区分DOM对象属性和标签属性
//this.src 获取的是DOM对象的属性
console.log(this.src); //绝对路径
//获取出来的就是标签上的属性 通过getAttribute('');获取的标签上的属性
console.log(this.getAttribute('src'));
单选框的操作
function $(id) {
return document.getElementById(id);
}
console.log( $('nan').checked); //对象的属性 单选框 提交后台 建议使用对象属性checked
console.log( $('nan').getAttribute('checked')); //标签上属性
关于DOM操作的案例
- 选项卡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
padding: 0;
margin: 0;
}
#tab {
width: 498px;
height: 300px;
background-color: red;
margin: 20px auto;
}
ul {
list-style: none;
}
ul:after {
content: '.';
display: block;
visibility: hidden;
height: 0;
clear: both;
}
a {
text-decoration: none;
}
ul li {
width: 166px;
height: 100px;
background-color: yellow;
float: left;
line-height: 100px;
text-align: center;
}
p {
display: none;
width: 100%;
height: 200px;
line-height: 200px;
text-align: center;
}
.active {
display: block;
background-color: red;
}
</style>
</head>
<body>
<div id="tab">
<ul>
<li class="active"><a href="javascript:void(0)">首页</a></li>
<li><a href="javascript:void(0)">新闻</a></li>
<li><a href="javascript:void(0)">图片</a></li>
</ul>
<p class="active">首页内容</p>
<p>新闻内容</p>
<p>图片内容</p>
</div>
<script>
var oLiList = document.getElementsByTagName('li');
var oPList = document.getElementsByTagName('p');
// 使用ESMA6的关键字let定义变量,作用是,它定义的变量作用域是当前范围
// var 定义的变量作用域是 全局范围
// for (let i=0;i<oLiList.length;i++){
// oLiList[i].onclick = function () {
// for (let j=0;j<oLiList.length;j++){
// oLiList[j].className = '';
// oPList[j].className = '';
// }
// this.className = 'active';
// oPList[i].className = 'active';
// }
//
// }
// 利用 var
for (var i = 0; i < oLiList.length; i++) {
// 绑定索引值(新增一个自定义属性:index属性)
//var 声明变量 全局作用域,存在变量提升,导致最后 i=3,不会变
oLiList[i].index = i;
oLiList[i].onclick = function () {
for (var j = 0; j < oLiList.length; j++) {
oLiList[j].className = '';
oPList[j].className = '';
}
this.className = 'active';
oPList[this.index].className = 'active';
}
}
</script>
</body>
</html>
- 模态框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
margin: 0;
padding: 0;
}
#box {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, .3);
position: fixed;
top: 0;
}
#content {
height: 400px;
width: 400px;
position: relative;
text-align: center;
line-height: 400px;
background-color: #f6e1b6;
color: red;
top: 150px;
margin: auto;
}
#shout {
position: absolute;
top: 0;
right: 0;
height: 15px;
width: 15px;
background-color: #fff;
color: black;
text-align: center;
line-height: 10px;
cursor: pointer;
}
</style>
</head>
<body>
<input type="button" id="btn" value="弹出">
<!--<div id="box">-->
<!--<div id="content">-->
<!--模态框成功弹出-->
<!--<div id="shout">X</div>-->
<!--</div>-->
<!--</div>-->
</body>
<script type="text/javascript">
var btn = document.getElementById('btn');
var box = document.createElement('div');
var content = document.createElement('div');
var shout = document.createElement('div');
content.innerText = '模态框成功弹出';
shout.innerText = 'X';
content.appendChild(shout);
box.appendChild(content);
shout.id = 'shout';
content.id = 'content';
box.id = 'box';
btn.onclick = function(){
this.parentNode.appendChild(box);
};
shout.onclick = function(){
btn.parentNode.removeChild(box);
}
</script>
</html>
- 简易留言板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>留言板</title>
<style>
* {
padding: 0;
margin: 0;
}
.close {
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
cursor: pointer;
background-color: rgba(0, 0, 0, .1);
margin-left: 20px;
}
</style>
</head>
<body>
<h1>简易留言板233</h1>
<div id="box">
<ul>
</ul>
</div>
<textarea id="text"></textarea>
<input type="button" id="btn" value="留言">
<input type="button" id="count" value="统计" onclick="sum()">
</body>
<script>
var oText = document.getElementById('text');
var oBtn = document.getElementById('btn');
var oUl = document.getElementsByTagName('ul')[0];
// var oBox = document.getElementById('box');
var count = 0;
oBtn.onclick = function () {
var oLi = document.createElement('li');
oLi.innerHTML = oText.value + "<span class='close'>X</span>";
oUl.appendChild(oLi);
oText.value = '';
count++;
var oSpanList = document.getElementsByTagName('span');
for (var i = 0; i < oSpanList.length; i++) {
oSpanList[i].onclick = function () {
// this.parentNode.parentNode.removeChild(this.parentNode);
oUl.removeChild(this.parentNode);
count--;
}
}
};
function sum() {
alert('一共发布了'+count+'条留言');
}
</script>
</html>
- 使用js模拟选择器中hover
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用js模拟选择器中hover</title>
<style>
button {
width: 100px;
height: 30px;
margin: 10px;
cursor: pointer;
}
.current {
background-color: red;
}
</style>
</head>
<body>
<button>按钮一</button>
<button>按钮二</button>
<button>按钮三</button>
<button>按钮四</button>
<button>按钮五</button>
</body>
<script>
var oBtnList = document.getElementsByTagName('button');
for (var i=0;i<oBtnList.length;i++){
oBtnList[i].onmouseover = function () {
this.className = 'current';
};
oBtnList[i].onmouseout = function () {
this.className = '';
}
}
</script>
</html>
JavaScript面向对象
创建对象的几种常用方式
- 使用Object或对象字面量创建对象
- 工厂模式创建对象
- 构造函数模式创建对象
- 原型模式创建对象
es6的用法
es6的用法:
- 模板字符串 `` 变量名使用${}
- class 类的概念
- 箭头函数 ()=>3 等价于 function()
- let 声明变量,局部作用局,不可重复定义相同变量
- const 声明常量,局部作用域,不可修改
// Object方式,JS中最基本的创建方式
var student = new Object();
student.name = '233';
student.age = 18;
// 字面量方式
var student = {
name: '233',
age: 18
};
// 但是上面两种在创建相同对象时需要重复大量代码,无法复用。
// 工厂模式
// JS中没有类的概念,那么我们不妨就使用一种函数将以上对象创建过程封装起来以便于重复调用,同时可以给出特定接口来初始化对象
function createStudent(name, age) {
var obj = new Object();
obj.name = name;
obj.age = age;
return obj;
}
var s1 = createStudent('张三', 99);
var s2 = createStudent('李四', 100);
var s3 = createStudent('王五', 430);
// 这种创建方式创建的对象,类型都是Object,无法区分类型。
// 构造函数方式创建对象
// 在进行自定义构造函数创建对象之前,我们首先了解一下构造函数和普通函数有什么区别。
// 1、实际上并不存在创建构造函数的特殊语法,其与普通函数唯一的区别在于调用方法。对于任意函数,使用new操作符调用,那么它就是构造函数;不使用new操作符调用,那么它就是普通函数。
// 2、按照惯例,我们约定构造函数名以大写字母开头,普通函数以小写字母开头,这样有利于显性区分二者。例如 new Array(),new Object()。
// 3、使用new操作符调用构造函数时,会经历(1)创建一个新对象;(2)将构造函数作用域赋给新对象(使this指向该新对象);(3)执行构造函数代码;(4)返回新对象;4个阶段。
// ok,了解了构造函数和普通函数的区别之后,我们使用构造函数将工厂模式的函数重写,并添加一个方法属性:
function Student(name, age) {
this.name = name;
this.age = age;
this.alertName = function () {
alert(this.name);
}
}
var s4 = new Student(22, 22);
alert(s4 instanceof Student); // true
// 这种方式创建的对象,可以区分对象类型。
// 此时,如果多个对象中有相同的东西,需要抽离出来,代码复用更高。但是东西多了,全局变量会多。更好的方案是通过原型对象模式来解决
// 可以把共同内容这样写
function Student(name, age) {
this.name = name;
this.age = age;
this.alertName = alertName;
}
function alertName() {
alert(this.name);
}
// 原型模式创建对象
// 原型链甚至原型继承,是整个JS中最难的一部分也是最不好理解的一部分。
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.fav = function () {
console.log(this.name);
};
let p1 = new Person('alex', 16);
let p2 = new Person('alex', 16);
p1.fav();
//es6 使用class关键字来创建对象
class Furit {
//初始化的构造器方法
constructor(name = 'alex', age = 16) {
this.name = name;
this.age = age
}
//对象的单体模式 等价于fav:function(){}
fav() {
console.log(this.age);
}
}
var f1 = new Furit();
f1.fav();
定时器
在js中的定时器分两种:
- setTimeout(),在指定的时间后执行一次,异步
- setInterval(),指定时间间隔周期循环执行,可以用它来做js动画,注意要清除定时器
function time() {
alert(new Date().getTime());
}
// 一秒后显示时间戳
var a = window.setTimeout(time, 1000);
// 每秒显示一次时间戳
var b = setInterval(time, 1000);
// 结束 setTimeout定时器
clearTimeOut(a);
// 结束 setInterval定时器
clearInterval(b);
BOM
JavaScript基础分为三个部分:
- ECMAScript:JavaScript的语法标准。包括变量、表达式、运算符、函数、if语句、for语句等。
- DOM:文档对象模型,操作网页上的元素的API。比如让盒子移动、变色、轮播图等。
- BOM:浏览器对象模型,操作浏览器部分功能的API。比如让浏览器自动滚动。
BOM介绍
BOM:Browser Object Model,浏览器对象模型。
BOM操作
- 弹出系统对话框
系统对话框有三种:
alert(); //不同浏览器中的外观是不一样的
confirm(); //兼容不好
prompt(); //不推荐使用
- 打开窗口、关闭窗口
window.open(url,target);
// url 要打开的地址
// target,新窗口的位置在,可以是:_blank 、_self、 _parent 父框架。默认_blank。
- location对象
window.location可以简写成location。location相当于浏览器地址栏,可以将url解析成独立的片段。
location对象的属性- href:跳转
- hash 返回url中#后面的内容,包含#
- host 主机名,包括端口
- hostname 主机名
- pathname url中的路径部分
- protocol 协议 一般是http、https
- search 查询字符串
location对象的方法
location.reload(); //重新加载整个网页
不建议使用,采用AJAX技术更佳(局部刷新)。
三种打开新网页的方法:
a标签href属性
location.reload()
location.href
-
navigator对象
window.navigator 的一些属性可以获取客户端的一些信息。- userAgent:系统,浏览器
- platform:浏览器支持的系统,win/mac/linux
-
history对象
1、后退:
history.back()
history.go(-1):0是刷新
2、前进:
history.forward()
history.go(1)
client、offset、scroll系列
client
- clientTop 内容区域到边框顶部的距离 ,边框的高度
- clientLeft 内容区域到边框左部的距离,边框的宽度
- clientWidth 内容区域+左右padding,可视宽度
- clientHeight 内容区域+ 上下padding,可视高度
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>client</title>
<style>
#box {
width: 200px;
height: 200px;
padding: 50px;
border: 10px solid red;
}
</style>
</head>
<body>
<div id="box">
啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
</div>
<script>
var oBox = document.getElementById('box');
console.log(oBox.clientTop); // 边框的高度
console.log(oBox.clientLeft); // 边框的宽度
console.log(oBox.clientHeight); // 可视高度,content+paddingTop+paddingBottom
console.log(oBox.clientWidth); // 可视宽度,content+paddingLeft+paddingRight
</script>
</body>
</html>
屏幕的可视区域
- 屏幕的可视宽度,
document.documentElement.clientWidth
- 屏幕的可视高度,
document.documentElement.clientHeight
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>client</title>
</head>
<body>
</body>
<script>
window.onload = function () {
document.documentElement; // 获取的是html标签
console.log(document.documentElement.clientHeight);
console.log(document.documentElement.clientWidth);
// 窗口大小发生改变会调用此方法
window.onresize = function () {
console.log(document.documentElement.clientHeight);
console.log(document.documentElement.clientWidth);
}
}
</script>
</html>
offset
- offsetWidth 占位宽 内容+padding+border
- offsetHeight 占位高
- offsetTop: 到body的顶部的距离
- offsetLeft: 到body的左部的距离
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
* {
padding: 0;
margin: 0;
}
</style>
</head>
<body style="height: 2000px">
<div>
<div style="height: 20px"></div>
<div class="wrap" style=" width: 300px;height: 300px;background-color: green;position: relative;">
<div id="box" style="width: 200px;height: 200px;border: 5px solid red;position: absolute;top:50px;left: 50px;">
</div>
</div>
</div>
</body>
<script type="text/javascript">
window.onload = function () {
var box = document.getElementById('box');
/*
offsetWidth 占位宽 内容+padding+border
offsetHeight 占位高
offsetTop: 到body的顶部的距离
offsetLeft: 到body的左部的距离
*/
console.log(box.offsetTop);
console.log(box.offsetLeft);
console.log(box.offsetWidth);
console.log(box.offsetHeight);
}
</script>
</html>
scroll
document.documentElement.scrollTop // 页面卷起的高度
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{padding: 0;margin: 0;}
</style>
</head>
<body style="width: 2000px;height: 2000px;">
<div style="height: 200px;background-color: red;"></div>
<div style="height: 200px;background-color: green;"></div>
<div style="height: 200px;background-color: yellow;"></div>
<div style="height: 200px;background-color: blue;"></div>
<div style="height: 200px;background-color: gray;"></div>
</body>
<script type="text/javascript">
window.onload = function(){
//实施监听滚动事件
window.onscroll = function(){
// console.log(1111);
// 页面卷起的高度
console.log('上'+document.documentElement.scrollTop)
// console.log('左'+document.documentElement.scrollLeft)
// console.log('宽'+document.documentElement.scrollWidth);//width+padding+border
// console.log('高'+document.documentElement.scrollHeight)
}
// var s = document.getElementById('scroll');
//
// s.onscroll = function(){
// // scrollHeight : 内容的高度+padding 不包含边框
// console.log('上'+s.scrollTop)
// console.log('左'+s.scrollLeft)
// console.log('宽'+s.scrollWidth)
// console.log('高'+s.scrollHeight)
// }
}
</script>
</html>
滚动固定导航栏
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
padding: 0;
margin: 0;
}
.header {
width: 100%;
height: 40px;
background-color: rgba(0, 0, 0, .5);
}
#search {
width: 100%;
height: 1000px;
position: absolute;
top: 300px;
left: 500px;
}
.fixed {
width: 100%;
height: 100px;
background-color: red;
position: fixed;
top: 0;
left: 0;
display: none;
}
</style>
</head>
<body style="height: 2000px;">
<div class="header">
</div>
<div id="search">
<form action="">
<input type="text">
<input type="submit">
</form>
</div>
<div class="fixed">
</div>
<script>
var searchDiv = document.getElementById('search');
var fixedDiv = document.getElementsByClassName('fixed')[0];
var offsettop = searchDiv.offsetTop;
console.log(offsettop);
window.onscroll = function () {
var scrollTop = document.documentElement.scrollTop;
console.log('scrollTop' + scrollTop); // 页面卷起的高度,动态变化
console.log('offsettop' + offsettop); // 标签距离body的距离,固定
if (scrollTop >= offsettop) {
fixedDiv.style.display = 'block';
} else {
fixedDiv.style.display = 'none';
}
}
</script>
</body>
</html>