-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
coder-new
committed
Apr 10, 2024
1 parent
b3e66d9
commit 64b92c9
Showing
7 changed files
with
1,017 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
--- | ||
title: JavaScript事件绑定 | ||
date: 2024-02-12 | ||
category: | ||
- javascript | ||
--- | ||
|
||
|
||
<!-- more --> | ||
|
||
## 事件类型 | ||
|
||
JavaScript事件类型有以下几种: | ||
1. 鼠标事件(Mouse Events):包括点击、双击、鼠标移入移出、鼠标按下释放等。 | ||
2. 键盘事件(Keyboard Events):包括按键按下、按键释放、按键组合等。 | ||
3. 表单事件(Form Events):包括表单提交、表单重置等。 | ||
4. 焦点事件(Focus Events):包括元素获得焦点、元素失去焦点等。 | ||
5. 触摸事件(Touch Events):包括触摸开始、触摸移动、触摸结束等。 | ||
6. 窗口事件(Window Events):包括窗口打开、窗口关闭、窗口刷新等。 | ||
|
||
### 鼠标事件 | ||
|
||
鼠标单击左键-`click`、鼠标单击右键、鼠标双击-`dbclick` | ||
鼠标移入-`mouseover`、鼠标悬停-`mouseover`、鼠标移出-`mouseleave` | ||
|
||
|
||
### 键盘事件 | ||
|
||
键盘按下-`keydown`、键盘松开-`keyup`、`keypress` | ||
|
||
### 表单事件 | ||
|
||
`input`、`change`、`submit`、`blur`、`focus`、`reset` | ||
|
||
### 触摸事件 | ||
开始触摸-`touchstart`、触摸移动-`touchmove`、触摸结束-`touchend`、触摸打算-`touchcancel` | ||
|
||
轻按-`tap`、长按-`longtap` | ||
|
||
columnchange: 'columnchange', | ||
linechange: 'linechange', | ||
error: 'error', | ||
scrolltoupper: 'scrolltoupper', | ||
scrolltolower: 'scrolltolower', | ||
scroll: 'scroll' | ||
|
||
|
||
## 事件委托 | ||
|
||
### 什么是事件委托 | ||
|
||
JavaScript事件委托(Event delegation)又叫事件代理,是一种在父元素上监听事件,然后通过事件冒泡机制来处理子元素的事件的技术。通过事件委托,可以避免为每个子元素都绑定事件处理程序,提高性能并简化代码。 | ||
|
||
### 事件委托基本原理 | ||
|
||
事件委托的基本原理是将事件处理程序绑定在父元素上,然后通过事件冒泡捕获到子元素的事件触发。这样,无论子元素是现有的还是动态生成的,它们的事件都会被父元素捕获并处理。 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,319 @@ | ||
--- | ||
title: 自封装的hook | ||
date: 2024-02-25 | ||
category: | ||
- 移动开发 | ||
--- | ||
|
||
|
||
### 根据path对文件进行签名 | ||
:::details 查看代码 | ||
```ts | ||
import SparkMD5 from "spark-md5"; | ||
export const md5File = ( | ||
path: string, | ||
): Promise<{ | ||
md5: string; | ||
size: number; | ||
}> => { | ||
return new Promise((resolve, reject) => { | ||
plus.io.requestFileSystem( | ||
plus.io.PRIVATE_WWW, | ||
(fs: PlusIoFileSystem) => { | ||
fs.root?.getFile( | ||
path, | ||
{ create: false }, | ||
(fileEntry: PlusIoFileEntry) => { | ||
fileEntry.file( | ||
(file: PlusIoFile) => { | ||
const fileReader: PlusIoFileReader = new plus.io.FileReader(); | ||
fileReader.onloadend = (evt: PlusIoFileEvent) => { | ||
resolve({ | ||
// @ts-ignore | ||
md5: calculateBase64Hash(evt.target?.result), | ||
size: file.size || 0, | ||
}); | ||
}; | ||
fileReader.readAsDataURL(file, "utf-8"); | ||
}, | ||
fileError => { | ||
reject("获取文件对象失败:" + fileError); | ||
}, | ||
); | ||
}, | ||
fileEntryError => { | ||
reject("读取文件失败:" + fileEntryError); | ||
}, | ||
); | ||
}, | ||
fsError => { | ||
reject("读取文件失败:" + fsError); | ||
}, | ||
); | ||
}); | ||
}; | ||
|
||
/** | ||
* 根据文件的base64生成md5 | ||
* | ||
* @param base64 文件的base64 | ||
* @returns 文件的md5码 | ||
*/ | ||
const calculateBase64Hash = (base64: string): string => { | ||
const spark = new SparkMD5(); | ||
spark.appendBinary(base64); | ||
return spark.end(); | ||
}; | ||
``` | ||
::: | ||
|
||
### 根据path判断文件是否存在 | ||
:::details 查看代码 | ||
```ts | ||
/** | ||
* 根据文件路径异步判断该路径下的文件是否存在 | ||
* | ||
* @param path 文件路径 | ||
* @returns 返回true代表该文件存在,返回false代表该文件不存在 | ||
*/ | ||
export const checkFileExists = (path: string): Promise<boolean> => { | ||
return new Promise(resolve => { | ||
if (path) { | ||
// #ifdef APP-PLUS | ||
plus.io.requestFileSystem( | ||
plus.io.PRIVATE_DOC, | ||
(fs: PlusIoFileSystem) => { | ||
fs.root?.getFile( | ||
path, | ||
{ create: false }, | ||
() => { | ||
resolve(true); | ||
}, | ||
error => { | ||
resolve(false); | ||
}, | ||
); | ||
}, | ||
() => { | ||
resolve(false); | ||
}, | ||
); | ||
// #endif | ||
// #ifdef H5 | ||
resolve(false); | ||
// #endif | ||
} else { | ||
resolve(false); | ||
} | ||
}); | ||
}; | ||
``` | ||
::: | ||
|
||
### 获取手机缓存文件总共多大 | ||
:::details 查看代码 | ||
```ts | ||
/** | ||
* 异步获取手机缓存有多大 | ||
* | ||
*/ | ||
export const calculateDeviceCacheSize = (): Promise<PromiseResolveValue> => { | ||
return new Promise(resolve => { | ||
// #ifdef APP-PLUS | ||
let isGetSuccess: boolean = false; | ||
plus.io.requestFileSystem( | ||
plus.io.PRIVATE_DOC, | ||
(fs: PlusIoFileSystem) => { | ||
/** | ||
* 允许最大时间查询文件大小,避免一些情况下卡住无法返回文件的大小 | ||
*/ | ||
let timer: NodeJS.Timeout = setTimeout(() => { | ||
!isGetSuccess && | ||
resolve({ | ||
flag: 1, | ||
data: formatBytes(0), | ||
}); | ||
clearTimeout(timer); | ||
}, 2000); | ||
fs.root?.getMetadata( | ||
(directoryEntry: PlusIoMetadata) => { | ||
isGetSuccess = true; | ||
resolve({ | ||
flag: 1, | ||
data: formatBytes(Number(directoryEntry.size)), | ||
}); | ||
clearTimeout(timer); | ||
}, | ||
getError => { | ||
resolve({ | ||
flag: 0, | ||
errMsg: getError, | ||
}); | ||
}, | ||
true, | ||
); | ||
}, | ||
error => { | ||
resolve({ | ||
flag: 0, | ||
errMsg: error, | ||
}); | ||
}, | ||
); | ||
// #endif | ||
// #ifdef H5 | ||
resolve({ | ||
flag: 0, | ||
errMsg: "仅支持在APP上获取缓存文件大小", | ||
}); | ||
// #endif | ||
}); | ||
}; | ||
``` | ||
::: | ||
### 清除手机缓存文件 | ||
:::details 查看代码 | ||
```ts | ||
/** | ||
* 异步清除设备缓存文件 | ||
*/ | ||
export const clearDeviceCache = (): Promise<PromiseResolveValue> => { | ||
return new Promise<PromiseResolveValue>(resolve => { | ||
// #ifdef APP-PLUS | ||
uni.showLoading({ | ||
title: "清除设备缓存中", | ||
}); | ||
plus.io.requestFileSystem( | ||
plus.io.PRIVATE_DOC, | ||
(fs: PlusIoFileSystem) => { | ||
fs.root?.removeRecursively( | ||
() => { | ||
uni.hideLoading(); | ||
resolve({ | ||
flag: 1, | ||
errMsg: "", | ||
}); | ||
}, | ||
failRes => { | ||
uni.hideLoading(); | ||
resolve({ | ||
flag: 0, | ||
errMsg: failRes.message, | ||
}); | ||
}, | ||
); | ||
}, | ||
error => { | ||
uni.hideLoading(); | ||
resolve({ | ||
flag: 0, | ||
errMsg: error.message, | ||
}); | ||
}, | ||
); | ||
// #endif | ||
// #ifdef H5 | ||
resolve({ | ||
flag: 0, | ||
errMsg: "仅在APP下支持清除缓存功能", | ||
}); | ||
|
||
// #endif | ||
}); | ||
}; | ||
``` | ||
::: | ||
### 根据bytes转换单位 | ||
:::details 查看代码 | ||
```ts | ||
/** | ||
* 将字节大小格式化如:1KB、1MB、1GB等 | ||
* | ||
* @param bytes 字节大小 | ||
* @returns 转换单位类似为:1KB、1MB、1GB等 | ||
*/ | ||
export const formatBytes = (bytes: number): string => { | ||
if (bytes === 0) return "0 MB"; | ||
const k = 1024; | ||
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; | ||
const i = Math.floor(Math.log(bytes) / Math.log(k)); | ||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i]; | ||
}; | ||
``` | ||
::: | ||
|
||
|
||
### 下载安装包 | ||
:::details 查看代码 | ||
```ts | ||
export const downloadAPK = (url: string, errorCallback: (...args: any) => void) => { | ||
if (plus.os.name?.toLocaleLowerCase() == "ios") { | ||
plus.runtime.openURL(url); | ||
} else { | ||
const waitingToast: PlusNativeUIWaitingObj = plus.nativeUI.showWaiting("正在初始化下载..."); | ||
let downloadTask: PlusDownloaderDownload = plus.downloader.createDownload( | ||
url + useJsonToUrl({ version: userInfoStore.userConf.latestAppVersion, appId: defaultConfig.appid }), | ||
{ | ||
method: "GET", | ||
timeout: 3, | ||
retryInterval: 1, | ||
retry: 2, | ||
}, | ||
(download: PlusDownloaderDownload, status: number) => { | ||
plus.downloader.clear(); | ||
waitingToast.setTitle("下载完成,等待安装..."); | ||
if (status == 200) { | ||
download.filename && | ||
plus.runtime.install( | ||
plus.io.convertLocalFileSystemURL(download.filename), | ||
{ | ||
force: true, | ||
}, | ||
() => { | ||
plus.nativeUI.closeWaiting(); | ||
}, | ||
installErrorMsg => { | ||
plus.nativeUI.closeWaiting(); | ||
errorCallback("安装错误:" + installErrorMsg); | ||
}, | ||
); | ||
} else { | ||
plus.nativeUI.closeWaiting(); | ||
errorCallback("下载最新APP版本失败,请稍后重试或联系APP开发者"); | ||
} | ||
}, | ||
); | ||
|
||
try { | ||
downloadTask.setRequestHeader("Authorization", userInfoStore.token.authorization); | ||
downloadTask.start(); | ||
downloadTask.addEventListener("statechanged", (task: PlusDownloaderDownload) => { | ||
switch (task.state) { | ||
case 1: | ||
waitingToast.setTitle("正在连接服务器..."); | ||
break; | ||
case 2: | ||
waitingToast.setTitle("服务器连接成功,开始下载..."); | ||
break; | ||
case 3: | ||
if (task.downloadedSize && task.totalSize) { | ||
const percent = parseInt(((parseFloat(task.downloadedSize.toString()) / parseFloat(task.totalSize.toString())) * 100).toString()); | ||
waitingToast.setTitle("正在下载(" + percent + "%)..."); | ||
} | ||
break; | ||
case 4: | ||
break; | ||
} | ||
}); | ||
} catch (err) { | ||
plus.nativeUI.closeWaiting(); | ||
errorCallback("下载失败,请稍后重试"); | ||
} | ||
} | ||
}; | ||
``` | ||
::: | ||
|
||
|
||
|
||
|
Oops, something went wrong.