首页 > 其他分享 >滑动验证码之鼠标移动轨迹绘制分析

滑动验证码之鼠标移动轨迹绘制分析

时间:2024-11-29 15:10:33浏览次数:6  
标签:nDiv 鼠标 元素 验证码 var 滑动 document event

Part1鼠标事件类型

这些是 JavaScript 中与鼠标事件相关的常见事件类型。具体介绍如下:

  • auxclick:表示鼠标的辅助按键被点击。辅助按键包括鼠标中键和右键。
  • click:表示鼠标单击操作被触发。
  • dblclick:表示鼠标双击操作被触发。
  • mousedown:表示鼠标按下操作被触发。
  • mouseup:表示鼠标松开操作被触发。
  • mouseover:表示鼠标移动到某个元素之上时被触发。
  • mousemove:表示鼠标在某个元素上移动时被触发。
  • mouseout:表示鼠标移出某个元素时被触发。
  • mouseenter:表示鼠标进入某个元素时被触发。与 mouseover 不同,mouseenter 不会在鼠标从元素的子元素进入时触发。
  • mouseleave:表示鼠标离开某个元素时被触发。与 mouseout 不同,mouseleave 不会在鼠标进入元素的子元素时触发。
  • mousewheel:表示鼠标滚轮被滚动时被触发。该事件在不同浏览器中的表现可能有所不同。
  • wheel:表示鼠标滚轮被滚动时被触发,与 mousewheel 类似。但是,wheel 事件提供更多的信息,比如滚动的距离和方向。
  • contextmenu:表示鼠标右键菜单被触发。

1鼠标位置

属性说明兼容性
clientX 以浏览器窗口左上顶角为原点,定位 x 轴坐标 所有浏览器,不兼容 Safari
clientY 以浏览器窗口左上顶角为原点,定位 y 轴坐标 所有浏览器,不兼容 Safari
offsetX 以当前事件的目标对象左上顶角为原点,定位 x 轴坐标 所有浏览器,不兼容 Mozilla
offsetY 以当前事件的目标对象左上顶角为原点,定位 y 轴坐标 所有浏览器,不兼容 Mozilla
pageX 以 document 对象(即文档窗口)左上顶角为原点,定位 x 轴坐标 所有浏览器,不兼容 IE
pageY 以 document 对象(即文档窗口)左上顶角为原点,定位 y 轴坐标 所有浏览器,不兼容 IE
screenX 计算机屏幕左上顶角为原点,定位 x 轴坐标 所有浏览器
screenY 计算机屏幕左上顶角为原点,定位 y 轴坐标 所有浏览器
layerX 最近的绝对定位的父元素(如果没有,则为 document 对象)左上顶角为元素,定位 x 轴坐标 Mozilla 和 Safari
layerY 最近的绝对定位的父元素(如果没有,则为 document 对象)左上顶角为元素,定位 y 轴坐标 Mozilla 和 Safari

2获取鼠标坐标

  1. 鼠标移动事件:

当鼠标在页面上移动时,通过event对象的pageX和pageY属性获取当前鼠标坐标。

document.addEventListener("mousemove", function(event){
    var x = event.pageX;
    var y = event.pageY;
    console.log("鼠标坐标为:" + x + ", " + y);
});
  1. 鼠标单击事件:

当鼠标在页面上单击时,通过event对象的clientX和clientY属性获取当前鼠标坐标。

document.addEventListener("click", function(event){
    var x = event.clientX;
    var y = event.clientY;
    console.log("鼠标单击坐标为:" + x + ", " + y);
});

注意:clientX和clientY属性是相对于当前窗口的位置,而pageX和pageY是相对于整个文档的位置。

3在鼠标静止不动时获取坐标

你可以使用 mousemove 事件监听鼠标移动,然后使用 setTimeout 和 setInterval 函数来判断鼠标是否停止移动。在鼠标停止移动的时候,就可以获取当前鼠标的位置坐标了。以下是示例代码:

