参考了这篇博客前端语言串讲(万字笔记) | 青训营笔记,并加入了一些分析思考
课程总结
前端语言的基本能力
基础的前端三剑客HTML、CSS、JavaScript
HTML(超文本标记语言)
HTML 是 Web 页面的基础结构。它用于描述网页的内容和结构。HTML 使用一系列标记(称为标签)来定义页面元素,如标题、段落、列表、图片和链接等。浏览器解析 HTML 代码,并根据标签的语义来显示页面内容。HTML 为网页提供了基本的骨架,使浏览器能够呈现文本、图像和其他媒体。
CSS(级联样式表)
CSS 用于描述 HTML 元素的外观和布局。CSS 允许我们定义如何显示 HTML 元素,例如字体、颜色、大小、间距等。通过使用 CSS,我们可以将样式与 HTML 结构分离,使得网站的设计和维护更加简便。CSS 还允许我们根据不同的设备和屏幕尺寸应用不同的样式(媒体查询),以实现响应式设计。
CSS结构
上图标记 | 释义 |
---|---|
选择器(Selector) | HTML 元素的名称位于规则集开始。它选择了一个或多个需要添加样式的元素(在这个例子中就是 p 元素)。要给不同元素添加样式只需要更改选择器就行了 |
声明(Declaration) | 一个单独的规则,如 color: red; 用来指定添加样式元素的属性 |
属性(Properties) | 改变 HTML 元素样式的途径。(本例中 color 就是 `` 元素的属性。)CSS 中,由编写人员决定修改哪个属性以改变规则 |
属性的值(Property value) | 在属性的右边,冒号后面即属性的值,它从指定属性的众多外观中选择一个值(我们除了 red 之外还有很多属性值可以用于 color ) |
CSS常用选择器
- 元素选择器,例如选择所有p标签,并设置字体大小为14px:
p { font-size: 14px; }
- 类选择器,例如选择带有“red-text”类的元素,并将字体颜色设置为红色:
.red-text { color: red; }
- ID选择器,例如选择ID为“header”的元素,并将背景颜色设置为灰色:
#header { background-color: gray; }
- 后代选择器,例如选择ul下面所有li元素,并将列表样式设置为无序:
ul li { list-style: none; }
- 相邻兄弟选择器,例如选择紧接在h1元素后面的p元素,并将字体大小设置为18px:
h1 + p { font-size: 18px; }
- 子元素选择器,例如选择ul下面直接子元素li,并将文字颜色设置为蓝色:
ul > li { color: blue; }
- 属性选择器,例如选择所有href属性值以“https”开头的链接,并将颜色设置为绿色:
a[href^="https"] { color: green; }
- 伪类选择器,例如选择鼠标悬停在按钮上时的状态,并将背景颜色设置为橙色:
button:hover { background-color: orange; }
JavaScript
JavaScript 是一种脚本语言,用于在浏览器中增加交互性和动态效果。它允许我们编写脚本来处理用户操作,例如点击按钮、输入表单、拖动元素等。通过使用 JavaScript,我们也可以操作 HTML 和 CSS,动态更改页面内容和样式,从而提供丰富的用户体验。JavaScript 也可以与服务器进行通信,以便在不刷新整个页面的情况下获取或提交数据(例如,通过 AJAX)。
基础语法
- 变量类型与C++/Java差距不大。
声明赋值
两个有趣的小例子如下
var a = 7 + "2"
console.log(a)//72,这是因为当它的操作数之一或两者都是字符串时,`+` 会变成字符串连接操作符。
var a = 7 - "2"
console.log(a)//5,因为 `-` 操作符仅适用于数字
- 这种操作会降低可读性,所以应该尽量避免
对象
- 键值对(Key-Value Pair): 对象由一组键值对组成,键是字符串,值可以是任何数据类型(包括原始类型和引用类型)。键也称为属性名(Property Name),而值称为属性值(Property Value)。键和值之间用冒号分隔,键值对之间用逗号分隔。
- 对象字面量(Object Literal): 对象字面量是创建对象的一种简洁表示方式。它使用大括号
{}
包围一组键值对。例如:
//注意 greet 存储一个函数
const person = {
name: "520Enterprise",
age: 20,
greet: function() {
console.log("Hello, my name is " + this.name);
}
};
- 几种操作如下
-
属性访问(Property Access): 可以使用点表示法(Dot Notation)或方括号表示法(Bracket Notation)访问对象的属性。例如:
console.log(person.name); // Output: "XiaoYu" console.log(person["age"]); // Output: 20
-
属性操作(Property Manipulation): 可以通过赋值操作符为对象添加新属性,也可以通过赋值操作符修改现有属性的值。要删除对象的属性,可以使用
delete
操作符。例如:person.gender = "Man"; // 添加新属性 person.name = "Enty520"; // 修改现有属性的值 delete person.gender; // 删除属性
-
方法(Method): 对象的属性值可以是函数。这种类型的属性称为方法(Method)。方法通常用于表示对象的行为,它们可以访问和操作对象的其他属性。例如:
person.greet(); // Output: "Hello, my name is 520Enterprise"
函数
函数(Function)是一种特殊的对象,它封装了一段可执行的代码。函数的主要作用是实现代码的复用、模块化和抽象。
-
函数声明(Function Declaration): 函数声明是定义函数的一种方法。函数声明以
function
关键字开始,后面跟着函数名、一对圆括号(包含参数列表)和一对大括号(包含函数体)function greet(name) { console.log("Hello, " + name); }
-
函数表达式(Function Expression): 函数表达式是另一种定义函数的方法。函数表达式将一个匿名函数赋值给一个变量。
const greet = function(name) { console.log("Hello, " + name); };
-
箭头函数(Arrow Function): 箭头函数是 ECMAScript 6(ES2015)引入的一种简洁的函数语法。箭头函数使用
=>
符号,它可以使代码更简洁、易读。const greet = (name) => { console.log("Hello, " + name); };
-
闭包(Closure): 闭包是指一个函数可以访问并操作其外部作用域中的变量,即使在外部作用域已经结束或函数已返回之后。闭包的一个常见用途是在一个函数内部创建另一个函数,这样内部函数可以访问和操作外部函数的变量。(类似Python)
function makeCounter() { let count = 0; return function() { count += 1; console.log(count); }; } const counter = makeCounter(); counter(); // Output: 1 counter(); // Output: 2,数量变成2,证明上一次调用的结果并没有被垃圾回收掉 //在这个例子中,makeCounter 函数返回一个匿名函数,这个匿名函数可以访问和操作 makeCounter 函数内的 count 变量。即使 makeCounter 函数已经执行完毕,counter(匿名函数的引用)仍然可以访问和操作 count 变量。这就是闭包的作用。
-
高阶函数(Higher-Order Function): 高阶函数是指接受其他函数作为参数或返回一个函数作为结果的函数。高阶函数在 JavaScript 中非常常见,特别是在函数式编程中。例如,
Array.prototype.map
、Array.prototype.filter
和Array.prototype.reduce
等内置函数都是高阶函数。const numbers = [1, 2, 3, 4, 5]; const doubled = numbers.map(function(num) { return num * 2; }); console.log(doubled); // Output: [2, 4, 6, 8, 10] //在这个例子中,我们使用 map 高阶函数将一个数组中的每个元素乘以 2。map 函数接受一个函数作为参数,并将这个函数应用于数组的每个元素。这个在React中会经常出现,用来替代for循环
HTML,CSS,JS如何在浏览器中编译运行
- HTTP 请求:浏览器向服务器发送请求,获取网页的 HTML、CSS、JavaScript 文件以及其他资源(如图片、字体等)。
- 构建 DOM 树:浏览器解析 HTML 文件,构建一个 DOM(Document Object Model)树。DOM 树是一个以节点形式表示的 HTML 文档结构。每个节点代表 HTML 文档中的一个元素、属性或文本。
- 计算 CSS 树:浏览器解析 CSS 文件,构建一个 CSSOM(CSS Object Model)树。CSSOM 树是一个以节点形式表示的 CSS 规则结构。
- 排版(Layout):浏览器将 DOM 树和 CSSOM 树结合,生成一个渲染树(Render Tree)。渲染树包含了 DOM 中的可见元素及其对应的 CSS 规则。接着,浏览器会计算渲染树中每个节点的位置和大小,这个过程称为排版或布局(Layout)。
- 渲染合成:浏览器将渲染树中的各个节点分层,创建渲染层(Render Layers)。每个层包含一个或多个节点,具有独立的绘制和合成上下文。
- 绘制(Painting):浏览器根据渲染层绘制每个节点的视觉效果(如文本、颜色、图像、边框、阴影等),生成位图(Bitmaps)。绘制过程可能会在 GPU(图形处理器)上完成,以提高性能。
- 合成(Compositing):浏览器将渲染层的位图合成为一个完整的屏幕图像,然后显示在屏幕上。合成过程通常由 GPU 完成,以实现高效的图像合成。
在这个过程中,JavaScript 代码的解析与执行可能穿插在各个阶段,因为 JavaScript 可以操作 DOM、CSSOM 和浏览器 API,从而改变页面的内容、样式和交互行为。这些变化可能需要浏览器重新执行排版、绘制和合成等任务。因此,在编写 JavaScript 代码时,应尽量减少对 DOM 和 CSSOM 的操作,以提高页面性能。
Browser(V8引擎工作流程)
JavaScript本质上也是一段文本,需要通过解释器才能够运行
- Source code:JavaScript 源代码作为 V8 引擎的输入。
- Parser:V8 引擎将 JavaScript 源代码解析成一个抽象语法树(Abstract Syntax Tree,简称 AST)。AST 是源代码的一种树状表示,其中每个节点表示一个源代码中的语法结构(如变量声明、函数调用等)。
- AST:生成的抽象语法树将用于接下来的编译和优化过程。
- Ignition:V8 引擎中的 Ignition 是一个解释器(Interpreter),它负责将 AST 转换为字节码(Bytecode)。字节码是一种中间表示,比源代码更接近机器代码,但仍具有平台无关性。
- Bytecode Execute:Ignition 解释器执行字节码,实现 JavaScript 源代码的功能。在执行字节码的过程中,V8 会收集代码的运行时信息(如类型信息等),用于后续的优化过程。
- Feedback:V8 引擎收集的运行时信息(如变量类型、函数调用频率等)称为反馈(Feedback)。这些信息将用于指导后续的即时编译(JIT)过程,生成更高效的机器代码。
- TurboFan:V8 引擎中的 TurboFan 是一个即时编译器(Just-In-Time Compiler,简称 JIT),它负责将字节码优化为机器代码。TurboFan 会根据收集到的反馈信息对代码进行特定的优化(如内联函数、消除数组边界检查等),生成性能更好的机器代码。
- Machine code (Intel, ARM, MIPS):TurboFan 生成的机器代码是针对特定处理器架构(如 Intel x86/x64、ARM、MIPS 等)的低级代码。这些机器代码可以直接在目标处理器上执行,实现更高的性能。
V8 引擎通过这个工作流程实现了 JavaScript 源代码的高效执行。在实际使用过程中,V8 会根据代码的运行情况动态调整优化策略,确保在不同场景下都能实现最佳性能。
前段语言的协作配合
CSS in HTML
从上向下 分别对应的是 行内式 内嵌式 外联式
JavaScript in HTML
同CSS,通过script
标签 引入外部资源 或者在script
标签块里面写脚本代码
JavaScript 是单线程的,意味着在一个时间点只能执行一个任务。为了处理异步操作和事件回调,JavaScript 引入了事件循环(Event Loop)。事件循环使用任务队列(Task Queues)来管理要执行的任务。任务队列分为两种类型:
-
宏任务队列(Macro-Task Queue): 宏任务队列存放宏任务(Macro-Task),它们通常是由外部事件触发的较大的任务。例如:
- setTimeout 和 setInterval 的回调函数
- I/O 操作(如文件读写、网络请求等)的回调函数
- 用户交互事件(如点击、滚动等)的回调函数
- 其他异步 API 的回调函数
-
微任务队列(Micro-Task Queue): 微任务队列存放微任务(Micro-Task),它们通常是 JavaScript 代码中产生的较小的、需要尽快执行的任务。例如:
- Promise 的 then、catch 和 finally 回调函数
- async/await
- MutationObserver 的回调函数
- 其他微任务 API
事件循环会按顺序执行宏任务队列中的任务。当一个宏任务执行完毕后,事件循环会检查微任务队列,执行其中的所有任务,然后再执行下一个宏任务。
HTML in JavaScript
CSS in JavaScript
这部分没太看懂,丢个链接以后看
你不知道的HTML(5)
HTML并非图灵完备,它只是一门标记语言。
基本语法
标签分类
- 文档型
- 闭合型
- 执行型
- H5 新增元素
不用死记,有个印象即可
两个常用的标签:
- meta : 约定好的键值对
<!--指定网页的字符集为 UTF-8,这样可以支持更多语言和字符。-->
<meta charset="UTF-8">
<!--告诉浏览器以最高版本的 IE 内核渲染页面,确保网页能在不同版本的 IE 浏览器中正常显示。-->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- 定义了网页在移动设备上的视口,使得网页布局更加适应不同的设备屏幕尺寸。-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
- link 引入外部CSS资源
<!--<link>标签的 rel 属性定义了链接的类型,href 属性指向要链接的资源文件,其中 type 属性可以省略,浏览器会自动识别资源类型 -->
<link rel="stylesheet" href="style.css">
HTML ARIA
ARIA(Accessible Rich Internet Applications)是一套让 Web 应用和网站更具可访问性的技术规范。ARIA 通过在 HTML 中添加特定的属性,帮助屏幕阅读器等辅助技术更好地理解页面内容和交互。
了解ARlA并非只是为了供盲人阅读,它可以为我们设计UI系统提供指导意义
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ARIA Example</title>
</head>
<body>
<!--为无法通过文本内容描述的元素(如 <nav>)提供一个可访问的标签-->
<nav aria-label="Main Navigation">
<ul>
<li><a href="#home">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
<main>
<h1 id="home">Welcome to our Website!</h1>
<!--将一个元素关联到一个或多个可见的标签元素,通常是标题元素(如 <h2>)。在这个例子中,我们将每个 <section> 元素关联到对应的标题元素-->
<section aria-labelledby="about-section">
<h2 id="about-section">About Us</h2>
<p>We are a company that specializes in creating accessible web applications.</p>
</section>
<section aria-labelledby="contact-section">
<h2 id="contact-section">Contact Us</h2>
<p>Feel free to reach out to us for any questions or inquiries.</p>
</section>
</main>
</body>
</html>
HTML5语义化标签
以下是一些常见的 HTML5 新增语义化标签:
<article>
:表示一个独立的内容块。<aside>
:定义一个附属信息的区域。<details>
:表示用户可以查看或隐藏的补充信息。<figcaption>
:为图片或图表添加标题。<figure>
:用于组合一组相关元素,例如图表和其标题。<footer>
:定义文档的页脚。<header>
:定义文档的页眉。<main>
:代表文档或应用程序的主要内容。<nav>
:用于定义导航链接集合的部分。<section>
:用于划分页面上的段落、主题、内容区块等。
建议: 用对比不用好,不用比用错好
HTML5存储
术语含义:
- Cookies:Cookies 是存储在客户端计算机上的小文件,用于存储用户与网站之间的数据。常用于记录用户的登录状态、购物车内容等信息。
- Local Storage:Local Storage 是 HTML5 新增的一种 Web 存储机制,用于在客户端存储持久化数据。与 Cookies 不同,Local Storage 的数据不会在每次请求时被发送到服务器,而是保存在客户端的本地存储空间中。
- Session Storage:Session Storage 与 Local Storage 类似,也是用于在客户端存储数据。不同之处在于,Session Storage 的数据只在用户会话期间有效,即在浏览器窗口或标签页关闭时自动清除。
- Capacity:Capacity 指的是 Local Storage 或 Session Storage 可以存储的最大数据量,通常为 5MB 到 10MB 不等。
- Browsers:Browsers 指的是 Web 浏览器,如 Google Chrome、Firefox、Safari 等。
- Accessible from:Accessible from 指的是可以从哪些网址访问到 Local Storage 或 Session Storage 中的数据。通常情况下,只有在同一域名下的页面才能够访问相同的 Local Storage 或 Session Storage 数据。
- Expires:Expires 指的是 Cookie 的过期时间,即 Cookie 将在何时失效。当 Cookie 的 Expires 属性为一个固定的时间点时,该 Cookie 将在该时间点失效;当 Expires 属性为 0 时,该 Cookie 将在浏览器关闭时失效。
- Storage Location:Storage Location 指的是 Local Storage 或 Session Storage 的存储位置。通常情况下,Local Storage 或 Session Storage 的数据是保存在客户端的本地存储空间中,而不是发送到服务器。
- Sent with requests:Sent with requests 指的是 Cookie 是否随着 HTTP 请求一起发送到服务器。通常情况下,浏览器会将 Cookie 的值添加到 HTTP 请求头中,以便服务器进行身份验证等操作。
Cookies | Local Storage | Session Storage | |
---|---|---|---|
Capacity | 4kb | 10mb | 5mb |
Browsers | HTML4 / HTML5 | HTML5 | HTML5 |
Accessible from | Any window | Any window | Same tab |
Expires | Manually set | Never | On tab close |
Storage Location | Browser and server | Browser only | Browser only |
Sent with requests | Yes | No | No |
Web存储
Web 存储包括 localStorage
和 sessionStorage
两种,可以保存在浏览器端,不需要每次向服务器请求数据,提高了网页加载速度。这两种存储方式都是以 key-value 对的形式进行存储,并且只能存储字符串类型的数据。
localStorage
:该存储方式保存于本地
,在整个浏览器中
都有效,在关闭浏览器后再次打开相同的页面时仍然可用。
sessionStorage
:该存储方式也保存于本地
,但它与会话相关
,意味着当用户关闭标签
或离开网站
时,存储的数据将被删除
。
下面是一个例子,展示如何使用 localStorage
存储和读取数据:
// 将数据存储到本地储存中
localStorage.setItem('username', 'John');
localStorage.setItem('password', '123456');
// 从本地储存中读取数据
var username = localStorage.getItem('username');
var password = localStorage.getItem('password');
console.log(username); // 输出 "John"
console.log(password); // 输出 "123456"
IndexedDB
IndexedDB 是浏览器中另一种存储机制,它是一种更灵活的对象数据库,支持离线应用,允许存储非字符串类型的数据,例如 Blob 和 ArrayBuffer 等。
IndexedDB 使用异步 API 进行操作,不会阻塞主线程,从而提高了页面的性能。
下面是一个简单的示例,展示如何使用 IndexedDB 存储和读取数据:
// 创建 IndexedDB 数据库
var request = indexedDB.open('myDatabase', 1);
var db;
request.onerror = function(event) {
console.log("IndexedDB 数据库打开失败");
};
request.onsuccess = function(event) {
// 将数据库对象存储在变量中
db = event.target.result;
console.log("IndexedDB 数据库打开成功");
// 使用事务进行读写操作
var transaction = db.transaction(['users'], 'readwrite');
var objectStore = transaction.objectStore('users');
var user = { username: 'John', password: '123456' };
// 存储数据
var request = objectStore.add(user);
request.onsuccess = function(event) {
console.log("数据存储成功");
};
// 读取数据
var getRequest = objectStore.get('John');
getRequest.onsuccess = function(event) {
console.log("数据读取成功", event.target.result);
};
};
需要注意的是,由于这两种存储方式都是针对客户端而言的,因此不宜存储敏感信息,例如密码等,以及过多的数据,否则可能会导致程序性能问题。
HTML5 PWA & AMP
- PWA(Progressive Web Apps):PWA 是一种 Web 应用程序的开发方式,旨在提供类似于原生应用程序的用户体验。它使用 Web 技术开发,可以在任何设备上运行,包括桌面、移动设备和平板电脑。PWA 具有以下特点:
- 可靠性:PWA 可以离线使用,并且具有快速的加载速度。
- 响应式设计:PWA 能够自适应不同的设备和屏幕尺寸。
- 安全性:PWA 使用 HTTPS 进行通信,确保用户的数据和隐私得到保护。
- 独立性:PWA 可以添加到设备的主屏幕上,就像原生应用程序一样。
- AMP(Accelerated Mobile Pages):AMP 是一种 Web 页面的开发方式,旨在提供快速的加载速度和优化的移动体验。它使用精简的 HTML 和 CSS,以及 AMP JavaScript 库来实现。AMP 具有以下特点:
- 快速加载:AMP 页面能够快速加载,提供更好的用户体验。
- 移动友好:AMP 页面被设计为移动优先,适应各种屏幕尺寸。
- 安全性:AMP 页面使用 AMP CDN 来缓存页面,并使用 HTTPS 进行通信。
- 限制性:AMP 页面不能包含一些复杂的功能和 JavaScript 库,以确保页面的速度和可靠性。
HTML5 Audio & Video
// 创建音频上下文
const audioCtx = new AudioContext();
// 创建正弦振荡器
const oscillator = audioCtx.createOscillator();
oscillator.type = 'sine'; // 正弦波
oscillator.frequency.value = 440; // 设置频率为 440Hz
// 创建音量增幅器
const gainNode = audioCtx.createGain();
gainNode.gain.value = 0.5; // 设置增益为 0.5
// 正弦振荡器关联音量增幅器
oscillator.connect(gainNode);
// 音量增幅器关联音频上下文的音频输出器
gainNode.connect(audioCtx.destination);
// 开始振荡
oscillator.start();
// 创建媒体源
const mediaSource = new MediaSource();
// 创建 video 元素
const video = document.createElement('video');
// 将 video 元素与媒体源关联
video.src = URL.createObjectURL(mediaSource);
// 为媒体源添加媒体数据
const sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
fetch('video.mp4')
.then(response => response.arrayBuffer())
.then(buffer => sourceBuffer.appendBuffer(buffer));
// 开始播放视频
video.play();
HTML5 二进制
实现了一个函数 loadAsText()
,用于从本地文件读取数据,并将其转换为不同的格式输出
function loadAsText(file) {
// 创建一个 FileReader 对象
const reader = new FileReader();
// 设置加载完成事件处理程序
reader.onload = function(loadedEvent) {
// 输出读取到的文件内容
console.log(loadedEvent.target.result);
}
// 以文本字符串格式读取文件内容
reader.readAsText(file);
// 以二进制数组格式读取文件内容
reader.readAsArrayBuffer(file);
// 以DataURL格式字符串读取文件内容
reader.readAsDataURL(file);
}
HTML5 API
HTML5 API是指HTML5标准所定义的JavaScript API,它们提供了开发者处理DOM
、Canvas
、Web Storage
、WebSocket
等各种功能的能力。
GeoLocation API 示例
使用
navigator.geolocation.getCurrentPosition()
方法获取当前设备的地理位置信息。当该方法调用成功时,将执行position
回调函数,传入一个position
对象,该对象包含了当前位置的经纬度信息。我们可以从position.coords.latitude
和position.coords.longitude
属性中获取当前位置的纬度和经度,并输出到控制台中。如果获取当前位置信息失败,将执行
error
回调函数,传入一个error
对象,该对象包含了错误信息。我们可以从error.message
属性中获取错误消息,并输出到控制台中
// 获取当前位置的经纬度信息
navigator.geolocation.getCurrentPosition(position => {
const latitude = position.coords.latitude;
const longitude = position.coords.longitude;
console.log(`当前位置:纬度 ${latitude},经度 ${longitude}`);
}, error => {
console.error(error.message);
});
Drag and Drop API 示例
首先,我们为拖拽源元素
dragSource
添加dragstart
事件处理程序。在该处理程序中,我们使用event.dataTransfer.setData()
方法设置拖拽数据,该方法接受两个参数:数据类型和数据内容。我们将数据类型设置为'text/plain'
,数据内容设置为'Hello, World!'
。然后,我们设置拖拽效果为'copy'
。接着,我们为拖放目标元素
dropTarget
添加dragover
和drop
事件处理程序。在dragover
处理程序中,我们首先阻止默认行为,允许元素被拖放到此处。然后,我们设置拖放效果为'copy'
。在drop
处理程序中,我们同样阻止默认行为,防止浏览器打开拖放的文件
// 为拖拽源元素添加拖拽事件处理程序
const dragSource = document.getElementById('dragSource');
dragSource.addEventListener('dragstart', event => {
// 设置拖拽数据
event.dataTransfer.setData('text/plain', 'Hello, World!');
// 设置拖拽效果
event.dataTransfer.effectAllowed = 'copy';
});
// 为拖放目标元素添加拖放事件处理程序
const dropTarget = document.getElementById('dropTarget');
dropTarget.addEventListener('dragover', event => {
// 阻止默认行为,允许元素被拖放到此处
event.preventDefault();
// 设置拖放效果
event.dataTransfer.dropEffect = 'copy';
});
dropTarget.addEventListener('drop', event => {
// 阻止默认行为,防止浏览器打开拖放的文件
event.preventDefault();
// 读取拖拽数据
const data = event.dataTransfer.getData('text/plain');
// 将拖拽数据输出到控制台中
console.log(data);
});
Web Worker
Web Worker 在主线程和后台线程之间建立了一条通信通道,主线程可以通过 postMessage() 方法向后台线程发送消息,后台线程也可以通过 onmessage 事件接收主线程发送的消息。这种通信方式是异步的,不会阻塞主线程,从而不会影响用户体验。
使用 Web Worker 的主要步骤如下:
- 创建一个 Web Worker 对象,指定后台线程脚本的 URL。
- 在主线程中向后台线程发送消息,可以使用 postMessage() 方法。
- 在后台线程中接收主线程发送的消息,可以通过 onmessage 事件监听。
- 在后台线程中执行相应的操作,并通过 postMessage() 方法将处理结果发送回主线程。
- 在主线程中接收后台线程发送的消息,可以通过 onmessage 事件监听。
需要注意的是,Web Worker 无法访问主线程的 DOM 对象和全局变量,需要通过 postMessage() 方法向主线程发送消息,才能访问这些对象和变量。此外,Web Worker 运行在独立的上下文环境中,无法访问与其它线程共享的变量和对象。
Web Socket
Web Socket 是一种在 Web 应用程序中实现实时通信的协议。它提供了一种双向通信机制,允许客户端和服务器之间进行实时的数据传输。与传统的 HTTP 请求/响应模式不同,Web Socket 采用了一种持久化的连接,可以在客户端和服务器之间保持通信通道,从而实现实时通信的功能。
Web Socket 协议基于 TCP 协议实现,使用了类似 HTTP 协议的握手过程来建立连接。客户端和服务器之间的通信采用帧(Frame)的形式进行,每个帧包含一个标识、一些附加信息和一段数据。客户端和服务器可以通过发送不同类型的帧来实现不同的功能,比如文本消息、二进制数据、ping-pong 等。
Web Socket 协议可以与任何支持该协议的服务器进行通信,包括自己开发的服务器和第三方提供的服务。它通常被用于实现实时聊天室、实时游戏、实时协作等应用场景。由于其实时性和高效性,越来越多的 Web 应用程序开始采用 Web Socket 技术来实现实时通信的功能
// 创建 Web Socket 连接
const socket = new WebSocket('ws://localhost:8080');
// 当连接打开时,发送一条消息到服务器
socket.addEventListener('open', event => {
socket.send('Hello, Server!');
});
// 当收到服务器发送的消息时,输出到控制台中
socket.addEventListener('message', event => {
console.log(`Received message from server: ${event.data}`);
});
// 当连接关闭时,输出一条消息到控制台中
socket.addEventListener('close', event => {
console.log('Web Socket connection closed');
});
// 当连接发生错误时,输出错误消息到控制台中
socket.addEventListener('error', event => {
console.error(`Web Socket error: ${event.message}`);
});
Shadow DOM
Shadow DOM 是 Web Components 技术中的一部分,用于实现 Web 页面上的组件化开发。它允许开发者将 HTML、CSS 和 JavaScript 封装到一个独立的、可重用的组件中,以便在不同的页面和应用程序中进行复用。
Shadow DOM 通过创建一个“影子树”来实现组件的封装和隔离。在一个 Shadow DOM 中,组件的 HTML 结构、CSS 样式和 JavaScript 行为都被包裹在一个独立的命名空间中,与外部页面的 HTML、CSS 和 JavaScript 不会互相干扰。这种隔离性使得组件可以在不同的页面和应用程序中进行复用,而不用担心样式和行为的冲突。
使用 Shadow DOM 可以创建一些高度可定制化的组件,比如自定义的表单控件、交互式组件等。Shadow DOM 还提供了一些 API,可以让开发者更加方便地控制组件的行为和样式。比如,可以使用 JavaScript 修改组件内部的 DOM 结构、监听组件内部的事件、控制组件内部的样式等。
Web Component
HTML5 的 Web Component 是一种基于标准 Web 技术实现的组件化开发模型,它由三个技术规范组成:Custom Elements、Shadow DOM 和 HTML Templates。
Custom Elements 允许开发者自定义 HTML 元素,可以通过 JavaScript API 来创建、注册和使用自定义元素。这样,开发者就可以将多个 HTML 元素封装为一个独立的组件,并在 Web 页面中进行复用。Custom Elements 还提供了一些生命周期方法和事件,可以让开发者控制自定义元素的创建和销毁过程。
Shadow DOM 允许开发者创建一个独立的、封装的 DOM 树,用于包含和隔离组件内部的 HTML 结构、CSS 样式和 JavaScript 行为。这样,开发者就可以将组件内部的实现细节隐藏起来,避免与外部页面的 HTML、CSS 和 JavaScript 冲突。Shadow DOM 还提供了一些 API,可以让开发者更加方便地控制组件内部的样式和行为。
HTML Templates 允许开发者将 HTML 片段封装为一个可重用的模板,并在 Web 页面中进行复用。HTML Templates 还支持使用 JavaScript API 来动态生成和填充模板内容,以适应不同的使用场景。
<!-- 定义一个自定义元素 my-button,使用 Shadow DOM 封装组件内部的样式和行为 -->
<template id="my-button-template">
<style>
button {
background-color: #007bff;
color: white;
border: none;
border-radius: 3px;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}
button:hover {
background-color: #0069d9;
}
</style>
<button>Click me!</button>
</template>
<!-- 在页面中使用自定义元素 my-button -->
<my-button></my-button>
// 定义一个 MyButton 类,继承自 HTMLButtonElement,用于创建自定义元素
class MyButton extends HTMLButtonElement {
constructor() {
super();
// 创建 Shadow DOM,并将模板内容插入其中
const shadow = this.attachShadow({ mode: 'open' });
const template = document.getElementById('my-button-template');
const clone = template.content.cloneNode(true);
shadow.appendChild(clone);
// 绑定按钮的点击事件
const button = shadow.querySelector('button');
button.addEventListener('click', () => {
console.log('Button clicked!');
});
}
}
// 将 MyButton 注册为自定义元素
customElements.define('my-button', MyButton, { extends: 'button' });
WebGL & WebGPU
WebGL 是一种在浏览器中呈现 3D 和 2D 图形的 JavaScript API,它是基于 OpenGL ES 2.0 的标准,支持硬件加速,并可与 HTML、CSS 和 JavaScript 无缝集成。使用 WebGL,开发者可以在浏览器中创建高性能的 3D 游戏、可视化工具和数据展示应用等。
WebGPU 是一个新的 Web 标准,旨在为 Web 平台提供低级别、跨平台的图形和计算 API,支持使用现代硬件的强大功能。WebGPU 由 Khronos Group 开发,它是 Metal、Vulkan 和 DirectX 12 的 Web 版本,支持多线程和多 GPU,并可以在 WebAssembly 上运行。WebGPU 的目标是为 Web 开发者提供更高效、更灵活的图形和计算功能,从而打造更加丰富和复杂的 Web 应用。
Some Amazing Demo:davidwalsh.name/webgl-demo
确实特别的震撼,尤其是那个水面的渲染
WebAssembly
WebAssembly(WASM)是一种新的编码方式,可以直接在浏览器中运行
WebAssembly(简称为 wasm)是一种新型的虚拟机技术,是一种由 W3C、Mozilla 和其他浏览器厂商共同推出的新 Web 标准。WebAssembly 可以将高性能的 C、C++、Rust 等语言的代码编译成二进制格式,在浏览器中运行,从而提供了比 JavaScript 更高的性能和更好的可移植性。
WebAssembly 具有许多优点,比如:
- 高性能:WebAssembly 的代码可以直接在浏览器中运行,可以比 JavaScript 更高效地利用硬件资源。
- 跨平台:WebAssembly 的二进制格式是跨平台的,可以在任何支持 WebAssembly 的平台上运行,包括浏览器、移动设备、IoT 设备等。
- 安全性:WebAssembly 的代码运行在沙箱环境中,不会对浏览器和计算机造成安全风险。
- 可扩展性:WebAssembly 可以与 JavaScript 无缝集成,并且可以与浏览器中的其他 Web 技术一起使用,比如 Canvas、WebGL 等。
HTML5 支持 WebAssembly 技术,并且可以通过 JavaScript 脚本来调用 WebAssembly 的函数,实现更高效、更复杂的 Web 应用程序。WebAssembly 技术在 Web 游戏、图像和音频处理、虚拟现实和人工智能等方面具有广泛的应用前景。
拓展分享
MVC & MVVM & MVP
MVC、MVVM 和 MVP 是三种常见的前端架构设计模式。
MVC 是 Model-View-Controller(模型-视图-控制器)的缩写。它是一种分层设计模式,通过将应用程序分为三个组件:模型(Model)、视图(View)和控制器(Controller),实现了应用程序逻辑和界面之间的分离。模型表示应用程序的数据和业务逻辑,视图表示用户界面,控制器负责协调模型和视图之间的通信。
MVVM 是 Model-View-ViewModel(模型-视图-视图模型)的缩写。它是一种基于数据绑定的设计模式,通过将应用程序分为三个组件:模型(Model)、视图(View)和视图模型(ViewModel),实现了数据的双向绑定。模型表示应用程序的数据和业务逻辑,视图表示用户界面,视图模型负责将模型数据绑定到视图上,并处理用户输入的数据。
MVP 是 Model-View-Presenter(模型-视图-表示器)的缩写。它是一种基于事件驱动的设计模式,通过将应用程序分为三个组件:模型(Model)、视图(View)和表示器(Presenter),实现了应用程序逻辑和界面之间的分离。模型表示应用程序的数据和业务逻辑,视图表示用户界面,表示器负责协调模型和视图之间的通信,并响应用户的事件。