整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

前端Rust生态的背后napi-rs如何让Rust与

前端Rust生态的背后napi-rs如何让Rust与JavaScript可以相互调用

napi-rs 是一个用于在 Rust 中构建 Node.js 预编译插件的框架。得益于 Rust 的卓越性能表现,它正逐渐在前端工具链中占据一席之地,而 napi-rs 则在 Rust 与 JavaScript 交互的实现中扮演着关键角色,因此得到了广泛的应用。

本文将深入探讨如何通过 napi-rs 实现 Rust 和 JavaScript 函数之间的互相调用,并剖析背后的工作机制。

napi-rs 与 N-API 的关系

N-API 是 Node.js 官方维护的一组 API,专为构建稳定且兼容各版本的 Node.js 原生插件而设计。

napi-rs 是基于 N-API 构建的,通过提供方便的 Rust 接口,它简化了在 Rust 中构建 Node.js 原生插件的过程。N-API 是 Node.js 提供的原生 API,而 napi-rs 是 N-API 的 Rust 封装,两者组合使得 Rust 开发者能够更容易地编写和集成 Node.js 的原生模块。

JavaScript 调用 Rust 函数

使用

在 napi-rs 中,将 Rust 函数暴露给 JavaScript 使用是异常直观。通过 napi-rs 的文档和工具,你可以迅速地得到一个 Rust 写的 sum 函数,并暴露给了 JavaScript。

#[napi] pub fn sum(a: i32, b: i32) -> i32 { a + b }

你可以在 JavaScript 中直接调用它。

sum(1, 2)

实现原理

为了深入理解 napi-rs 的运作,我们可以使用 cargo expand 命令对 #[napi] 宏进行展开,揭示其背后执行的具体步骤。

第一步

napi-rs 生成 __napi__sum 函数,此函数作为 Node.js 插件中的桥梁,实现 Rust sum 函数与 JavaScript 环境之间的参数接收和返回值传递。

#[doc(hidden)] #[allow(non_snake_case)] #[allow(clippy::all)] extern "C" fn __napi__sum( env: napi::bindgen_prelude::sys::napi_env, cb: napi::bindgen_prelude::sys::napi_callback_info, ) -> napi::bindgen_prelude::sys::napi_value { unsafe { napi::bindgen_prelude::CallbackInfo::<2usize>::new(env, cb, None, false) .and_then(|mut cb| { let arg0={ <i32 as napi::bindgen_prelude::FromNapiValue>::from_napi_value( env, cb.get_arg(0usize), )? }; let arg1={ <i32 as napi::bindgen_prelude::FromNapiValue>::from_napi_value( env, cb.get_arg(1usize), )? }; napi::bindgen_prelude::within_runtime_if_available(move || { let _ret={ sum(arg0, arg1) }; <i32 as napi::bindgen_prelude::ToNapiValue>::to_napi_value(env, _ret) }) }) .unwrap_or_else(|e| { napi::bindgen_prelude::JsError::from(e).throw_into(env); std::ptr::null_mut::<napi::bindgen_prelude::sys::napi_value__>() }) } }
  1. extern "C" 表示这个函数使用 C 语言的调用约定,它告诉编译器生成的函数应与外部 C 代码或其他语言兼容,这是创建 Node.js 原生模块所必需的。
  2. 函数签名:定义了函数的参数和返回类型。根据 N-API 的要求,参数包括环境句柄 napi_env 和回调信息 napi_callback_info。返回类型是 napi_value,这表示了 JavaScript 值。
  3. unsafe 块:因为涉及到 FFI (Foreign Function Interface 外部函数接口) 与 Node.js 的交互,所以需要在 unsafe 代码块中运行。
  4. CallbackInfo::<2usize>:一个帮助器结构,封装了回调信息,并知道期望两个参数。
  5. 参数提取:使用 from_napi_value 方法将 JavaScript 参数转换为 Rust 的 i32 类型。
  6. 计算和返回:调用 Rust 中的 sum 函数,并使用 to_napi_value 方法将结果转换回 JavaScript 可以识别的值。
  7. 错误处理:如果在参数转换或函数执行过程中发生错误,通过 unwrap_or_else 来捕获并处理,这包括将错误转换为 JavaScript 错误并抛出。

第二步

napi-rs 生成 sum_js_function 函数,定义了一个用作 N-API 的原生函数,名为 __napi__sum。它允许你在 JavaScript 环境中调用一个名为 sum 的函数,当 JavaScript 代码调用 sum 函数时,底层调用的将是 __napi__sum Rust 函数。

