标签 js 下的文章

目录结构

tree .
.
├── assets
│   ├── logo.png
│   └── upload.png
├── css
│   ├── chunk-vendors.css
│   ├── content.css
│   ├── popup.css
│   └── sidePanel.css
├── favicon.ico
├── index.html
├── js
│   ├── background.js
│   ├── content.js
├── manifest.json
├── options.html
├── popup.html

content.js

// content-script.js
//assets/img.avif是根目录下
async function autoUploadExtensionImage(imagePath = 'assets/upload.png') {
    try {
        // 1. 获取扩展内图片URL
        const imageUrl = chrome.runtime.getURL(imagePath);
        console.log('扩展资源URL:', imageUrl);

        // 2. 直接获取二进制数据
        const response = await fetch(imageUrl);
        if (!response.ok) throw new Error(`HTTP错误: ${response.status}`);

        // 3. 转换为File对象
        const blob = await response.blob();
        const file = new File([blob], 'auto_upload.png', {
            type: blob.type || 'image/png',
            lastModified: Date.now()
        });

        // 4. 执行上传操作
        const input = document.querySelector('input[type="file"]');
        const dataTransfer = new DataTransfer();
        dataTransfer.items.add(file);
        input.files = dataTransfer.files;

        // 5. 触发完整事件链
        ['input', 'change'].forEach(eventType => {
            input.dispatchEvent(new Event(eventType, {bubbles: true}));
        });
    } catch (error) {
        console.error('自动化上传失败:', error);
        throw error;
    }
}

nexe build

nexe main.js --build

ℹ nexe 4.0.0-rc.6
✔ Already downloaded...
✔ Configuring node build: --dest-cpu=x64
✔ Finished in 5.814s

Error: python ./configure.py --dest-cpu=x64 exited with code: 1

See nexe -h for usage..

指定python版本

#nexe build specify python
export PYTHON=/Library/Frameworks/Python.framework/Versions/3.7/bin/python3

方式一

const dragAndDrop = async (elem, startX, startY, distance) => {
    // 初始化鼠标事件
    const dispatchMouseEvent = (type, x, y) => {
        const event = new MouseEvent(type, {
            view: window,
            bubbles: true,
            cancelable: true,
            clientX: Math.floor(x),
            clientY: Math.floor(y),
            screenX: Math.floor(x + window.screenX),
            screenY: Math.floor(y + window.screenY),
            button: 0,
            // 当是 mousedown 或 mousemove 时,保持左键按下状态
            buttons: type === 'mouseup' ? 0 : 1,
        });
        elem.dispatchEvent(event);
    };

    // 贝塞尔曲线运动参数
    const duration = 800 + Math.random() * 400; // 随机持续时间
    const startTime = performance.now();
    const humanizeFactor = 0.3; // 人类操作随机因子

    // 触发初始按下事件
    dispatchMouseEvent('mousedown', startX, startY);

    // 使用requestAnimationFrame实现平滑动画
    return new Promise(resolve => {
        const animate = (currentTime) => {
            const elapsed = currentTime - startTime;
            const progress = Math.min(elapsed / duration, 1);

            // 应用缓动函数(三次贝塞尔曲线)
            const easedProgress = Math.sin(progress * Math.PI / 2);

            // 添加人类操作随机扰动
            const randomOffset = Math.random() * humanizeFactor * distance;
            const currentX = startX + (distance * easedProgress) + randomOffset;
            const currentY = startY + Math.sin(progress * Math.PI) * 5; // 自然Y轴波动

            dispatchMouseEvent('mousemove', currentX, currentY);

            if (progress < 1) {
                requestAnimationFrame(animate);
            } else {
                // 结束操作
                dispatchMouseEvent('mouseup', currentX, currentY);
                resolve();
            }
        };

        requestAnimationFrame(animate);
    });
};

// 优化后的启动函数
const simulateHorizontalDrag = async (slide, distance) => {
    const elem = document.querySelector(slide);
    if (!elem) {
        logger.error('selector:%s not found', slide);
        return;
    }

    const rect = elem.getBoundingClientRect();
    const startX = rect.left + rect.width * 0.3 + Math.random() * rect.width * 0.4;
    const startY = rect.top + rect.height * 0.3 + Math.random() * rect.height * 0.4;

    await dragAndDrop(elem, startX, startY, distance);
};

方式二

function dragandDrop(id, clientX, clientY, distance) {
    const elem = document.querySelector(id);
    let k = 0;
    iME(elem, "mousedown", 0, 0, clientX, clientY);
    const interval = setInterval(function () {
        k++;
        iME(elem, "mousemove", clientX + k, clientY, clientX + k, clientY);

        if (k >= distance) {
            clearInterval(interval);
            iME(elem, "mouseup", clientX + k, clientY, clientX + k, clientY);
        }
    }, 8);

    function iME(obj, event, screenXArg, screenYArg, clientXArg, clientYArg) {
        const mousemove = document.createEvent("MouseEvent");
        mousemove.initMouseEvent(event, true, true, window, 0,
            screenXArg, screenYArg, clientXArg, clientYArg, 0, 0, 0, 0, 0, null);
        obj.dispatchEvent(mousemove);
    }
}

function simulateHorizontalDrag(slide, distance) {
    const obj = document.querySelector(slide);
    obj.target = '_self';
    const _owh = obj.getBoundingClientRect();
    let _ox = _owh.width / 2, _oh = _owh.height / 2;
    _ox = Math.floor(Math.random() * _ox + 60);
    _oh = Math.floor(Math.random() * _oh + 60);
    _ox = _ox + _owh.x;
    _oh = _oh + _owh.y;
    dragandDrop(slide, _ox, _oh, distance);
}

// 引入 html2canvas
import html2canvas from 'html2canvas';


async function captureElement(elementSelector, image_name = 'screenshot_from_html2canvas') {
    const element = document.querySelector(elementSelector);
    // 获取元素的实际渲染尺寸
    const rect = element.getBoundingClientRect();
    const width = rect.width;
    const height = rect.height;

    // 创建临时容器(避免截取时元素被缩放影响布局)
    const container = document.createElement('div');
    Object.assign(container.style, {
        position: 'fixed',
        left: '-9999px',      // 隐藏到屏幕外
        width: `${width}px`,  // 固定容器尺寸
        height: `${height}px`
    });
    document.body.appendChild(container);

    // 克隆元素到临时容器(保持样式)
    const clone = element.cloneNode(true);
    container.appendChild(clone);

    // width和height是为了和屏幕上显示的大小一致,不加也可以
    const canvas = await html2canvas(element, {
        useCORS: true,       // 允许跨域资源
        logging: false,      // 关闭日志
        scale: 1,            // 必须设为 1,否则尺寸会缩放
        width: width,        // 显式设置宽高
        height: height,
        backgroundColor: null // 透明背景
    });

    // 转换为图片 URL
    const url = canvas.toDataURL('image/png', 1.0);
    const data = {
        url: url,
        filename: `${image_name}.png`
    }
    // downloadImg(data);
    postMessage({type: "download_image", data})
    return url
}

安装

pnpm install json-editor-vue

使用

<template>

<JsonEditorVue
        v-model="json"
        mode="text"
        :mainMenuBar="false"
        :statusBar="true"
        :stringified="false"
    />
</template>

<script lang="ts" setup>

import JsonEditorVue from 'json-editor-vue'
const json = {"name":"张三"}
</script>