【问题标题】:What can cause click() method to fail?什么会导致 click() 方法失败?
【发布时间】:2018-03-30 00:14:27
【问题描述】:

我有一个元素(一个复选框),带有这个 HTML:

<button type="button" class="_f_V1 noMargin o365button" aria-labelledby="_ariaId_28" role="checkbox" aria-checked="false">
    <span class="_fc_3 owaimg checkboxImage wf-size-checkboxMultiselectSize ms-bg-color-white ms-border-color-neutralSecondaryAlt"> </span>
    <span class="_fc_4 o365buttonLabel _fc_2" id="_ariaId_28" style="display: none;"></span>
</button>

请注意,它是一个按钮元素,尽管它的行为类似于 &lt;input [type="checkbox"]&gt;

我的目标是使用click() 方法选择并单击此元素。选择正确,但click()方法失败。

我做了什么:

document.querySelector('._f_V1.noMargin.o365button').click();

但什么也没发生 - 复选框不会被选中。

鉴于这个(第一个)元素只是类似元素列表中的一个,我也尝试过:

(()=>{
    document.querySelectorAll('button span').forEach((e)=>{
        e.click()
    });
})();

同样,第一个复选框和任何其他复选框都没有被选中。

通过在控制台中运行querySelector()querySelectorAll()(及其相关的选择器),我得到了我想要的元素(我没有得到undefined),所以这意味着我的选择是正确的。

既然选择正确,为什么click()方法无效?

当我用鼠标点击时 --- 复选框被选中,但是当我在同一个元素上使用 click() 时,它没有。

如果您想尝试在线复制,您需要有一个 Hotmail 电子邮件帐户,其中包含您已删除的邮件。如果是这种情况:


  1. 转到“已删除项目”。
  2. 转到“恢复已删除的项目”。
  3. 将打开一个窗口,其中包含已删除的对话。
  4. 在每个对话附近都会有一个复选框(鼠标悬停后)。这是我遇到问题的元素。

注意:鼠标悬停只会改变复选框的不透明度。

【问题讨论】:

  • 能否提供代码 sn-p 以便我查看?
  • e.setAttribute("aria-checked", "true") 代替e.click() 怎么样
  • 你确定你在屏幕上看到的元素真的和你附加点击事件的一样吗?
  • Dhaval, this 没有显示整个代码。似乎需要更多的 HTML,但鉴于没有任何有效的方法来复制 DOM 代码(至少,不是我所知道的),遗憾的是,即使我想要,我也可能不会提供这样的东西...
  • @dann,我已经用setAttribute() 尝试了几个操作,包括您给出的确切示例,但没有帮助。

标签: javascript jquery html css checkbox


【解决方案1】:

您可以使用 jQuery click method 尝试它,它只适用于创建的 jQuery 集合,例如:

jQuery( 'your whatever selector(s) here' ) // form here on you can call .click() now

因此,对于您的具体方法,您可以这样做:

jQuery('._f_V1.noMargin.o365button').click();

还有:

jQuery('button span').click();

由于 jQuery click 方法仅在 jQuery 集合的第一个 DOM 元素上触发点击事件,您可以将其与 jQuery method each 组合如下:

jQuery('._f_V1.noMargin.o365button').each(function() {
    $(this).click();
});

还有:

jQuery('button span').each(function() {
    $(this).click();
});

【讨论】:

  • Axel,我可以发誓我有几个案例至少 document.querySelector('something').click(); 有效。无论如何,jQuery('button span').click(); 似乎有效,但它在一个元素之后停止。在通过一些 jQuery QA 会话的快速搜索中,我没有找到如何在 jQuery 中模拟 document.querySelectorAll(我只知道香草,从未使用过 jQuery)。你将如何模仿这个?
  • @fayalikt 看到我的更新,如果它不适合你,请随时发表评论......
  • @fayalikt 我现在有点没时间了 - 但会添加一些额外信息以便您更好地理解 - 好吗?
  • @Kaiido 非常感谢你我不知道!您永远不会停止学习,并且会尽快更新我的答案
  • 当然,阿克塞尔,我来了。 Danke schon(对不起,没有 omlauts)的一切!
【解决方案2】:
 function handelClick(){
  if(this.getAttribute("aria-checked")=="true"){
   this.setAttribute("aria-checked", "false");
  }else{
  this.setAttribute("aria-checked", "true");
 }
}
var button=document.getElementsByTagName('button');

for (var i = 0; i < button.length; i++) {
 button[i].addEventListener('click', handelClick);}

 goto https://jsfiddle.net/7xnwpgbk/5/
 it may help you

【讨论】:

  • 遗憾的是代码在 hotmail.com 中不起作用(他们似乎实现了一些导致不自然行为的库)。
【解决方案3】:

如果问题是:

什么会导致 click() 方法失败?