var timer = null;
var lastX = null;
var lastY = null;
function onm ouseMove(e) {
  var x = e.clientX;
  var y = e.clientY;
  if (lastX === null && lastY === null) {
    // 第一次移动
    lastX = x;
    lastY = y;
    return;
  }
  if (x === lastX && y === lastY) {
    // 鼠标停止移动
    clearInterval(timer);
    console.log('鼠标坐标:', lastX, lastY);
  } else {
    // 继续移动
    lastX = x;
    lastY = y;
  }
}
document.addEventListener('mousemove', function(e) {
  clearTimeout(timer);
  timer = setInterval(function() {
    onm ouseMove(e);
  }, 50);
});

这段代码会监听鼠标移动事件,每当鼠标移动时,会清除定时器和设置新的定时器,定时器的作用是每隔一段时间(这里是50毫秒)检查鼠标移动是否停止。如果鼠标停止移动,就会清除定时器并打印输出鼠标坐标。

Part2鼠标移动轨迹可视化

思路:当鼠标在页面上移动时,动态创建一个小圆点(位置就是鼠标的当前位置)。一秒后,再把该圆点删除掉。仅需要js代码就能实现。

//鼠标移动时,动态创建div,一秒后删除
window.onmousemove = function(event) {
    var nDiv = document.createElement('div')
    //创建新的div
    var e = event || window.event
    //获取事件对象
    //设置div的样式(红色小圆点)和位置(鼠标当前位置)
    nDiv.style.cssText = "position:absolute; width:5px; height:5px;  border-radius:50%"
    nDiv.style.left = e.pageX + "px"
    nDiv.style.top = e.pageY + "px"
    //把创建好的div添加到body里面
    document.body.appendChild(nDiv)

    //延迟定时器实现一秒后删除效果
    setTimeout(function() {
        nDiv.remove();
    }, 1000)
}

4写法1

function handleEvent(event) {
    var nDiv = document.createElement('div')
    var e = event || window.event
    if (event.type === 'mousemove') {
        nDiv.style.cssText = "position:absolute; width:5px; height:5px;  border-radius:50%; z-index:9999; pointer-events:none"
    } elseif (event.type === 'mousedown') {
        nDiv.style.cssText = "position:absolute; width:10px; height:10px;  border-radius:50%; z-index:10000; pointer-events:none"
    } elseif (event.type === 'mouseup') {
        nDiv.style.cssText = "position:absolute; width:100px; height:100px;  border-radius:50%; z-index:10001; pointer-events:none"
    } elseif (event.type === 'click') {
        nDiv.style.cssText = "position:absolute; width:10px; height:10px;  border-radius:50%; z-index:10002; pointer-events:none"
    }
    nDiv.style.left = e.pageX + "px"
    nDiv.style.top = e.pageY + "px"
    document.body.appendChild(nDiv)
    setTimeout(function() {
        nDiv.remove();
    }, 1000)
}

window.onmousemove = handleEvent
window.onmousedown = handleEvent
window.onmouseup = handleEvent
window.onclick = handleEvent

5写法2

window.onmousemove = function(event) {
    var nDiv = document.createElement('div')
    var e = event || window.event
    nDiv.style.cssText = "position:absolute; width:5px; height:5px;  border-radius:50%; z-index:9999; pointer-events:none"
    nDiv.style.left = e.pageX + "px"
    nDiv.style.top = e.pageY + "px"
    document.body.appendChild(nDiv)
    setTimeout(function() {
        nDiv.remove();
    }, 1000)
}

window.onclick = function(event) {
    var nDiv = document.createElement('div')
    var e = event || window.event
    nDiv.style.cssText = "position:absolute; width:10px; height:10px;  border-radius:50%; z-index:10002; pointer-events:none"
    nDiv.style.left = e.pageX + "px"
    nDiv.style.top = e.pageY + "px"
    document.body.appendChild(nDiv)
    setTimeout(function() {
        nDiv.remove();
    }, 1000)
}

6写法3(推荐)

window.addEventListener('mousemove', function(event) {
    var nDiv = document.createElement('div')
    var e = event || window.event
    nDiv.style.cssText = "position:absolute; width:5px; height:5px;  border-radius:50%; z-index:9999; pointer-events:none"
    nDiv.style.left = e.pageX + "px"
    nDiv.style.top = e.pageY + "px"
    document.body.appendChild(nDiv)
    setTimeout(function() {
        nDiv.remove();
    }, 1000)
});

