DOM
DOM(文档对象模型) 是浏览器对 html 文件的描述方式, DOM API是浏览器提供给JavaScript操作html页面内元素的方式。简而言之, 浏览器提供了一些内置函数来让我们操作页面(增删改查)
查找元素
代码语言:javascript复制// 查找元素使用document.querySelector函数
// 函数参数是一个选择器(和 CSS 选择器一样)
// 元素选择器
var div = document.querySelector('div')
// class 选择器, 用的是 .类名
var form = document.querySelector('.login-form')
// id 选择器, 用的是 #id
var user = document.querySelector('#id-input-username')
操作元素默认属性
获得特定属性值
代码语言:javascript复制var userValue = user.getAttribute('value')
设置特定属性值
代码语言:javascript复制user.setAttribute('value', '新用户名')
查询属性是否存在
代码语言:javascript复制log(user.hasAttributes()) // 查看元素是否有属性
log(user.hasAttribute('value')) // 查看元素是否有特定属性
删除某个属性
代码语言:javascript复制user.removeAttribute('value')
获得所有属性
代码语言:javascript复制var attributes = user.attributes
操作元素
创建
代码语言:javascript复制// 用document.createElement函数创建一个元素
var button = document.createElement('button');
// 添加文本或者html
// 1.
button.innerHTML = '注册用户'
// 2.
button.insertAdjacentHTML('beforeend', '注册用户')
修改
代码语言:javascript复制var form = document.querySelector('.login-form')
form.appendChild(button) // 用appendChild给一个元素添加子元素
删除
代码语言:javascript复制var pwd = document.querySelector('#id-input-password')
// 以下两种方法都可以删除元素
// 一种是自毁
pwd.remove()
// 一种是父节点删除子元素
form.removeChild(pwd)
事件
事件是用来处理响应的一个机制,这个响应可以来自于用户(点击, 鼠标移动, 滚动等), 也可以来自于浏览器
这里描述了js所有事件
添加事件监听
代码语言:javascript复制var loginBtn = document.querySelector('#id-button-login')
// 添加click事件
loginBtn.addEventListener('click', function(event) {
console.log(event.target '按下了')
})
事件委托
可以把事件绑定在父元素上, 然后在运行时检查触发事件的对象(event.target), 来处理对应的业务
事件冒泡
事件的响应像水泡一样上升至最顶级对象
当一个元素接收到事件的时候, 会把他接收到的事件传给自己的父级, 一直到window (注意这里传递的仅仅是事件, 并不传递所绑定的事件函数. 所以如果父级没有绑定事件函数, 就算传递了事件也不会有什么表现, 但事件确实传递了。)
代码语言:javascript复制// 阻止事件向上冒泡
// 1.
event.stopPropagation()
// 2.
event.cancelBubble = true
事件捕获
事件流描述的是从页面中接受事件的顺序,微软(IE)和网景(Netscape)开发团队提出了两个截然相反的事件流概念,IE的事件流是事件冒泡流(event bubbling),而Netscape的事件流是事件捕获流(event capturing)。
- addEventListener添加事件监听时不传第三个参数时, 默认为冒泡流
- addEventListener的第三个参数是useCapture, 传入true时采用事件捕获
localStorage(本地存储)
浏览器自带的功能, 可以用来存储字符串数据, 在浏览器关闭后依然存在, 不同页面拥有各自独立的localStorage
代码语言:javascript复制// 把数组写入localStorage
var save = function(array) {
var s = JSON.stringify(array) // JSON序列化
localStorage.todos = s
}
// 读取localStorage中的数据并解析返回
var load = function() {
var s = localStorage.todos
return JSON.parse(s) // JSON反序列化
}
ajax
代码语言:javascript复制// 创建AJAX对象
var r = new XMLHttpRequest()
// 设置请求方法和请求地址
r.open('POST', '/login', true)
// 设置发送的数据的格式
r.setRequestHeader('Content-Type', 'application/json')
// 注册响应函数
r.onreadystatechange = function() {
if (r.readyState === 4) {
console.log('state change', r, r.status, r.response)
var response = JSON.parse(r.response)
console.log('response', response)
} else {
console.log('change')
}
}
// 发送请求
var account = {
username: 'username',
password: '123',
}
var data = JSON.stringify(account)
r.send(data)
面向对象 (OO, Object Oriented)
定义类
代码语言:javascript复制// 声明类
var Student = function(name, age) {
this.name = name
this.age = age
}
// 增加方法
Student.prototype.print = function() {
console.log(`${this.name} is ${this.age}`)
}
实例化对象
代码语言:javascript复制var s1 = new Student('caicai', 22)
s1.print()
常用组件
点击展开详情的菜单
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>点击展开的菜单</title>
<style>
.menu-content {
height: 100px;
width: 100px;
border: 1px solid red;
}
.hide {
display: none;
}
</style>
</head>
<body>
<div class="menu">
<button class="menu-toggle">点击展开</button>
<div class="menu-content hide">详情</div>
</div>
<div class="menu">
<button class="menu-toggle">点击展开</button>
<div class="menu-content hide">详情</div>
</div>
<div class="menu">
<button class="menu-toggle">点击展开</button>
<div class="menu-content hide">详情</div>
</div>
<script src='1.js'></script>
</body>
</html>
代码语言:javascript复制var toggleClass = function(element, className) {
if (element.classList.contains(className)) {
element.classList.remove(className)
} else {
element.classList.add(className)
}
}
var bindEventToggle = function() {
var menus = document.querySelectorAll('.menu')
for (var i = 0; i < menus.length; i ) {
menus[i].addEventListener('click', function(event) {
content = event.target.parentElement.querySelector('.menu-content')
toggleClass(content, 'hide')
})
}
}
bindEventToggle()
鼠标划过菜单项高亮效果
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>鼠标划过菜单项高亮效果</title>
<style>
.menu-item {
width: 138px;
height: 138px;
opacity: 0.6;
}
.highlight {
opacity: 1;
}
</style>
</head>
<body>
<div class="menu">
<div class="menu-item"><img src="1.jpg" ></div>
<div class="menu-item"><img src="2.jpg" ></div>
<div class="menu-item"><img src="3.jpg" ></div>
</div>
<script src='2.js'></script>
</body>
</html>
代码语言:javascript复制var bindEventHighlight = function() {
var items = document.querySelectorAll('.menu-item')
for (var i = 0; i < items.length; i ) {
items[i].addEventListener('mouseenter', function(event) {
event.target.classList.add('highlight')
})
items[i].addEventListener('mouseleave', function(event) {
event.target.classList.remove('highlight')
})
}
}
bindEventHighlight()
轮播图
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>轮播图</title>
<style>
.slide-div {
position: relative;
height: 470px;
width: 590px;
margin: 0 auto;
}
.hide {
display: none;
}
.show {
display: inline-block;
}
.slide-button {
/* 子元素绝对定位的参考对象是往上找到一个非static的元素, 一般使用子绝父相 */
position: absolute;
}
.next {
right: 0;
top: 50%;
transform: translateY(-50%);
}
.prev {
left: 0;
top: 50%;
transform: translateY(-50%);
}
.indicators {
position: absolute;
right: 50%;
bottom: 5px;
transform: translateX(50%);
}
.indicator {
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
background: white;
margin-right: 5px;
}
.choose {
background: black;
}
</style>
</head>
<body>
<div class='slide-div' data-count='3' data-active='0'>
<img id='id-img-0' class='hide show' src="1.jpg" height="470" width="590" >
<img id='id-img-1' class='hide' src="2.jpg" height="470" width="590" >
<img id='id-img-2' class='hide' src="3.jpg" height="470" width="590" >
<button class='slide-button next'>下一张</button>
<button class='slide-button prev'>上一张</button>
<div class="indicators">
<div id='id-indicator-0' class="indicator choose"></div>
<div id='id-indicator-1' class="indicator"></div>
<div id='id-indicator-2' class="indicator"></div>
</div>
</div>
<script src='./3.js'></script>
</body>
</html>
代码语言:javascript复制var updateSlide = function(active_index) {
var active_id = 'id-img-' active_index
// 隐藏当前img
document.querySelector('.show').classList.remove('show')
// 显示下一张img
document.querySelector('#' active_id).classList.add('show')
// 隐藏当前indicator
document.querySelector('.choose').classList.remove('choose')
// 显示下一个indicator
document.querySelector('#id-indicator-' active_index).classList.add('choose')
}
var bindEventSlide = function() {
var slide = document.querySelector('.slide-div')
// 事件委托
slide.addEventListener('click', function(event) {
var classs = event.target.classList
if (classs.contains('slide-button')) {
var slide = event.target.parentElement
// img数量
var count = parseInt(slide.dataset.count)
// 当前显示的img的index
var active_index = parseInt(slide.dataset.active)
// 计算下一张(或上一张)img的index
active_index = classs.contains('next') ? (active_index 1) : (active_index - 1 count)
active_index = active_index % count
// 改写data-active
slide.dataset.active = String(active_index)
// 更新显示
updateSlide(active_index)
}
})
// 定时器 3s
window.setInterval(function() {
document.querySelector('.next').click()
}, 3000)
}
bindEventSlide()
ES6 (ECMAScript 6标准)
ECMAScript是一种语言标准,而JavaScript是网景公司对ECMAScript标准的一种实现
ECMAScript 6标准(简称ES6)已经在2015年6月正式发布
模板字符串
代码语言:javascript复制var className = 'center'
var text = 'hello world'
// 反引号`...`来表示多行字符串, 并支持自动替换字符串中${...}
var t = `
<div class='${className}'>
${text}
</div>
`
let
通过var定义的变量, 作用域是整个封闭函数.
而let定义的变量作用域在块中.
代码语言:javascript复制for (var i = 0; i < 3; i ) {
// ...
}
// 输出结果: 3
console.log(i)
// -------------------------------
for (let j = 0; j < 3; j ) {
// ...
}
// 访问j, 报错
console.log(j)
const
相当于C 中的指针常量, 指向不可修改, 但可修改指向对象中的值
cpp
代码语言:javascript复制int * const num = &a;
js
代码语言:javascript复制const a = 1
a = 2 // 错误
// 下面的是修改指向对象中的值, 所以可行
const arr = [1, 2]
arr.push(3)
// arr: [1, 2, 3]
Set
使用方法和array相似, 但set的元素不重复
代码语言:javascript复制var s = new Set()
// add方法添加元素, 和push一样
s.add(1)
s.add(2)
// has方法检查元素是否在set中
s.has(1) // true
s.has(3) // false
// size属性相当于length
s.size // 2
// delete方法删除一个元素
s.delete(1)
s.has(1)
s.size // 1
Map
js默认的object表示方法{}
相当于java中的HashMap之类的数据结构, 即键值对. 但与java的HashMap不同之处在于, js对象的键必须是字符串. 为了解决这个问题, ES6中引入了Map
数据类型.
Map和Object相似, 在python中有dict和object两种数据结构, js在ES6也有独立的dict(Map).
代码语言:javascript复制// Map
var m = new Map()
// set方法增加一个值
m.set('name', 'cai')
// get方法得到一个值
m.get('name')
// -------------------------------------------------------------
// object
let o = {}
// set
o.name = 'cai'
// get
o.name
…(扩展符号)
作用是把数组解开成单独的元素
代码语言:javascript复制var a1 = [1, 2, 3]
var a2 = [...a1, 4]
// 结果是 [1, 2, 3, 4]
// ...可以用来传参
var a1 = [1, 2, 3]
log(...a1)
// 相当于log(1, 2, 3)
// 类似于log.apply(window, a1)
// 可变参数
// 用 ... 语法可以实现可变长度的参数, 多余的参数会被放进 args 数组中
var foo = function(a, ...args) {
log(a, args.length)
}
foo(1, 2, 3, 4)
解构赋值
python中拥有的特性
代码语言:javascript复制// a, b分别被赋值为1, 2
var [a, b] = [1, 2]
// 相当于下面的代码
var arr = [1, 2]
var a = arr[0]
var b = arr[1]
// swap a and b
[a, b] = [b, a]
函数默认参数
大部分高级语言拥有的特性, 参数缺省
代码语言:javascript复制var fun = function(a, name='cai') {
log(a, name)
}
箭头函数(Lambda表达式)
匿名函数定义的简化版本
语法
代码语言:javascript复制() => { 多条语句 }
(参数1, 参数2) => { 多条语 句 }
(参数1, 参数2) => 单条语句
// 上面等价于下面定义
function(参数1, 参数2) {
return 语句
}
例子
代码语言:javascript复制var a1 = [1, 2, 3]
var a2 = a1.map( n => n * n )
// 等价于
var a2 = a1.map(function(n) {
return n * n
})
BOM
BOM(browser object model) 包含5个内容
- location 管理 URL
- navigator 管理浏览器
- history 管理历史记录
- screen 管理屏幕
- window 管理浏览器所有的东西
location
location对象用来管理url的
代码语言:javascript复制// www.taobao.com页面的location对象的属性及方法
ancestorOrigins: DOMStringList {length: 0}
assign: ƒ ()
hash: ""
host: "www.taobao.com"
hostname: "www.taobao.com"
href: "https://www.taobao.com/" // 改变href就可以跳转页面
origin: "https://www.taobao.com"
pathname: "/"
port: ""
protocol: "https:"
reload: ƒ reload() // 该方法用来刷新当前页面
replace: ƒ () // 该方法用来替换当前页面, 参数为url
search: ""
toString: ƒ toString()
valueOf: ƒ valueOf()
Symbol(Symbol.toPrimitive): undefined
__proto__: Location
navigator
navigator对象是用来查询浏览器的信息的, 比如当前的操作系统平台, 浏览器型号厂商等
代码语言:javascript复制// navigator.userAgent的值
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36"
// navigator.platform的值
"MacIntel"
history
history对象是用来处理历史记录的
代码语言:javascript复制history.length // 历史列表中的 url 数量
history.back() // 相当于点击后退按钮
history.forward() // 相当于点前进
history.go(-2) // 相当于点击两次后退按钮
/*
* 三个参数依次为: state, title, url
* state: 一个与指定网址相关的状态对象,popstate事件触发时,该对象会传入回调函数。不需要则可以传null
* title: 新页面的标题,但是所有浏览器目前都忽略这个值, 故可以传null (可以设置document.title代替)
* url: 新的网址,必须与当前页面处在同一个域,
*/
history.pushState(null, 'title', '/profile')
// 用户点击前进或后退按钮时会触发window的popstate事件
window.addEventListener("popstate", function(event) {
// state就是pushState的第一个参数
var state = event.state;
console.log('pop state', state)
})
// 作用和参数都和pushState相同, 但不生成一条历史记录
history.replaceState(null, 'title', '/profile')
strict模式
js在设计之初, 并不强制要求用var声明变量, 未用var声明的变量作为全局变量, 用var声明的变量作用域限制在函数体内
为了修补js这一严重设计缺陷, ECMA在后续规范中推出了strict模式, 在strict模式下运行的js代码, 强制通过var声明变量,未用var声明变量就使用的, 将导致运行错误
启用strict模式的方法是在js文件中第一行写上
代码语言:javascript复制'use strict'
注意: 浏览器内嵌的开发者工具的控制台可能不支持strict模式
本文作者: Ifan Tsai (菜菜)
本文链接: https://cloud.tencent.com/developer/article/2164561
版权声明: 本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!