【问题标题】:When exactly does the :active pseudo class get applied:active 伪类究竟什么时候被应用
【发布时间】:2012-11-10 13:48:34
【问题描述】:

我试图使用querySelector 来查找页面中的活动元素。我假设绑定到文档上的 mousedown 事件的处理程序将触发 事件从目标返回后,这意味着应该已经应用了 :active 伪类。

document.addEventListener("mousedown",function(e){

    console.log(document.querySelector("*:active"));// logs null

    // expected value was the target of the mousedown event, that is,
    console.log(e.target);

});

我的问题是::active 伪类究竟适用于什么时候?请注意,当我记录该值时,mousedown 事件已在目标上触发。

有关示例,请参阅 http://jsfiddle.net/tK67w/2/。这里要注意的一件有趣的事情是,如果您在处理程序中设置断点,您可以看到我为 a:active 定义的 css 规则已经应用,尽管 querySelector 正在返回 null

编辑:

感谢 TJ 提出了一个更好的 demonstration。但问题仍然存在:在 IE 和 Chrome 以外的浏览器中,如何在所有活动元素变为活动元素时获取它们的 HTMLCollection?

【问题讨论】:

  • 它不会向我记录null,它会记录 html 元素。 e.target 记录锚点。
  • @bfavaretto 也许这是浏览器特定的问题?我正在使用火狐。 e.target 确实记录了锚点,但第一个记录了 null

标签: javascript css css-selectors dom-events pseudo-class


【解决方案1】:

我认为问题在于,当您使用 querySelector 时,您只会获得 first 活动元素。但是你的锚点在树的下方。

更新:有趣的是,我在 Firefox 或 Opera 上什么都没有,但我在 Chrome 上。以下是 Chrome 结果。请参阅下面的更多内容。

考虑 (live copy):

document.addEventListener("mousedown", handler, false);
function handler(e){
    console.log(
        "event " + e.type + ": " +
        Array.prototype.join.call(document.querySelectorAll("*:active")));
}​

当我单击锚点时,我会在控制台中看到:

事件 mousedown: [object HTMLHtmlElement],[object HTMLBodyElement],[object HTMLDivElement],http://fiddle.jshell.net/_display/#

注意最后的 URL,这是HTMLAnchroElement 实例的默认toString,由join 触发。

由于querySelectorAll 需要按文档顺序返回元素,如果您想要最具体的活动元素,您将使用最后一个。示例(live copy):

(function() {
    document.addEventListener("mousedown",handler, false);

    function handler(e){
        var active = document.querySelectorAll("*:active");
        var specific = active && active.length && active[active.length-1];
        display("Most specific active element: " +
                (specific ? specific.tagName : "(none)"));
    }

    function display(msg) {
        var p = document.createElement('p');
        p.innerHTML = String(msg);
        document.body.appendChild(p);
    }
})();
​

在我的例子中(使用 Chrome),我看到了最具体元素的标签名称(如果我单击链接,则为锚点等)。


Chrome 似乎遵循规范,而 Firefox 和 Opera 却没有。来自 CSS3 选择器规范的Section 6.6.1.2

:active 伪类在用户激活元素时应用。例如,在用户按下鼠标按钮并释放它的时间之间。

在我看来,:active 因此应该适用于上述情况。如果我们使用这个 CSS,这个断言就会被备份:

*:active {
    background-color: red;
}

...使用此 JavaScript:

(function() {
    document.addEventListener("mousedown", mouseDown, false);
    document.addEventListener("mouseup", mouseUp, false);

    function mouseDown(){
        var active = document.querySelectorAll("*:active");
        var specific = active && active.length && active[active.length-1];
        display("Mouse down: Most specific active element: " +
                (specific ? specific.tagName : "(none)"));
    }

    function mouseUp() {
        display("Mouse up");
    }

    function display(msg) {
        var p = document.createElement('p');
        p.innerHTML = String(msg);
        document.body.appendChild(p);
    }
})();

Live Copy

在我尝试过的所有三种浏览器(Chrome、Firefox、Opera)中,当鼠标按下时元素变为红色背景,当我释放它时又变为白色;但 mousedown 处理程序在 Firefox 或 Opera 中看不到 :active 元素,只有 Chrome。

但我不是 CSS 规范律师。 :-)

【讨论】:

  • 在我的控制台中,我看到:event mousedown: 。我正在使用 Firefox。
  • @Asad:有趣,似乎是浏览器的不同。 Chrome 给了我列表。
  • @Asad:当你创建 CSS *:active { ... } 而不是 span:active 时会更有趣(尤其是因为你的小提琴中没有跨度)。它在鼠标按下时被应用,但处理程序在querySelector(All) 中仍然看不到它。
  • @Asad:刚刚更新。我会说 Chrome 是,Firefox 和 Opera 不是。但这是我的解释。
  • 是的,span 是我将问题简化为示例时的疏忽。我最初有一个跨度。我已经在问题中提到了这种行为。
【解决方案2】:

似乎在帧被渲染之后设置,或者可能在当前执行队列之后设置,至少 Firefox 是这样。

立即使用setTimeout 获得结果(也适用于requestAnimationFrame):

document.addEventListener('mousedown', e => {

  setTimeout(_ => console.log(document.querySelectorAll(':active')));

});

【讨论】:

    猜你喜欢
    • 2015-10-12
    • 2018-09-20
    • 2014-09-09
    • 2023-02-25
    • 1970-01-01
    • 2019-12-31
    • 2021-04-15
    • 2017-12-11
    • 2021-08-03
    相关资源
    最近更新 更多