V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
shanlanlan
V2EX  ›  JavaScript

请问如何触发“移动端”的点击动作?

  •  
  •   shanlanlan · 2020-06-20 19:44:13 +08:00 · 3661 次点击
    这是一个创建于 1608 天前的主题,其中的信息可能已经有所发展或是发生改变。

    尝试给:m.taobao.com 添加 JavaScript 功能的时候,发现按钮不能用:domNode.click()模拟点击。 分析元素发现按钮其实是 div,并不是 button 。如果不使用 chrome 浏览器的模拟移动设备访问,改成 pc 访问,鼠标是不能点击的。 结合查询的资料,淘宝移动网页应该是监听了"touch"事件。 我使用了下面的代码尝试,未成功:

    //选定要操作的 dom 节点
    var elem =  document.querySelector("#submitBlock_1 > div > div > div > div:nth-child(3) > div:nth-child(2)");
    
    // 创建事件.
    var event = document.createEvent('Events');
    
    // 初始化一个点击事件,可以冒泡,无法被取消
    event.initEvent('touchstart', true, false);
    
    
    // 触发点击事件
    elem.dispatchEvent(event);
    
    

    请问各位,如何使用代码模拟“移动端点击”?

    12 条回复    2020-06-22 01:24:38 +08:00
    wxsm
        1
    wxsm  
       2020-06-20 19:50:58 +08:00   ❤️ 1
    试试 touchend
    shanlanlan
        2
    shanlanlan  
    OP
       2020-06-20 19:57:15 +08:00
    @wxsm #1 原文:“试试 touchend”
    ======
    回复:#1 其实“ontouchstart”能触发。但是页面的按钮没有反应。比如代码触发“ontouchstart”后,控制台能打印出淘宝的锚点日志信息。说明锚点是监听了这个事件。我也尝试过触发`touchend`,按钮没有反应。我猜想触发按钮的效果不是这 2 个事件。我再试试。
    shanlanlan
        3
    shanlanlan  
    OP
       2020-06-20 20:04:39 +08:00
    测试链接在这里,这里面的勾选和提交订单按钮都不能直接通过 click 触发。也尝试过“touchstart 和 touchend”。均不能触发。
    pinkSlime
        5
    pinkSlime  
       2020-06-20 21:10:23 +08:00   ❤️ 1
    devtools 里面的 Event Listeners 里面瞅一眼对应的元素到底绑了什么事件
    shanlanlan
        6
    shanlanlan  
    OP
       2020-06-20 21:29:04 +08:00
    @pinkSlime #5 原文:“devtools 里面的 Event Listeners 里面瞅一眼对应的元素到底绑了什么事件”
    ======
    回复:#5 绑定的还挺多:
    ![image.png]( https://i.loli.net/2020/06/20/VZr1zTUyOxdFEXG.png)
    mostkia
        7
    mostkia  
       2020-06-20 21:50:10 +08:00   ❤️ 1
    试试合成事件,直接模拟交互操作
    shanlanlan
        8
    shanlanlan  
    OP
       2020-06-20 23:10:07 +08:00
    @mostkia #7 原文:“试试合成事件,直接模拟交互操作”
    ======
    回复:#7 还没试过,我查查资料。
    mostkia
        9
    mostkia  
       2020-06-21 10:06:06 +08:00   ❤️ 1
    @shanlanlan 嗯,js 的合成事件能够主动模拟 UI 交互激活相关的事件句柄,具体方法如下:
    ```
    //注册事件类型(我这边选了最常见的鼠标事件作为例子)
    var evObj = document.createEvent('MouseEvents');
    //模拟场景(参数很多,有些我也不太懂,大都是关于当前事件模拟鼠标的状态的)
    evObj.initMouseEvent('click',true,true,window,1,10,10,10,10,false,false,false,false,2,null);
    //将设定好的合成事件作用到你想手动激活的元素上
    document.querySelector('.conInt_tag_btn > a').dispatchEvent(evObj);
    ```
    不过需要注意的一点,我这边实际使用时发现,必须是绑定了自定义的事件的元素才有效,无法激活浏览器默认事件,比如一个没有任何 js 代码关联的超链接<a>,手动点击肯定能跳转,但它是没有绑定 js 事件,使用该方法就无法主动激活。具体可以百度一下相关的资料,网上很多的。
    ccraohng
        10
    ccraohng  
       2020-06-21 11:09:46 +08:00   ❤️ 1
    TouchEvent 合成 touchstart touchend 事件, 不过 isTrusted 直接降维打击
    shanlanlan
        11
    shanlanlan  
    OP
       2020-06-22 01:23:09 +08:00
    @ccraohng #10 原文:“TouchEvent 合成 touchstart touchend 事件, 不过 isTrusted 直接降维打击”
    ======
    回复:#10

    尝试下面代码进行合成操作,但是如你所述,确实在源代码里发现了`isTrusted`方法。而且是在每次触摸的时候都会调用。
    ```javascript
    var elem = document.querySelector("#confirmOrder_1 > div.tpl-wrapper > div > div");

    var touch = new Touch({
    identifier: 42,
    target: elem,
    clientX: 200,
    clientY: 200,
    screenX: 300,
    screenY: 300,
    pageX: 200,
    pageY: 200,
    radiusX: 5,
    radiusY: 5
    });

    //开始合成事件

    // 创建事件.
    var event = document.createEvent('Events');

    // 初始化一个按下事件
    var touchEventStart = new TouchEvent("touchstart", {
    cancelable: true,
    bubbles: true,
    composed: true,
    touches: [touch],
    targetTouches: [touch],
    changedTouches: [touch]
    });
    // 触发按下事件
    elem.dispatchEvent(touchEventStart);

    // 初始化一个抬起事件
    var touchEventEnd = new TouchEvent("touchend", {
    cancelable: true,
    bubbles: true,
    composed: true,
    touches: [touch],
    targetTouches: [touch],
    changedTouches: [touch]
    });
    // 触发点击抬起事件
    elem.dispatchEvent(touchEventEnd);
    ```

    网站被混淆过的代码地址: https://g.alicdn.com/secdev/sufei_data/3.8.7/index.js:formatted
    ```javascript
    function a(n) {
    Y = n.isTrusted;
    var t = n.touches[0];
    K = t.clientX,
    Z = t.clientY,
    F++,
    nn = o(tn, rn)
    }
    ```
    shanlanlan
        12
    shanlanlan  
    OP
       2020-06-22 01:24:38 +08:00
    11L 的 js 链接有误: https://g.alicdn.com/secdev/sufei_data/3.8.7/index.js

    另外目前失去头绪,暂未解决。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1151 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 83ms · UTC 22:57 · PVG 06:57 · LAX 14:57 · JFK 17:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.