当前位置: 首页 > news >正文

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.lryc.cn/news/205091.html

相关文章:

  • Linux内核VFS详解
  • 在自己的服务器上部署个人博客和开源项目:实现数字存在感
  • 【AI视野·今日Robot 机器人论文速览 第五十九期】Fri, 20 Oct 2023
  • Chromium浏览器启动参数
  • 【计算机视觉】MoCo v3 讲解
  • MySQL - 对字符串字段创建索引
  • Qt pro文件中 CONFIG += debug 作用
  • java解析生成定时Cron表达式工具类
  • 庆祝1024
  • 时间格式记录
  • hive插入动态分区数据时,return code 2报错解决
  • 解决报错:gnutls_handshake() failed: The TLS connection was non-properly terminated.
  • 《 汇编语言的系统学习》一、编程语言、机器语言与汇编语言
  • 【RocketMQ系列十四】RocketMQ中消息堆积如何处理
  • Ubuntu - sudo apt update 报错源问题解决方案
  • MSQL系列(八) Mysql实战-SQL存储引擎
  • vue3 + fastapi 实现选择目录所有文件自定义上传到服务器
  • html 常见兼容性问题
  • PCL 点云投影到圆柱(C++详细过程版)
  • 以太网链路聚合与交换机堆叠,集群
  • 5G RedCap工业智能网关
  • STM32-ADC实验
  • 05、Python -- 爬取ts文件格式视频思路
  • 【QT】其他常用控件2
  • django报错--Not Found The requested URL was not found on the server.
  • VLOOKUP函数的使用方法
  • 关于前端如何下载后端接口返回content-type为application/octet-stream的文件
  • 报错:SSL routines:ssl3_get_record:wrong version number
  • Flask后端开发(一)-基础知识和前期准备
  • 基于SSM的幼儿园管理系统