JS操作DOM及CSS

 JS创造于1994年,其目的是为浏览器显示的文档赋予动态行为。

1 Web编程基础

本节讲解如何编写Web应用中的js程序,如果将这些程序加载到浏览器,以及如何获取输入、产出输出,如何运行响应事件的异步代码。

1.1 js 脚本

虽然现在不再提倡使用document.write()生成内容了,但由于还存在这种可能,浏览器在解析遇到<script>元素时的默认行为是必须要运行脚本,就是为了确保不漏掉脚本可能输出的HTML内容,然后才能再继续解析和渲染文档。这有可能拖慢网页的解析和渲染过程。

1.1.1 脚本运行时机

<script>标签支持defer和async两个属性,它们会导致脚本以不同的方式执行。这两个属性都会明确告诉浏览器,当前链接的脚本中没有使用document.write()生成的HTML输出。

async:让浏览器尽早运行脚本,但不会阻塞文档解析。

defer:推迟到文档完全加载和解析之后。

module:默认defer,但可用async覆盖。

可以把<script>标签放到HTML文件末尾,可确保脚本运行时就知道前面的文档内容已经解析了。

1.1.2 按需加载脚本

1)以模块形式编写,使用import()来按需加载。

2)向文档动态添加<script>标签。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button οnclick="addJs()">点击动态加载js</button>
</body>
<script>
    function addJs() {
        let s = document.createElement("script");
        s.append('console.log("hello js")');
        document.head.append(s);
    }
</script>
</html>

1.2 JS 程序的执行

图 js 程序从脚本执行阶段过度到事件处理阶段到步骤

1.3 程序错误

1)window.onerror属性,能定义一个终极错误处理程序,在未捕获异常时调用。当未捕获异常沿调用栈一路向上传播,错误消息即将现身在开发者控制台时,window.onerror函数将会以三个参数被调用(描述错误的消息,包含导致错误的js代码的url,文档中发生错误的行号)。 如果onerror处理程序返回true,意味着通知浏览器它已经处理了错误,不需要进一步行动了。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button οnclick="makeError()">制造错误</button>
</body>
<script>
    function makeError() {
        throw new Error("未捕获的错误");
    }
    window.onerror = (msg,url,num) => {
        console.log(msg,url,num);
        return true;
    }
    // Uncaught Error: 未捕获的错误 http://localhost:63342/js-study/day5/s2.html?_ijt=v4mqhcotbhl7e6bfrfbd9db8nd&_ij_reload=RELOAD_ON_SAVE 12
</script>
</html>

2)window.addEventListener() 为 “unhandlerejection(期约被拒绝而没有catch()函数处理它)”事件注册一个处理程序来发现它。这个函数第一个参数是一个promise对象,第二个参数是reason,其值为本来要传给.catch()函数的拒绝理由。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button οnclick="makeError()">制造错误</button>
</body>
<script>
    function makeError() {
        return new Promise((resolve,reject) => {
            reject("拒绝原因");
        })
    }
    window.onunhandledrejection = (promise,reason) => {
        console.log("onunhandledrejection",promise,reason);
    }
    // onunhandledrejection PromiseRejectionEvent {isTrusted: true, reason: '拒绝原因', type: 'unhandledrejection', target: Window, currentTarget: Window, …} undefined
</script>
</html>

2 事件

图 事件传播的三个阶段

第一个阶段也叫做“捕获”阶段。addEventListener()接收的第三个可选参数,如果该值是true或{capture: true},那么就表明该事件处理程序会注册为捕获事件处理程序。

捕获阶段差不多与冒泡阶段正好相反:最先调用Window对象上注册的捕获处理程序,然后才调用Document对象的捕获处理程序,接着才是<body>元素,然后沿着DOM树一直向下,直到事件目标父元素的捕获事件处理程序被调用。注册在事件目标本身的捕获事件处理程序不会在这个阶段被调用。

事件捕获提供了把事件发送到目标之前先行处理到机会。

2.1 事件取消

调用事件对象的preventDefault()方法可以阻止浏览器执行其默认的动作(如果注册程序程序时传入了passive选项,则会导致该方法失效)。