那么答案是:Kinda NOTHING! 如果click-method 可用于 HTMLElement,那么调用 HTMLElement.click() 就不会“失败”(在这个意义上)。可能发生的情况是,在此元素上调用 click 不会产生预期的效果/影响——问题作者就是这种情况! “只是为了完整性......”


经过深入调查,这是我的结论。

  1. 负责检查和取消检查的实际事件处理程序(以及与之相关的所有内容)是在这些button._f_V1.noMargin.o365button-元素(boot.worldwide.0.mouse.js:37)上“侦听”mousedown-事件的回调;所以你不会在任何地方触发click-events。有人可能会问:“你怎么能这么说?”。我可以这么说是因为我删除了所有其他事件侦听器,首先遍历两个父元素,然后从那里一直向下遍历每个子元素,除了我离开 mousedown-eventListener 的button。并且功能仍然完好无损。在删除最后一个事件侦听器后,功能就消失了。所以我猜:是的,我可以这么说:)
  2. 我的下一步是在button 上触发mousedown-事件,如下所示:

    $('._f_V1.noMargin.o365button').each(function() {
        $(this).mousedown();
    })
    

    但是不,这不起作用。

  3. 那么,像这样在每个可能相关的元素上歇斯底里地触发事件呢:

    var $El = $('._f_V1.noMargin.o365button').parent().parent();
    $El.add( $El.find('*') ).each(function() {
        $(this).mousedown().mouseup().click();
        // may be one event is cancelling the result of another one out
        // so I also tried $(this).mousedown()
    });
    

    不 - 这也不起作用。

  4. 所以我想出了我的最后一种方法,它也不起作用。让我们从选定的button 中模拟属性和属性。顺便说一句,实际上负责使“伪复选框”看起来像选中/未选中的元素是button-元素的第一个span-childNode。因此,如果您在浏览器 devtool 的控制台中输入以下代码,所有内容都将与正确单击(或者说鼠标按下)完全相同:

    $('._f_V1.noMargin.o365button').each(function() {
        $(this).trigger('mousedown').addClass('_f_V1 noMargin o365button _f_W1').attr('aria-checked', 'true').prop('aria-checked', true)
            .children(':first').trigger('mousedown').addClass('_fc_3 owaimg ms-Icon--check wf-size-checkboxMultiselectSize ms-bgc-w ms-fcl-nsa-b ms-fcl-ns-b ms-border-color-neutralSecondaryAlt')
                .parent().parent().parent().trigger('mousedown').attr('aria-selected', 'true').prop('aria-selected', true)
    })
    

    请参阅下面的屏幕截图,我将上面的 sn-p 直接粘贴到 devtools 控制台中,并且“伪复选框”在单击时出现。


那么现在该怎么办?问另一个问题!一个更具体的。类似于:“如何 [recover|deepDelete] hotmail.com 中所有已删除的邮件” 因为这是问题的实际意图 - 不确定,但我猜。


只想再次强调这一点:通常来自 OP 的代码以及此答案中的代码都有效。可以这么说,它确实是正确的。但它无法达到作者想要达到的效果。


另外,这里是 OPs 代码实际工作的证明:

document.querySelector('._f_V1.noMargin.o365button').addEventListener(
  'click', function() { console.log('jepp') }
);

document.querySelector('._f_V1.noMargin.o365button').click();
// BTW: yep HTMLElement.click() returns undefined
console.log(
  'yep HTMLElement.click() returns: ',
  document.querySelector('._f_V1.noMargin.o365button').click()
)
button {width: 100%; height: 100%; position: fixed}
<button type="button" class="_f_V1 noMargin o365button" aria-labelledby="_ariaId_28" role="checkbox" aria-checked="false">
    <span class="_fc_3 owaimg checkboxImage wf-size-checkboxMultiselectSize ms-bg-color-white ms-border-color-neutralSecondaryAlt"> </span>
    <span class="_fc_4 o365buttonLabel _fc_2" id="_ariaId_28" style="display: none;"></span>
</button>

【讨论】:

  • 阿克塞尔,非常感谢。竖起大拇指。请编辑和删除一些示例末尾的's'。为了简短起见,最好以单数方式编写示例,通常就足够了。关于你写的最后一件事> [recover|deepDelete] hotmail.com 中所有已删除的邮件> 好吧,你能试着重新解释一下你认为那里发生的事情吗?
  • @fayalikt 抱歉,我应该重新解释什么?
  • 对不起,我的意思是引用答案中的这句话:[recover|deepDelete] all deleted messages in hotmail.com
  • @fayalikt 这是一个建议。您要检查“伪复选框”(我已经回答过......)还是要从已删除文件夹中恢复/删除项目?如果是后者,那么特别要求这个。你知道我的意思吗?
  • 我现在明白你的意思了。我个人的意思只是为了选择伪复选框(好术语,我应该这样描述它^__^)。据我从您的回答中了解到,您说在click()setAttribute() 方法中检查这些伪复选框是不可能?正确的?也许我错过了第三种方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多