选择:document.ready()上的目标

时间:2013-08-22 03:57:55

标签: javascript jquery cross-browser

以下是一个简单的测试用例,用于演示我正在尝试做的事情:

<html>
<head>
<title>Test</title>
</head>
<body>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function()
{
    $(":target").css('color', 'red');
});
</script>
<ul>
    <li id="one">One</li>
    <li id="two">Two</li>
    <li id="three">Three</li>
</ul>
</body>
</html>

想法是通过jQuery / Javascript对目标项目执行某些操作(例如,test.html#2)。

这正如我在Firefox和IE 10中预期的那样,但在Chrome,Opera或Safari中没有,这让我想知道这是否是某些浏览器中的错误,如果我想要做的是某种方式错误,或者如果我违反了某些规范或其他规范中不完全精确的部分。

如果我改变jQuery代码

alert($(":target").length);
很明显,Chrome,Opera和Safari在document.ready()期间找不到:target元素,但稍后调用相同的代码(通过附加到click事件的控制台或函数)会找到元素。 / p>

什么时候应该:JS可以访问目标?

5 个答案:

答案 0 :(得分:2)

这是作为评论发布的,但后来被删除了,您可以尝试等待窗口加载事件:

$(window).on('load hashchange', function(){
    $(':target').css('color', 'red');
});

这对我来说在Chrome上产生了混合结果,它在进行页面刷新(F5)时起作用,但在点击输入地址栏时却没有。

我不知道是否有任何方法可以使用:target选择器在页面加载时正确处理此问题,但您始终可以获取哈希值并将其用作选择器:

$(window).on('load hashchange', function(){
    var target = window.location.hash;
    $(target).css('color', 'red');
});

更新

我一直在研究这个问题以及一些测试,我有几个见解要分享:

首先,我们需要了解当调用$(':target') jQuery内部使用querySelectorAll(':target')时,这意味着它与伪类的CSS规范直接相关,但为什么不在内部工作document.ready()

好吧,我发现在setTimeout(fn,0)中包装代码实际上使选择器可用:

$(document).ready(function(){
    setTimeout(function(){
        $(':target').css('color', 'red'); //THIS WORKS
    },0);
});

您可以阅读this answer以获取有关如何添加零毫秒超时实际上有所作为的解释,但基本上它允许浏览器完成其他非JavaScript相关任务(我们会在其中找到实际的CSS伪类可用于查询)。我相信Firefox以某种方式管理其内部流程的方式不同,这就是为什么代码在那里工作而不需要超时。

现在我还发现jQuery的内部sizzle选择器引擎为不支持CSS :target伪类的浏览器提供了后备,你可以在document.ready()内使用它而不会出现问题:

$(document).ready(function(){
    $(':target()').css('color', 'red');
});

这是有效的,因为它不是依赖于CSS类,而是使用window.location对象上的hash属性的javascript实现,在内部定义如下:

"target": function( elem ) {
        var hash = window.location && window.location.hash;
        return hash && hash.slice( 1 ) === elem.id;
    }

唯一的想法是你应该注意的是,如果没有传递像:target(div)之类的选择器,这个函数将遍历页面上的每个元素,所以我相信使用我之前提供的解决方法仍然是比此

答案 1 :(得分:1)

因为页面未重新加载。您需要将其绑定到hashchange

$(window).on('hashchange', function(){
    $(":target").css('color', 'red');
});

http://jsfiddle.net/sXsYx/

请注意,您需要做更多工作才能做到正确,可能会将其与$(document).ready

结合使用

答案 2 :(得分:0)

您可以使用css3目标选择器进行样式化工作

:target
{
 color:red;
}

答案 3 :(得分:0)

由于您的示例(if语句等)中没有专门的逻辑,为什么不在CSS中进行样式设置? :target伪类是CSS3 selector

:target {
    color: red;
}

请注意,这适用于所有现代浏览器,甚至是一些非常旧的浏览器(例如Chrome 1和Firefox 1.3),但使用Internet Explorer时,仅从版本9开始支持。

如果您愿意,您也可以在这两个地方(CSS和JavaScript)执行此操作,但是,除非您特别需要IE&lt; = 8兼容性,否则JavaScript似乎是多余的。

我注意到你使用的是jQuery版本1.10.1,它保留了对IE&lt; = 8的支持。这很重要吗?如果没有,你也可以转到jQuery 2.0.2(编写本文时的最新版本)。

答案 4 :(得分:-1)

你应该这样做

$("li:target")

这将选择元素。这是更好的方式

请参阅,

http://api.jquery.com/target-selector/

或者您应该删除文档准备好并将脚本放在html文档的末尾