#[allow(non_snake_case)] #[allow(clippy::all)] unsafe fn sum_js_function( env: napi::bindgen_prelude::sys::napi_env, ) -> napi::bindgen_prelude::Result<napi::bindgen_prelude::sys::napi_value> { let mut fn_ptr=std::ptr::null_mut(); { let c=napi::bindgen_prelude::sys::napi_create_function( env, "sum>#[allow(non_snake_case)] #[allow(clippy::all)] unsafe fn sum_js_function( env: napi::bindgen_prelude::sys::napi_env, ) -> napi::bindgen_prelude::Result<napi::bindgen_prelude::sys::napi_value> { let mut fn_ptr=std::ptr::null_mut(); { let c=napi::bindgen_prelude::sys::napi_create_function( env, "sum\0".as_ptr().cast(), 3usize, Some(__napi__sum), std::ptr::null_mut(), &mut fn_ptr, ); match c { ::napi::sys::Status::napi_ok=> Ok(()), _=> { Err( ::napi::Error::new( ::napi::Status::from(c), { let res=::alloc::fmt::format( format_args!("Failed to register function `{0}`", "sum"), ); res }, ), ) } } }?; napi::bindgen_prelude::register_js_function( "sum\0", sum_js_function, Some(__napi__sum), ); Ok(fn_ptr) }<".as_ptr().cast(), 3usize, Some(__napi__sum), std::ptr::null_mut(), &mut fn_ptr, ); match c { ::napi::sys::Status::napi_ok=> Ok(()), _=> { Err( ::napi::Error::new( ::napi::Status::from(c), { let res=::alloc::fmt::format( format_args!("Failed to register function `{0}`", "sum"), ); res }, ), ) } } }?; napi::bindgen_prelude::register_js_function( "sum>#[allow(non_snake_case)] #[allow(clippy::all)] unsafe fn sum_js_function( env: napi::bindgen_prelude::sys::napi_env, ) -> napi::bindgen_prelude::Result<napi::bindgen_prelude::sys::napi_value> { let mut fn_ptr=std::ptr::null_mut(); { let c=napi::bindgen_prelude::sys::napi_create_function( env, "sum\0".as_ptr().cast(), 3usize, Some(__napi__sum), std::ptr::null_mut(), &mut fn_ptr, ); match c { ::napi::sys::Status::napi_ok=> Ok(()), _=> { Err( ::napi::Error::new( ::napi::Status::from(c), { let res=::alloc::fmt::format( format_args!("Failed to register function `{0}`", "sum"), ); res }, ), ) } } }?; napi::bindgen_prelude::register_js_function( "sum\0", sum_js_function, Some(__napi__sum), ); Ok(fn_ptr) }<", sum_js_function, Some(__napi__sum), ); Ok(fn_ptr) }
  1. unsafe fn sum_js_function(...) 声明是 unsafe 的,因为它调用了 FFI(外国函数接口)相关代码,这些代码可能会触碰到编译器正常安全检查之外的领域。
  2. napi_env 是一个表示当前 Node.js 环境的句柄。
  3. 在闭包中,napi_create_function 由 napi crate 提供,它是 N-API 的 Rust 绑定。这个函数用于创建一个新的 JavaScript 函数,该函数的名称是 sum(C 风格的字符串,以空字节结尾 >在闭包中,napi_create_function 由 napi crate 提供,它是 N-API 的 Rust 绑定。这个函数用于创建一个新的 JavaScript 函数,该函数的名称是 sum(C 风格的字符串,以空字节结尾 \0),函数指针是 Some(__napi__sum)。<),函数指针是 Some(__napi__sum)。
  4. napi_create_function 返回的是 napi_status 枚举,标明操作是否成功。如果操作成功,Ok(()) 被返回;如果失败,则构建一个错误信息并返回 Err。
  5. ? 操作符用于提前返回错误。 如果前面的调用失败返回 Err,? 将立即将错误传播出当前函数,后续操作不会执行。
  6. register_js_function 可能是另一个在当前环境中注册 JavaScript 函数的帮助器功能(不是 N-API 的一部分,可能是作者自己建立的额外封装)。
  7. 放置到 fn_ptr 的函数指针(napi_value)被返回,这样 JavaScript 端就能拿到并使用这个函数。

第三步

napi-rs 生成 __napi_register__sum_0 函数,在 Node.js 环境中使用 N-API 注册本地模块的功能。整段代码的功能是注册一个名为 sum 的 JavaScript 函数,并关联我们编写的 Rust 函数。

#[allow(clippy::all)] #[allow(non_snake_case)] #[cfg(all(not(test), not(feature="noop"), not(target_family="wasm")))] extern fn __napi_register__sum_0() { napi::bindgen_prelude::register_module_export(None, "sum>#[allow(clippy::all)] #[allow(non_snake_case)] #[cfg(all(not(test), not(feature="noop"), not(target_family="wasm")))] extern fn __napi_register__sum_0() { napi::bindgen_prelude::register_module_export(None, "sum\0", sum_js_function); }<", sum_js_function); }

第四步

