CSS/JavaScript/hacking:Detect:在链接*上访问样式,而不*直接检查,或者比我快
这是为了研究 考虑以下代码:CSS/JavaScript/hacking:Detect:在链接*上访问样式,而不*直接检查,或者比我快,javascript,css,history,Javascript,Css,History,这是为了研究 考虑以下代码: <style> div.csshistory a { display: none; color: #00ff00;} div.csshistory a:visited { display: inline; color: #ff0000;} </style> <div id="batch" class="csshistory"> <a id="1" href="http://foo.com">anythin
<style>
div.csshistory a { display: none; color: #00ff00;}
div.csshistory a:visited { display: inline; color: #ff0000;}
</style>
<div id="batch" class="csshistory">
<a id="1" href="http://foo.com">anything you want here</a>
<a id="2" href="http://bar.com">anything you want here</a>
[etc * ~2000]
</div>
div.cshistory a{显示:无;颜色:#00ff00;}
div.cshistory a:已访问{显示:内联;颜色:#ff0000;}
[etc*~2000]
我的目标是检测foo是否已使用:visted样式进行渲染
$('1').getComputedStyle
(或在Internet Explorer中,currentStyle
)或该元素上的任何其他直接方法
这样做的目的是绕过一个潜在的浏览器限制,这将阻止直接检查访问链接的样式
例如,您可以在和中放置一个子元素以获得当前速度测试结果
中,我正在咨询和其他一些相当知名的安全研究人员
如果你贡献了一种新的方法或加速,你会在(如果你想成为:-p)得到感谢,并且可能会在未来发表的论文中得到感谢
ETA:赏金只会因以下建议而获得奖励:
- 在Firefox上,可以避免上面第1点中描述的假设限制,或者
- 在我有足够当前数据的任何浏览器上,执行速度至少比下面图表中列出的最佳执行方法快10%
如果不止一个建议符合任何一个标准,那么做得最好的人获胜
ETA 2:我添加了前两个最佳测试方法的基于宽度的变体(reuse_noinsert,Firefox/Mozilla上的最佳测试方法,以及mass_insert,其非常接近的竞争对手)。请从不同的浏览器多次访问;我会自动得到速度测试结果,这样我们就能知道它是否比以前的方法好,如果是的话,会比以前的方法好多少。谢谢
ETA 3:目前的测试表明,使用offsetWidth
(而不是getCalculatedStyle
/currentStyle
)在Chrome中可以节省约2ms(1.8%)的速度,在Firefox中可以节省约24ms(4.3%)的速度,这不是我想要获得丰厚奖金的10%。你知道如何弥补剩下的10%吗?[新更新]
如果您只想将结果用于视觉演示,那么最快的方法就是使用CSS计数器
CSS:
这将在id为“results”的元素之前添加已访问链接的数量
不幸的是,无法从JavaScript访问它,只能显示它
[初始答案]
您知道jQuery直接支持:visted
选择器吗
比如$('a:visted')
[更新]
或者,您可以应用一个CSS属性,该属性不依赖于getComputedStyle
进行检索
像a:visted{height:1px;display:block;}
然后检查offsetHeight
在锚点内添加子对象(例如跨度)
使用color:inherit
检测子对象的颜色(JS)
警告:恐怕它在lte ie7上不起作用
对于lte ie7,我们必须
- 在子对象上添加
可见性:隐藏和可见性:继承
- 使用javascript检查子对象的可见性(hidden=visited)
一个类似的想法,但避开了
。getComputedStyle()
:
a:已访问{显示:内联块;字体系列:monospace;}
正文{字体系列:无衬线;}
功能测试(){
var visited=document.getElementById(“v”).childNodes[1].firstChild.clientWidth;
var unvisited=document.getElementById(“u”).childNodes[1].firstChild.clientWidth;
var rows=document.getElementsByTagName(“tr”);
for(变量i=1,长度=rows.length;i
当然,诀窍是确保已访问和未访问的链接具有不同的宽度(这里,通过使用sans-serf和monospace字体),并将它们设置为内联块
,以便可以通过clientWidth
访问它们的宽度。经测试可在FF3.6、IE7、Chrome 4和Opera 10上运行
在我的测试中,访问clientWidth
的速度始终比任何依赖于计算样式的东西都要快(有时高达40%,但差异很大)
(哦,为这些废话道歉;我已经很久没有在IE中尝试在没有框架的情况下执行事件了,我已经厌倦了与之抗争。)由于IE的所有版本(是的,即使启用了怪癖的版本8)都支持CSS表达式,因此color属性仍然不安全。您可能可以通过以下方法加快IE测试(未经测试):
此外,您的问题并未真正涉及到这一点,但您当然可以非常轻松地在子节点中设置属性以启动检测,任何解决方案都必须防止:
a.google:visited span { background-image: url(http://example.com/visited/google); }
您还需要保护相邻的兄弟姐妹,而不仅仅是后代:
a.google:visited + span { }
也
a:visited { color: expression( arrVisited.push(this.href) ); }
a.google:visited span { background-image: url(http://example.com/visited/google); }
a.google:visited + span { }
a.google:visited:before {content: "visited"; visibility: hidden;}
visited links = document.evaluate('//a[text()="visited"]')