Показать сообщение отдельно
  #1 (permalink)  
Старый 08.02.2017, 18:36
Аватар для ruslan_mart
Профессор
Отправить личное сообщение для ruslan_mart Посмотреть профиль Найти все сообщения от ruslan_mart
 
Регистрация: 30.04.2012
Сообщений: 3,018

Detect visited links
Доброго времени суток!

Появилась необходимость написать скрипт, который будет проверять несколько сайтов на посещаемость юзером.

Сразу же на ум пришла такая идея:

var links = document.querySelectorAll('a:visited');


Но не всё так просто, браузер не даёт получить такие ссылки.
Далее на ум приходит такая идея: с помощью CSS дать определённый цвет текста для :visited и проверять его с помощью getComputedStyle, но не всё так просто... браузер и это блокирует!

Ну и тут мне на ум пришла такая мысль:
Мы знаем, что по умолчанию все ссылки синие, а visited - розовые. А что, если visited покрасить в чёрный и наложить 10к ссылок друг на друга? Ведь "чёрные" ссылки по идее должны отрисоваться быстрее.

Набросал такой скрипт:

.links {
	position: absolute;
}
.links a {
	left: 0;
	position: absolute;
	top: 0;
}
.links a::after {
	content: 'abcdefghijklmnopqrstuvwxyz1234567890';
}
.links a:visited {
	color: #000;
}
.links span {
	opacity: 0.004;
}


window.addEventListener('DOMContentLoaded', function() {
	'use strict';

	function getDrawTime(link) {
		//Сохраняем начальный timestamp
		var d = Date.now();

		//Создаём и вставляем 10000 элементов наложением друг на друга
		for(var el1, el2, i = 0; i < 1E4; i++) {
			el1 = document.createElement('span');
			el2 = document.createElement('a');
			el2.href = link;
			el1.appendChild(el2);
			wrapper.appendChild(el1);
		}


		//Записываем разницу между начального и текущего timestamp'а
		var r = Date.now() - d;

		//Удаляем все элементы
		while(wrapper.firstChild) {
			wrapper.removeChild(wrapper.firstChild);
		}

		//Вохвращем ту самую разницу
		return r;
	}

	var wrapper = document.createElement('div');
	wrapper.className = 'links';
	document.body.appendChild(wrapper);


	//Вычислям среднее время непосещённой ссылки, для следующего сравнения с посещённой
	var notVisitedTime = (function() {
		for(var i = 0, n = 0; i < 5; i++) {
			n += getDrawTime('http://' + Math.random().toString(36) + '.cx');
		}
		return Math.floor(n / 5);
	})();


	var callback = function(data) {
			console.log(data);
		},
		i = 0,
		links = ['http://javascript.ru', 'http://test228.ru', 'http://google.ru'],
		visitedData = {};


	setTimeout(function fn() {
		var link = links[i];

		visitedData[link] = getDrawTime(link) < notVisitedTime - 10;

		if(++i < links.length) {
			setTimeout(fn, 10);
		}
		else {
			callback(visitedData);
		}
	}, 10);

});


По началу, мне казалось, что всё работает как нужно, но всё-таки что-то не так. Каждый раз разный результат.
У кого какие идеи и предложения, коллеги?
Ответить с цитированием