如何检测页面上访问和未访问的链接?

我的目标是检测网页上的未经访问的链接,然后创build一个用于点击这些链接的greasemonkey脚本。 通过这里unvisited链接我的意思是不是由我打开的链接。 由于我可以看到所有的浏览器提供了改变访问和未访问链接的颜色的能力,因此可以以任何方式检测这些链接。 虽然search我来到这个链接: http : //www.mozdev.org/pipermail/greasemonkey/2005-November/006821.html但有人在这里告诉我,这是不可能的。 请帮忙。

正确的说,javascript无法检测是否在Firefox或Chrome中访问了一个链接 – 这是在这个Greasemonkey上下文中唯一可用的两个浏览器。

这是因为Firefox和Chrome认真对待安全和隐私。 从CSS2规范 :

注意。 样式表作者可能会滥用:link和:visited伪类来确定用户未经用户同意访问过哪些网站。

因此,UA可能将所有链接视为未访问的链接,或者实施其他措施来保护用户的隐私,同时呈现访问和未访问的链接。 有关处理隐私的更多信息,请参见[P3P]。

另请参阅“隐私和访问select器”
你可以看到一个演示,显示安全浏览器不会让你嗅探jsfiddle.net/n8F9U访问过的链接。




对于您的具体情况 ,因为您正在访问一个页面并保持打开状态,您可以帮助脚本logging访问的链接。 这不是傻瓜,但我相信它会做你所要求的。

首先,通过执行以下操作查看脚本

  1. 按原样安装脚本。
  2. 浏览到testing页面jsbin.com/download 。
    testing页面每次重新加载或刷新时都会添加一个新的链接。
  3. GM脚本在运行的页面上添加2个button。 左上angular的“开始/停止”button和右下angular的“清除”button。

    当您按下“开始”button时,它会执行以下操作:

    1. 该页面上的所有现有链接都logging为“已访问”。
    2. 它启动一个定时器(默认设置:3秒),当定时器closures时,它重新加载页面。
    3. 每次页面重新加载,它都会打开任何新的链接,并启动一个新的重载计时器。
    4. 按“停止”button停止重新加载,访问的链接列表被保留。

    “清除”button擦除访问页面的列表。
    警告:如果在刷新循环处于活动状态时按下“清除”,则下一次页面重新加载时, 所有链接将在新选项卡中打开。

接下来, 要在您的网站上使用该脚本

仔细阅读脚本中的注释,您将不得不更改@include @exclude@include @excludeselectorStr值以匹配您正在使用的网站。

为获得最佳效果,请禁用任何“重新加载每个”加载项或“自动更新”选项。

重要笔记:

  1. 该脚本必须使用永久存储来跟踪链接。
    选项包括:cookies, sessionStoragelocalStorageglobalStorageGM_setValue()IndexedDB

    这些都有缺点,在这种情况下(单个站点,可能数量巨大的链接,多个会话), localStorage是最好的select( IndexedDB可能是,但仍然太不稳定 – 导致我的机器频繁的FF崩溃)。

    这意味着链接只能在每个站点的基础上进行跟踪,“安全”,“隐私”或“更清洁”的工具可以阻止或清除已访问的链接列表。 (就像清除浏览器的历史logging一样,将重置访问链接的任何CSS样式。)

  2. 目前,该脚本仅限于Firefox。 它不应该在Chrome上运行,即使安装了Tampermonkey,也不需要重新devise。