napi-rs 生成 __napi_register__sum_0___rust_ctor___ctor 静态变量,用于在 Node.js 原生模块被加载时自动执行 __napi_register__sum_0 函数。这是 Rust 中创建初始化函数的一种方式,用于在动态库加载到应用程序时设置某些状态或执行某些初始化任务。

在深入解析下述代码前,重要的是要知道 Node.js 扩展通常是以 .node 扩展名出现的文件,这些文件实质上是动态链接库(DLL)。Node.js 在运行时会动态地加载这些 .node 文件并执行其中的代码。

#[used] #[allow(non_upper_case_globals)] #[doc(hidden)] #[link_section="__DATA,__mod_init_func"] static __napi_register__sum_0___rust_ctor___ctor: unsafe extern "C" fn() -> usize={ unsafe extern "C" fn __napi_register__sum_0___rust_ctor___ctor() -> usize { __napi_register__sum_0(); 0 } __napi_register__sum_0___rust_ctor___ctor };
  1. #[used]: 这个属性是为了确保链接器在最终的程序中包含这个静态变量,即使它看起来未被使用。
  2. #[allow(non_upper_case_globals)]: 允许这个全局静态变量命名为非大写格式,Rust 的规范是全局变量应该命名为大写格式。
  3. #[link_section="__DATA,__mod_init_func"]: 指定了该静态变量要放置在链接器的哪个段中。在 Mac系统中,__DATA,__mod_init_func 是用来存放模块初始化函数的链接器段。当动态库被加载时,这段里的函数会自动被执行。
  4. static __napi_register__sum_0___rust_ctor___ctor: 定义了一个名为 __napi_register__sum_0___rust_ctor___ctor 的全局静态变量,它是一个函数指针,指向下面定义的 unsafe extern "C" 函数。
  5. unsafe extern "C" fn __napi_register__sum_0___rust_ctor___ctor(): 这是一个实际的函数实现,它将由静态变量引用,并在库加载时执行。此函数调用 __napi_register__sum_0(),执行 Node.js 原生模块的初始化代码。
  6. 函数返回0:通常用于表示成功,这是 Unix 程序的一种传统习惯。

Rust 调用 JavaScript 函数

有时,在我们的应用中,需要从 Rust 发起对 JavaScript 函数的调用,通常这种情况出现在异步操作完成后,例如执行回调函数。

使用

我们以实现一个类似于 Node.js 中的 fs.readFile() 方法为例,但更为简化。其在 JavaScript 中的类型定义如下:

function readFile(path: string, callback: (err: Error | null, data?: string)=> void): void;

使用 napi-rs 可以轻松地用 Rust 语言编写这个函数的实现:

#[napi(js_name="readFile", ts_return_type="void")] pub fn read_file(env: Env, path: String, callback: JsFunction) { // ... }

这里的参数 callback 是 napi::JsFunction 类型,指明了它是 JavaScript 中的一个函数。

那么我们如何调用这个 JavaScript 函数呢?

同步调用

当我们在同一个线程里执行 callback 函数时,事情变得相对简单。我们可以直接利用 JsFunction 提供的 call 方法来同步执行 JavaScript 函数。

fn sync_read_file(path: String) -> Result<String> { let mut file=File::open(path)?; let mut contents=String::new(); file.read_to_string(&mut contents)?; Ok(contents) } #[napi(js_name="readFile", ts_return_type="void")] pub fn read_file(env: Env, path: String, callback: JsFunction) { let contents=sync_read_file(path); match contents { Ok(contents)=> { let js_contents=env.create_string(&contents).unwrap(); let js_null=env.get_null().unwrap(); callback.call(None, &[js_null.into_unknown(), js_contents.into_unknown()]).unwrap(); }, Err(err)=> { let js_error=env.create_error(err.into()).unwrap(); callback.call(None, &vec![js_error]).unwrap(); } } }

此实现为同步调用,在 Rust 中进行文件读取时会导致 JavaScript 线程停下来等待,直至读取操作完成。通常当我们使用 callback 时,希望异步执行此操作,以让 Node.js 主线程保持非阻塞状态。

异步调用

如果我们尝试将这个同步的 readFile 方法内部简单地创建一个新的线程来进行异步处理,会遇到问题:

#[napi(js_name="readFile", ts_return_type="void")] pub fn read_file(env: Env, path: String, callback: JsFunction) { + spawn(move || { let contents=sync_read_file(path); match contents { Ok(contents)=> { let js_contents=env.create_string(&contents).unwrap(); let js_null=env.get_null().unwrap(); callback.call(None, &[js_null.into_unknown(), js_contents.into_unknown()]).unwrap(); }, Err(err)=> { let js_error=env.create_error(err.into()).unwrap(); callback.call(None, &vec![js_error]).unwrap(); } } + }); }

