可以发现:当直接修改输入框的 value
属性不会触发一些框架(如 React、Vue 等)或自定义事件所依赖的输入变化检测。这意味着虽然你看到输入框的值改变了,但在后台或框架管理的状态中,输入框的值可能并没有更新。由上述这个情况会造成生成过程中的用户值出现问题。
因此需要解决上述问题,所以尝试使用第一种方法,但是失败了,
触发原生的 input
和 change
事件
除了设置 value
属性,还需要手动触发 input
和 change
事件。这些事件告诉网页的前端框架输入值已经发生了变化,并且需要将这个变化传递给后台。
随后便使用第二种方法
使用 setNativeValue 填充输入框
可以将所输入的内容直接填入相关的地段,通过创建一个 setNativeValue
函数来模拟用户的输入,从而更新框架的内部状态。
遇到的原始情况:
// ==UserScript==
// @name 示例脚本:模拟点击
// @namespace http://tampermonkey.net/
// @version 0.1
// @description 尝试自动点击ID为myButton的按钮
// @author
// @match
// @grant unsafewindow
// @require http://libs.baidu.com/jquery/2.0.0/jquery.min.js
// @require https://cdn.bootcdn.net/ajax/libs/artDialog/7.0.0/dialog.js
// @grant GM_log
// @grant GM_registerMenuCommand
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const loopCount = 10;
let currentValue = 208930000000010; // 初始值
// 页面加载后立即弹出提示框
function promptToStart() {
let activate = confirm("是否开始执行脚本?");
if (activate) {
console.log("开始执行脚本");
runAutomationLoop(); // 开始执行10次循环
} else {
console.log("脚本未启动");
}
}
// 循环执行操作
function runAutomationLoop() {
for (let i = 0; i < loopCount; i++) {
setTimeout(() => {
delayedAction(currentValue);
currentValue++; // 每次循环后增加值
}, i * 1000); // 每次循环之间间隔10秒
}
}
// 执行点击和填充操作
function delayedAction(value) {
console.log("执行第 " + (value - 208930000000000) + " 次操作");
// 查找并点击按钮
let button = document.querySelector('button.subscribers__button.btn.btn-primary');
if (button) {
button.click();
console.log("按钮已点击");
// 点击按钮后执行填充输入框的操作
fillInputField(value);
} else {
console.log("未找到指定的按钮");
}
}
// 填充输入框的函数
function fillInputField(value) {
let inputField = document.querySelector('input.form-control#root_ueId');
if (inputField) {
inputField.value = value;
// 触发 input 事件
let inputEvent = new Event('input', { bubbles: true });
inputField.dispatchEvent(inputEvent);
// 触发 change 事件
let changeEvent = new Event('change', { bubbles: true });
inputField.dispatchEvent(changeEvent);
// 触发输入框的变化事件,以确保表单能够捕捉到输入值的变化
console.log("输入框已填充新值: " + value);
// 填充完成后执行提交操作
//clickSubmitButton();
} else {
console.log("未找到指定的输入框");
}
}
// 点击提交按钮的函数
function clickSubmitButton() {
let submitButton = document.querySelector('button.btn.btn-info[type="submit"]');
if (submitButton) {
submitButton.click();
console.log("提交按钮已点击");
} else {
console.log("未找到提交按钮");
}
}
// 页面加载后立即执行提示
setTimeout(promptToStart, 5000);
})();
优化后的成功案例
// ==UserScript==
// @name 示例脚本:模拟点击
// @namespace http://tampermonkey.net/
// @version 0.2
// @description 尝试自动点击ID为myButton的按钮
// @author
// @match
// @grant unsafewindow
// @require http://libs.baidu.com/jquery/2.0.0/jquery.min.js
// @require https://cdn.bootcdn.net/ajax/libs/artDialog/7.0.0/dialog.js
// @grant GM_log
// @grant GM_registerMenuCommand
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const loopCount = 10;
let currentValue = 208930000000010; // 初始值
// 页面加载后立即弹出提示框
function promptToStart() {
let activate = confirm("是否开始执行脚本?");
if (activate) {
console.log("开始执行脚本");
runAutomationLoop(); // 开始执行10次循环
} else {
console.log("脚本未启动");
}
}
// 循环执行操作
function runAutomationLoop() {
for (let i = 0; i < loopCount; i++) {
setTimeout(() => {
delayedAction(currentValue);
currentValue++; // 每次循环后增加值
}, i * 1000); // 每次循环之间间隔1秒
}
}
// 执行点击和填充操作
function delayedAction(value) {
console.log("执行第 " + (value - 208930000000000) + " 次操作");
// 查找并点击按钮
let button = document.querySelector('button.subscribers__button.btn.btn-primary');
if (button) {
button.click();
console.log("按钮已点击");
// 点击按钮后执行填充输入框的操作
fillInputField(value);
} else {
console.log("未找到指定的按钮");
}
}
// 使用 setNativeValue 填充输入框
function setNativeValue(element, value) {
const valueSetter = Object.getOwnPropertyDescriptor(element, 'value').set;
const prototype = Object.getPrototypeOf(element);
const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set;
if (valueSetter && valueSetter !== prototypeValueSetter) {
prototypeValueSetter.call(element, value);
} else {
valueSetter.call(element, value);
}
const event = new Event('input', { bubbles: true });
element.dispatchEvent(event);
}
// 填充输入框的函数
function fillInputField(value) {
let inputField = document.querySelector('input.form-control#root_ueId');
if (inputField) {
setNativeValue(inputField, value.toString());
console.log("输入框已填充新值并触发事件: " + value);
// 填充完成后点击提交按钮的函数
clickSubmitButton();
} else {
console.log("未找到指定的输入框");
}
}
// 点击提交按钮的函数
function clickSubmitButton() {
let submitButton = document.querySelector('button.btn.btn-info[type="submit"]');
if (submitButton) {
submitButton.click();
console.log("提交按钮已点击");
} else {
console.log("未找到提交按钮");
}
}
// 页面加载后立即执行提示
setTimeout(promptToStart, 5000);
})();