window.addEventListener('click', function(event) {
    var nDiv = document.createElement('div')
    var e = event || window.event
    nDiv.style.cssText = "position:absolute; width:10px; height:10px;  border-radius:50%; z-index:10002; pointer-events:none"
    nDiv.style.left = e.pageX + "px"
    nDiv.style.top = e.pageY + "px"
    document.body.appendChild(nDiv)
    setTimeout(function() {
        nDiv.remove();
    }, 1000)
});

7针对元素滑块

如果你想在滑块元素上记录鼠标的按下和移动事件,你可以尝试以下的代码:

var sliderElements = document.getElementsByClassName('passMod_slide-btn ');
var sliderElement = sliderElements[0];

sliderElement.addEventListener('mousedown', function(event) {
    console.log('Mouse down at:', event.clientX, event.clientY);
});

sliderElement.addEventListener('mousemove', function(event) {
    console.log('Mouse move at:', event.clientX, event.clientY);
});

这段代码会在鼠标在滑块元素上按下和移动时,打印出鼠标的位置。请注意,mousemove 事件会在鼠标在元素上移动时持续触发,即使鼠标按钮没有被按下。

如果你只想在鼠标按下并拖动滑块时才记录鼠标的移动,你可能需要添加一些额外的逻辑来跟踪鼠标的状态,例如:

var sliderElements = document.getElementsByClassName('passMod_slide-btn ');
var sliderElement = sliderElements[0];
var isMouseDown = false;

sliderElement.addEventListener('mousedown', function(event) {
    console.log('Mouse down at:', event.clientX, event.clientY);
    isMouseDown = true;
});

sliderElement.addEventListener('mousemove', function(event) {
    if (isMouseDown) {
        console.log('Mouse move at:', event.clientX, event.clientY);
    }
});

sliderElement.addEventListener('mouseup', function(event) {
    isMouseDown = false;
});

这段代码只有在鼠标按下并在滑块元素上移动时,才会打印出鼠标的位置。

8难点解释

z-index

解决元素遮盖的问题

在CSS中,元素的堆叠顺序(也就是哪个元素在上面,哪个元素在下面)是由多个因素决定的,包括元素的位置(position)、浮动(float)、层叠上下文(stacking context)、层叠等级(z-index)等。

在代码中,新创建的div元素的position属性被设置为absolute,这意味着这个元素会被放置在一个新的层叠上下文中。然而,如果页面中的其他元素也有自己的层叠上下文,并且它们的z-index值比新创建的div元素的z-index值大,那么这些元素就会覆盖在新创建的div元素上面。

因此可以通过给新创建的div元素添加一个较大的z-index值来解决这个问题。例如:

nDiv.style.cssText = "position:absolute; width:5px; height:5px;  border-radius:50%; z-index:9999"

这样,无论页面中的其他元素的z-index值是多少,新创建的div元素总是会显示在最上面。

pointer-events

解决无法操作下方滑块元素的问题

可以使用CSS的pointer-events属性来确保新创建的div元素总是显示在最上层。pointer-events属性指定了元素如何响应鼠标事件。如果你将其设置为none,那么鼠标事件将会“穿透”这个元素,直接作用于下面的元素。这样,即使新创建的div元素在视觉上覆盖了其他元素,用户仍然可以与这些被覆盖的元素互动。

  • 在CSS中,pointer-events属性用于指定元素如何响应鼠标或触摸事件。当你将pointer-events设置为none时,元素将不再是鼠标事件的目标。也就是说,任何对该元素的点击或悬停操作都会“穿透”该元素,直接作用于其下面的元素。

这个属性在很多情况下都非常有用。例如,如果你有一个透明的元素覆盖在其他元素上面,你可以通过设置pointer-events: none来让用户可以与被覆盖的元素互动。或者,如果你有一个元素你不希望用户能够与其互动(例如,一个正在进行动画的元素),你也可以使用pointer-events: none

两种方法区别

document.addEventListener("mousemove", function(event){
    var x = event.pageX;
    var y = event.pageY;
    console.log("鼠标坐标为:" + x + ", " + y);
});


window.onmousemove = function(event) {
    var x = event.pageX;
    var y = event.pageY;
    console.log("鼠标坐标为:" + x + ", " + y);
}