我们需要先回头看一下先前编写的同步调用代码,其中 read_file() 函数的第一个参数是 env: Env,这个参数由 napi-rs 自动提供,而不是由 JavaScript 传递的。此 Env 用于在对应的 JavaScript 环境中创建传递给 callback 的参数,我们使用 create_string() 创建 JavaScript 字符串,使用 env.create_error() 或 get_null() 方法创建 JavaScript 异常。

在多线程环境中,无法直接访问 Env,因为 Node.js 是设计为单线程运行的,你无法在另外一个线程上访问 env: Env。

Node-API 提供了 Threadsafe Function API 来安全地在其他线程上调用 JavaScript 函数。尽管它的实现较为复杂,很多开发者可能还不熟悉如何正确使用它,但 napi-rs 提供了一个更简洁易用的 Threadsafe Function API 封装,我们可以使用这个封装后的版本。

fn sync_read_file(path: String) -> Result<String> { let mut file=File::open(path)?; let mut contents=String::new(); file.read_to_string(&mut contents)?; Ok(contents) } #[napi(js_name="readFile", ts_return_type="void")] pub fn read_file(path: String, callback: JsFunction) { let tsfn: ThreadsafeFunction<Result<String>, ErrorStrategy::CalleeHandled>=callback .create_threadsafe_function(0, |ctx: ThreadSafeCallContext<std::prelude::v1::Result<String, Error>>| { match ctx.value { Ok(value)=> { let js_contents=ctx.env.create_string(&value).unwrap(); Ok(vec![js_contents]) }, Err(err)=> { Err(err) }, } }).unwrap(); spawn(move || { let contents=sync_read_file(path); tsfn.call(Ok(contents), ThreadsafeFunctionCallMode::Blocking); }); }

当在 JavaScript 中执行 readFile() 方法,Rust 会开启一个新的线程来处理 IO 操作,避免阻塞 JavaScript 的主线程。这样,JavaScript 主线程便能无干扰地继续处理其他任务。一旦 Rust 完成文件内容的读取,它就会在该线程上触发 callback,执行回调函数。

参考资料

  • Working with JavaScript functions
  • N-API ThreadSafeFunction
  • napi-rs ThreadsafeFunction


作者:聪聪正在递归下降
链接:https://juejin.cn/post/7322288075850039359
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

、HTML简介

1.HTML是什么?

HTML:htper text markup language超文本标记(标签)语言

由各种标签组成,用来制作网页,告诉浏览器如何显示页面

2.作用

  • 制作网页,控制网页和内容的显示
  • 插入图片、音乐、视频、动画等多媒体
  • 通过链接来检索信息
  • 使用表单获取用户的信息,实现交互

3.版本

w3c:world wide web consortium万维网联盟,制定web技术相关标准和规范的组织,HTML技术hi由w3c制定的标准

两个版本:HTML4.0.1、HTML5.0-----通常H5

官网:http://www.W3shcool.com.cn

4.扩展名

HTML文档是以.html或.htm结尾

二、HTML文档结构

1.基本结构

1.1简介

  • HTML标签是由尖括号括起来的关键词,如,通常是成对出现的,如<html></html>
  • <html>为根标签,包含: <head>头部和<body>主体部分
  • 头部提供关于网页的相关信息,如标题、文档类型、字符编码、关键字等摘要信息
  • 主体部分提供网页的显示内容,真正显示在页面中的内容
  • 合理地进行缩进
  • 标签名不区分大小写,但是一般要用小写

1.2.开发工具

记事本notepad、sublime、Notepad++、Dreamweaver、VScode、Webstorm等

使用步骤:

  1. 新建文件(cltr+N),然后保存(ctrl+s),指定扩展名为.html
  2. 编写HTML代码
  3. 在浏览器中打开文件

使用技巧:

  • 先保存再写代码,否则代码无颜色提示
  • 创建一个文件夹,用于保存所有的网页内容,将文件夹拖拽到sublime中,便于管理
  • 显示/隐藏侧边栏方式1:查看–>侧边栏–>显示/隐藏侧边栏方式2:ctrl+K紧接着按B
  • 显示多栏方式1:查看–>布局–>列数:2列方式2:Alt+shift+2

1.3浏览器

常见的浏览器:IE浏览器微软、chrome谷歌浏览器、fifirefox火狐、safari苹果

浏览器的作用是读取html文件,并以网页的形式来显示

浏览器不会直接显示html标签,而是使用标签来解释网页的内容

2.标签

2.1标签的组成

一个完整的html标签的组成:

<标签名 属性名="属性值">内容</标签名>

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>标签</title>
	</head>
	<body  bgcolor="red" text="blue">
		html从入门到精通!
    </body>
</html>
12345678910

属性值要用双撇号括起来,一般用双引号

2.2标签的分类

根据标签是否关闭,分为,关闭型和非关闭型

  • 关闭型:有结束标签,即标签成对出现
<html></html>
<head></head>
<title></title>