事件对象的stopPropagation()方法会取消事件传播,但同一对象上的其他事件处理程序会照常执行。

stopImmediatePropagation()方法会阻止同一个对象上注册的后续事件处理程序执行。

2.2 派发自定义事件

CustomEvent()构造函数创建自定义事件对象,第一个参数是表示事件类型的字符串;第二个参数是一个对象,用于指定事件对象的属性。配置参数({bubbles: true} 表示希望其沿着文档树向上冒泡)。

事件目标的dispatchEvent()方法用于派发自定义事件,其唯一参数是CustomEvent类型对象,

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <button id="btn">dispatchEvent</button>
</div>
</body>
<script>
    let customEvent = new CustomEvent("sayHello",{detail: this});
    let btn = document.querySelector("#btn");

    btn.addEventListener("sayHello",(e) => {
        console.log(e)
    });

    btn.dispatchEvent(customEvent);
</script>
</html>

图 btn的sayHello事件对象

3 操作DOM

Element对象的querySelector()方法接收一个css选择符作为参数,返回它在文档中找到的第一个匹配的元素。

querySelectorAll()方法返回Element对象的后代及其本身所有匹配的元素。

closest()从当前元素开始,沿着DOM树向上匹配(而上面的方法是沿着DOM树向下匹配)。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="divC" id="div0">
<div class="divC" id="firstDiv">
    <span class="spanC">12</span>
    <span class="spanC">34</span>
    <div class="divC">56</div>
</div>
</div>
<div class="divC">aa</div>
<div class="divC">bb</div>
</body>
<script>
    let divElement = document.querySelector("#firstDiv");
    let nodeList = divElement.querySelector(".divC");
    console.log(nodeList); // <div class="divC">56</div>
    let elements = divElement.closest(".divC");
    console.log(elements);
    // <div className="divC" id="firstDiv">
    //     <span className="spanC">12</span>
    //     <span className="spanC">34</span>
    //     <div className="divC">56</div>
    // </div>
</script>
</html>

3.1 元素的内容

元素的内容有HTML表示和纯文本表示。Element的textContent表示元素的纯文本内容。html表示有以下方法:

1)innerHTML属性。通常效率很高,不过要注意,通过+=操作符给innerHTML追加文本的效率不高(这个操作既会涉及序列化操作,也会涉及解析操作:先把元素内容转换为字符串,然后再把新字符串转换回元素内容)。返回值不包含元素自身。设置innerHTML属性时,新内容会替换当前元素的内容。

2)outerHTML属性,返回值包含元素自身。在设置outerHTML时,新内容会取代元素本身。

3)insertAdjacentHTML()方法,用于插入与指定元素“相邻”的任意HTML标记字符串,要插入的标签作为第二个参数传入,而第一个枚举参数用于指定其位置(beforebegin、afterbegin、beforeend、afterend)。

图 inserAdjacentHTML()方法的插入位置

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div><button οnclick="divClickHandle(1)">innerHTML插入div1</button></div>
<div><button οnclick="divClickHandle(2)">outerHTML插入div2</button></div>
<div><button οnclick="divClickHandle(3)">insertAdjacentHTML插入div3</button></div>
<div id="div1">div1</div>
<div id="div2">div2</div>
<div id="div3">div3</div>
</body>
<script>
    function divClickHandle(type) {
        let element,str = '<span style="color:red">插入的内容</span>';
        if (type === 1) {
            element = document.querySelector("#div1");
            element.innerHTML = str;
        } else if (type === 2) {
            element = document.querySelector("#div2");
            element.outerHTML = str;
        } else {
            element = document.querySelector("#div3");
            element.insertAdjacentHTML("beforeend", str);
        }
    }
</script>
</html>
<style>
    #div1,#div2,#div3 {
        margin-top: 20px;
        border: solid 1px green;
        width: 200px;
    }
</style>

图 依次点击一次btn后的界面

4 操作CSS

Element对象的classList属性表示元素的类集。可以通过其add或者remove方法为该元素添加或者删除类名。

