DSGVO konforme Lösung beim Absprung (Verlinken) auf fremde Domains in vanilla JS!
§19 TTDSG Technische und organisatorische Vorkehrungen,
(3) Die Weitervermittlung zu einem anderen Anbieter von Telemedien ist dem Nutzer anzuzeigen.
Beispiel:
- www.ssllabs.com
- securityheaders.com
- Google PageSpeed Insights
- IPv6 test
- wave.webaim.org
- W3C - Markup Validation Service
HTML:
<!DOCTYPE html >
<html lang="de">
<head>
<meta charset="utf-8" />
<title>leave Domain Example</title>
<link rel="stylesheet" type="text/css" href="externalLinks.css" />
</head>
<body>
<ul>
<li><a href="https://www.ssllabs.com/ssltest/" rel="nofollow noopener noreferrer" target="_blank">www.ssllabs.com</a></li>
<li><a href="https://securityheaders.com/" rel="nofollow noopener noreferrer" target="_blank">securityheaders.com</a></li>
<li><a href="https://pagespeed.web.dev/" rel="nofollow noopener noreferrer" target="_blank">Google PageSpeed Insights</a></li>
<li><a href="https://ipv6-test.com/" rel="nofollow noopener noreferrer" target="_blank">IPv6 test</a></li>
<li><a href="https://wave.webaim.org/" rel="nofollow noopener noreferrer" target="_blank">wave.webaim.org</a></li>
<li><a href="https://validator.w3.org/" rel="nofollow noopener noreferrer" target="_blank">W3C - Markup Validation Service</a></li>
</ul>
<script src="externalLinks.js"></script>
</body>
</html>
JavaScript:
// coding: utf-8
/*! Created by: Udo Schmal | https://www.gocher.me/ */
(function () {
// polyfill Array.prototype.includes for old Internet Explorer 11
if (!Array.prototype.includes) {
Object.defineProperty(Array.prototype, 'includes', {
value: function(searchElement, fromIndex) {
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
var len = o.length >>> 0;
if (len === 0) {
return false;
}
var n = fromIndex | 0;
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
function sameValueZero(x, y) {
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
}
while (k < len) {
if (sameValueZero(o[k], searchElement)) {
return true;
}
k++;
}
return false;
}
});
}
function externalLink(event) {
event.preventDefault();
let href = this.href;
let domain = /https?:\/\/([^\/]*)/i.exec(href)[1];
var overlay = document.createElement('div');
overlay.className = 'overlay';
document.body.appendChild(overlay);
let dialog = document.createElement('div');
dialog.classList.add('dialog');
dialog.classList.add('external-link');
overlay.appendChild(dialog);
let header = document.createElement('div');
header.classList.add('header');
let h = document.createElement('h3');
h.appendChild(document.createTextNode('Inhalt auf exterener Seite'));
header.appendChild(h);
let close = document.createElement('button');
close.classList.add('close');
close.appendChild(document.createTextNode('×'));
header.appendChild(close);
dialog.appendChild(header);
let content = document.createElement('div');
content.classList.add('content');
let p = document.createElement('p');
p.appendChild(document.createTextNode('Sie werden weitergeleitet zu:'));
p.appendChild(document.createElement('br'));
p.appendChild(document.createTextNode(domain));
content.appendChild(p);
dialog.appendChild(content);
let footer = document.createElement('div');
footer.classList.add('footer');
let no = document.createElement('button');
no.classList.add('no');
no.appendChild(document.createTextNode('Abbrechen'));
footer.appendChild(no);
let yes = document.createElement('button');
yes.classList.add('yes');
yes.appendChild(document.createTextNode('Weiter'));
footer.appendChild(yes);
dialog.appendChild(footer);
function closeDialog() {
document.body.removeChild(overlay);
}
close.addEventListener('click', closeDialog);
no.addEventListener('click', closeDialog);
yes.addEventListener('click', function () { closeDialog(); window.open(href, '_blank').focus();});
}
let refs = document.querySelectorAll("a[href]");
if (refs.length > 0) {
let host = window.location.host;
for (let i = 0; i < refs.length; i++) {
let href = refs[i].getAttribute('href');
let hit = /https?:\/\/(www\.)?([^\/]*)/i.exec(href);
if (hit && hit[2]) {
if ((host != hit[1]+hit[2]) || (local_domains && !local_domains.includes(hit[2]))) {
// console.log(href, hit[1]);
refs[i].addEventListener('click', externalLink);
}
}
}
}
})();
Stylesheet:
/* coding: utf-8 */
/*! Created by: Udo Schmal | https://www.gocher.me/ */
.overlay {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1000;
background-color: rgba(0,0,0,.8);
}
.dialog.external-link {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 480px;
max-width: 90%;
background-color: #fff;
border-radius: 10px;
}
.dialog.external-link .header {
border-bottom: 1px solid #e9ecef;
padding: 0px 20px;
}
.dialog.external-link h3 {
display: inline-block;
}
.dialog.external-link button.close {
float: right;
font-size: xx-large;
border: none;
background: none;
cursor: pointer;
color: #6c757d;
}
.dialog.external-link .content {
padding: 20px;
}
.dialog.external-link .footer {
border-top: 1px solid #e9ecef;
padding: 5px 20px;
text-align: right;
}
.dialog.external-link .footer button {
border-radius: 5px;
border: 1px solid transparent;
padding: 10px 20px;
box-shadow: none;
color: #fff;
cursor: pointer;
margin-right: 10px;
}
.dialog.external-link .footer button.no {
background-color: #6c757d;
}
.dialog.external-link .footer button.yes {
background-color: #832025;
}