实现的功能

  1. 账密展示
  2. 原生 Toast 展示复制情况
  3. 点击复制

为什么强调原生

因为不需要引用第三方库,可以提高保密性并且在无网环境/内网环境中使用
html 复健

如何使用

密码写在 html 中或者引入 pwd.js

若密码写在 html 中,则注释此行<script src="./pwd.js"></script>(默认)
若密码单独写在 pwd.js 中,则注释 html 中 pwdInfo 的部分 (便于维护)

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MiHoYo Password</title>
<!-- <script src="./pwd.js"></script> -->
<script>
const pwdInfo = [
{
id: 0,
name: "aaa",
phone: "111",
password: "111",
},
{
id: 1,
name: "bbb",
phone: "222",
password: "222",
},
];
</script>
<style>
* {
font-family: PingFang SC, Helvetic1, sans-serif;
padding: 0;
margin: 0;
}

.layout {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}

.bigBox {
margin: auto;
display: flex;
flex-flow: wrap;
justify-content: center;
}

.personBox {
height: 100px;
max-height: 200px;
max-width: 300px;

display: flex;
flex-flow: column;
justify-content: center;
align-items: start;

padding: 8px 20px;
margin: 15px;
border-radius: 10px;
background-color: #4b6f98ef;
transition: background-color 0.2s;
}

.personBox:hover {
background-color: #2b4460;
}

h3 {
color: #eee;
padding-bottom: 3px;
}

a {
cursor: pointer;
padding: 1px 0;
font-size: 14px;
color: #eee;
transition: font-size 0.5s;
}

a:hover {
font-size: 15px;
}

/* 以下为toast */
/* toast内容样式 */
.toast {
position: fixed;
top: 0;
right: 0;

margin: 15px;
padding: 15px;

background-color: white;
border-radius: 5px;
border: 1px solid #eee;
/* 加入边框 */
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
/* 加入阴影 */
z-index: 1000;
/* 确保toast在顶层 */
}

.content {
display: flex;
font-weight: bold;
font-size: 16px;
}

/* 显示toast的动画 */
.show-toast {
animation: slideIn 0.5s ease forwards;
}

/* 隐藏toast的动画 */
.hide-toast {
animation: slideOut 0.5s ease forwards;
}

/* 入场动画 */
@keyframes slideIn {
from {
transform: translateX(200px);
opacity: 0;
}

to {
transform: translateX(0);
opacity: 1;
}
}

/* 出场动画 */
@keyframes slideOut {
from {
transform: translateX(0);
opacity: 1;
}

to {
transform: translateX(200px);
opacity: 0;
}
}
</style>
</head>

<body>
<div id="Toast"></div>
<div class="layout">
<div class="bigBox"></div>
</div>
</body>
<script>
function myCopy(id, info) {
navigator.clipboard.writeText(pwdInfo[id][info]);
showToast(`复制成功:${pwdInfo[id].name}${info}`, 1200);
}

let toastNumber = -1;
function showToast(content, duration = 1000) {
toastNumber++;
let toast = document.getElementById("Toast");
let toastItem = document.createElement("div");
toastItem.setAttribute("class", "toast");
toastItem.style.top = `${toastNumber * 65}px`;
toastItem.innerHTML = /*html*/ `
<div class="content">
<svg style="width:23px;color: rgb(10, 194, 58);" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path fill="currentColor" d="M512 64a448 448 0 1 1 0 896 448 448 0 0 1 0-896m-55.808 536.384-99.52-99.584a38.4 38.4 0 1 0-54.336 54.336l126.72 126.72a38.272 38.272 0 0 0 54.336 0l262.4-262.464a38.4 38.4 0 1 0-54.272-54.336z"></path></svg>
<span style="margin-left:5px">${content}</span>
</div>
`;
toast.appendChild(toastItem);
// 使用Promise来同步setTimeout
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
// 显示toast
// 播放开始动画
toastItem.classList.add("show-toast");
// 等待 进入动画+duration 时间后播放关闭动画
// toastItem.style.top = `${toastNumber * 65}px`;
delay(duration + 500).then(() => {
toastItem.classList.add("hide-toast");
toastNumber--;
});
// 等待 进入动画+duration+出场动画 时间后播放移除节点
delay(duration + 500 + 500).then(() => {
if (toastItem) {
toastItem.remove();
}
});
}

bigBox = document.querySelector(".bigBox");

pwdInfo.forEach((info) => {
const showInfo = (category, tag) => {
return info[category]
? /*html*/ `<a class="btn" onclick="myCopy(${info.id}, '${category}' )">
${tag}:${info[category]}
</a>`
: "";
};

bigBox.innerHTML += /*html*/ `
<div class="personBox">
<h3>${info.name}</h3>
${showInfo("email", "Email")}
${showInfo("phone", "Phone")}
${showInfo("password", "Password")}
</div>`;
});
</script>
</html>

pwd.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const pwdInfo = [
{
id: 0,
name: "aaa",
phone: "111",
password: "111",
},
{
id: 1,
name: "bbb",
phone: "222",
password: "222",
},
];