非关闭型:没有结束标签

<meta>
<br>
<h1>....<h6>

根据标签是否独占一行,分为块级标签和行级标签

块级标签:显示为块状,独占一行

<h1>大家好</h1>
<hr>

行级标签:在行内显示,可与其他内容在同一行显示

<span></span>

2.3注释

注释在浏览器中不会显示,是用来标注解释html语句,但通过查看源代码的方式可以看到

语法:

<--注释内容-->

2.4实体字符

也称为特殊字符,用于显示一些特殊符号,如<>&空格等

语法:

<&实体字符的名称>

2.5文档类型

在html文档的第一行,使用<!DOCTYPE html>

声明HTML文档的类型用来告诉浏览器页面的文档嘞型,用来制定html版本的规范

目前基本上最常用的html5

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	
</body>
</html>
12345678910

三\常用标签

3.1基本标签

  • 块级标签\亲啊后有明显的间隔 |
    | h1…h5 | 标题标签 | 按照h1到h6逐渐变小.块级标签 |
    | | | |
    | | | |


  • 三、常用标签

1.基本标签

1.1 有序列表
ol:ordered listli:list item默认使用阿拉伯数字、从1开始标记,可以通过属性进行修改
· type属性:设置列表的符号标记、取值;数字1(默认)、字母(a或A)、罗马数字(i或I) · start属性:设置起始值,值必须是数字
1.2 无序列表
ul:unodered list
li:list item
默认情况下使用实心圆表作为符号标记,可以通过属性进行修改
· type属性:设置列表的符号标记、取值:disc实心圆(默认)、circle空心圆、square正方形、none不 显示项目符号
1.3 定义列表
dl:definition list
dt:definition title
dd:definition description
1.4 水平线标签
hr:horizontal
常用属性:
· color:颜色

两种方式:

颜色名称:如red、green、blue、white、black、pink、orange等

16进制的RGB表示法:Red、Green、Blue用法:#RRGGBB 每种颜色的取值范值0-255,转换为16 进制00-FF

如: #FF0000 红色 #00FF00绿色 #0000FF蓝色 #FFFFFF白色、#CCCCCC #FF7300桔色

· size:粗细,数值

· width宽度

两种写法:

? 像素:绝对值(固定值)

? 百分比:相对值,相对于水平线标签所在父容器宽度的百分比

· align对齐

? 取值:center居中 left right
1.5图像标签
img:image
常见的图片格式:.jpg .png .gif .bmp
常见的属性:
· src:source指定图片的路径(来源),必选叁数

如果图片与html源代码在同一个文件夹中,可以直接在src中写图片名称即可

习惯上,我们会将多个图片与html代码文档分别放在同一个文件夹project中的不同目录下,此时需要 在src中指定图片的路径为相对路径

路径的分类:

? · 相对路径

? 表示: ./当前路径
…/当前位置的上一级文件夹

? 提示:…/image

? · alt:当图片无法显示时显示的提示信息

? · title:当鼠标放到图片上时显示的提示信息

? · width和 height:设置图片的宽度和高度
默认图片以原始尺寸显示

? 如果只设置其中一个,则另一个会按比例缩放

? 如果同时设置宽和高,可能导致图片变形

? 两种写法:

? 像素:绝对值(固定值)

? 百分比:相对值,相对于父容器的尺寸的百分比
2.其他标签

为了更好语义化
3.头部标签
· meta定义网页的摘要信息,如字符编码,关键词,描述,作者等
· title定义网页的标题
· style定义内容css样式
· link引用外部css样式
· script定义或引用脚本
· base定义基础路径
默认以当前页面文件所在的位置为相对路径参照
4.标签嵌套
一个标签中嵌套另外一个标签
标签不能乱嵌套
浏览器渲染后显示的页面代码与编码时有所不同
chrome浏览器提供的开发工具:帮助开发人员查看和调试页面的
如何打开:
· Elements:从浏览器的角度来看页面,浏览器渲染页面时内部的结构
· console:控制台,显示各种警告和错误信息
· network:查看网络请求信息,浏览器向服务器请求了哪些资源,资源大小,
加载资源所消耗的时间

四、超链接
1.简介
使用超链接可以从一个页面跳转到另外一个页面,实现页面之间导航
当鼠标移动到超链接文本或图片时,鼠标箭头会变成一只小手
超链接有三种类型:
普通链接/页面间的链接,跳转到另一个页面 锚链接:链接到锚点(链接到同一个页面的指定位置) 功能链接:实现特殊功能(发邮件,下载)
2.基本用法
使用 标签来创建超链接
语法格式:

常用属性:
href:链接地址或路径,链接地址

world

链接文本或图片

1 2 3 4 5 1 target:链接打开的位置,取值

