库
| url | ramark |
|---|---|
| https://animate.style/ | 动画 |
| Three.js – JavaScript 3D Library (threejs.org) | 3D |
| https://github.com/mattboldt/typed.js | 打字机效果 |
| parallax.js (wagerfield.com) | 视差js |
文章
JavaScript 教程 - 网道 (wangdoc.com)
大佬个人博客
VuePress Plume 主题作者:鹏展博 | 鹏展博
防抖节流:防抖节流 | Bing🐣
压缩 HTML
在线工具
工具名称 功能 链接 HTML Compressor 支持删除注释/压缩JS/CSS htmlcompressor.com Minify Code 一键压缩HTML+JS+CSS minifycode.com 本地工具
Node.js工具链
npm install html-minifier terser clean-css -g压缩命令:
html-minifier input.html --remove-comments --collapse-whitespace --minify-js --minify-css -o output.html--minify-js:调用Terser压缩JS--minify-css:调用clean-css压缩CSS
构建工具集成
- Webpack:使用
html-minimizer-webpack-plugin+terser-webpack-plugin - Gulp:通过
gulp-htmlmin和gulp-terser组合
- Webpack:使用
通过chrome控制台发起请求
注意:http只能请求http,https只能请求https
也可以在chrome控制台内发送请求权输入以下代码回车可以查看是否存在跨域问题
POST
let xhr = new XMLHttpRequest();
xhr.open('POST', 'https://zsfwpt.yazhou-bay.com/port/pc/rm/space/listSpaceForImportant');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.responseType = "application/json";
// let jsonData = {pageNumber:1, pageSize:10};
let jsonData = {};
xhr.send(JSON.stringify(jsonData));
xhr.onload = function(e) {
let xhr = e.target;
// console.log(xhr.responseText);
console.log(JSON.parse(xhr.responseText));
}
- 参数体是json
let xhr = new XMLHttpRequest();
xhr.open('POST', 'https://zsfwpt.yazhou-bay.com:8802/api/getUser');
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
xhr.responseType = "application/json";
let jsonData = {pageNumber:1, pageSize:10};
xhr.send(JSON.stringify(jsonData));
xhr.onload = function(e) {
var xhr = e.target;
console.log(JSON.parse(xhr.responseText));
}
- 使用
FormData格式的参数,参数中包含file的测试
let formData = new FormData();
// 添加普通文本参数
formData.append('sys', 'zszy');
formData.append('type', 'PARK_THUMB_MAIN');
formData.append("rid", "underfined");
// 添加文件参数
formData.append('file', new Blob(['image content'], { type: 'image/png' }), "avator.png");
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://zsfwpt.yazhou-bay.com:8802/file-api/upload');
// 设置请求头(不需要手动设置Content-Type,FormData会自动设置)
// xhr.setRequestHeader('Content-Type', 'multipart/form-data');
// 如果有其他需要的请求头,也可以在这里设置
xhr.responseType = "application/json";
xhr.send(formData); // get请求send(null)或“a=1&b=2”
xhr.onload = function(e) {
var xhr = e.target;
console.log(JSON.parse(xhr.responseText));
}
GET
// get请求xhr.send(null)或“a=1&b=2”
https://zsfwpt.yazhou-bay.com:8802/file-api/img/164fe1bb7bd14e25970075f85dafce34
https://zsfwpt.yazhou-bay.com:8802/api/getUser
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://zsfwpt.yazhou-bay.com:8802/file-api/img/164fe1bb7bd14e25970075f85dafce34');
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
xhr.responseType = "application/json";
xhr.send(null);
xhr.onload = function(e) {
var xhr = e.target;
console.log(xhr.responseText);
}
// 获取所有的 img 元素
let imgElements = document.getElementsByTagName('img');
let imgElement;
// 遍历 img 元素
for (var i = 0; i < imgElements.length; i++) {
// 获取当前 img 元素的 src 属性
var src = imgElements[i].getAttribute('src');
// 判断是否符合条件(这里使用一个假设的条件作为示例)
if (src === 'http://zsfwpt.yazhou-bay.com:8802/file-api/img/1953414320d6493a987f0f94963babc7') {
// 找到目标元素,进行操作
console.log('找到目标元素:', imgElements[i]);
imgElement = imgElements[i];
break; // 如果只需要找到一个元素,找到后可以跳出循环
}
}
this
函数中有this关键字的函数,被称为构造函数,例如:
function Fubar(foo, bar) {
if (!(this instanceof Fubar)) {
return new Fubar(foo, bar);
}
this._foo = foo;
this._bar = bar;
}
// 由于做了 instanceof 判断,所以可以不用 new 关键字声明对象
Fubar(1, 2)._foo // 1
(new Fubar(1, 2))._foo // 1
JSON Vs Form-data
JSON
Content-Type: application/json复杂数据结构:JSON 非常适合传送具有复合结构的数据,例如列表或嵌套对象。
API 交互:在构建 RESTful API 时,JSON 几乎成为了标准选择,原因在于它的可读性和结构化特征使得开发者更容易创建和维护 API。
Form-data
Content-Type: multipart/form-data文件上传:Form-data 是处理文件上传的首选方法,尤其在 Web 表单中,需要同时提交文件和数据时,Form-data 展现出了其独特优势。
传统 Web 表单:许多基于 HTML 表单的传统 Web 应用倾向于使用 Form-data 方式提交数据,因为这种方式不需要额外的 JavaScript 代码即可直接与表单元素交互。
选择 JSON 还是 Form-data,很大程度上取决于你的具体需求:
- 如果你需要传送简单或结构化的数据给服务器,而不涉及文件上传,那么
JSON可能是更优的选择。 - 如果你的场景中需要上传文件,尤其是在 Web 表单中,
Form-data则无疑更为合适。 - 对于需要同时处理文件和数据的情况,
Form-data提供了一套完善的解决方案。
JS原生加载事件
油猴脚本中的 IIFE 会在脚本加载时立即执行
// 这个函数会立即执行 // 标准 IIFE 写法 (function() { xxx })() // OR !function() { xxx }(); // 各种有效的 IIFE 写法 +function(){}(); -function(){}(); ~function(){}(); void function(){}(); 0,function(){}();(function() { xxx })()最标准和最常用的 IIFE(立即执行函数表达式)写法。!function() { xxx }()使用逻辑非操作符,将函数声明转换为函数表达式。这是因为 JavaScript 引擎在解析代码时,函数声明需要在全局作用域中,而用!(或其他运算符)将其变为表达式后,JavaScript 将其视为表达式。function() { xxx }()语法错误,直接尝试立即执行函数声明。报错SyntaxError: Function statements require a function name。
DOMContentLoaded事件DOMContentLoaded事件在HTML文档被完全加载和解析完成时触发,但不需要等待样式表、图像和子框架的完成加载。这个事件适用于当你需要在文档结构加载完成后立即执行一些代码,而无需等待所有资源的加载。document.addEventListener('DOMContentLoaded', function() { console.log('DOM fully loaded and parsed'); // 这里可以安全地操作DOM元素 });load事件load事件在页面的所有资源(如样式表、图像和子框架)都完全加载完成后触发。如果你需要确保所有外部资源都加载完毕后再执行某些操作,使用load事件。window.addEventListener('load', function() { console.log('All resources finished loading!'); // 这里可以操作依赖于外部资源的功能 });
WebSocket
通常情况下,客户端可以主动向服务端发送消息,但服务端并不能主动向客户端发送消息,使用WebSocket技术就可以让服务端主动向客户端发送消息:如服务端要处理的长时间任务,主动给客户端发送执行状态进度信息等...
websocket实现服务端主动给客户端推送消息 - Mr沈 - 博客园 (cnblogs.com)
uniapp
招商银行聚合支付
uniapp小程序微信招商银行聚合支付_招行聚合 拉起微信支付-CSDN博客
if
在 if(变量) 中,只有假值(如 false、0、""、null、undefined、NaN)会使 if 条件判断为 false。其他任何值(包括对象、数组、非零数字、非空字符串等)都会使条件判断为 true。
N-API
获取js端传入的参数
这部分代码并不是固定写法,但它是 N-API 中处理函数参数的一种标准用法,可以根据实际需求进行调整。这段代码的作用是从 JavaScript 调用中获取参数,并检查参数是否符合预期。下面是它的关键点以及可调整的地方:
1. 固定部分(必须遵守的流程)
napi_get_cb_info:- 这是获取函数调用信息的核心方法,用于提取 JavaScript 调用时传递的参数。
- 参数
argc用来表示期望接收的参数个数,同时返回实际接收到的参数个数。 - 参数
args是一个数组,用于存储接收到的参数。
- 错误检查(
status != napi_ok):- 每次调用 N-API 函数时,都应该检查返回的
napi_status是否为napi_ok,以确保调用成功。 - 如果失败,可以通过
napi_throw_error抛出异常。
- 每次调用 N-API 函数时,都应该检查返回的
**2. **可调整部分
以下部分可以根据需求灵活调整:
(1) 参数个数 (argc)
size_t argc = 1;
如果您需要接收多个参数,可以将
argc改为需要的参数个数。例如:
size_t argc = 2; // 函数需要两个参数 napi_value args[2];
(2) 参数检查和类型验证
目前的写法检查了参数是否为字符串:
napi_valuetype valuetype;
napi_typeof(env, args[0], &valuetype);
if (valuetype != napi_string) {
napi_throw_type_error(env, nullptr, "Expected a string argument");
return nullptr;
}
如果您需要支持其他类型参数,可以根据需求添加类型检查:
if (valuetype != napi_number) { napi_throw_type_error(env, nullptr, "Expected a number argument"); return nullptr; }
(3) 错误处理
当前的错误处理是通过 napi_throw_error 抛出异常,您也可以改为返回特定的错误值。例如:
if (status != napi_ok) {
napi_value error;
napi_create_string_utf8(env, "Failed to parse arguments", NAPI_AUTO_LENGTH, &error);
return error;
}
JavaScript 端可以通过返回的值判断错误,而不是捕获异常。
(4) 处理额外的参数
如果接收到的参数多于预期,可以忽略或处理。例如:
if (argc > 1) {
printf("Extra arguments provided, ignoring them.\n");
}
3. 总结模板
以下是一个稍微通用的模板,适合处理多个参数和多种类型:
static napi_value ExampleFunction(napi_env env, napi_callback_info info) {
size_t argc = 2; // 假设需要接收两个参数
napi_value args[2];
napi_status status;
// 获取参数
status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
if (status != napi_ok || argc < 2) {
napi_throw_error(env, nullptr, "Expected two arguments");
return nullptr;
}
// 检查第一个参数是否为字符串
napi_valuetype valuetype;
napi_typeof(env, args[0], &valuetype);
if (valuetype != napi_string) {
napi_throw_type_error(env, nullptr, "First argument must be a string");
return nullptr;
}
// 将字符串赋值给静态属性 g_filePath
// 如果已经有静态属性:static std::string g_filePath = "";
g_filePath = std::string(buffer);
// 检查第二个参数是否为数字
napi_typeof(env, args[1], &valuetype);
if (valuetype != napi_number) {
napi_throw_type_error(env, nullptr, "Second argument must be a number");
return nullptr;
}
// 处理参数(这里只是示例)
size_t str_len;
napi_get_value_string_utf8(env, args[0], nullptr, 0, &str_len);
char* buffer = new char[str_len + 1];
napi_get_value_string_utf8(env, args[0], buffer, str_len + 1, &str_len);
double number;
napi_get_value_double(env, args[1], &number);
printf("String: %s, Number: %f\n", buffer, number);
delete[] buffer;
// 返回结果
napi_value result;
napi_get_boolean(env, true, &result);
return result;
}
4. 总结
这部分代码不是完全固定的写法,而是一个灵活的模式。主要步骤(获取参数、检查参数、错误处理)是必要的,您可以根据需求调整接收的参数个数、类型检查、错误处理方式以及返回值。
箭头函数、普通函数、this
假设现在有一个父组件中有一个方法:
title = 'parentTitle'
function showTitle(){
console.log(this.title)
}
有一个子组件有一个属性,接收一个回调方法:
callback: () => void
父组件中代码:包含了子组件,需要子组件来触发父组件的showTitle方法,则方法内的this根据定义时不同,指向也不同:
// 第一种,this指向调用处环境,也就是子组件,子组件没有`title`属性,非严格模式下undefined,严格模式下报错。
callback = showTitle
// 第二种,箭头函数,this指向定义时候的环境,也就是父组件环境,此时正确打印出`title`。
callback = () => { showTitle() }
ES6
删除对象属性的方法
以下是三种主要的方法:使用delete操作符、使用Reflect.deleteProperty方法以及利用解构赋值。
使用 delete 操作符
delete 操作符用于删除对象的某个属性。如果没有指向这个属性的引用,那它最终会被释放。其语法如下:delete object.property; delete object['property'];示例:
const car = { color: 'blue', brand: 'Ford' }; delete car.brand; // 或者 delete car['brand']; console.log(car); // {color: 'blue'}需要注意的是,delete 操作符不能删除变量和原型链中的属性。
使用 Reflect.deleteProperty 方法
Reflect.deleteProperty 方法等同于 delete 操作符,但它提供了更安全的删除方式,并且会返回一个布尔值,表示删除是否成功。其语法如下:Reflect.deleteProperty(object, property);示例:
const obj = { page: 1, size: 10, sort: 'id', order: 'desc', model: {}, ext: [], other: null }; Reflect.deleteProperty(obj, 'other'); console.log(obj); // {page: 1, size: 10, sort: 'id', order: 'desc', model: {}, ext: []}如果删除成功,或者被删除的属性不存在,返回 true;删除失败,返回 false。
利用解构赋值
解构赋值可以用于批量删除对象中的多个属性。其语法如下:let { property1, property2, ...newObject } = object;示例:
const obj = { page: 1, size: 10, sort: 'id', order: 'desc', model: {}, ext: [], other: null }; const { sort, order, other, ...newObj } = obj; console.log(newObj); // {page: 1, size: 10, model: {}, ext: []}这种方法不会改变原始对象,而是创建一个新的对象。
通过以上三种方法,可以根据具体需求选择合适的方式来删除对象的属性。无论是单个删除还是批量删除,都能有效地管理对象的属性。
stream
List -> Map
const list = [
{ id: 1, name: '项目A', other: '...' },
{ id: 2, name: '项目B', other: '...' },
{ id: 3, name: '项目C', other: '...' }
];
一、使用 Map 构造函数
返回<key,对象>的情况(类型匹配名称)
const dictMap = new Map(dictList.map(item => [item.id, item]));
console.log(dictMap);
// Map(3) {
// 1 => { id: 1, name: '项目A' },
// 2 => { id: 2, name: '项目B' },
// 3 => { id: 3, label: '项目C' }
// }
二、使用 Object(如果需要普通对象)
// 转换为普通对象
const objMap = list.reduce((accumulator, currentValue) => {
accumulator[item.id] = { value: currentValue.id, label: currentValue.name };
return accumulator;
}, {});
console.log(objMap);
// {
// 1: { value: 1, label: '项目A' },
// 2: { value: 2, label: '项目B' },
// 3: { value: 3, label: '项目C' }
// }
三、使用 for...of 循环
const map = new Map();
for (const item of list) {
map.set(item.id, { value: item.id, label: item.name });
}
四、如果需要数组形式(常见于 Select 组件)
const options = list.map(item => ({
value: item.id,
label: item.name
}));
console.log(options);
// [
// { value: 1, label: '项目A' },
// { value: 2, label: '项目B' },
// { value: 3, label: '项目C' }
// ]
这里的对象字面量 { ... } 外面包裹了一个括号 (),是因为箭头函数中的大括号 {} 有两种含义:
- 函数体:包含多条语句
- 对象字面量:创建对象
如果直接使用
item => { value: item.id, label: item.projectName }
其中的 {} 会被 JavaScript 解析器为函数体,而不是对象。其中的 value: item.id 被当作标签语句,导致语法错误。
在箭头函数中,当你想直接返回一个 对象字面量 时,如果不使用 return 关键字则必须用括号 () 括起来。这是。
