window.$_ = (() => { 'use strict'; /** * La classe GSDom est une classe écrite en pur Javascript qui permet de simplifier la manipulation du DOM. * * @class GSDom * * @example * // Ajout d'une classe `my_class` à tous lel `a` * $_("a").addClass("my_class"); * @example * // Ajout d'une classe `my_class` à tous les `a` enfants de `div#main` * $_("a", "div#main").addClass("my_class"); * @example * // Ajout d'une classe `my_class` à tous les `a` enfants de l'élément `my_scope` du DOM * let my_scope = document.querySelector("div#main"); * $_("a", my_scope).addClass("my_class"); * @example * // Instanciation de GSDom avec un élément du DOM et ajout d'une classe `my_class` à cet élément * let element = document.querySelector("p#intro"); * $_(element).addClass("my_class"); * * @param {(String|HTMLElement)} selector Sélecteur utilisé ou un élément du DOM (scope est alors ignoré) * @param {(String|HTMLElement)} [scope=document] Sélecteur utilisé (le 1er élément trouvé est utilisé) ou un élément du DOM */ class GSDom { constructor(selector, scope) { this.shortversion = '2.0.0'; this.longversion = 'GSDom 2.0.0 by Séb'; if (!selector) { // On ne va pas plus loin s'il n'y a pas de sélecteur return; } if (selector === 'document') { // Cas particulier pour document this.elems = [document, ]; } else if (selector === 'window') { // CAs particulier pour window this.elems = [window, ]; } else { if (selector instanceof HTMLElement) { // Cas où un élément du DOM est fourni this.elems = [selector, ]; } else { // Cas ou un sélecteur est fourni let root = false; if (!scope) { // Si pas de scope, on utilise le document root = document; } else { if (!((scope instanceof HTMLElement)) && (typeof scope === 'string')) { // Si le scope est un selecteur, on utilise le premier élément de DOM correspondant root = document.querySelector(scope); } else { // On utilise l'élément du DOM fourni root = scope; } } if (root) this.elems = root.querySelectorAll(selector); else this.elems = []; } } } /** * Parcours de tous les éléments sélectionnés * * @example * //appliquer une fonction sur tous les éléments ayant `my_class` * $_(".my_class").each((item, index) => { * // Do something with item et index * }); * * @param {eachCallback} callback La fonction de rappel */ each(callback) { if (!callback || typeof callback !== 'function') { return; } this.elems.forEach((element, index) => { callback(element, index); }); return this; } /** * Fonction de rappel la méthode each() * @callback eachCallback * @see {@link #each} * @param {HTMLElement} element L'élément du DOM concerné * @param {number} index L'index de l'élément */ /** * Ajout d'une classe aux éléments sélectionnés * * @example * $_("p","div#main").addClass("my_class"); * * @param {String} className Le nom de la classe à ajouter * @returns {this} Chainage */ addClass(className) { this.each(item => { item.classList.add(className); }); return this; } /** * Suppression d'une classe aux éléments sélectionnés * * @example * $_("p","div#main").removeClass("my_class"); * * @param {String} className Le nom de la classe à ajouter * @returns {this} Chainage */ removeClass(className) { this.each(item => { item.classList.remove(className); }); return this; } /** * Suppression de toutes les classes des éléments sélectionnés * * @example * $_("p","div#main").removeAllClasses("myClass"); * * @returns {this} Chainage */ removeAllClasses() { this.each(item => { item.className = ""; }); return this; } /** * Remplace une classe par une autre parmi les éléments sélectionnés * * @example * $_("p","div#main").replaceClass("my_old_class", "my_new_class"); * * @param {String} oldClass Nom de la classe à remplacer * @param {String} newClass Nom de la classe de remplacement * @returns {this} Chainage */ replaceClass(oldClass, newClass) { this.each(item => { item.classList.replace(oldClass, newClass); }); return this; } /** * Définit un attribut et sa valeur * * @example * $_("input.my_class").setAttr("readonly", ""); * * @param {String} attr Nom de l'attribut * @param {String} value Valeur de l'attribut * @returns {this} Chainage */ setAttr(attr, value) { this.each(item => { item.setAttribute(attr, value); }); return this; } /** * Supprime un attribut dans les éléments sélectionnés * * @example * $_(input.my_class).delAttr("readonly"); * * @param {String} attr Nom de l'attribut à supprimer * @returns {this} Chainage */ delAttr(attr) { this.each(item => { item.removeAttribute(attr); }); return this; } /** * Ajoute l'attribut hidden aux éléments sélectionnés * * @example $_("span.my_class").setHidden(); * * @returns {this} Chainage */ setHidden() { this.setAttr('hidden', ''); return this; } /** * Ajoute l'attribut `readonly` aux éléments sélectionnés * * @example * $_("input.my_class").setReadOnly(); * * @returns {this} Chainage */ setReadOnly() { this.setAttr('readonly', ''); return this; } /** * Ajoute l'attribut `disabled` aux éléments sélectionnés * * @example * $_("input.my_class").setDisabled(); * * @returns {this} Chainage */ setDisabled() { this.setAttr('disabled', ''); return this; } /** * Supprime l'attribut `hidden` aux éléments sélectionnés * * @example * $_("span.my_class").delHidden(); * * @returns {this} Chainage */ delHidden() { this.delAttr('hidden'); return this; } /** * Supprime l'attribut `readonly` aux éléments sélectionnés * * @example * $_("input.my_class").delReadOnly(); * * @returns {this} Chainage */ delReadOnly() { this.delAttr('readonly'); return this; } /** * Supprime l'attribut `disabled` aux éléments sélectionnés * * @example * $_("input.my_class").delDisabled(); * * @returns {this} Chainage */ delDisabled() { this.delAttr('disabled'); return this; } /** * switche l'attribut `hidden` des éléments sélectionnés * * @example * $_("span.my_class").toggleHidden(); * * @returns {this} Chainage */ toggleHidden() { this.each(item => { if (item.hasAttribute('hidden')) { item.removeAttribute('hidden'); } else { item.setAttribute('hidden', ''); } }); return this; } /** * switche l'attribut `readonly` des éléments sélectionnés * * @example * $_("input.my_class").toggleReadOnly(); * * @returns {this} Chainage */ toggleReadOnly() { this.each(item => { if (item.hasAttribute('readonly')) { item.removeAttribute('readonly'); } else { item.setAttribute('readonly', ''); } }); return this; } /** * switche l'attribut `disabled` des éléments sélectionnés * * @example * $_("input.my_class").toggleDisabled(); * * @returns {this} Chainage */ toggleDisabled() { this.each(item => { if (item.hasAttribute('disabled')) { item.removeAttribute('disabled'); } else { item.setAttribute('disabled', ''); } }); return this; } /** * Ajoute un gestionnaire d'événement aux éléments sélectionnés * * @example * $_("button#event").on("mouseover", (evt, el) => { * // Do something with evt and el * }, false); * * @param {String} type Nom de l'événement * @param {evtCallback} callback Gestionnaire de l'événement * @param {Boolean} useCapture Propagation de l'événement */ on(type, callback, useCapture) { this.each(item => { item.removeEventListener(type, callback, useCapture || false); item.addEventListener(type, evt => { callback(evt, item); }, useCapture || false); }); return this; } /** * Ajout d'un gestionnaire d'événement 'click' pour les éléments sélectionnés * * @example * $_("button#event").onClick( (evt, el) => { * // Do something with evt and el * }, false); * * @param {evtCallback} callback Gestionnaire de l'événement * @param {Boolean} useCapture Propagation de l'événement */ onClick(callback, useCapture) { this.on('click', callback, useCapture || false); return this; } /** * Fonction de rappel des méthodes on() et onClick() * @callback evtCallback * @see {@link #on} * @see {@link #onclick} * @param {Event} evt L'événement qui s'est produit * @param {HTMLElement} item L'élément du DOM concerné par lévénement */ /** * Retourne si un élément a été trouvé * * @example * let found = $_("#main").found(); * * @returns {Boolean} `true` si un élément au moins du DOM trouvé. `false` sinon */ found() { return this.elems.length > 0; } /** * Retourne le premier élément trouvé * * @example * let htmlElement = $_("p.paragraphe").first(); * * @param {Boolean} [isHTMLElement=false] `true` pour obtenir un élément du DOM, `false` pour un Objet GSDom * @returns {HTMLElement} l'élément du DOM trouvé */ first(isHTMLElement) { return this.found() ? (isHTMLElement === true ? this.elems[0] : new GSDom(this.elems[0])) : false; } /** * Retourne le dernier élément trouvé * * @example * let htmlElement = $_("p.paragraphe").last(); * * @param {Boolean} [isHTMLElement=false] `true` pour obtenir un élément du DOM, `false` pour un Objet GSDom * @returns {(GSDom|HTMLElement)} L'élément du DOM trouvé ou un Objet GSDom correspondant pour chainage */ last(isHTMLElement) { return this.found() ? (isHTMLElement === true ? this.elems[this.elems.length - 1] : new GSDom(this.elems[this.elems.length - 1])) : false; } version(long) { return long === true ? this.longversion : this.shortversion; } } return (selector, root) => { return new GSDom(selector, root); }; })();