document.addEventListener("mousemove", function(event){...}) 和 window.onmousemove = function(event) {...} 都是用来监听鼠标移动事件的,但它们之间存在一些差异:

  1. 事件监听器的添加方式addEventListener 方法允许你为同一事件添加多个监听器,而 onmousemove 属性只能设置一个监听器。如果你多次设置 onmousemove,那么后面的设置会覆盖前面的设置。

    • 更推荐的做法是使用 addEventListener 方法来添加事件监听器,因为这种方法可以添加多个监听器到同一个事件。
  2. 事件的冒泡和捕获addEventListener 方法允许你选择是否在捕获阶段处理事件,只需要将第三个参数设置为 true 即可。而 onmousemove 只在冒泡阶段处理事件。

    element.addEventListener('click', function(event) {
    console.log('Clicked!');
    }, true);
  3. 监听的对象不同document 和 window 是两个不同的对象,它们的范围和行为可能会有所不同。在大多数情况下,鼠标移动事件会冒泡到这两个对象,所以你可能不会注意到它们之间的差异。但在某些特殊情况下,比如当你的页面包含滚动条或者是在一个 iframe 中时,document 和 window 可能会接收到不同的事件。

两种对象区别

window.addEventListener 和 document.addEventListener 都是用来在 JavaScript 中添加事件监听器的方法。它们的主要区别在于它们监听的对象不同:

  • window.addEventListener 是在全局 window 对象上添加事件监听器。这意味着,无论事件在文档的哪个部分发生,只要它最终到达了 window,就会触发该事件监听器。
  • document.addEventListener 是在 document 对象上添加事件监听器。由于 document 对象代表了 HTML 文档,因此,只有当事件在 HTML 文档内部发生并且冒泡到 document 时,才会触发该事件监听器。

至于哪个更推荐使用,这完全取决于你的具体需求。如果你希望在整个窗口范围内监听事件(包括滚动条、地址栏等),那么 window.addEventListener 可能是更好的选择。如果你只关心在 HTML 文档内部发生的事件,那么 document.addEventListener 可能更适合。在大多数情况下,两者可以互换使用,因为大多数事件都会从触发它的元素冒泡到 document,然后再冒泡到 window。但是,有些事件(如 loadunload 和 resize)只能在 window 上监听到。所以,你应该根据你的具体需求来选择使用哪个。

问题:无法监听到 mouseup 事件

应该可以通过监听 click 事件来代替

在某些情况下,你可能无法在浏览器中监听到 mouseup 事件。这可能是由于以下原因:

  1. 事件冒泡被阻止:如果在事件处理程序中调用了 event.stopPropagation(),那么 mouseup 事件将不会冒泡到 window 或 document。你需要检查是否有代码阻止了事件冒泡。
  2. 默认行为被阻止:如果在 mousedown 事件处理程序中调用了 event.preventDefault(),那么浏览器可能不会触发 mouseup 事件。你需要检查是否有代码阻止了默认行为。
  3. 事件监听器被移除:如果在 mousedown 或 mousemove 事件处理程序中移除了 mouseup 事件监听器,那么你将无法监听到 mouseup 事件。
  4. 验证码防护机制:对于一些验证码(如百度的旋转滑块验证码),它们可能使用了一些防护机制来防止自动化操作。这可能包括阻止事件冒泡、阻止默认行为、移除事件监听器,或者使用其他的技术手段。

Part3通过坐标点绘制移动轨迹

var data = [
    {
        "t": 1700642911180,
        "fx": 518,
        "fy": 418
    },
    {
        "t": 1700642911381,
        "fx": 524,
        "fy": 412
    },
    {
        "t": 1700642911690,
        "fx": 518,
        "fy": 393
    },
    {
        "t": 1700642911892,
        "fx": 590,
        "fy": 394
    }
];

