PageSourceSearch

https://www.vitron.de/js/_essentials/basics.js

js vitron.de collected 2026-10-08 09:44:38 UTC 5,321 bytes, 158 lines download raw bytes

1/**
2 * replace external link target and rel attributes 
3 * to open external links in a new tab
4 * @param {string} selector css selector for all links to handle 
5 */
6function handleExternalLinks(selector) {
7    selector = selector ?? `a[href]:not([href*="${window.location.hostname}"]):not([href^="javascript"])`
8    const links = document.querySelectorAll(selector);
9    links.forEach(link => {
10        if (link.hostname !== window.location.hostname) {
11            if (!link.target) {
12                link.target = '_blank';
13            }
14            if (!link.hasAttribute("rel")) {
15                link.setAttribute('rel', 'noreferrer');
16            }
17        }
18    });
19}
20
21/**
22 * body class handling for no-js and touch devices
23 */
24function applyBodyClasses() {
25    const body = document.body;
26    body.classList.remove('no-js');
27    body.classList.add('javascript');
28    if ('ontouchstart' in document.documentElement) body.classList.add('is-touch');
29}
30
31/**
32 * create email links from data-email placeholders
33 */
34function createEmailLinks() {
35    const mailLinks = document.querySelectorAll('a[data-email]');
36    mailLinks.forEach(link => {
37        const data = JSON.parse(link.getAttribute('data-email')),
38            escape = link.querySelector('span.escape');
39        link.href = `mailto:${data.name}@${data.host}`
40        if (escape) escape.outerHTML = '@';
41    });
42}
43
44/**
45 * check if a current css breakpoint of viewport width is matching
46 * @param {string} width name of the breakpoint 
47 * @param {string} direction direction, can be either "min", or "max"
48 * @returns boolean
49 */
50function breakpoint(width, direction) {
51    const breakpoints = new Array();
52    for (bp in cssData['gridMap']) {
53        if (cssData['gridMap'][bp].width === '$rowMaxWidth') breakpoints[bp] = parseInt(cssData['rowMaxWidth'].replace('px', '')) / 16 + 'em';
54        else breakpoints[bp] = parseInt(cssData['gridMap'][bp].width.replace('px', '')) / 16 + 'em';
55    }
56    direction = (typeof direction === 'undefined') ? 'min' : direction;
57    if (typeof width === 'undefined') {
58        return breakpoints
59    } else {
60        if (direction === 'min') return window.matchMedia("(min-width: " + breakpoints[width] + ")").matches;
61        else return window.matchMedia("(max-width: " + breakpoints[width].replace(/(\d|\W)*/, function (m) { return parseFloat(m) - 0.0625 }) + ")").matches
62    }
63}
64
65/**
66 * returns the current css breakpoints name as a string, e.g. "large"
67 * @author Dominik Kressler
68 * @thanks Eric Holtkamp
69 * @date 2020-05-05
70 * 
71 */
72function currentBp() {
73    const bp = breakpoint();
74    const checkWidth = (window.innerWidth + 1) / parseInt(cssData['base-font-size']);
75    const values = Object.values(bp).map(function (x) { return parseFloat(x); });
76    values.sort(function (a, b) { return a - b; });
77    let result = false;
78
79    for (let i = 0, c = values.length; i < c; i++) {
80        if (i < values.length - 1 && checkWidth >= values[i] && checkWidth <= values[(i + 1)]) {
81            result = values[i];
82            break;
83        }
84    }
85    if (result === false) result = values[values.length - 1];
86
87    return Object.keys(bp)[Object.values(bp).indexOf(result + 'em')];
88}
89
90/**
91 * add direction of scrolling as body class
92 * @param {HTMLElement} element the element to apply classes to
93 */
94function addScrollDirection(element) {
95    let lastScrollTop = 0;
96    document.addEventListener('scroll', function (e) {
97        const scrollTop = window.scrollY || document.documentElement.scrollTop;
98        if (scrollTop > lastScrollTop) {
99            element.classList.add('scrolling-down');
100            element.classList.remove('scrolling-up');
101        }
102        else if (scrollTop != lastScrollTop) {
103            element.classList.remove('scrolling-down');
104            element.classList.add('scrolling-up');
105        }
106        lastScrollTop = scrollTop <= 0 ? 0 : scrollTop;
107    });
108}
109
110/**
111 * allow clicking elements with a matching tab index by pressing "Enter"
112 */
113function handleEnterKeyClick() {
114    window.addEventListener('keydown', function (e) {
115        if (e.key === "Enter" && document.activeElement.getAttribute('tabindex') != null) {
116            document.activeElement.click();
117        }
118    });
119}
120
121/**
122 * add class to element if scroll detection injection
123 * @param {string or number} scrollDetect detect a element or fix number for init
124 * @param {string} scrollClassName name of scroll class for element
125 * @param {HTMLElement} element the element to apply classes to
126 */
127function addScrollClass(scrollDetect = 100, scrollClassName = 'scrolled', element = document.body) {
128    if (typeof scrollDetect === "string") {
129        scrollDetect = document.querySelector(scrollDetect).getBoundingClientRect().height
130    }
131
132    function init() {
133        const scrollTop = window.scrollY || document.documentElement.scrollTop;
134        if (scrollTop >= scrollDetect) {
135            element.classList.add(scrollClassName)
136        }
137        else {
138            element.classList.remove(scrollClassName)
139        }
140    }
141
142    init()
143
144    window.addEventListener('scroll', () => {
145        init()
146    }, false)
147}
148
149/**
150 * summarize all basics functions
151 */
152function basics() {
153    applyBodyClasses();
154    createEmailLinks();
155    handleExternalLinks();
156    addScrollDirection(document.body);
157    handleEnterKeyClick();
158}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.