路径分类:
绝对路径 以根开始的路径
file:///D:/software/b.html https://www.baidu.com/img/bd_logo1.png
相对路径 相对于当前页面文件所在的路径,不是以根开始的路径 ./ 当前路径 …/ 当前位置上一级目录

3.锚链接
3.1简介
点击链接后跳转到某一个页面的指定位置(锚点anchor)
锚链接的分类:
页面内的锚链接 页面间的锚链接
3.2 页面内的锚链接
步骤:

  1. 定义锚点(标记)
  2. 链接锚点
    _self 自身,当前,默认值 _blank新的,空白的 _parent父层框架 _top顶层框架
    目标位置
    1 2 3 4
    1

3.3 页面间的锚链接

4.功能链接
5.URL
5.1 简介
URL:Uniform Resource Locator 统一资源定位器,用来定位资源所在的位置,最常见的就是网址

5.2 组成
一个完整的URL由8个部分组成:
协议:prococol 如 http:超文本传输协议,用来访问WEB网站Hyper text Transfer protocal https:更加安全的协议 SSL安全套接子层 ftp文件传输协议,用来访问服务器上的文件,实现文件的上传和下载File Transfer protocol file:文件协议,用来访问本地文件 主机名hostname服务器地址或服务器Netbios名称,如www.baidu.com ftp://10.255.254.254 端口:port位于主机名的后面,使用冒号进行分隔 不同的协议使用不同的端口,如http使用80端口,https使用的443端口,ftp使用20和21 如果使用的是默认端口,则端口可以省略 如果使用的不是默认端口,则必须指定端口http://59.49.32.213:7070/ 路径:path目标文件所在的路径结构,如:www.baidu.com/img/ 资源resource要访问的目标文件,如bd_logo1.png 查询字符串:query string 也称为参数 在资源后面使用?开头的一组名称/值
链接文本
链接文本
https://www.baidu.com/img/bd_logo1.png?name=tom&age=2&sex=male https://www.w3school.com.cn/html/html_quotation_elements.asp file:///C:/Users/Administrator/Desktop/project/code/09.%E5%B8%B8%E7%94%A8%E6%A0%87%E7%A D%BE3.html http://www.sxgjpx.net/ ftp://10.255.254.253/
1
1
1 2 3
4 5
名称和值之间以=分隔,多个之间用&分隔,如:name=tom&age=2&sex=male 锚点anchor,在资源后面使用#开头的文本,如#6 身份认证authentication,指定身份信息,如:ftp://账户:密码@ftp.bbshh010.com
五、表格
1.简介
表格是一个规则的行列结构,每个表格是由若干行组成,每行由若干个单元格组成
table row column
2.基本结构
2.1 table标签
用来定义表格
常用属性:
border:表格边框 默认为0 width/height:宽度/高度 bordercolor:边框的颜色 align:对齐方式,取值:left(默认) center居中 right居右 bgcolor:背景颜色 background:背景图片 cellspacing间距:单元格与单元格之间的距离 cellpadding边距:单元格中的内容到边界之间的距离
2.2 tr标签
用来定义行:table row
常用属性:
align:水平对齐 取值:left(默认) center right valign垂直对齐 取值:top center bottom bgcolor:背景颜色 background:背景图片
2.3 td标签
用来定义单元格,table data
常用属性:align、valign、bgcolor、background
注意:表格必须是由行组成,行必须由单元格来组成,数据必须放到单元格中
3.合并单元格
合并单元格也称为单元格的跨行跨列
两个属性:
rowspan 设置单元格所跨的行数 colspan 设置单元格所跨的列数
步骤:

  1. 在跨越的单元格中设置rowspan/colspan属性 2. 将被跨越的单元格删除
    必须要保证每行的实际列数是相同的,否则表格可能会出错乱
    4.高级标签
    4.1caption标签
    表格的标题标签
    4.2thead标签
    表格的头部table head
    4.3th标签
    表格的头部标题table head title
    一般用在thead中,设置头部的标题,替代td标签,与td的区别,th中的文本会加粗且居中显示
    4.4tbody标签
    表格的主体table body
    4.5tfoot标签
    表格的底部table foot




六、表单
1.简介
表单是一个包含若干个表单元素的区域,用于获取琐类型的用户数据

表单元素是允许用户在表单输入信息的元素,如文本框、密码框、单选按钮、复选框、下拉列表、按钮等
2.表单结构
2.1表单语法

1

2.2form标签
用来定义表单,可以包含多个表单元素
常用属性:
action:提交数据给谁处理,即处理数据的程序,默认为当前页面 method:提交数据的方式或方法,取值:get(默认),post get和post的区别: get:以查询字符串的形式提交,在地址栏中能看到,长度有限制,不安全 post以表单数据组的形式进行提交,在地址栏中看不到,长度无限制,安全 enctype(encode type)编码类型:提交数据的编码,取值:application/X-www-form-urlencoded(默 认)、multipart/form-data(文件上传)
3.表单元素
大多数的表单元素都是使用 标签来定义的,通过设置属性type来定义不同的表单元素

