javascript - tag - ¿Cómo puedo detectar enlaces visitados y no visitados en una página?
title js (2)
Mi objetivo es detectar los enlaces no visitados en una página web y luego crear un script greasemonkey para hacer clic en esos enlaces. Por enlaces no visitados aquí me refiero a los enlaces que no he abierto. Dado que puedo ver que todos los navegadores proporcionan la capacidad de cambiar el color del enlace visitado y no visitado, es posible detectar estos enlaces de cualquier manera. Durante la búsqueda, encontré este enlace: http://www.mozdev.org/pipermail/greasemonkey/2005-November/006821.html pero alguien aquí me dijo que esto ya no es posible. Por favor ayuda.
Correcto, no es posible que javascript detecte si se ha visitado un enlace en Firefox o Chrome, que son los únicos 2 navegadores aplicables en este contexto de Greasemonkey .
Esto se debe a que Firefox y Chrome toman en serio la seguridad y la privacidad. De la especificación de CSS2 :
Nota. Es posible que los autores de hojas de estilo abusen del: enlace y: pseudo-clases visitadas para determinar qué sitios ha visitado un usuario sin el consentimiento del usuario.
Por lo tanto, los UA pueden tratar todos los enlaces como enlaces no visitados, o implementar otras medidas para preservar la privacidad del usuario al tiempo que representan los enlaces visitados y no visitados de manera diferente. Consulte [P3P] para obtener más información sobre el manejo de la privacidad.
Ver también, "Privacidad y el selector visitado".
Puede ver una demostración que muestra que los navegadores de modo seguro no le permitirán jsfiddle.net/n8F9U enlaces visitados en jsfiddle.net/n8F9U .
Para su situación específica , ya que está visitando una página y la mantiene abierta, puede ayudar a un script a realizar un seguimiento de los enlaces visitados. No es infalible, pero creo que hará lo que usted ha pedido.
Primero, vea el script en acción haciendo lo siguiente:
- Instale el script, tal como está.
- Vaya a la página de prueba, jsbin.com/eledog .
La página de prueba agrega un nuevo enlace, cada vez que se vuelve a cargar o actualizar. La secuencia de comandos de GM agrega 2 botones a las páginas en las que se ejecuta. Un botón de "inicio / parar" en la parte superior izquierda y un botón de "Borrar" en la parte inferior derecha.
Cuando presionas el botón "Inicio", hace lo siguiente:
- Todos los enlaces existentes en la página se registran como "visitados".
- Inicia un temporizador (configuración predeterminada: 3 segundos), cuando el temporizador se apaga, vuelve a cargar la página.
- Cada vez que la página se vuelve a cargar, se abren nuevos enlaces y se inicia un nuevo temporizador de recarga.
- Presione el botón "Detener" para detener las recargas, se conserva la lista de enlaces visitados.
El botón "Borrar" borra la lista de páginas visitadas.
ADVERTENCIA: si presiona "Borrar" mientras el ciclo de actualización está activo, la próxima vez que la página se vuelva a cargar, todos los enlaces se abrirán en nuevas pestañas.
A continuación, para utilizar el script en su sitio ...
Lea atentamente los comentarios en el script, tendrá que cambiar los valores @include
, @exclude
y selectorStr
para que coincidan con el sitio que está utilizando.
Para obtener los mejores resultados, desactive los complementos "Recargar cada" o las opciones de "Actualización automática".
Notas importantes:
El script tiene que usar almacenamiento permanente para rastrear los enlaces.
Las opciones son: cookies,sessionStorage
,localStorage
,globalStorage
,GM_setValue()
eIndexedDB
.Todos estos tienen inconvenientes, y en este caso (sitio único, potencialmente una gran cantidad de enlaces, sesiones múltiples),
localStorage
es la mejor opción (IndexedDB
puede ser, pero aún así es demasiado inestable, lo que provoca bloqueos frecuentes de FF en mi máquina).Esto significa que los enlaces solo se pueden rastrear por sitio, y que las utilidades de "seguridad", "privacidad" o "limpiador" pueden bloquear o borrar la lista de enlaces visitados. (Al igual que al borrar el historial del navegador, se restablecerá cualquier estilo CSS para los enlaces visitados).
El script es solo para Firefox, por ahora. No debería funcionar en Chrome, incluso con Tampermonkey instalado, sin un poco de reingeniería.
La secuencia de comandos:
/*******************************************************************************
** 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; /
} /
" );
Puede analizar todos los enlaces en la página y obtener su propiedad de color CSS. Si un color del enlace coincide con el color del enlace no visitado que definió en CSS, este enlace no se visita.
Este tipo de técnica se utiliza generalmente para determinar todos los enlaces visitados. Esto es una especie de infracción de seguridad que le permite determinar si un usuario visitó un sitio web en particular. Usado generalmente por los vendedores de mala calidad.
Este tipo de trucos generalmente se clasifica como "trucos de manipulación de la historia del navegador".
Más información con el código: http://www.stevenyork.com/tutorial/getting_browser_history_using_javascript