Правильно, для javascript невозможно определить, посещена ли ссылка в Firefox или Chrome, которые являются единственными 2 браузерами, применимыми в этом контексте Greasemonkey .
Этопотому что Firefox и Chrome серьезно относятся к безопасности и конфиденциальности.От спецификация CSS2 :
Примечание.Авторы таблиц стилей могут использовать псевдоклассы: link и: visit, чтобы определить, какие сайты посетил пользователь без согласия пользователя.
Таким образом, UA могут обрабатывать все ссылки как непосещенные ссылки или внедрять другие.меры по сохранению конфиденциальности пользователя при различном отображении посещенных и не посещенных ссылок.См. [P3P] для получения дополнительной информации о конфиденциальности.
См. Также, "Конфиденциальность и селектор посещений"
Вы можете увидеть демонстрацию, показывающую, что браузеры secure-ish не позволят вам прослушивать посещенные ссылки на jsfiddle.net / n8F9U .
Для вашей конкретной ситуации , поскольку вы посещаете страницу и держите ее открытой, вы можете помочьскрипт отслеживания того, какие ссылки были посещены.Это не защищает от ошибок, но я верю, что это сделает то, о чем вы просили.
Сначала посмотрите сценарий в действии , выполнив следующее:
- Установите скрипт, как есть.
- Перейдите на тестовую страницу, jsbin.com / eledog .
Тестовая страница добавляет новую ссылку при каждой перезагрузке илиобновлен. Сценарий GM добавляет 2 кнопки к страницам, на которых он работает.Кнопка «Пуск / Стоп» в левом верхнем углу и кнопка «Очистить» в правом нижнем углу.
При нажатии кнопки «Пуск» выполняется следующее:
- Все существующие ссылки на странице регистрируются как «посещенные».
- Запускает таймер (настройка по умолчанию: 3 секунды), когда таймер выключается, он перезагружает страницу.
- КаждаяКогда страница перезагружается, она открывает все новые ссылки и запускает новый таймер перезагрузки.
- Нажмите кнопку «Стоп», чтобы остановить перезагрузку, список посещенных ссылок сохраняется.
Кнопка «Очистить» стирает список посещенных страниц.
ВНИМАНИЕ: Если вы нажмете «Очистить», когда активен цикл обновления, то в следующий разстраница перезагрузится, все ссылки будут открыты в новых вкладках.
Далее, для использования скрипта наваш сайт ...
Внимательно прочитайте комментарии в сценарии, вам придется изменить значения @include
, @exclude
и selectorStr
, чтобы они соответствовали сайту, который вы используете.
Для достижения наилучших результатов отключите все надстройки «Перезагрузить каждый» или «Автообновление».
Важные примечания:
Скрипт должен использовать постоянное хранилище для отслеживания ссылок.
Возможны следующие варианты: куки, sessionStorage
, localStorage
, globalStorage
, GM_setValue()
и IndexedDB
.
Все они имеют недостатки, и в этом случае (один сайт, потенциально огромное количество ссылок, несколько сеансов), localStorage
являетсялучший выбор (IndexedDB
может быть, но он все еще слишком нестабилен - вызывает частые сбои FF на моем компьютере).
Это означает, что ссылки могут отслеживаться только для отдельных сайтов, и это "Утилиты безопасности, конфиденциальности и очистки могут блокировать или стирать список посещенных ссылок.(Точно так же, очистка истории браузера сбросит любой стиль CSS для посещенных ссылок.)
На данный момент скрипт предназначен только для Firefox.Он не должен работать на Chrome, даже с установленным Tampermonkey, без небольшой доработки.
Сценарий:
/*******************************************************************************
** 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; \
} \
" );