1

3.1单行文本框
常用属性:
·name名称,很重要,如果没有定义name属性,则该表单元素的数据是无法提交的

·value初始值

·size显示宽度

·maxlength:大字符数,默认是没有限制

·readonly只读:readonly=“readonly”,可简写readonly,即只写属性名

·disabled禁用:disabled=“disabled”, 可简写disabled完全禁用

表单元素被提交的两个条件,1.有name属性2.非disabled

3.2 单选按钮
常用属性:

·name名称:多个radio的name属性必须相同,才能实现互斥(单选)

·value值

·checked:是否被选中,两种状态,选中,未选中 checked=“checked” 简写 checked

3.3 复选框
常用属性与单选按钮radio类似

3.4 文件选择器
常用属性:

·name:名称

·accept设置可选择的文件类型,用来限制上传的文件类型

使用MIME格式字符串对资源类型进行限制

常见的MIME类型:

·纯文本:text/plain text/xml text/html

· 图像:image/png image/jpeg image/gif

4.特殊表单元素

4.1下拉列表

select常用属性:

·name名称

·size行数,同时显示多个选项

·multiple允许同时选择多个

option常用属性:

·value选项值

·selected设置默认选中项

optgroup常用属性:

·label分组的标签

4.2文本域

·name名称

·rows行数

·cols列数


5、其他标签

5.1 label标签

为表单元素提供标签,当选中label标签中的文本内容时会自动将光标切换到与之相关联的表单元素。

常用属性:

·for必须将该属性值设置为与相关联的表单元素的Id属性值相同。

注:几乎所有HTML标签都具有id属性,且id值必须唯一。

5.2 button标签

也表示按钮,与input按钮类似

语法:

1按钮文字或图像

常用属性:

·type按钮的类型,取值: submit(默认)、reset、button

5.3 fieldset和legend标签

fieldset标签,对表单元素进行分组

legend标签,对分组添加标题

七、内嵌框架
1、简介

使用iframe可以在一个页面中引用另一个页面,实现复用、灵活

2、基本用法

语法:

1

常用属性:

· src:引用的页面

· width/height宽度/高度 ,像素或百分比

· frameborder是否显示边框,取值:1(yes) 0(no)—默认

· scrolling是否显示滚动条,取值:yes no auto

· name属性 为框架定义名称

3、在框架中打开链接

1

2

3链接的文本或图像

八、HTML5简介

1、发展

W3C于1992年12月发布了HTML4.0.1标准
W3C于2014年10月发布了HTML5标准

2、特点

· 取消了过时的标签,如font、center等,它们仅具有展示外观的功能

· 增加了一些更具有语义化的标签,如header、footer、aside等

· 增加了一些新功能标签,如canvas、audio、video

· 增加了一些表单控件,如email、date、time、url、search等

· 可以直接在浏览器中绘画(canvas),无需flash

· 增加了本地存储的支持

3、兼容性

http://caniuse.com

提供了各种浏览器版本对HTML5和CSS规范的支持度

九、HTML5新增内容
1、结构相关的标签

用来进行页面结构布局,本身无任何特殊样式,需要使用CSS进行样式设置

· article定义一个独立的内容,完整的文章

· section定义文档的章节、段落

· header文章的头部、页眉、标题

· footer文章的底部、页脚、标注

· aside定义侧边栏

· figure图片区域

· figcaption为图片区域定义标题

· nav定义导航菜单

结构标签只是表明各部分的角色,并无实际的外观样式,与普通div相同

2、语义相关的标签
2.1 mark标签
标注,用来突出显示文本,默认添加黄色背景
2.2 time标签
定义日期和时间,便于搜索引擎智能查找
2.3 details和 summary标签
默认显示summary中的内容,点击后显示details中的内容
注:并不是所有的浏览器都兼容,chrome、opera支持、Firefox、IE浏览器不支持
2.4 meter标签
计数仪,表示度量
常用属性:

· max定义大值,默认为1

· min定义小值,默认为0

· value定义当前值

· high定义限定为高的值

· low定义限定为低的值

· optimum定义佳值

规则:

  1. 如果optimum大于high,则表示值越大越好

当value大于high时为绿色

当value在low与high之间时为黄色

当value小于low时为红色

  1. 如果optimum小于low,则表示值越小越好

当value小于low时为绿色

当value在low与high之间时为黄色

当value大于high时为红色

  1. 当optimum介于low和high之间,则表示值在low和high之间好当value在low与high之间时显示绿色,否则显示黄色

2.5 progress标签
进度条,表示运行中的进度
常用属性:

· value定义当前值

· max定义完成的值

3.表单相关
3.1 新增表单元素
新增以下type类型:

· email接收邮箱

