// ==UserScript==
// @name 替换网页中的内容
// @name:en Replace content in a webpage
// @name:zh-CN 替换网页中的内容
// @name:zh-TW 替換網頁中的內容
// @namespace http://tampermonkey.net/
// @version 1.0.3
// @description 替换网页中的文本内容
// @description:en Replace text content in a webpage
// @description:zh-CN 替换网页中的文本内容
// @description:zh-TW 替換網頁中的文本內容
// @author linmii
// @include *
// @grant none
// @downloadURL none
// ==/UserScript==
/**
* 需要进行值处理的input类型
*/
const inputTypeArray = ["text", "search", "checkbox"];
let rWindowHeight = getTop();
let rWindowWidth = getWidth();
(function () {
'use strict';
initCss();
initModal();
initRImg();
initDialog();
window.addEventListener("scroll", function () {
reInitDialog();
});
window.addEventListener("resize", function () {
rWindowHeight = getTop();
rWindowWidth = getWidth();
reInitDialog();
})
})();
/**
* 判断数组是否包含某个元素
*/
function isArrayContains(arr, obj) {
for (var i = 0; i < arr.length; i++) {
if (obj === arr[i]) {
return true;
}
}
return false;
}
/**
* 初始化css样式
*/
function initCss() {
let lmStyle = document.createElement("style");
lmStyle.type = "text/css";
lmStyle.innerHTML
= '.lm-r-button {'
+ 'padding: 10px 18px;'
+ 'font-size: 14px;'
+ 'border-radius: 4px;'
+ 'line-height: 1;'
+ 'white-space: nowrap;'
+ 'cursor: pointer;'
+ 'background: #409EFF;'
// + 'border: 1px solid #409EFF;'
+ 'border: none;'
+ 'color: #fff;'
+ 'font-weight: 500;'
+ '}'
+ '.lm-r-button:hover {background: #66b1ff; border-color: #66b1ff; color: #fff;}'
+ '.lm-r-button:focus {background: #66b1ff; border-color: #66b1ff; color: #fff;}'
+ '.lm-r-input {'
+ '-webkit-appearance: none;'
+ 'background-color: #fff;'
+ 'background-image: none;'
+ 'border-radius: 4px;'
+ 'border: 1px solid #dcdfe6;'
+ 'box-sizing: border-box;'
+ 'color: #606266;'
+ 'display: inline-block;'
+ 'font-size: 14px;'
+ 'height: 40px;'
+ 'line-height: 40px;'
+ 'outline: none;'
+ 'padding: 0 15px;'
+ 'transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);'
+ 'width: 100%;'
+ '}'
+ '.lm-r-input:hover {border-color: #C0C4CC;}'
+ '.lm-r-input:focus {border-color: #409EFF;}';
document.querySelector("head").appendChild(lmStyle);
}
/**
* 初始化R图标
*/
function initRImg() {
let rImg = document.createElement("div");
rImg.id = "lm-r-img";
rImg.innerText = 'R';
rImg.style.cssText = "z-index: 999999; position: fixed; top: 0; left: 0; font-size: 14px; border-radius: 4px; background-color: #fff; width: 20px; height: 20px; text-align: center; opacity: 0.5; cursor: pointer; border: solid 1px #999999;";
document.querySelector("body").prepend(rImg);
rImgBindEvent();
}
/**
* 初始化遮罩
*/
function initModal() {
let lmModal = document.createElement("div");
lmModal.id = 'lm-r-modal';
lmModal.style.cssText = 'position: fixed; left: 0; top: 0; width: 100%; height: 100%; opacity: 0.5; background: #000; z-index: 999999; display: none;';
lmModal.onclick = function () {
document.querySelector("#lm-btn-close").click();
};
document.querySelector("body").appendChild(lmModal);
}
/**
* 初始化弹出框
*/
function initDialog() {
let dialogDiv = document.createElement("div");
dialogDiv.id = "lm-dialog-div";
let htmlText = '
';
htmlText += '';
htmlText += '';
htmlText += '';
htmlText += '';
htmlText += '';
htmlText += '
';
dialogDiv.innerHTML = htmlText;
dialogDiv.style.border = 'solid 1px grey';
dialogDiv.style.padding = '10px';
dialogDiv.style.textAlign = 'center';
dialogDiv.style.zIndex = '99999999';
dialogDiv.style.position = 'absolute';
dialogDiv.style.display = 'none';
dialogDiv.style.width = '250px';
dialogDiv.style.height = '130px';
dialogDiv.style.background = '#fff';
dialogDiv.style.borderRadius = '4px';
dialogDiv.style.fontSize = '14px';
dialogDiv.style.left = (rWindowWidth - dialogDiv.style.width.replace('px', '')) / 2 + document.documentElement.scrollLeft + "px";
let scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
dialogDiv.style.top = (rWindowHeight - dialogDiv.style.width.replace('px', '')) / 2 + scrollTop + "px";
let body = document.querySelector("body");
body.appendChild(dialogDiv);
document.querySelector("#lm-replace-btn").addEventListener("click", replaceContent);
}
/**
* 重新定位dialog
*/
function reInitDialog() {
let dialogDiv = document.querySelector("#lm-dialog-div");
dialogDiv.style.left = (rWindowWidth - dialogDiv.style.width.replace('px', '')) / 2 + document.documentElement.scrollLeft + "px";
let scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
dialogDiv.style.top = (rWindowHeight - dialogDiv.style.width.replace('px', '')) / 2 + scrollTop + "px";
}
/**
* 替换
*/
function replaceContent() {
let findText = document.querySelector("#lm-find-content").value;
let replaceText = document.querySelector("#lm-replace-content").value;
if ("" !== findText) {
let inputValues = fetchAllInputValue(findText, replaceText);
let textareaValues = fetchElementValues("textarea", true, findText, replaceText);
let selectValues = fetchElementValues("select", false);
let body = document.querySelector("body");
body.innerHTML = body.innerHTML.replace(new RegExp(findText, "gm"), replaceText);
// 设置替换前的输入内容
fillInputValues(inputValues);
fillElementValues("textarea", textareaValues);
fillElementValues("select", selectValues);
// document.querySelector("#lm-find-content").value = findText;
// document.querySelector("#lm-replace-content").value = replaceText;
// 重新绑定替换点击事件
document.querySelector("#lm-replace-btn").addEventListener("click", replaceContent);
document.querySelector("#lm-r-modal").addEventListener("click", closeBindEvent);
rImgBindEvent();
}
}
/**
* 获取input元素的值
* @param findText 查找内容
* @param replaceText 替换内容
* @returns input元素的值
*/
function fetchAllInputValue(findText, replaceText) {
let result = {};
let radioValues = {};
let inputValues = [];
let inputArrays = document.getElementsByTagName("input");
let length = inputArrays.length;
for (let index = 0; index < length; index++) {
let node = inputArrays[index];
let type = node.type;
// 处理text和checkbox
if (isArrayContains(inputTypeArray, type)) {
switch (type) {
case 'text':
case 'search':
// 查找输入框的内容不进行处理
if (node.id === "lm-find-content") {
inputValues.push(node.value);
} else {
inputValues.push(node.value.replace(new RegExp(findText, "gm"), replaceText));
}
break;
case 'checkbox':
inputValues.push(node.checked);
break;
default:
}
}
if ("radio" === type && node.checked) {
radioValues[node.name] = node.value;
}
}
result.radioValues = radioValues;
result.inputValues = inputValues;
return result;
}
/**
* 替换内容后,设置input元素的值
* @param replacedInputValues input元素的值
*/
function fillInputValues(replacedInputValues) {
let inputArrays = document.getElementsByTagName("input");
const radioValues = replacedInputValues.radioValues;
const inputValues = replacedInputValues.inputValues;
let valueIndex = 0;
let length = inputArrays.length;
for (let index = 0; index < length; index++) {
let node = inputArrays[index];
let type = node.type;
if (isArrayContains(inputTypeArray, type)) {
switch (type) {
case 'text':
case 'search':
node.value = inputValues[valueIndex];
break;
case 'checkbox':
node.checked = inputValues[valueIndex];
break;
default:
}
valueIndex++;
}
}
for (let radioName in radioValues) {
let findParam = "input[type=radio][name=" + radioName + "][value=" + radioValues[radioName] + "]";
let node = document.querySelector(findParam);
if (node) {
node.checked = true;
}
}
}
/**
* 获取元素的值
* @param tagName 标签名称
* @param isReplace 是否替换内容
* @param findText 查询内容
* @param replaceText 替换内容
* @returns 元素的值
*/
function fetchElementValues(tagName, isReplace, findText, replaceText) {
let nodeList = document.getElementsByTagName(tagName);
let result = [];
let length = nodeList.length;
for (let index = 0; index < length; index++) {
let node = nodeList[index];
if (isReplace) {
result.push(node.value.replace(new RegExp(findText, "gm"), replaceText));
} else {
result.push(node.value);
}
}
return result;
}
/**
* 填充元素的值
* @param tagName 标签名称
* @param elementValues 元素的值
*/
function fillElementValues(tagName, elementValues) {
let nodeList = document.getElementsByTagName(tagName);
let length = nodeList.length;
for (let index = 0; index < length; index++) {
nodeList[index].value = elementValues[index];
}
}
/**
* R图标绑定事件
*/
function rImgBindEvent() {
let rImg = document.querySelector("#lm-r-img");
rImg.onclick = function () {
document.querySelector("#lm-r-modal").style.display = 'block';
document.querySelector("#lm-dialog-div").style.display = 'block';
};
rImg.onmouseover = function () {
document.querySelector("#lm-r-img").style.opacity = 1;
};
rImg.onmouseleave = function () {
document.querySelector("#lm-r-img").style.opacity = 0.5;
};
}
/**
* 弹出框关闭事件
*/
function closeBindEvent() {
document.querySelector("#lm-btn-close").click();
document.querySelector("#lm-r-modal").style.display = 'none';
}
/**
* 获取屏幕高度
*/
function getTop() {
let dHeight = document.documentElement.clientHeight;
let bHeight = document.body.clientHeight;
return dHeight < bHeight ? dHeight : bHeight;
}
/**
* 获取屏幕宽度
*/
function getWidth() {
let dWidth = document.documentElement.clientWidth;
let bWidth = document.body.clientWidth;
return dWidth < bWidth ? dWidth : bWidth;
}