方式一

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);
}

标签: js, 模拟, 模拟拖动鼠标, 验证码

已有 5 条评论

  1. 情感真挚自然,字里行间传递出强烈的感染力。

  2. 文化差异分析可再深化以避免误读。

  3. ?叙事类评语?

  4. 批判锋芒犀利,直指问题症结所在。

  5. 作者的才华横溢,让这篇文章成为了一篇不可多得的艺术品。

添加新评论