· url接收URL

· tel接收电话号码,目前仅在移动设备上有效

· search搜索文框

· number/range接收数字/数字滑块,包含min,max,step属性

· date/month/week/time/datetime日期时间选择器,兼容性不好

· color颜色拾取

作用:

· 具有格式校验的功能

· 可以与移动设备的键盘相关联

3.2新增表单属性
form标签的属性:

· autocomplete是否启动表单的自动完成功能, 取值:on(默认)、o?

· novalidate提交表单时不进行校验,默认会进行表单校验

3.3 新增表单元素的属性
新增表单元素属性:input/select/textarea等

· placeholder提示文字

· required是否必填

· autocomplete是否启用该表单元素的自动完成功能

· autofocus设置初始焦点元素

· pattern使用正则表达式(RegExp后面会讲解),进行数据校验

· list使文本元素具有下拉列表的功能,需要配合datalist和option标签一起使用

· form可以将表单元素写在form标签外面,然后通过该属性关联指定的表单

4、多媒体标签
4.1audio标签
在页面中插入音频,不同的浏览器对音频格式的支持不一样
audio常用属性:

· src音频文件的来源

· controls是否显示控制面板,默认不显示

· autoplay是否自动播放,默认不自动播放

· loop是否循环播放

· muted是否静音

· preload是否预加载,取值:none不预加载、auto预加载(默认)、metadata只加载元数据

如果设置了autoplay属性,则该属性无效

可以结合source标签使用,指定多个音频文,浏览器会检测并使用第一个可用的音频文件

4.2 video标签
在页面中插入视频,不同的浏览器对视频格式的支持不一样
用法与audio标签基本相同,增加属性:

· widht/height视频播放器的宽度/高度

· poster在视频加载前显示的图片

案例1hello.html

<html>
	<body>
		<tiele>HTML技术</tiele>
	</body>
	<body>
		大家好,欢迎学习html技术!
	</body>
</html>1234567

效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h271e4v6-1593240920352)(C:\Users\lenovo\Desktop\新建文件夹\静态网页2\案例\result\案例1.png)]

案例2标签的组成.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>标签</title>
</head>
<body text="blue">
	标签的组成
	<br>
	html从入门到精通!
	<hr>
	<h1>标签的分类</h1>
	<hr>

	<h2>标签的分类</h2>
	<hr>

	<h6>标签的分类</h6>
	<hr>

	<span>哈哈</span>嘿嘿
	
</body>
</html>1234567891011121314151617181920212223

效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jx6zJE1P-1593240920354)(C:\Users\lenovo\Desktop\新建文件夹\静态网页2\案例\result\案例2.png)]

案例3实体字符.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	图书:<<HTML从入门到精通<<
	<hr>

	北京      上海      广州
	<hr>

	在HTML中用<表示<小于号
	<hr>

	“HTML语言” 或 &qout;HTML语言&qout;
	<hr>

	版权所有? 2000-2020 高教培训
	<hr>

	×关闭符号
</body>
</html>123456789101112131415161718192021222324

效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nuFLl3hm-1593240920355)(C:\Users\lenovo\Desktop\新建文件夹\静态网页2\案例\result\案例3.png)]

(剩下的下期出)

原文链接:https://blog.csdn.net/WanXuang/article/details/106982782?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160513384519724835852804%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=160513384519724835852804&biz_id=&utm_medium=distribute.pc_search_top_result.none-task-code-2~all~top_position~default-1-106982782-12.nonecase&utm_term=html

作者:WanXuang

出处:从CSDN

MACSS(Sentence Modular And Compound Structure)是一种将 CSS 代码分解为相互关联的独立模块的方法。它可以提高 CSS 代码的可重用性、可维护性和可读性。

SMACSS 的优势

* 可重用性:使用模块可以提高 CSS 代码的可重用性。

* 可维护性:结构化代码简化了维护。

* 可读性:清晰的模块结构易于阅读和理解。

SMACSS 的核心概念

1. 句法 (Sentence)

* 完整的 CSS 语句。

* 应该表示一个可重用的独立功能或外观。

2. 模块 (Module)

* 组织 CSS 规则的组。

* 每个模块应表示界面设计中的特定概念或功能。

3. 组合 (Compound)

* 简单的 CSS 选择器,包含多个元素。

* 应用于将多个元素组合成更复杂的结构。

工具和集成

* 各种工具可用于使用 SMACSS。

* 许多 IDE 和 CSS 管理工具集成了 SMACSS 功能。

使用 SMACSS 的优点

* 提高 CSS 代码的可重用性。

* 提高 CSS 代码的可维护性。

* 提高 CSS 代码的可读性。

结论

SMACSS 是一种强大的 CSS 组织方法,可以提高 CSS 代码的可重用性、可维护性和可读性。它是现代 web 开发中使用最广泛的组织方法之一。