样式表是通过<style>或<link>标签与HTML文档关联起来的,这两个标签都是普通的HTML标签(可以为其指定一个id属性来方便querySelector方法的查找),其对应的Element对象都有disabled属性,可以用它禁用整个样式表。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button οnclick="disabledDefaultStyle()">禁用样式</button>
<button οnclick="addBlueStyle()">新增样式(字体成蓝色)</button>
<div id="div0">这是一个样式</div>
</body>
<style id="defaultStyle">
    #div0 {
        color: red;
    }
</style>
<script>
    function disabledDefaultStyle() {
        let element = document.querySelector("#defaultStyle");
        element.disabled = true;
    }

    function addBlueStyle() {
        let styleElement = document.createElement("style");
        styleElement.innerText='#div0{ color: blue}'
        document.body.append(styleElement);
    }
</script>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/118928.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是 Node.js

目标 什么是 Node.js&#xff0c;有什么用&#xff0c;为何能独立执行 JS 代码&#xff0c;演示安装和执行 JS 文件内代码 讲解 Node.js 是一个独立的 JavaScript 运行环境&#xff0c;能独立执行 JS 代码&#xff0c;因为这个特点&#xff0c;它可以用来编写服务器后端的应用…

mybatisPlus逻辑删除注解@TableLogic

当我做了一个实体类&#xff0c;字段为del_flag的逻辑删除字段&#xff0c;要通过这个字段控制数据库中的数据逻辑删除。 重写mapper中的deleteById&#xff0c; 先按id查出数据&#xff0c;在更新此数据中的del_flag字段为1&#xff0c;调用update方法更新数据。 这种方式我…

多继承的实例介绍

一、多继承同名覆盖 子类中的成员与父类中的成员同名问题&#xff0c;通过作用域分辨符&#xff08;&#xff1a;&#xff1a;&#xff09;进行限定类的访问&#xff0c;从而实现对不同类中的同名成员各自赋值。 #include<iostream> using namespace std; class A{//父…

54. 螺旋矩阵

54. 螺旋矩阵 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a;__54螺旋矩阵 原题链接&#xff1a; 54. 螺旋矩阵 https://leetcode.cn/problems/spiral-matrix/description/ 完成情况&#xff1a; 解题思路&#xff1a; 跟59题。很类似…

python实验16_网络爬虫

实验16&#xff1a;网络爬虫 1.实验目标及要求 &#xff08;1&#xff09;掌握简单爬虫方法。 2. 实验主要内容 爬取中国票房网 ① 爬取中国票房网&#xff08;www.cbooo.cn)2019年票房排行榜前20名的电影相关数据 代码部分: import time from selenium.webdriver impor…

成为CSS选择器大师,让你的网页瞬间提升品味!

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一、选…

【tg】9 : InstanceImpl 、 虚拟的音频渲染设备FakeAudioDeviceModuleImpl

代码分布 WebRTC-Manager 线程:manager线程 G:\CDN\P2P-DEV\tdesktop-offical\Telegram\ThirdParty\tgcalls\tgcalls\InstanceImpl.h Manager 使用的是 WebRTC-Manager 线程 InstanceImpl 对Manager 的封装和调用 #

pycharm转移缓存目录

原来的缓存目录为C:\Users\86176\AppData\Local\JetBrains&#xff0c;各种配置文件、缓存文件随着pycharm的使用堆积在这里&#xff0c;导致C盘逐渐爆满。 因此需要将缓存目录转移至D盘。首先需要了解缓存目录的知识。 PyCharm 和其他 JetBrains 的 IDE 通常会有两个关键的目…

Nodejs和Node-red的关系

NPM相关知识 npm概念 npm&#xff1a;Node Package Manager&#xff0c;Node包管理器。是Node.js默认的&#xff0c;以JavaScript编写的软件包管理系统。 npm工作原理 npm的操作原理是各个官网使用npm publish把代码提交到npm的服务器&#xff0c;其他人想要使用这些代码&am…

适用于 Linux 和 Unix 的特权访问管理

凭据、SSH 密钥、服务帐户、数字签名、文件系统等内容构成了Linux 环境的关键部分&#xff0c;虽然大多数PAM供应商为基于Windows的环境提供无缝的特权访问管理&#xff0c;但它们的通用性不足以为Linux&#xff0c;Unix和*nix环境扩展相同的功能和功能。 Linux 中的root权限是…

