替换网页中的内容

替换网页中的文本内容

目前为 2019-08-17 提交的版本。查看 最新版本

// ==UserScript==
// @name         替换网页中的内容
// @name:en      Replace content in a webpage
// @name:zh-CN   替换网页中的内容
// @name:zh-TW   替換網頁中的內容
// @namespace    http://tampermonkey.net/
// @version      1.0.1
// @description  替换网页中的文本内容
// @description:en     Replace text content in a webpage
// @description:zh-CN  替换网页中的文本内容
// @description:zh-TW  替換網頁中的文本內容
// @author       linmii
// @include      *
// @grant        none
// ==/UserScript==

/**
 * 需要进行值处理的input类型
 */
const inputTypeArray = ["text", "search", "checkbox"];

(function () {
    'use strict';

    initCss();
    initModal();
    initRImg();
    initDialog();

    window.addEventListener("scroll", function () {
        let dialogDiv = document.querySelector("#lm-dialog-div");
        dialogDiv.style.left = (document.documentElement.clientWidth - dialogDiv.style.width.replace('px', '')) / 2 + document.documentElement.scrollLeft + "px";
        let scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
        dialogDiv.style.top = (getTop() - dialogDiv.style.width.replace('px', '')) / 2 + scrollTop + "px";
    });
})();

/**
 * 判断数组是否包含某个元素
 */
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 = '<div><input id="lm-find-content" class="lm-r-input" placeholder="请输入查找内容(支持正则)" style="width: 230px;"></div>';
    htmlText += '<div style="margin-top: 5px;"><input id="lm-replace-content" class="lm-r-input" placeholder="请输入替换内容" style="width: 230px;"></div>';
    htmlText += '<div style="margin-top: 5px;">';
    htmlText += '<button id="lm-replace-btn" class="lm-r-button">替 换</button>';
    htmlText += '<button style="margin-left: 10px;" class="lm-r-button" onclick="document.querySelector(\'#lm-find-content\').value = \'\';document.querySelector(\'#lm-replace-content\').value = \'\';">清 空</button>';
    htmlText += '<button id="lm-btn-close" style="margin-left: 10px;" class="lm-r-button" onclick="document.querySelector(\'#lm-dialog-div\').style.display = \'none\'; document.querySelector(\'#lm-r-modal\').style.display = \'none\';">关 闭</button>';
    htmlText += '</div>';
    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 = (document.documentElement.clientWidth - dialogDiv.style.width.replace('px', '')) / 2 + document.documentElement.scrollLeft + "px";
    let scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
    dialogDiv.style.top = (getTop() - dialogDiv.style.width.replace('px', '')) / 2 + scrollTop + "px";
    let body = document.querySelector("body");
    body.appendChild(dialogDiv);
    document.querySelector("#lm-replace-btn").addEventListener("click", replaceContent);
}

/**
 * 替换
 */
function replaceContent() {
    let findText = document.querySelector("#lm-find-content").value;
    let replaceText = document.querySelector("#lm-replace-content").value;
    if ("" !== findText && "" !== replaceText) {
        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;
}

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址