/**
* @Datei dom.js
* @modul dom
* /
dokument aus 'global/document' importieren;
import window from 'global/window';
import fs from '../fullscreen-api';
import log from './log.js';
importiere {isObject} von './obj';
import computedStyle from './computed-style';
import * as browser from './browser';
/**
* Erkennen, ob ein Wert eine Zeichenkette mit Zeichen ohne Leerzeichen ist.
*
* @privat
* @param {string} str
* Die zu prüfende Zeichenkette
*
* @return {boolean}
* Wird `true`, wenn die Zeichenkette nicht leer ist, sonst `false`.
*
* /
function isNonBlankString(str) {
// wir verwenden str.trim, da es alle Leerzeichen abschneidet
// von der Vorderseite oder Rückseite von Zeichen ohne Leerzeichen. aka
// Jede Zeichenfolge, die keine Leerzeichen enthält, wird
// enthalten sie nach dem "Abschneiden" immer noch, aber nur Zeichenketten mit Leerzeichen
// hat eine Länge von 0, da diese Prüfung nicht bestanden wurde.
return typeof str === 'string' && Boolean(str.trim());
}
/**
* Wirft einen Fehler, wenn die übergebene Zeichenkette Leerzeichen enthält. Dies wird verwendet von
* klassenmethoden, um relativ konsistent mit der classList-API zu sein.
*
* @privat
* @param {string} str
* Die Zeichenkette, die auf Leerzeichen geprüft werden soll.
*
* @throws {Fehler}
* Wirft einen Fehler, wenn die Zeichenkette Leerzeichen enthält.
* /
function throwIfWhitespace(str) {
// str.indexOf anstelle von regex, da str.indexOf leistungsfähiger ist.
if (str.indexOf(' ') >= 0) {
throw new Error('class has illegal whitespace characters');
}
}
/**
* Erzeugen eines regulären Ausdrucks für den Abgleich eines Klassennamens mit dem Klassennamen eines Elements.
*
* @privat
* @param {string} className
* Der Klassenname, für den die RegExp generiert werden soll.
*
* @return {RegExp}
* Der RegExp, der nach einem bestimmten `className` in einem Element sucht
* className.
* /
function classRegExp(className) {
return new RegExp('(^|\\s)' + className + '($|\\s)');
}
/**
* Ob die aktuelle DOM-Schnittstelle real zu sein scheint (d.h. nicht simuliert).
*
* @return {boolean}
* Wird `true` sein, wenn das DOM echt zu sein scheint, sonst `false`.
* /
export function isReal() {
// Sowohl Dokument als auch Fenster werden dank `global` niemals undefiniert sein.
return document === window.document;
}
/**
* Bestimmt mittels Enten-Typisierung, ob ein Wert ein DOM-Element ist oder nicht.
*
* @param {Mixed} Wert
* Der zu prüfende Wert.
*
* @return {boolean}
* Wird `true`, wenn der Wert ein DOM-Element ist, sonst `false`.
* /
export function isEl(value) {
return isObject(value) && value.nodeType === 1;
}
/**
* Ermittelt, ob das aktuelle DOM in einen Iframe eingebettet ist.
*
* @return {boolean}
* Wird `true` sein, wenn das DOM in einen iframe eingebettet ist, `false`
* sonst.
* /
export function isInFrame() {
// Wir brauchen hier ein try/catch, weil Safari beim Versuch Fehler auslöst
// um entweder `parent` oder `self` zu erhalten
Versuchen {
return window.parent !== window.self;
} catch (x) {
true zurückgeben;
}
}
/**
* Erzeugt Funktionen zur Abfrage des DOM mit einer bestimmten Methode.
*
* @privat
* @param {string} Methode
* Die Methode, mit der die Abfrage erstellt wird.
*
* @return {Funktion}
* Die Abfragemethode
* /
function createQuerier(method) {
return function(selector, context) {
if (!isNonBlankString(selector)) {
return document[method](null);
}
if (isNonBlankString(context)) {
context = document.querySelector(context);
}
const ctx = isEl(context) ? context : document;
return ctx[Methode] && ctx[Methode](selector);
};
}
/**
* Erzeugt ein Element und wendet Eigenschaften und Attribute an und fügt Inhalte ein.
*
* @param {string} [tagName='div']
* Name des zu erstellenden Tags.
*
* @param {Object} [properties={}]
* Zu verwendende Elementeigenschaften.
*
* @param {Object} [attributes={}]
* Zu verwendende Elementattribute.
*
* @param {module:dom~ContentDescriptor} content
* Ein Content-Deskriptor-Objekt.
*
* @return {Element}
* Das Element, das erstellt wurde.
* /
export function createEl(tagName = 'div', properties = {}, attributes = {}, content) {
const el = document.createElement(tagName);
Object.getOwnPropertyNames(properties).forEach(function(propName) {
const val = properties[propName];
// Siehe #2176
// Ursprünglich akzeptierten wir sowohl Eigenschaften als auch Attribute in der
// dasselbe Objekt, aber das funktioniert nicht so gut.
if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') {
log.warn('Einstellung von Attributen im zweiten Argument von createEl()\n' +
' wurde veraltet. Verwenden Sie stattdessen das dritte Argument.\n' +
erzeugenEl(Typ, Eigenschaften, Attribute). Es wird versucht, ${propName} auf ${val} zu setzen.`);
el.setAttribute(propName, val);
// Behandeln Sie textContent, da es nicht überall unterstützt wird und wir eine
// Methode für sie.
} else if (propName === 'textContent') {
textInhalt(el, val);
} else if (el[propName] !== val || propName === 'tabIndex') {
el[propName] = val;
}
});
Object.getOwnPropertyNames(attributes).forEach(function(attrName) {
el.setAttribute(attrName, attributes[attrName]);
});
wenn (Inhalt) {
appendContent(el, content);
}
zurück el;
}
/**
* Fügt Text in ein Element ein und ersetzt den vorhandenen Inhalt vollständig.
*
* @param {Element} el
* Das Element, in das der Textinhalt eingefügt wird
*
* @param {string} text
* Der hinzuzufügende Textinhalt.
*
* @return {Element}
* Das Element mit dem hinzugefügten Textinhalt.
* /
export function textInhalt(el, text) {
if (typeof el.textContent === 'undefined') {
el.innerText = text;
} else {
el.textInhalt = text;
}
zurück el;
}
/**
* Einfügen eines Elements als erster untergeordneter Knoten eines anderen
*
* @param {Element} Kind
* Element zum Einfügen
*
* @param {Element} parent
* Element zum Einfügen des Kindes in
* /
export function prependTo(child, parent) {
if (parent.firstChild) {
parent.insertBefore(child, parent.firstChild);
} else {
parent.appendChild(child);
}
}
/**
* Prüfen, ob ein Element einen Klassennamen hat.
*
* @param {Element} element
* Zu prüfendes Element
*
* @param {string} classToCheck
* Klassenname, auf den geprüft werden soll
*
* @return {boolean}
* Wird `true`, wenn das Element eine Klasse hat, sonst `false`.
*
* @throws {Fehler}
* Wirft einen Fehler, wenn `classToCheck` Leerzeichen enthält.
* /
export function hasClass(element, classToCheck) {
throwIfWhitespace(classToCheck);
if (element.classList) {
return element.classList.contains(classToCheck);
}
return classRegExp(classToCheck).test(element.className);
}
/**
* Hinzufügen eines Klassennamens zu einem Element.
*
* @param {Element} element
* Element, dem der Klassenname hinzugefügt werden soll.
*
* @param {string} classToAdd
* Klassenname zum Hinzufügen.
*
* @return {Element}
* Das DOM-Element mit dem hinzugefügten Klassennamen.
* /
export function addClass(element, classToAdd) {
if (element.classList) {
element.classList.add(classToAdd);
// WirfIfWhitespace" ist hier nicht nötig, da `hasElClass` dies erledigt
// für den Fall, dass classList nicht unterstützt wird.
} else if (!hasClass(element, classToAdd)) {
element.className = (element.className + ' ' + classToAdd).trim();
}
rückgabeelement;
}
/**
* Entfernen eines Klassennamens aus einem Element.
*
* @param {Element} element
* Element, aus dem ein Klassenname entfernt werden soll.
*
* @param {string} classToRemove
* Zu entfernender Klassenname
*
* @return {Element}
* Das DOM-Element mit entferntem Klassennamen.
* /
export function removeClass(element, classToRemove) {
// Schutz für den Fall, dass der Spieler entsorgt wird
if (!element) {
log.warn("removeClass wurde mit einem Element aufgerufen, das nicht existiert");
null zurückgeben;
}
if (element.classList) {
element.classList.remove(classToRemove);
} else {
throwIfWhitespace(classToRemove);
element.className = element.className.split(/\s+/).filter(function(c) {
return c !== classToRemove;
}).join(' ');
}
rückgabeelement;
}
/**
* Die Callback-Definition für toggleClass.
*
* @callback module:dom~PredicateCallback
* @param {Element} element
* Das DOM-Element der Komponente.
*
* @param {string} classToToggle
* Der "Klassenname", der umgeschaltet werden soll
*
* @return {boolean|undefined}
* Wenn `true` zurückgegeben wird, wird die `classToToggle` zu der
* element". Wenn `false`, wird die `classToToggle` aus
* das "Element". Wenn "undefiniert", wird der Rückruf ignoriert.
* /
/**
* Fügt einen Klassennamen zu/aus einem Element hinzu oder entfernt ihn, abhängig von einer optionalen
* bedingung oder das Vorhandensein bzw. Nichtvorhandensein des Klassennamens.
*
* @param {Element} element
* Das Element, mit dem ein Klassenname eingeschaltet werden kann.
*
* @param {string} classToToggle
* Die Klasse, die umgeschaltet werden soll.
*
* @param {boolean|module:dom~PredicateCallback} [Prädikat]
* Siehe den Rückgabewert für {@link module:dom~PredicateCallback}
*
* @return {Element}
* Das Element mit einer Klasse, die umgeschaltet wurde.
* /
export function toggleClass(element, classToToggle, predicate) {
// Dies kann `classList` intern NICHT verwenden, da IE11 die
// zweiter Parameter der Methode `classList.toggle()`! Das ist auch gut so, denn
// `classList` wird von den add/remove-Funktionen verwendet.
const has = hasClass(element, classToToggle);
if (typeof predicate === 'function') {
predicate = predicate(element, classToToggle);
}
if (typeof predicate !== 'boolean') {
prädikat = !hat;
}
// Wenn die erforderliche Klassenoperation mit dem aktuellen Zustand der
// Element, ist keine Aktion erforderlich.
if (Prädikat === has) {
rückkehr;
}
if (Prädikat) {
addClass(element, classToToggle);
} else {
removeClass(element, classToToggle);
}
rückgabeelement;
}
/**
* Attribute auf ein HTML-Element anwenden.
*
* @param {Element} el
* Element, dem Attribute hinzugefügt werden sollen.
*
* @param {Object} [Attribute]
* Zu verwendende Attribute.
* /
export function setAttributes(el, attributes) {
Object.getOwnPropertyNames(attributes).forEach(function(attrName) {
const attrValue = attributes[attrName];
if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) {
el.removeAttribute(attrName);
} else {
el.setAttribute(attrName, (attrValue === true ? '' : attrValue));
}
});
}
/**
* Abrufen der Attributwerte eines Elements, wie sie im HTML-Tag definiert sind.
*
* Attribute sind nicht dasselbe wie Eigenschaften. Sie sind auf dem Tag definiert
* oder mit setAttribute.
*
* @param {Element} tag
* Element, von dem Tag-Attribute abgerufen werden sollen.
*
* @return {Object}
* Alle Attribute des Elements. Boolesche Attribute werden als "wahr" oder
* `false`, andere sind Zeichenketten.
* /
export function getAttributes(tag) {
const obj = {};
// bekannte boolesche Attribute
// wir können nach übereinstimmenden booleschen Eigenschaften suchen, aber nicht alle Browser
// und nicht alle Tags kennen diese Attribute, so dass wir sie immer noch manuell überprüfen wollen
const knownBooleans = ',' + 'autoplay,controls,playsinline,loop,muted,default,defaultMuted' + ',';
if (tag && tag.attributes && tag.attributes.length > 0) {
const attrs = tag.attributes;
for (let i = attrs.length - 1; i >= 0; i--) {
const attrName = attrs[i].name;
let attrVal = attrs[i].value;
// Prüfung auf bekannte Boolesche Werte
// die passende Elementeigenschaft gibt einen Wert für typeof zurück
if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) {
// Der Wert eines eingeschlossenen booleschen Attributs ist normalerweise ein leerer
// String (''), der falsch wäre, wenn wir nur auf einen falschen Wert prüfen würden.
// wir wollen auch keinen schlechten Code wie autoplay='false' unterstützen
attrVal = (attrVal !== null) ? true : false;
}
obj[attrName] = attrVal;
}
}
return obj;
}
/**
* Ermittelt den Wert des Attributs eines Elements.
*
* @param {Element} el
* Ein DOM-Element.
*
* @param {string} attribut
* Attribut, dessen Wert ermittelt werden soll.
*
* @return {string}
* Der Wert des Attributs.
* /
export function getAttribute(el, attribute) {
return el.getAttribute(attribute);
}
/**
* Den Wert eines Attributs eines Elements festlegen.
*
* @param {Element} el
* Ein DOM-Element.
*
* @param {string} attribut
* Zu setzendes Attribut.
*
* @param {string} Wert
* Wert, auf den das Attribut gesetzt werden soll.
* /
export function setAttribute(el, attribute, value) {
el.setAttribute(attribut, wert);
}
/**
* Das Attribut eines Elements entfernen.
*
* @param {Element} el
* Ein DOM-Element.
*
* @param {string} attribut
* Zu entfernendes Attribut.
* /
export function removeAttribute(el, attribute) {
el.removeAttribute(attribute);
}
/**
* Versuchen Sie, die Möglichkeit der Textauswahl zu blockieren.
* /
export function blockTextAuswahl() {
document.body.focus();
document.onselectstart = function() {
return false;
};
}
/**
* Schalten Sie die Blockierung der Textauswahl aus.
* /
export function unblockTextSelection() {
document.onselectstart = function() {
true zurückgeben;
};
}
/**
* Identisch mit der systemeigenen Funktion `getBoundingClientRect`, stellt aber sicher, dass
* die Methode überhaupt unterstützt wird (in allen Browsern, die wir angeblich unterstützen)
* und dass sich das Element im DOM befindet, bevor Sie fortfahren.
*
* Diese Wrapper-Funktion unterdrückt auch Eigenschaften, die nicht von einigen
* älteren Browsern (insbesondere IE8).
*
* Außerdem unterstützen einige Browser nicht das Hinzufügen von Eigenschaften zu einer
* `ClientRect`/`DOMRect`-Objekt; also kopieren wir es mit der Standardmethode "shallow-copy
* eigenschaften (außer "x" und "y", die nicht allgemein unterstützt werden). Dies hilft
* implementierungen zu vermeiden, bei denen die Schlüssel nicht aufzählbar sind.
*
* @param {Element} el
* Element, dessen `ClientRect` wir berechnen wollen.
*
* @return {Object|undefined}
* Gibt immer ein einfaches Objekt zurück - oder `undefined`, wenn dies nicht möglich ist.
* /
export function getBoundingClientRect(el) {
if (el && el.getBoundingClientRect && el.parentNode) {
const rect = el.getBoundingClientRect();
const result = {};
['bottom', 'height', 'left', 'right', 'top', 'width'].forEach(k => {
if (rect[k] !== undefiniert) {
ergebnis[k] = rect[k];
}
});
if (!result.height) {
result.height = parseFloat(computedStyle(el, 'height'));
}
if (!result.width) {
result.width = parseFloat(computedStyle(el, 'width'));
}
ergebnis zurückgeben;
}
}
/**
* Stellt die Position eines DOM-Elements auf der Seite dar.
*
* @typedef {Object} module:dom~Position
*
* @Eigenschaft {Nummer} links
* Bildpunkte nach links.
*
* @Eigenschaft {Nummer} oben
* Bildpunkte von oben.
* /
/**
* Ermittelt die Position eines Elements im DOM.
*
* Verwendet die Technik "getBoundingClientRect" von John Resig.
*
* @see http://ejohn.org/blog/getboundingclientrect-is-awesome/
*
* @param {Element} el
* Element, von dem der Offset abgeleitet werden soll.
*
* @return {module:dom~Position}
* Die Position des Elements, das übergeben wurde.
* /
export function findPosition(el) {
if (!el || (el && !el.offsetParent)) {
Rückkehr {
links: 0,
oben: 0,
Breite: 0,
Höhe: 0
};
}
const width = el.offsetWidth;
const height = el.offsetHeight;
let left = 0;
let top = 0;
while (el.offsetParent && el !== document[fs.fullscreenElement]) {
left += el.offsetLeft;
oben += el.offsetTop;
el = el.offsetParent;
}
Rückkehr {
links,
oben,
breite,
Höhe
};
}
/**
* Stellt x- und y-Koordinaten für ein DOM-Element oder einen Mauszeiger dar.
*
* @typedef {Object} module:dom~Coordinates
*
* @Eigenschaft {Zahl} x
* x-Koordinate in Pixel
*
* @Eigenschaft {Nummer} y
* y-Koordinate in Pixel
* /
/**
* Ermittelt die Zeigerposition innerhalb eines Elements.
*
* Die Basis der Koordinaten ist die untere linke Seite des Elements.
*
* @param {Element} el
* Element, auf dem die Zeigerposition ermittelt werden soll.
*
* @param {EventTarget~Event} event
* Ereignis-Objekt.
*
* @return {module:dom~Coordinates}
* Ein Koordinatenobjekt, das der Mausposition entspricht.
*
* /
export function getPointerPosition(el, event) {
const translated = {
x: 0,
y: 0
};
if (browser.IS_IOS) {
let item = el;
while (item && item.nodeName.toLowerCase() !== 'html') {
const transform = computedStyle(item, 'transform');
if (/^matrix/.test(transform)) {
const values = transform.slice(7, -1).split(/,\s/).map(Number);
übersetzt.x += Werte[4];
translated.y += values[5];
} else if (/^matrix3d/.test(transform)) {
const values = transform.slice(9, -1).split(/,\s/).map(Number);
übersetzt.x += Werte[12];
übersetzt.y += Werte[13];
}
item = item.parentNode;
}
}
const position = {};
const boxTarget = findPosition(event.target);
const box = findPosition(el);
const boxW = box.width;
const boxH = box.height;
let offsetY = event.offsetY - (box.top - boxTarget.top);
let offsetX = event.offsetX - (box.left - boxTarget.left);
if (event.changedTouches) {
offsetX = event.changedTouches[0].pageX - box.left;
offsetY = event.changedTouches[0].pageY + box.top;
if (browser.IS_IOS) {
offsetX -= translated.x;
offsetY -= translated.y;
}
}
position.y = (1 - Math.max(0, Math.min(1, offsetY / boxH)));
position.x = Math.max(0, Math.min(1, offsetX / boxW));
rückkehrposition;
}
/**
* Bestimmt über die Enteneingabe, ob ein Wert ein Textknoten ist oder nicht.
*
* @param {Mixed} Wert
* Prüfen, ob dieser Wert ein Textknoten ist.
*
* @return {boolean}
* Wird `true`, wenn der Wert ein Textknoten ist, sonst `false`.
* /
export function isTextNode(value) {
return isObject(value) && value.nodeType === 3;
}
/**
* Entleert den Inhalt eines Elements.
*
* @param {Element} el
* Das Element zum Leeren der Kinder von
*
* @return {Element}
* Das Element ohne Kinder
* /
export function emptyEl(el) {
while (el.firstChild) {
el.removeChild(el.firstChild);
}
zurück el;
}
/**
* Dies ist ein gemischter Wert, der den Inhalt beschreibt, der in das DOM eingefügt werden soll
* über irgendeine Methode. Es kann von den folgenden Typen sein:
*
* Typ | Beschreibung
* -----------|-------------
* zeichenkette" | Der Wert wird in einen Textknoten normalisiert.
* element" | Der Wert wird so akzeptiert, wie er ist.
* textNode" | Der Wert wird so akzeptiert, wie er ist.
* array" | Ein eindimensionales Array von Strings, Elementen, Textknoten oder Funktionen. Diese Funktionen sollten einen String, ein Element oder einen Textknoten zurückgeben (jeder andere Rückgabewert, wie ein Array, wird ignoriert).
* funktion" | Eine Funktion, von der erwartet wird, dass sie eine Zeichenkette, ein Element, einen Textknoten oder ein Array zurückgibt - einen der anderen oben beschriebenen möglichen Werte. Dies bedeutet, dass ein Inhaltsdeskriptor eine Funktion sein kann, die ein Array von Funktionen zurückgibt, diese Funktionen der zweiten Ebene jedoch Zeichenfolgen, Elemente oder Textknoten zurückgeben müssen.
*
* @typedef {string|Element|TextNode|Array|Funktion} module:dom~ContentDescriptor
* /
/**
* Normalisiert den Inhalt für die eventuelle Einfügung in das DOM.
*
* Dies ermöglicht eine breite Palette von Methoden zur Definition von Inhalten, trägt aber zum Schutz der
* in die Falle zu tappen, einfach in `innerHTML` zu schreiben, was zu
* ein XSS-Problem sein.
*
* Der Inhalt für ein Element kann in mehreren Typen übergeben werden und
* kombinationen, deren Verhalten wie folgt ist:
*
* @param {module:dom~ContentDescriptor} content
* Ein Inhaltsdeskriptionswert.
*
* @return {Array}
* Der gesamte Inhalt, der übergeben wurde, normalisiert zu einem Array von
* elemente oder Textknoten.
* /
export function normalizeContent(content) {
// Rufen Sie zunächst den Inhalt auf, wenn es sich um eine Funktion handelt. Wenn es ein Array erzeugt,
// die vor der Normalisierung erfolgen muss.
if (typeof content === 'function') {
inhalt = Inhalt();
}
// Als Nächstes normalisieren wir auf ein Array, so dass ein oder mehrere Elemente normalisiert werden können,
// gefiltert und zurückgegeben.
return (Array.isArray(content) ? content : [content]).map(value => {
// Rufen Sie zunächst value auf, wenn es eine Funktion ist, um einen neuen Wert zu erzeugen,
// die anschließend in einen Knoten irgendeiner Art normalisiert werden.
if (typeof Wert === 'Funktion') {
wert = Wert();
}
if (isEl(Wert) || isTextNode(Wert)) {
rückgabewert;
}
if (typeof wert === 'string' && (/\S/).test(wert)) {
return document.createTextNode(value);
}
}).filter(value => value);
}
/**
* Normalisiert den Inhalt und fügt ihn an ein Element an.
*
* @param {Element} el
* Element, an das der normalisierte Inhalt angehängt wird.
*
* @param {module:dom~ContentDescriptor} content
* Ein Inhaltsdeskriptionswert.
*
* @return {Element}
* Das Element mit angehängtem normalisiertem Inhalt.
* /
export function appendContent(el, content) {
normalizeContent(content).forEach(node => el.appendChild(node));
zurück el;
}
/**
* Normalisiert und fügt Inhalt in ein Element ein; dies ist identisch mit
* `appendContent()`, mit dem Unterschied, dass es das Element zuerst leert.
*
* @param {Element} el
* Element, in das normalisierte Inhalte eingefügt werden.
*
* @param {module:dom~ContentDescriptor} content
* Ein Inhaltsdeskriptionswert.
*
* @return {Element}
* Das Element mit eingefügtem normalisiertem Inhalt.
* /
export function insertContent(el, content) {
return appendContent(emptyEl(el), content);
}
/**
* Prüfen, ob ein Ereignis ein einfacher Linksklick war.
*
* @param {EventTarget~Event} event
* Ereignis-Objekt.
*
* @return {boolean}
* Wird `true`, wenn ein einzelner Linksklick, sonst `false`.
* /
export function isSingleLeftClick(event) {
// Hinweis: Wenn Sie etwas Ziehbares erstellen, müssen Sie darauf achten, dass
// Aufruf bei den Ereignissen "Mousedown" und "Mousemove",
// sonst sollte `mousedown` für eine Schaltfläche ausreichen
if (event.button === undefined && event.buttons === undefined) {
// Wozu brauchen wir "Schaltflächen"?
// Weil die mittlere Maus das manchmal hat:
// e.button === 0 und e.buttons === 4
// Außerdem wollen wir einen Kombinationsklick verhindern, etwa so
// Halten Sie die mittlere Maustaste gedrückt und klicken Sie dann mit der linken Maustaste, das wäre dann
// e.button === 0, e.buttons === 5
// nur `Button` wird nicht funktionieren
// Gut, was macht dieser Block dann?
// dies ist für Chrom `simulieren mobile Geräte`
// Ich möchte dies ebenfalls unterstützen
true zurückgeben;
}
if (event.button === 0 && event.buttons === undefined) {
// Touchscreen, manchmal bei bestimmten Geräten auch "Tasten"
// hat nichts (safari auf ios, blackberry...)
true zurückgeben;
}
// Das Ereignis `Mouseup` bei einem einzelnen Linksklick hat
// Knöpfe" und "Knöpfe" gleich 0
if (event.type === 'mouseup' && event.button === 0 &&
event.buttons === 0) {
true zurückgeben;
}
if (event.button !== 0 || event.buttons !== 1) {
// Dies ist der Grund für die obigen if else-Blöcke
// Wenn es einen Sonderfall gibt, können wir ihn auffangen und durchgehen lassen
// wir machen es oben, wenn wir hier ankommen, ist das definitiv
// ist-nicht-links-geklickt
return false;
}
true zurückgeben;
}
/**
* Findet ein einzelnes DOM-Element, das `selector` entspricht, innerhalb der optionalen
* kontext" eines anderen DOM-Elements (Standardwert ist "Dokument").
*
* @param {string} selector
* Ein gültiger CSS-Selektor, der an `querySelector` übergeben wird.
*
* @param {Element|String} [context=document]
* Ein DOM-Element, innerhalb dessen die Abfrage erfolgen soll. Kann auch ein Selektor sein
* in diesem Fall wird das erste übereinstimmende Element verwendet
* als Kontext. Wenn es fehlt (oder kein Element mit dem Selektor übereinstimmt), fällt
* zurück zu `Dokument`.
*
* @return {Element|null}
* Das Element, das gefunden wurde, oder null.
* /
export const $ = createQuerier('querySelector');
/**
* Findet alle DOM-Elemente, die dem `Selektor` innerhalb der optionalen
* kontext" eines anderen DOM-Elements (Standardwert ist "Dokument").
*
* @param {string} selector
* Ein gültiger CSS-Selektor, der an `querySelectorAll` übergeben wird.
*
* @param {Element|String} [context=document]
* Ein DOM-Element, innerhalb dessen die Abfrage erfolgen soll. Kann auch ein Selektor sein
* in diesem Fall wird das erste übereinstimmende Element verwendet
* als Kontext. Wenn es fehlt (oder kein Element mit dem Selektor übereinstimmt), fällt
* zurück zu `Dokument`.
*
* @return {NodeList}
* Eine Elementliste der gefundenen Elemente. Wird leer sein, wenn keine
* gefunden wurden.
*
* /
export const $$ = createQuerier('querySelectorAll');