微信小程序获取用户信息

个人博客 微信小程序获取用户信息 个人微信公众号&#xff0c;求关注&#xff0c;求收藏&#xff0c;求指错。 文章概叙 本文主要讲的是小程序获取用户信息的&#xff0c;更新测试时间是2023-10-25 更改原因 首先&#xff0c;官网上的解释是这样的&#xff0c;为了安全合…

PAM从入门到精通(二十六)

接前一篇文章&#xff1a;PAM从入门到精通&#xff08;二十五&#xff09; 本文参考&#xff1a; 《The Linux-PAM Application Developers Guide》 先再来重温一下PAM系统架构&#xff1a; 更加形象的形式&#xff1a; 七、PAM-API各函数源码详解 前边的文章讲解了各PAM-API…

【AI视野·今日Robot 机器人论文速览 第五十七期】Wed, 18 Oct 2023

AI视野今日CS.Robotics 机器人学论文速览 Wed, 18 Oct 2023 Totally 17 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers Underwater and Surface Aquatic Locomotion of Soft Biomimetic Robot Based on Bending Rolled Dielectric Elastomer Actua…

No module named ‘cv2’ 解决方法

目录 解决方案1解决方案2 解决方案1 一般情况下的解决方案 在自己的虚拟环境里面安装就行 pip install opencv-python解决方案2 但是我遇到的情况没有这么简单,我使用了pip list | grep open 搜索含有open字样的opencv的包,结果显示已经安装了 我直接进入我的自定义的虚拟…

亚马逊注册账号时老是显示内部错误

最近你们是否遇到注册亚马逊账号时一直遇到"内部错误"的情况&#xff1f;&#xff0c;这可能是由多种原因引起的。以下是一些可能有助于解决这个问题的步骤&#xff1a; 1、清除缓存和Cookie&#xff1a;有时浏览器缓存和Cookie中的问题可能导致网站错误。可以试试清…

如何在Ubuntu下安装RabbitMQ服务并异地远程访问?

文章目录 前言1.安装erlang 语言2.安装rabbitMQ3. 内网穿透3.1 安装cpolar内网穿透(支持一键自动安装脚本)3.2 创建HTTP隧道 4. 公网远程连接5.固定公网TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 前言 RabbitMQ是一个在 AMQP(高级消息队列协议)基…

WeakHashMap 源码解析

目录 一. 前言 二. 源码解析 2.1. 类结构 2.2. 成员变量 2.3. 构造方法 2.4. Entry 2.5. 添加元素 2.6. 扩容 2.7. 删除元素 2.8. 获取元素 一. 前言 WeakHashMap&#xff0c;从名字可以看出它是某种 Map。它的特殊之处在于 WeakHashMap 里的entry可能会被GC自动删除…

新手投资如何分配股票仓位?诺奖得主的秘诀是什么?| 附代码【邢不行】

2023年6月22日&#xff0c;诺贝尔经济学奖得主哈里.马克维茨于美国去世&#xff0c;享年95岁。 作为现代金融先驱者&#xff0c;马科维茨不仅是将数学引入金融的第一人&#xff0c;更用数学解释了分散投资的重要性。 更令人惊叹的是&#xff0c;过去十几年中如果按他的理论在中…

docker部署prometheus+grafana服务器监控(一)

docker-compose 部署prometheusgrafana Prometheus Prometheus 是有 SoundCloud 开发的开源监控系统和时序数据库&#xff0c;基于 Go 语言开发。通过基于 HTTP 的 pull 方式采集时序数据&#xff0c;通过服务发现或静态配置去获取要采集的目标服务器&#xff0c;支持多节点工…

18.2 使用NPCAP库抓取数据包

NPCAP 库是一种用于在Windows平台上进行网络数据包捕获和分析的库。它是WinPcap库的一个分支&#xff0c;由Nmap开发团队开发&#xff0c;并在Nmap软件中使用。与WinPcap一样&#xff0c;NPCAP库提供了一些API&#xff0c;使开发人员可以轻松地在其应用程序中捕获和处理网络数据…