目录
一、DOM
1.1.DOM的基本概念
1.2.DOM的树结构
1.3.DOM的使用
1.获取DOM
2.通过关系获取节点
3.操作DOM节点
1.4.事件处理
1.5.字符串(内置方法)
二、BOM
2.1.windows对象
alert()
confirm()
prompt()
定时器和延时器(同步异步)
定时器
延时器
同步异步
异步方法
注意:
2.2.location对象
常用属性
常用方法
2.3.history对象
常用方法
获取元素的偏移位置:
2.5.screen对象
常用属性
三、事件
3.1.事件类型
1.鼠标事件
2.键盘事件
3.表单事件
4.窗口事件
5.拖拽事件
3.2.事件处理
1.添加事件监听器
2.移除事件监听器
3.事件对象
3.3.事件冒泡与捕获
捕获阶段
目标阶段
冒泡阶段
阻止事件传播
阻止默认行为
移除事件监听器
自定义事件
3.4.事件委托
工作原理
优点
实现步骤
示例
一、DOM
1.1.DOM的基本概念
DOM(Document Object Model)是文档对象模型的缩写,是W3C组织推荐的处理可扩展标记语言(HTML/XML)的标准编程接口。通过DOM,开发者可以改变页面中的样式、结构、内容。在DOM中,文档、元素、节点都以对象的形式存在。
1.2.DOM的树结构
DOM将HTML文档表示为树结构,每个节点都是文档的一部分。节点类型包括元素节点(如<div>
、<p>
等)、文本节点、属性节点和注释节点等。
1.3.DOM的使用
1.获取DOM
document.getElementById() //通过id查找节点
document.getElementByTagName() //通过标签名获取节点,返回的是一个伪数组,伪数组里面存放的是获取的节点。
document.getElementByClassName() //通过类名获取节点,返回的是一个伪数组,伪数组里面存放的是获取的节点
document.querySelector() //获取单个节点
document.querySelectorAll() //获取符合条件的所有子节点,返回值是伪数组
提示:伪数组没有正常数组的内置方法,但是伪数组有长度能遍历
2.通过关系获取节点
nextElementSibling 获取下一个兄弟
previousElementSibling 获取上一个兄弟
children 获取所有子节点
parentNode 获取父级节点
3.操作DOM节点
创建节点:document.createElement(节点的名字)
添加子节点:appendChild(); //例如:ul.appendChild(li);---li是新创建的节点,添加新节点到ul内部
注意:只能创建一次添加一次,不能创建一次添加多次
插入节点:insertBefore(要添加的新节点,被参考的节点(要插入到哪个节点之前));
删除节点:
1.remove() 删除节点,谁调用他 删除谁
2.removeChild(子节点) —删除子节点,调用者为父级,传入需要删除的子节点
替换节点:replaceChild(新节点,要被替换的节点) ——调用者为父级
克隆节点:clone() ——(也就是复制节点)false为浅克隆——浅克隆只会克隆标签本身,不克隆里面的内容;true为深克隆——深克隆既会克隆标签,也会克隆里面的内容
修改节点内容
html" title=javascript>javascript">element.innerHTML = '<h1>Hello, World!</h1>'; // 修改元素的HTML内容
element.textContent = 'Hello, World!'; // 修改元素的纯文本内容
注意:用innerHTML写入标签,最后添加的标签会覆盖前面的标签
box.innerHTML = ""; //清空box的所有内容
box.innerHTML 能设置能获取,还能实现创建和添加节点的功能
let name = "张三";
拼接:
1.box.innerHTML = "<h1 class='one'>"+name+"</h1>";---必须注意外面双引号里面单引号,反之同理
2. box.innerHTML = `<h1 class="one">${name}</h1>`;//模板字符串,把变量放在${}中
修改节点属性
html" title=javascript>javascript">imageElement.src = 'newImage.jpg'; // 修改<img>元素的src属性
linkElement.href = 'https://www.example.com'; // 修改<a>元素的href属性
修改节点样式
html" title=javascript>javascript">imageElement.src = 'newImage.jpg'; // 修改<img>元素的src属性
linkElement.href = 'https://www.example.com'; // 修改<a>元素的href属性
或者通过添加、删除CSS类名来修改样式
html" title=javascript>javascript">element.className = 'newClass'; // 修改元素的类名,这将覆盖原有的类名
element.classList.add('newClass'); // 添加一个新的类名,不覆盖原有的类名
element.classList.remove('oldClass'); // 删除一个类名
element.classList.toggle('class'); // 如果元素具有指定的类名,则删除它;如果没有,则添加它
属性操作
setAttribute(属性的名字,属性的值) 设置属性
getAttribute(属性名字) 获取属性值
removeAttribute(属性名) 删除属性
1.4.事件处理
onclick点击,onmousedown 鼠标按下,onmouseup鼠标抬起,oncontextmenu鼠标右键点击
onmouseenter鼠标移入,onmouseleave鼠标移出,onmousemove鼠标移动
事件冒泡:当子元素的事件被触发时,该事件会开始逐级向上传播,进而影响父级,触发父级的相同的事件。
event.stopPropagation();阻止事件冒泡;
event.preventDefault();阻止默认行为;
输入框事件:onblur输入框失去焦点触发该事件, onfouse输入框获取焦点触发该事件, oninput输入时触发, onchange当输入框中的内容发生改变的时候触发(在失去焦点时)
输入框节点.value 来获取或设置输入框中的文本
例如:input.value = “abc”;
键盘事件:onkeydown, onkeyup (键盘码 keyCode)
绑定事件:节点.onclick = function(){}
事件监听:节点.addEventListener()
// 第一个参数:事件类型 (click/mouseenter)
// 第二个参数:事件触发时要调用的函数
// 第三个参数:(选填)false—默认
事件冒泡(由内向外扩散);true 事件捕获(由外向内传递)
事件委托:当我们点击ul的子元素li时,子元素会通过默认的事件冒泡去触发父级的点击事件,我们利用这一现象,把本应该绑定在li的事件委托给父元素,让父元素担当事件监听的职务。
例如:
html"><ul><li>海贼王</li><li>火影忍者</li>
</ul>
<script>
let ul = document.querySelector("ul");
ul.onclick = function(e){console.log("12334");e.target.style.color = "red";
} //最终效果就是点击哪个li标签,哪个标签字体颜色变红
</script>
1.5.字符串(内置方法)
1、字符串的拼接
html">let name = "张三";
let age = 22;
let str = ("我叫"+name+",今年"+age+",练习了两年半代码");
let str2 = `我叫${name},今年${age},练习了两年半代码`;
2、行内式绑定点击事件
html" title=javascript>javascript">div.innerHTML = "<h1 class='one' onclick='f1()'>我是h1</h1>";
function f1(){console.log(1111);
}
3、字符串的内置方法
charAt(index):
返回指定索引处的字符。索引范围从0到字符串长度减1。如果索引超出范围,将返回一个空字符串。
html" title=javascript>javascript">let str = "Hello";
console.log(str.charAt(1)); // 输出 "e"
charCodeAt(index):
返回指定索引处字符的Unicode编码。索引范围从0到字符串长度减1。如果索引超出范围,将返回NaN。
html" title=javascript>javascript">let str = "Hello";
console.log(str.charCodeAt(1)); // 输出 101 (e的Unicode编码)
concat():
用于连接两个或多个字符串,并返回新的字符串。虽然+
运算符通常用于连接字符串,但concat()
方法也是一种选择。
html" title=javascript>javascript">let str1 = "Hello";
let str2 = "World";
console.log(str1.concat(" ", str2)); // 输出 "Hello World"
includes(searchString, position):
判断一个字符串是否包含在另一个字符串中,根据情况返回true
或false
。position
参数是可选的,表示搜索的起始位置。
html" title=javascript>javascript">let str = "Hello World";
console.log(str.includes("World")); // 输出 true
indexOf(searchValue, fromIndex):
返回在字符串中首次找到指定值的索引,如果未找到则返回-1。fromIndex
参数是可选的,表示搜索的起始位置。
html" title=javascript>javascript">let str = "Hello World";
console.log(str.indexOf("World")); // 输出 6
lastIndexOf(searchValue, fromIndex):
返回在字符串中最后一次找到指定值的索引,如果未找到则返回-1。fromIndex
参数是可选的,表示搜索的起始位置,但搜索会从该位置向前进行。
html" title=javascript>javascript">let str = "Hello Hello World";
console.log(str.lastIndexOf("Hello")); // 输出 7
match(regexp):
使用正则表达式与字符串相匹配,并返回一个数组。如果没有匹配项,则返回null
。
html" title=javascript>javascript">let str = "Hello World";
console.log(str.match(/o/g)); // 输出 ["o", "o"]
replace(searchValue, newValue):
在字符串中查找匹配的子串,并用新值替换它。返回一个新的字符串,原始字符串不会被改变
html" title=javascript>javascript">let str = "Hello World";
console.log(str.replace("World", "JavaScript")); // 输出 "Hello JavaScript"
search(regexp):
执行正则表达式和字符串之间的搜索匹配,并返回匹配项的索引。如果没有找到匹配项,则返回-1。
html" title=javascript>javascript">let str = "Hello World";
console.log(str.search(/World/)); // 输出 6
slice(beginIndex, endIndex):
提取字符串的片段,并在新的字符串中返回被提取的部分。beginIndex
是必需的,表示提取的起始位置;endIndex
是可选的,表示提取的结束位置(但不包括该位置的字符)。
html" title=javascript>javascript">let str = "Hello World";
console.log(str.slice(0, 5)); // 输出 "Hello"
split(separator, limit):
使用指定的分隔符字符串将字符串分割成数组。separator
是必需的,表示用作分隔符的字符串;limit
是可选的,表示返回数组的最大长度。
html" title=javascript>javascript">let str = "Hello World";
console.log(str.split(" ")); // 输出 ["Hello", "World"]
substring(startIndex, endIndex):
提取字符串中介于两个指定下标之间的字符。startIndex
是必需的,表示提取的起始位置;endIndex
是可选的,表示提取的结束位置(但不包括该位置的字符)
html" title=javascript>javascript">let str = "Hello World";
console.log(str.substring(0, 5)); // 输出 "Hello"
toLowerCase():
将字符串中的所有字符转换为小写。
html" title=javascript>javascript">let str = "Hello World";
console.log(str.toLowerCase()); // 输出 "hello world"
toUpperCase():
将字符串中的所有字符转换为大写。
html" title=javascript>javascript">let str = "Hello World";
console.log(str.toUpperCase()); // 输出 "HELLO WORLD"
trim():
去除字符串两端的空白字符。
html" title=javascript>javascript">let str = " Hello World ";
console.log(str.trim()); // 输出 "Hello World"
二、BOM
BOM(Browser Object Model,浏览器对象模型)是 JavaScript 的一部分,它提供了与浏览器进行交互的对象和方法。BOM 不是由任何标准化组织定义的,而是由各大浏览器厂商实现的,因此不同浏览器的 BOM 实现可能有所不同。但幸运的是,现代浏览器在 BOM 上的实现已经相当一致了。
2.1.windows对象
window 是 BOM 的顶层对象,它表示浏览器窗口或框架。
所有在全局作用域中声明的变量、函数和对象都会成为 window 对象的属性。
window 对象提供了很多方法和属性来控制浏览器窗口,比如
alert()
、confirm()
、prompt()
、定时器和延时器(setInterval()
、setTimeout())、location
、navigator
、history
、screen
等。
alert()
html" title=javascript>javascript">// 弹出一个警告框
window.alert("Hello, world!");
confirm()
html" title=javascript>javascript">// 弹出一个确认框,并返回用户选择的布尔值
let userConfirmed = window.confirm("Are you sure?");
console.log(userConfirmed); // 如果用户点击"确定",则返回true;否则返回false
prompt()
html" title=javascript>javascript">// 弹出一个输入框,并返回用户输入的值
let userInput = window.prompt("Enter your name:");
console.log(userInput); // 用户输入的值
定时器和延时器(同步异步)
定时器
无限循环,每隔一段时间执行一次函数,除非清除定时器,才可以将它停止或浏览器关闭
setInterval() --添加定时器
第一个参数:定时要执行的函数
第二个参数:每次执行的间隔时间,单位为毫秒 1000毫秒==1s
clearInterval(要清除的定时器(其实就是setInterval的返回值))---清除定时器
延时器
等待一段时间以后再执行函数,执行完延时器销毁
setTimeout()---添加延时器
第一个参数:要延时执行的参数
第二个参数:延时的时间,单位也是毫秒,默认是4毫秒,如果设置的低于4毫秒则使用默认的4毫秒
clearTimeout() ----清除延时器,传入延时器的返回值,清除后延时器不再执行
避免添加多个定时器
例
html"><button>开始</button>
<button>停止</button>
<script>let btn = document.querySelectorAll("button");let timer;btn[0].onclick = function(){// 每点击一下,就会在浏览器上添加一个定时器,点击多次添加多个,不会自动覆盖// 所以我们先清除再添加,来避免添加多个定时器的情况出现clearInterval(timer);timer = setInterval(function(){console.log("唱跳rap")},1000)}btn[1].onclick = function(){clearInterval(timer);}
</script>
拓展:什么是防抖?什么是节流?
防抖就是多次执行变为最后一次执行,实现函数的防抖:延时器
节流就是多次执行变成每隔一段时间执行。实现函数节流的方法:定时器和时间戳
同步异步
同步:指的是一个程序执行完了,再执行下一个
异步:指的是多个程序同时执行,互相不联系
js ——同步执行代码
js执行代码的时候,会将所有的同步代码放在一个执行栈当中(也叫主线程)
代码从上至下执行,当遇到异步方法的时候,就会把异步方法存入到异步队列当中等待,直到主线程上的同步代码执行完毕,才会开始逐步的执行异步代码
异步方法
异步方法: setInterval ,setTimeout
例
html" title=javascript>javascript">function f1(){setTimeout(function(){},2000)return "123";
}
let a = f1();
console.log(a);----输出123,如果把return写在延时器里,则会输出undefined
注意:
不要在异步方法里面return返回数据,函数的调用不会等待异步方法执行完毕(先执行同步,再执行异步)
拓展:什么是异步,什么是同步?
同步:在执行完一个函数或方法之后,一直等待系统返回值或消息,只有接收到返回的值或消息后才往下执行其他的命 令。 具有等待功能
异步,执行完函数或方法后,不必等待返回值或消息,就可以直接执行下一个命令。不用等待
事件循环机制是什么?
js是单线程语言,一次只能完成一个任务,如果同时完成多个任务怎么办?js把任务分为同步和异步任务,把所有的同步放到
主线程上去执行,把所有的异步任务放到事件队列里去,当所有的同步任务都执行完之后,去事件队列中看看有没有没有执行
的异步任务,如果有把需要先执行的异步任务拉到主线程上去执行,当这个任务执行完后,再去事件队列里看有没有没完成的
任务,如果有再把任务拉到主线程去执行,这样就形成一个事件循环。
2.2.location对象
location 对象包含了有关当前 URL 的信息,并允许 JavaScript 动态地改变浏览器的 URL。
常用属性
location.href 指的是url地址信息
location.port 获取端口号
location.hostname(返回 web 主机的域名)
location.pathname(返回 URL 的路径部分)
location.search 获取地址栏拼接的参数
常用方法
location.reload() 用于刷新当前页面,等同于浏览器上的刷新按钮
location.replace() 替换当前页,不能返回上一页
location.assign() 可以返回上一页
encodeURI() 对中文进行转码(转码)
decodeURI() 将乱码转为中文(解码)
地址栏拼接参数:location.href = "./55详情页.html?name=" + encodeURI(text) + "&age=22";
//比如xxx.html?名=值&名=值&名=值
html" title=javascript>javascript">// 获取当前页面的URL
let currentUrl = location.href;
console.log(currentUrl);// 重定向到一个新的URL
location.href = "https://www.example.com";// 获取URL的查询字符串部分
let queryString = location.search;
console.log(queryString);
2.3.history对象
history 对象包含了浏览器的历史记录
常用方法
history.back() 相当于浏览器上的向左的箭头---回到前一个
history.forward() 相当于浏览器上的向右的箭头---回到后一个
history.forward(); 前进
history.go() 既能前进也能后退,填正数为前进,填负数为后退
window.onresize 浏览器尺寸发生改变时触发
window.onload 等待页面内容加载完毕后再触发
window.onscroll 当页面滚动时触发
获取元素的偏移位置:
offsetTop 获取的是容器距离顶部的距离
offsetLeft 获取容器距离左边的距离
注意:如果父级有定位属性,都会改变他的参考目标,变为以父级作为参考点
2.4.navigator对象
navigator 对象包含了有关浏览器的信息,比如浏览器的名称、版本、平台等
常用属性:navigator.userAgent
(返回用户代理字符串)、navigator.appName
(返回浏览器的名称)、navigator.appVersion
(返回浏览器的平台和版本信息)等
html" title=javascript>javascript">// 获取用户代理字符串,包含了浏览器、操作系统等信息
let userAgent = navigator.userAgent;
console.log(userAgent);// 获取浏览器的名称
let appName = navigator.appName;
console.log(appName);
2.5.screen对象
screen 对象包含了有关用户屏幕的信息。
常用属性
screen.width
(返回访问者屏幕的宽度)
screen.height
(返回访问者屏幕的高度)
screen.availWidth
(返回访问者屏幕的宽度(减去如任务栏之类的特性))
html" title=javascript>javascript">// 获取屏幕的宽度
let screenWidth = screen.width;
console.log(screenWidth);// 获取屏幕的高度
let screenHeight = screen.height;
console.log(screenHeight);
三、事件
3.1.事件类型
1.鼠标事件
click
:鼠标单击时触发。 dblclick
:鼠标双击时触发。
mouseover
:鼠标指针移入元素上方时触发。 mouseout
:鼠标指针移出元素上方时触发。
mousedown
:鼠标按钮按下时触发。 mouseup
:鼠标按钮释放时触发。
2.键盘事件
keydown
:键盘按键按下时触发。 keyup
:键盘按键释放时触发。
keypress
:键盘按键被按下并产生字符时触发(已废弃,建议使用keydown
或keyup
)。
3.表单事件
focus
:元素获得焦点时触发。 blur
:元素失去焦点时触发。
change
:元素的值改变时触发(例如,用户输入后失去焦点)。
submit
:表单提交时触发。 reset
:表单重置时触发。
4.窗口事件
load
:页面或资源加载完成时触发。 resize
:窗口大小改变时触发。
scroll
:页面滚动时触发。
5.拖拽事件
drag
:元素正在被拖拽时触发。 dragend
:拖拽操作结束时触发。
dragenter
:拖拽元素进入目标区域时触发。 dragleave
:拖拽元素离开目标区域时触发。
dragover
:拖拽元素在目标区域上方时触发。 dragstart
:拖拽操作开始时触发。
drop
:拖拽元素释放到目标区域时触发
3.2.事件处理
1.添加事件监听器
可以使用
addEventListener
方法为元素添加事件监听器。例如
html" title=javascript>javascript">const button = document.querySelector('button');button.addEventListener('click', function(event) {console.log('Button clicked!');
});
2.移除事件监听器
可以使用
removeEventListener
方法移除事件监听器。移除时需要提供与添加时相同的函数引用:
html" title=javascript>javascript">function handleClick(event) {console.log('Button clicked!');
}button.addEventListener('click', handleClick);
// ... later
button.removeEventListener('click', handleClick);
3.事件对象
事件监听器的回调函数会接收一个事件对象(Event Object),该对象包含了事件的所有相关信息,如触发事件的元素、事件类型、按键信息等。
例如:
html" title=javascript>javascript">button.addEventListener('click', function(event) {console.log('事件类型:', event.type);console.log('目标元素:', event.target);
});
3.3.事件冒泡与捕获
事件传播机制分为三个阶段:捕获阶段、目标阶段和冒泡阶段。默认情况下,事件监听器是在冒泡阶段被触发的
捕获阶段
在捕获阶段,事件从文档的根节点向目标元素传播。
目标阶段
在目标阶段,事件到达目标元素并触发。
冒泡阶段
在冒泡阶段,事件从目标元素向上传播,直到文档的根节点。
可以通过addEventListener
的第三个参数来指定事件是在捕获阶段还是冒泡阶段触发
html" title=javascript>javascript">// 捕获阶段
button.addEventListener('click', function(event) {console.log('捕获到了!');
}, true);// 冒泡阶段(默认)
button.addEventListener('click', function(event) {console.log('冒泡!');
}, false);
阻止事件传播
使用event.stopPropagation()
方法来阻止事件进一步传播
html" title=javascript>javascript">button.addEventListener('click', function(event) {event.stopPropagation();console.log('已停止事件传播');
});
阻止默认行为
使用event.preventDefault()
方法来阻止事件的默认行为。
html" title=javascript>javascript">const form = document.querySelector('form');
form.addEventListener('submit', function(event) {event.preventDefault();console.log('已阻止表单提交');
});
移除事件监听器
使用removeEventListener
方法可以移除之前添加的事件监听器。但需要注意的是,移除时需要提供与添加时相同的函数引用
html" title=javascript>javascript">function handleClick(event) {console.log('按钮被点击了!');
}button.addEventListener('click', handleClick);// 移除事件监听器
button.removeEventListener('click', handleClick);
自定义事件
可以创建和触发自定义事件
html" title=javascript>javascript">// 创建一个自定义事件
const customEvent = new Event('自定义事件');// 添加自定义事件监听器
document.addEventListener('自定义事件', function(event) {console.log('自定义事件被触发!');
});// 触发自定义事件
document.dispatchEvent(customEvent);
3.4.事件委托
事件委托是一种利用事件冒泡机制来减少事件监听器数量的技术。通过将事件监听器添加到父元素上,可以处理多个子元素的事件。这样做的好处是,即使子元素是动态添加的也可以捕获到它们的事件
工作原理
当事件在DOM元素上触发时,它会按照“事件冒泡”的原理,从触发事件的元素(目标元素)开始,逐级向上传播,直到达到根元素(通常是
document
对象)。事件委托利用了这一机制,在父级元素上设置事件监听器,然后通过检查事件对象(event
)的target
属性来确定实际触发事件的元素。
优点
1、减少内存消耗
2、简化代码
3、动态添加元素
实现步骤
1.选择父级元素:确定哪个父级元素将作为事件监听器的容器。
2.添加事件监听器:使用addEventListener
方法为该父级元素添加事件监听器。
3.检查事件目标:在事件处理器中,通过检查事件对象的target
属性来确定实际触发事件的元素。
4.执行相应操作:根据target
元素的不同,执行相应的操作。
示例
html" title=javascript>javascript">// 选择父级元素(ul)
const ul = document.querySelector('ul');// 为父级元素添加点击事件监听器
ul.addEventListener('click', function(event) {// 检查事件目标是否是列表项(li)if (event.target && event.target.nodeName === 'LI') {// 如果是,则执行相应操作console.log('点击列表项:', event.target.textContent);}
});// 动态添加新的列表项(这些新添加的项也会自动继承父级元素上的事件监听器)
const newLi = document.createElement('li');
newLi.textContent = 'New Item';
ul.appendChild(newLi);