-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontent.js
More file actions
189 lines (158 loc) · 5.09 KB
/
content.js
File metadata and controls
189 lines (158 loc) · 5.09 KB
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
// 内容脚本 - 注入到所有网页中
class SignInContentScript {
constructor() {
this.init();
}
init() {
// 监听来自后台脚本的消息
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === 'performSignIn') {
this.performSignIn(message.selector)
.then(result => sendResponse({ success: true, result }))
.catch(error => sendResponse({ success: false, error: error.message }));
return true; // 异步响应
}
});
}
async performSignIn(selector) {
try {
console.log('开始执行签到操作,选择器:', selector);
// 等待元素出现
const element = await this.waitForElement(selector);
if (!element) {
throw new Error(`未找到签到元素: ${selector}`);
}
// 检查元素是否可见和可点击
if (!this.isElementClickable(element)) {
throw new Error('签到元素不可点击');
}
// 滚动到元素位置
element.scrollIntoView({ behavior: 'smooth', block: 'center' });
// 等待一下确保滚动完成
await this.sleep(500);
// 尝试多种点击方式
const success = await this.clickElement(element);
if (success) {
console.log('签到操作执行成功');
// 等待页面响应
await this.sleep(2000);
// 检查是否有成功提示
const successMessage = this.checkSignInResult();
return {
success: true,
message: successMessage || '签到完成',
timestamp: new Date().toLocaleString()
};
} else {
throw new Error('点击签到元素失败');
}
} catch (error) {
console.error('签到失败:', error);
throw error;
}
}
async waitForElement(selector, timeout = 10000) {
return new Promise((resolve, reject) => {
// 首先检查元素是否已经存在
const element = document.querySelector(selector);
if (element) {
resolve(element);
return;
}
// 如果不存在,使用 MutationObserver 监听
const observer = new MutationObserver(() => {
const element = document.querySelector(selector);
if (element) {
observer.disconnect();
resolve(element);
}
});
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true
});
// 设置超时
setTimeout(() => {
observer.disconnect();
reject(new Error(`等待元素超时: ${selector}`));
}, timeout);
});
}
isElementClickable(element) {
const rect = element.getBoundingClientRect();
const style = window.getComputedStyle(element);
return (
rect.width > 0 &&
rect.height > 0 &&
style.visibility !== 'hidden' &&
style.display !== 'none' &&
!element.disabled
);
}
async clickElement(element) {
try {
// 方法1: 直接点击
element.click();
await this.sleep(100);
// 方法2: 如果直接点击无效,尝试事件派发
const clickEvent = new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window
});
element.dispatchEvent(clickEvent);
// 方法3: 尝试触发其他相关事件
const events = ['mousedown', 'mouseup', 'touchstart', 'touchend'];
for (const eventType of events) {
const event = new MouseEvent(eventType, {
bubbles: true,
cancelable: true,
view: window
});
element.dispatchEvent(event);
await this.sleep(50);
}
return true;
} catch (error) {
console.error('点击元素失败:', error);
return false;
}
}
checkSignInResult() {
// 常见的签到成功提示关键词
const successKeywords = [
'签到成功', '打卡成功', '签到完成', '打卡完成',
'今日已签到', '今日已打卡', '连续签到', '获得',
'success', 'complete', 'done'
];
// 检查页面中是否有成功提示
const bodyText = document.body.innerText.toLowerCase();
for (const keyword of successKeywords) {
if (bodyText.includes(keyword.toLowerCase())) {
return `检测到签到成功提示: ${keyword}`;
}
}
// 检查是否有弹窗或通知
const notifications = document.querySelectorAll([
'.notification', '.alert', '.toast', '.message',
'.success', '.tips', '.popup'
].join(','));
for (const notification of notifications) {
const text = notification.innerText.toLowerCase();
for (const keyword of successKeywords) {
if (text.includes(keyword.toLowerCase())) {
return `检测到签到成功通知: ${keyword}`;
}
}
}
return null;
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
// 初始化内容脚本
if (typeof window !== 'undefined' && !window.signinContentScript) {
window.signinContentScript = new SignInContentScript();
}