var canvas = document.createElement('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.style.cssText = "position:absolute; top:0; left:0; z-index:9999; pointer-events:none";
document.body.appendChild(canvas);

var context = canvas.getContext('2d');
context.lineWidth = 2;

data.forEach(function(point, index) {
    // 绘制红色线条
    context.beginPath();
    context.strokeStyle = 'red';
    if (index !== 0) {
        context.moveTo(data[index - 1].fx, data[index - 1].fy);
        context.lineTo(point.fx, point.fy);
        context.stroke();
    }

    // 绘制黄色圆点
    context.beginPath();
    // 这里的第3个参数可以修改圆的半径
    context.arc(point.fx, point.fy, 4, 0, 2 * Math.PI, false);
    context.fillStyle = 'black';
    context.fill();

    // 添加序号标签
    context.beginPath();
    // 如果你改变了字体大小,你也应该相应地改变 textHeight 的值,以确保文本仍然能够垂直居中显示
    context.font = "6px Verdana";
    context.fillStyle = "white";
    var textWidth = context.measureText(index).width;
    var textHeight = 6; // 这是字体大小的近似值
    context.fillText(index, point.fx - textWidth / 2, point.fy + textHeight / 2);
});

  

 
   

 

标签:nDiv,鼠标,元素,验证码,var,滑动,document,event
From: https://www.cnblogs.com/yoyo1216/p/18576805

相关文章

  • 【验证码逆向专栏】某里 v2 滑动验证码分析
    声明本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作......
  • 【验证码逆向专栏】某多多验证码逆向分析
    声明本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作......
  • 简单实用的鼠标滑过图片遮罩层动画jQuery插件
    nsHover是一款简单实用的鼠标滑过图片遮罩层动画JQUERY插件。该插件可以在图片或块级元素上制作鼠标滑过时的遮罩层动画效果,它可以设置遮罩层的前景色和背景色,可以制作圆形图片等,非常实用。在线演示  下载 使用方法使用该鼠标滑过插件需要引入jQuery和ns.hover.min.js文......
  • Python 使用shapely、geopandas、matplotlib绘制全国各个省份2023年GDP热力图,鼠标点击
    以下是一个示例代码,用于在使用matplotlib和geopandas绘制地图并设置区域后,当鼠标点击地图上的某个区域时,返回该区域的名称。首先,确保你已经安装了matplotlib、geopandas和descartes库(descartes库用于在matplotlib中绘制地理空间数据)。如果没有安装,可以通过pipinstallmatplot......
  • 【C++习题】16.滑动窗口_最小覆盖子串
    文章目录题目链接:题目描述:解法C++算法代码:图解题目链接:76.最小覆盖子串题目描述:解法暴力解法:列出所有符合要求的字串,然后比较大小。滑动窗口+哈希表比如,如果已经符合要求了那么left右移一位的话,right需要移动吗?left指向的地方恰好有符合t的字符,-......
  • 【C++习题】15.滑动窗口_串联所有单词的子串
    文章目录题目链接:题目描述:解法C++算法代码:图解题目链接:30.串联所有单词的子串题目描述:解法滑动窗口+哈希表这题和第14题不同的是:哈希表不同:hash<string,int>left与right指针的移动不同:移动的步长是每个单词的长度滑动窗口执行的次数不同C++算法代......
  • 【LC】239. 滑动窗口最大值
    题目描述:给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回 滑动窗口中的最大值 。示例1:输入:nums=[1,3,-1,-3,5,3,6,7],k=3输出:[3,3,5,5,6,7]解释......
  • AutoHotkey (AHK) 是一款开源的自动化脚本语言,AutoHotkey(AHK)具备广泛的应用场景,适用于
    AutoHotkey(AHK)是一款开源的自动化脚本语言,主要用于Windows平台上的桌面应用程序自动化、键盘鼠标操作模拟、热键设置、窗口管理等任务。它的简单性和强大的灵活性使得AHK成为许多用户进行日常自动化和重复性任务的首选工具。1. AutoHotkey是什么?AutoHotkey是一种脚本......
  • 银河麒麟桌面系统——桌面鼠标变成x,窗口无关闭按钮的解决办法
    银河麒麟桌面系统——桌面鼠标变成x,窗口无关闭按钮的解决办法1、支持环境2、详细操作说明步骤1:用root账户登录电脑步骤2:导航到kylin-wm-chooser目录步骤3:编辑default.conf文件步骤4:重启电脑3、结语......
  • 【C++习题】14.滑动窗口_找到字符串中所有字母异位词
    文章目录题目链接:题目描述:解法C++算法代码:图解题目链接:438.找到字符串中所有字母异位词题目描述:解法暴力解法:字母排序后运用滑动窗口解题。滑动窗口+哈希表:我们可以优化一下,比如下面cba到bae,实际上只是把c去掉,加上一个e,没必要三个全删。left=......