剧本:

 /******************************************************************************* ** This script: ** 1) Keeps track of which links have been clicked. ** 2) Refreshes the page at regular intervals to check for new links. ** 3) If new links are found, opens those links in a new tab. ** ** To Set Up: ** 1) Carefully choose and specify `selectorStr` based on the particulars ** of the target page(s). ** The selector string uses any valid jQuery syntax. ** 2) Set the @include, and/or, @exclude, and/or @match directives as ** appropriate for the target site. ** 3) Turn any "Auto update" features off. Likewise, do not use any ** "Reload Every" addons. This script will handle reloads/refreshes. ** ** To Use: ** The script will place 2 buttons on the page: A "Start/Stop" button in ** the upper left and a "Clear" button in the lower left. ** ** Press the "Start" button to start the script reloading the page and ** opening any new links. ** When the button is pressed, it is assumed that any existing links have ** been visited. ** ** Press the "Stop" button to halt the reloading and link opening. ** ** The "Clear" button erases the list of visited links -- which might ** otherwise be stored forever. ** ** Methodology: ** Uses localStorage to track state-machine state, and to keep a ** persistent list of visited links. ** ** Implemented with jQuery and some GM_ functions. ** ** For now, this script is Firefox-only. It probably will not work on ** Chrome, even with Tampermonkey. */ // ==UserScript== // @name _New link / visited link, tracker and opener // @include http://jsbin.com/* // @exclude /\/edit\b/ // @require http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js // @grant GM_addStyle // ==/UserScript== /*- The @grant directive is needed to work around a design change introduced in GM 1.0. It restores the sandbox. */ //--- Key control/setup variables: var refreshDelay = 3000; //-- milliseconds. var selectorStr = 'ul.topicList a.topicTitle'; //--- Add the control buttons. $("body") .append ( '<div id="GM_StartStopBtn" class="GM_ControlWrap">' + '<button>Start checking for new links.</button></div>' ) .append ( '<div id="GM_ClearVisitListBtn" class="GM_ControlWrap">' + '<button>Clear the list of visited links.</button></div>' ); $('div.GM_ControlWrap').hover ( function () { $(this).stop (true, false).fadeTo ( 50, 1); }, function () { $(this).stop (true, false).fadeTo (900, 0.8); }// Coordinate with CSS. ); //--- Initialize the link-handler object, but wait until the load event. var stateMachine; window.addEventListener ("load", function () { stateMachine = new GM_LinkTrack ( selectorStr, '#GM_StartStopBtn button', '#GM_ClearVisitListBtn button', refreshDelay ); /*--- Display the current number of visited links. We only update once per page load here. */ var numLinks = stateMachine.GetVisitedLinkCount (); $("body").append ('<p>The page opened with ' + numLinks + ' visited links.</p>'); }, false ); /*--- The link and state tracker object. Public methods: OpenAllNewLinks () StartStopBtnHandler () ClearVisitedLinkList () StartRefreshTimer (); StopRefreshTimer (); SetAllCurrentLinksToVisited () GetVisitedLinkCount () */ function GM_LinkTrack (selectorStr, startBtnSel, clearBtnSel, refreshDelay) { var visitedLinkArry = []; var numVisitedLinks = 0; var refreshTimer = null; var startTxt = 'Start checking for new links.'; var stopTxt = 'Stop checking links and reloading.'; //--- Get visited link-list from storage. for (var J = localStorage.length - 1; J >= 0; --J) { var itemName = localStorage.key (J); if (/^Visited_\d+$/i.test (itemName) ) { visitedLinkArry.push (localStorage[itemName] ); numVisitedLinks++; } } function LinkIsNew (href) { /*--- If the link is new, adds it to the list and returns true. Otherwise returns false. */ if (visitedLinkArry.indexOf (href) == -1) { visitedLinkArry.push (href); var itemName = 'Visited_' + numVisitedLinks; localStorage.setItem (itemName, href); numVisitedLinks++; return true; } return false; } //--- For each new link, open it in a separate tab. this.OpenAllNewLinks = function () { $(selectorStr).each ( function () { if (LinkIsNew (this.href) ) { GM_openInTab (this.href); } } ); }; this.StartRefreshTimer = function () { if (typeof refreshTimer != "number") { refreshTimer = setTimeout ( function() { window.location.reload (); }, refreshDelay ); } }; this.StopRefreshTimer = function () { if (typeof refreshTimer == "number") { clearTimeout (refreshTimer); refreshTimer = null; } }; this.SetAllCurrentLinksToVisited = function () { $(selectorStr).each ( function () { LinkIsNew (this.href); } ); }; this.GetVisitedLinkCount = function () { return numVisitedLinks; }; var context = this; //-- This seems clearer than using `.bind(this)`. this.StartStopBtnHandler = function (zEvent) { if (inRefreshCycle) { //--- "Stop" pressed. Stop searching for new links. $(startBtnSel).text (startTxt); context.StopRefreshTimer (); localStorage.setItem ('inRefreshCycle', '0'); //Set false. } else { //--- "Start" pressed. Start searching for new links. $(startBtnSel).text (stopTxt); localStorage.setItem ('inRefreshCycle', '1'); //Set true. context.SetAllCurrentLinksToVisited (); context.StartRefreshTimer (); } inRefreshCycle ^= true; //-- Toggle value. }; this.ClearVisitedLinkList = function (zEvent) { numVisitedLinks = 0; for (var J = localStorage.length - 1; J >= 0; --J) { var itemName = localStorage.key (J); if (/^Visited_\d+$/i.test (itemName) ) { localStorage.removeItem (itemName); } } }; //--- Activate the buttons. $(startBtnSel).click (this.StartStopBtnHandler); $(clearBtnSel).click (this.ClearVisitedLinkList); //--- Determine state. Are we running the refresh cycle now? var inRefreshCycle = parseInt (localStorage.inRefreshCycle, 10) || 0; if (inRefreshCycle) { $(startBtnSel).text (stopTxt); //-- Change the btn lable to "Stop". this.OpenAllNewLinks (); this.StartRefreshTimer (); } } //--- Style the control buttons. GM_addStyle ( " \ .GM_ControlWrap { \ opacity: 0.8; /*Coordinate with hover func. */ \ background: pink; \ position: fixed; \ padding: 0.6ex; \ z-index: 666666; \ } \ .GM_ControlWrap button { \ padding: 0.2ex 0.5ex; \ border-radius: 1em; \ box-shadow: 3px 3px 3px gray; \ cursor: pointer; \ } \ .GM_ControlWrap button:hover { \ color: red; \ } \ #GM_StartStopBtn { \ top: 0; \ left: 0; \ } \ #GM_ClearVisitListBtn { \ bottom: 0; \ right: 0; \ } \ " ); 

你可以parsing页面上的所有链接,并获得他们的CSS颜色属性。 如果链接的颜色与您在CSS中定义的未访问链接的颜色相匹配,则此链接未被访问。

这种技术通常用于确定所有访问过的链接。 这是一种安全漏洞,允许您确定用户是否访问了特定的网站。 通常由低劣的营销人员使用。

这种伎俩通常被归类为“浏览器的历史操纵技巧”。

更多信息附加码: http : //www.stevenyork.com/tutorial/getting_browser_history_using_javascript