【探索】利用a:visited检测用户是否上过某个网站(已过时)
学习过HTML的无人不知a:visted的作用,但一般也只是给访问过的超链接换个颜色而已。既然可以改变颜色,当然也可以改变文字字体、大小等。若一个超链接文字只有10px大小,而它的:visted样式有60px,显然他所在的层会被撑开。如果固定了层的高度,那么取而代之的自然是一个垂直的滚动条。
配合脚本,我们创建一个a元素,置于固定尺寸的DIV,并设置上href属性。若是DIV出现滚动条,说明这个:visted样式被应用上了,这个href里的URI曾经被访问过。
原理是不是很简单。代码同样也很简单。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>看看你上过哪些网站</title> </head> <body> <style> .box { position: absolute; left: -999px; width: 30px; height: 30px; overflow: scroll; visibility: hidden; } a{font-size: 10px} a:visited{font-size: 60px} </style> <script> /** * history url detect * by etherdream */ var $c = function(t){return document.createElement(t)}; /* * 函数:hasVisted * 参数:url * 说明:检测最近是否访问过这个url * 原理:<a href='URL'>X</a> * 如果访问过这个url, * 那么a:visited 样式将被使用在此元素上。 * 通过脚本检测该样式产生的影响, * 即可判断是否访问过。 * * 本例通过设置超大字体, * 检测外层元素的滚动条来判定。 * 相信有更好的方法。 */ function hasVisted(url) { var div = $c("div"); var lnk = $c("a"); var h; div.className = "box"; lnk.href = url; lnk.innerHTML = "X"; div.appendChild(lnk); document.body.appendChild(div); h = div.scrollHeight; div.removeChild(lnk); document.body.removeChild(div); return h > 30; } </script> <p>你最近浏览过:</p> <script> var demo = [ "http://www.google.com", "http://www.baidu.com", "http://tieba.baidu.com", "http://hi.baidu.com", "http://www.qq.com", "http://qzone.qq.com", "http://www.163.com", "http://www.sina.com", "http://www.sohu.com", "http://www.cnblogs.com", "http://www.csdn.com", "http://bbs.blueidea.com" ]; var url; for(var i=0; i<demo.length; i++) { url = demo[i]; if(hasVisted(url)) document.write("<img src='" + url + "/favicon.ico' /> " + url + "<br />"); } </script> </body> </html>
当然,这里的滚动条总感觉有些累赘。事实上,更精简的方法还是有的。这里的滚动条只是为了得到一种状态的表现,而与其自身功能毫无关系。我们需要的仅仅是这么一个方法:获取元素最终变现出来的样式。这个方法是存在的,IE里有currentStyle属性,其他的浏览器则是getComputedStyle方法。因此就有了更简单的方法:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>看看你上过哪些网站</title> </head> <body> <style> a{display:none} a:visited{display:none; font-size:60px} </style> <script> function hasVisted(url) { var lnk = document.createElement("a"); lnk.href = url; document.body.appendChild(lnk); try{ var sty = lnk.currentStyle || getComputedStyle(lnk, null); return sty.fontSize == "60px"; } catch(e){} finally{ document.body.removeChild(lnk); } } </script> <p>你最近浏览过:</p> <script> var demo = [ "http://www.google.com", "http://www.baidu.com", "http://tieba.baidu.com", "http://hi.baidu.com", "http://www.qq.com", "http://qzone.qq.com", "http://www.163.com", "http://www.sina.com", "http://www.sohu.com", "http://www.cnblogs.com", "http://www.csdn.com", "http://community.csdn.net", "http://bbs.blueidea.com" ]; var url; for(var i=0; i<demo.length; i++) { url = demo[i]; if(hasVisted(url)) document.write("<img src='" + url + "/favicon.ico' /> " + url + "<br />"); } </script> </body> </html>
Demo:
当然凡事都有个例外。Chrome浏览器对:visted只能修改字体颜色,其他的都不会变化,并且getComputedStyle也是没法得到改变了的颜色值。不知这是一个BUG还是特意的安全性。(2010/10/1)