我在之前的文章里提到过html和css和js的关系,假设现在有一个游乐园,那么html就是它的骨架和地基,css就是它的装饰和装潢,js就是游乐园里面的游玩设施。
js的引入方式
1.嵌入到html文件中
我们可以在html文件里通过标签来引入js,以下为代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
console.log("hello javascript!!!")
</script>
</body>
</html>
此时就在控制台中打印出了hello javascript!!!
2.引入本地js文件
当然我们也可以通过文件来引入js,通过以下方式:
<body>
<script type="text/javascript" src="您的js文件路径">
</script>
</body>
js的数据类型及变量定义方法
定义方法
js对于变量的定义比较类似于python,他也是不用自己来定义数据类型,变量会根据你赋给它的值来确认数据类型;
以下是定义方法:
var 变量名 = 变量值;
数据类型
js的数据类型有六种,而在es6中又新增了两种。
1.数值(number)
数值包括浮点数,整数,运算后的数值等。
<script>
var num1 = 1.2;
var num2 = 1;
var num3 = 1+2;
console.log(typeof num1);
console.log(typeof num2);
console.log(typeof num3);
</script>
上述代码中的 typeof num 会获取num变量的数据类型,然后通过console.log打印在控制台中
可以看到结果为:
2.字符串(String)
字符串必须被双引号或单引号包裹
<script>
var str1 = "字符串";
var str2 = "zifuchuan";
var str3 = "123";
var str4 = '123';
console.log(typeof str1);
console.log(typeof str2);
console.log(typeof str3);
console.log(typeof str4);
</script>
3.布尔值(Boolean)
布尔数据类型有true和false两种值。
<script>
var b1 = true;
var b2 = false;
console.log(typeof b1);
console.log(typeof b2);
</script>
4.复合类型/对象(object)
复合类型也可以看成是一个对象,或者说看成一个存放多种数据类型的容器。
<script>
var obj = {
name:"javascript",
age: 20,
boo:true
}
console.log(typeof obj);
</script>
5.undefined
<script>
var js = undefined;
console.log(typeof js);
</script>
6.NULL
<script>
var js = null;
console.log(typeof js);
</script>
可以看出,虽然undefined和null都表示空的意思,但他两也是有区别的,可以看到返回null的数据类型是一个对象,也就表示它是一个空对象,具体的细节可以在开发过程中体会。
js操作页面的方法
DOM概述
什么是dom?
DOM 是JavaScript 操作网页的接口,全称为“文档对象模型”(Document Object Model)。它的作用是将网页转为一个JavaScript 对象,从而可以用脚本进行各种操作(比如对元素增删内容)
浏览器会根据 DOM 模型,将结构化文档HTML解析成一系列的节点,再由这些节点组成一个树状结构(DOMTree)。所有的节点和最终的树状结构,都有规范的对外接口
DOM 只是一个接口规范,可以用各种语言实现。所以严格地说,DOM 不是JavaScript语法的一部分,但是DOM 操作是|avaScript最常见的任务,离开了 DOM,JavaScript 就无法控制网页。另一方面,JavaScript也是最常用于 DOM 操作的语言
总的来说,dom就是js操作网页的接口,没有dom,js就无法操作网页。
Document对象的方法
什么是document对象?
document对象是整个html元素的顶层节点,以标签的角度来理解,它就是我们html文件中的html标签。
doucument获取元素
通过标签名来获取元素
var divs = document.getElementsByTagName("标签名")
此时divs就是我们根据标签名获取到的标签数组
示例代码:
<body>
<div>
hello world111!!
</div>
<div>
hello world222!!
</div>
<script>
var div = document.getElementsByTagName("div")
console.log(div[0])
console.log(div[1])
</script>
</body>
此时控制台输出为:
可以看到我们已经成功通过标签名来获取了元素。
通过class来获取元素
var divclass = document.getElementsByClassName("class名")
同样的,此时获取到的值也是个数组,并且getElementsByClassName内的参数可有多个值,表示获取有多个class的元素。
通过id来获取元素
var divid = document.getElementById("d1")
那么我们知道,元素的id具有唯一性,那么此时固然返回的不是一个数组,而是一个元素。
通过name来获取元素
var name = document.getElementsByName("name名")
h5新增,通过css类选择器获取元素
var newclass = document.querySelector("类选择器")
var all = document.querySelectorAll("类选择器")
上面两种方法的区别是:
document.queryselector:如果有多个节点满足匹配条件,则返回第一个匹配的节点
document.querySelectorAll可获取全部节点
document创建元素
创建一个标签
//创建一个p标签 document.createElement
var text = document.createElement("p");
创建一个文本
//创建一个文本 document.createTextNode
var content = document.createTextNode("文本");
将文本放入标签内
text.appendChild(content)
设置一个标签的属性值(以id举例)
var ididid = document.createAttribute("id")
ididid.value = "root"
text.setAttributeNode(ididid)
将创建好的元素放入页面中
//将创建好的元素放入页面中
var container = document.getElementById("container") //先获取要放入的父级元素
container.appendChild(text)
获取元素位置
<body>
<div class="box" id="box">
</div>
<h3> 1 </h3>
<h3> 1 </h3>
<h3> 1 </h3>
<h3> 1 </h3>
<script>
var box = document.getElementById("box")
//element.clientHeight 和 element.clientWidth
console.log(box.clientHeight) //高度包括padding部分,不包括margin和border
console.log(box.clientWidth) //宽度包括padding部分,不包括margin和border
//document.documentElement.clientHeight获取当前视口高度,即浏览器窗口的高度
console.log(document.documentElement.clientHeight)
//获取宽度
console.log(document.documentElement.clientWidth)
//获取页面总内容高度
console.log(document.body.clientHeight)
console.log(box.scrollHeight) //高度包括padding部分,不包括margin和border,和溢出不可见部分
console.log(box.scrollWidth) //宽度包括padding部分,不包括margin和border
//获取横向滚动高度
console.log(document.documentElement.scrollLeft)
//获取纵向滚动高度
console.log(document.documentElement.scrollTop)
//获取元素css垂直高度
console.log(box.offsetHeight) //不包括margin
//获取元素css水平高度
console.log(box.offsetWidth) //不包括margin
//元素的左外边框至父级元素的左内边框之间的像素距离
console.log(box.offsetLeft)
//元素的上外边框至父级元素的上内边框之间的像素距离
console.log(box.offsetTop)
</script>
</body>
操作元素属性
<body>
<div class="box" id="root">
Hello
</div>
<script>
var div1 = document.getElementById("root")
//修改id值
//div1.id="roots"
//修改class值
//div1.className="clssssss 231"
//Element.classList有四个方法
//console.log(div1)
//添加class
//div1.classList.add("new")
//移除class
//div1.classList.remove("box")
//判断class是否存在
//console.log(div1.classList.contains("box")) 返回值为true或者false
//如果存在则删除,不存在则添加,相当于一个开关
//div1.classList.toggle("box1")
//innerHTML 设置内容
//div1.innerHTML = "aha"
//innerText 也是设置内容 innerHTML和innText的区别在于 innerHTML可识别标签,innerText不可以
// div1.innerText = "aha"
// var str = '<a href="https://www.baidu.com/">123</a>'
// div1.innerHTML = str
</script>
</body>
操作css
<body>
<div class="box" id="box">
</div>
<script>
var box = document.getElementById("box")
//直接设置css的方法,
//box.setAttribute("style","width:200px;height:200px;background:red;")
//下面的方法相比上面的能够更加清晰
// box.style.width = "300px"
// box.style.height = "300px"
//设置cssText属性,同1方法,只不过更加清晰而已。
box.style.cssText = "width:200px;height:200px;background:red;"
</script>
事件处理
html事件
<body>
<!-- html事件-->
<button onclick="clickHandle()">按钮</button>
<script>
//缺点,html和js没有分开
function clickHandle(){
console.log("点击了")
}
</script>
上述事件的缺点在于,没有将html和js分开
dom0级事件
<body>
<button id="btn"> 按钮</button>
<script>
//优点:html和js是分离的
//缺点:多个事件会被覆盖
var btn = document.getElementById("btn")
btn.onclick = function (){
console.log("点击了1")
}
btn.onclick = function (){
console.log("点击了2")
}
</script>
优点:html和js是分离的
缺点:多个事件会被覆盖,假设我给一个元素设置两个点击事件,那么当我点击后只会触发第一个,在上述代码中,当我点击按钮,那么只会在控制台打印 "点击了1"
dom2级事件
<body>
<button id="btn"> 按钮 </button>
<script>
//优点:不会被覆盖
var btn = document.getElementById("btn")
btn.addEventListener("click",function (){
console.log("点击了1")
})
btn.addEventListener("click",function (){
console.log("点击了2")
})
</script>
</body>
它相比于dom0级事件的优点就是,多个事件不会被覆盖。
鼠标事件
<style>
.box1{
width: 100px;
height: 100px;
background-color: red;
}
.box2{
width: 100px;
height: 100px;
background-color: green;
}
.box3{
width: 100px;
height: 100px;
background-color: blue;
}
.box4{
width: 100px;
height: 100px;
background-color: pink;
}
.box5{
width: 100px;
height: 100px;
background-color: sandybrown;
}
</style>
<body>
<button id="btn1"> 单击 </button>
<button id="btn2"> 双击 </button>
<button id="btn3"> 鼠标按下 </button>
<button id="btn4"> 鼠标抬起 </button>
<div id="btn5" class="box1"></div>
<div id="btn6" class="box2"></div>
<div id="btn7" class="box3"></div>
<div id="btn8" class="box4"></div>
<div id="btn9" class="box5"></div>
<script>
var btn1 = document.getElementById("btn1")
var btn2 = document.getElementById("btn2")
var btn3 = document.getElementById("btn3")
var btn4 = document.getElementById("btn4")
var btn5 = document.getElementById("btn5")
var btn6 = document.getElementById("btn6")
var btn7 = document.getElementById("btn7")
var btn8 = document.getElementById("btn8")
var btn9 = document.getElementById("btn9")
btn1.onclick = function (){
console.log("单击事件")
}
btn2.ondblclick = function (){
console.log("双击事件")
}
btn3.onmousedown = function (){
console.log("鼠标按下")
}
btn4.onmouseup = function (){
console.log("鼠标抬起")
}
btn5.onmousemove = function (){
console.log("鼠标移动了")
}
btn6.onmouseenter = function (){ //进入子节点时不会触发事件
console.log("鼠标进入了")
}
btn7.onmouseleave = function (){
console.log("鼠标离开了")
}
//以下两个事件和上两个事件的区别在于,如果我为父节点设置了下面这两个事件,那么当鼠标进入父节点中的子节点也会触发该事件,当从子节点里出来时也会触发该事件
btn8.onmouseover = function (){
console.log("鼠标进入了")
}
btn9.onmouseout = function (){
console.log("鼠标离开了")
}
// document.onwheel = function (){
// console.log("滚轮")
// }
// document.documentElement.onwheel = function (){
// console.log("滚轮")
// }
btn9.onwheel = function (){
// console.log("滚轮")
// }
// document.body.onwheel = function (){
// console.log("滚轮")
// }
</script>
</body>
这里除了
element.onmouseenter element.onmouseleave
和
element.onmouseover element.onmouseout
容易混淆以外,别的看代码就能明白怎么操作
这边我将演示一下后者
<style>
#d1{
width: 500px;
height: 500px;
background-color: red;
}
#d2{
width: 200px;
height: 200px;
background-color: green;
}
</style>
<body>
<div id="d1">
<div id="d2">
</div>
</div>
<script>
var div1 = document.getElementById("d1")
div1.onmouseover = function (){
console.log("鼠标进入了")
}
div1.onmouseout= function (){
console.log("鼠标出去了")
}
</script>
</body>
当鼠标进入父元素时
当鼠标进入绿色子元素时
此时相当于鼠标出了父元素,又进了子元素,所以会有这样的输出。
那么当从子元素里又出来时同样会触发两个输出,先出子元素,再进父元素。
event事件对象
<body>
<button id="btn">按钮</button>
<a href="https://www.baidu.com/" id="baidu">123123</a>
<script>
var btn = document.getElementById("btn");
btn.onclick = function (event){
//event.target 获取事件元素
//event.type 获取事件类型
console.log(event.target)
}
//方法
var baidu = document.getElementById("baidu")
baidu.onclick = function (event){
event.preventDefault() //此时点击后将不会跳转,阻止默认事件
console.log("点击了")
event.stopPropagation() //阻止事件冒泡
}
</script>
</body>
event事件对象的使用方法如上:
并且可通过event.target来获取事件元素,通过event.type来获取事件类型,当然还有很多别的属性,只不过这两种比较常用,你也可以直接打印event来查看都有上面属性。
这里比较重要的就是阻止默认事件和阻止事件冒泡
阻止默认事件
event.preventDefault()
什么是阻止默认事件?
当我们给一个a标签定义了一个跳转链接后,点击它将会跳转到对应链接,那么这就是一个默认事件,当我们给该元素设置阻止默认事件后,点击后将不会跳转。
阻止事件冒泡
ev.stopPropagation()
什么是事件冒泡?
假设我现在在一个div标签里又设置了一个子级div标签,并同时给他们都设置了点击事件。
当我点击子元素时,它会同时触发点击子元素和父元素的事件。
上图是一个红色父元素包裹一个绿色子元素,当我点击图中位置后,会出现下面的情况:
那么这种情况就被称为事件冒泡
当我们给子元素添加阻止冒泡方法后,将不会出现这种情况。
键盘事件
<body>
<input type="text" id="username">
<script>
var username =document.getElementById("username")
// username.onkeydown = function (event){ //onkeydown当键盘按下时
// console.log(event.target.value)
// }
username.onkeyup = function (event) { //onkeyup当键盘抬起时
// console.log(event.target.value)//获取输入的值
console.log(event.keyCode)
}
// username.onkeypress = function (event) { //不会识别alt shift等没内容的键
// console.log("onkeypress")
// }
//每个键都有一个唯一标识,event.KeyCode === 13时,对应的是回车
</script>
</body>
表单事件
<body>
<input type="text" id="username">
<form id="myform" onsubmit="submitHandle()">
<input type="text" name="username">
<button id="resetBtn">重置</button>
<button>提交</button>
</form>
<script>
var username = document.getElementById("username")
var resetBtn = document.getElementById("resetBtn")
var myform = document.getElementById("myform")
//oninput事件
// username.oninput = function (ev){ //当值发生变化就会触发这个事件
// console.log(ev.target.value)
// }
//onselect事件
// username.onselect = function (){ //选中文本就会触发这个事件
// alert("您想复制吗?")
// }
//onchange事件 与oninput不同,当值改变完毕后才会触发(失去焦点或回车)
username.onchange = function (ev){
console.log(ev.target.value)
}
//reset事件和submit事件 添加在form元素中,在最上方代码中
resetBtn.onclick = function (){
myform.reset() //重置表单
}
function submitHandle(){
console.log("干什么")
}
</script>
</body>
事件代理
<body>
<ul id="list">
<li>
列表1
</li>
<li>
列表2
</li>
<p>
nihao
</p>
</ul>
<script>
var list = document.getElementById("list")
list.addEventListener("click",function (ev){
if(ev.target.tagName === "LI"){ //如果点击的元素的标签是LI(tagName获取默认大写)的话,则打印文本
console.log(ev.target.innerHTML)
}
})
</script>
</body>
事件代理应用于要同时给多个元素设置相同的事件,那么只需对父级元素设置即可,当然也可以加一写触发事件的条件。
定时器
setTimeout
设置定时器:
定时器名称=setTimeout(要执行的函数,3000) //3000毫秒后执行函数
取消定时器:
clearTimeout(定时器名称)
setInterval
设置定时器:
定时器名称=setInterval(要执行的函数,3000) //每3000毫秒执行一次函数
取消定时器:
clearInterval(定时器名称)
防抖和节流
假设现在我们给一个div标签设置了一个事件,onmousemove,当鼠标在元素内移动时都会打印一条信息,那么我们用鼠标轻轻的在标签内滑动一下就会出现好几百条数据,很显然我们不需要这么多数据,当我们只需要最后一条数据时,此时就造成了浏览器性能浪费,防抖和节流就是用来避免这种情况的。
防抖和节流的区别
防抖的逻辑是:2s内用户没有操作才会触发事件,如果有,则重新开始计时(2s只是个假设)
节流的逻辑是:当用户有操作时,2s后我触发事件,接下来若用户还要操作,那么我2s后再次触发事件。
接下来给出示例代码:
防抖:
<style>
#div1{
width: 500px;
height: 500px;
background: red;
}
</style>
<body>
<div id="div1">
</div>
<script>
var div1 = document.getElementById("div1")
div1.onmousemove = fangdou("123")
//防抖简单来说就是如果一个事件触发频率过高,那我只要它最后一次事件的状态
function fangdou(data){ //用到了闭包思想
var time=null
return function (){
if(time){
clearTimeout(time)
}
time = setTimeout(function (){
console.log("移动了")
console.log(data)
},500)
}
}
</script>
</body>
节流
<style>
div{
width: 500px;
height: 500px;
background: red;
}
</style>
<body>
<div id="div1">
</div>
<script>
var div = document.getElementById("div1")
div.onmousemove = jieliu()
function jieliu(){
var value = true
return function (){
if(!value){
return false
}
value = false
setTimeout(function (){
console.log("你好")
value = true
},2000)
}
}
</script>
</body>