9
votes

Comment hériter de la classe d'élément DOM

Je veux écrire des classes JavaScript qui étendent les nœudes DOM (afin que je puisse insérer des instances de ma classe directement dans le DOM), mais j'ai du mal à trouver la classe / prototype que je devrais hériter de.

par exemple : p>

function myExtendedElement() {
       this.superclass = ClassA;
       this.superclass();
       delete this.superclass;
} 


2 commentaires

DUP: Stackoverflow.com/Questtions/1384564/ ...


Vous pouvez aussi bien simplement faire classa.call (ceci), la manière standard d'héritage d'une classe de base.


5 Réponses :


1
votes

Vous pouvez simplement ajouter de nouvelles fonctions aux prototypes DOM, par exemple.

Element.prototype.myNameSpaceSomeFunction = function(...){...}


2 commentaires

Notez que cela ne fonctionnera sur aucune version d'IE avant IE8.


Ce n'est pas ce que je recherche car je souhaite avoir plusieurs types d'éléments étendus, donc ne peut donc pas limer le prototype de tous les éléments



0
votes

J'ai trouvé un hack qui fonctionne ... au moins, cela me permet d'accéder aux propriétés d'objet étendues via l'élément DOM et inversement. Mais il est à peine élégant.

var DOMelement = document.getElementById('myID'); // or  $('#myID')[0]; in jQuery
DOMelement.extended = new extensionClass(this);

function extensionClass(element) {
    this.element = element;
    ...
}


2 commentaires

Vous devriez en réalité éviter d'ajouter des propriétés aux éléments comme celui-ci (également appelé expulsions). Non seulement il n'est pas sûr d'augmenter les objets hôtes, les chances que vous créez accidentellement une référence circulaire entre objet hôte et objet natif, que fuit dans certaines versions (<8, IIRC) de IE.


Je me méfie de créer des références circulaires et je testerai mon application avec des instances ridiculement importantes pour voir si un effet est perceptible. Pourquoi n'est-ce pas sans danger pour augmenter des objets hôtes?



20
votes

C'est pas une bonne idée forte> pour le faire.

Tout d'abord, d'hériter de DOM Element, vous devez avoir accès au prototype de ce élément. Le problème est que Tous les navigateurs ne fournissent pas accès aux prototypes d'éléments DOM forts>. Les nouveaux clients de Gecko et de Webkit, par exemple, exposer certains de ces prototypes en tant qu'objets globaux - HTMLDivelement, HTMLElement, élément, noeud, etc. P>

Par exemple, l'élément divisa a généralement une chaîne de prototype similaire à : P>

typeof myDivElement.nodeName; // "undefined"
myDivElement.innerHTML = '<span>foo<\/span>';
myDivElement.childNodes; // Error


5 commentaires

perfectionkills.com/whats-wrong-obith-extending -Le-dom


> 5 ans plus tard, peut-être que cela est obsolète?


@hellochris perfectionkills.com/whats-wrong-obith-extending -Le-dom / ...


Ceci est obsolète. Vous pouvez étendre le DOM avec des éléments personnalisés, qui sont nécessaires pour hériter de HTMLElement; Le travail est en cours depuis au moins 2013 w3.org/tr/custom-elements


Lolz le travail est en cours depuis au moins 2013 et pourtant c'est 2017 et RegisterElement sur Caniuse.com est toujours à peu près rouge à travers le tableau!



3
votes

ancienne q mais il y a une meilleure réponse que "faire" ou "ne" pas "maintenant que IE6 est principalement défunt. Tout d'abord, les constructeurs de noyau du prototypage de l'ECMA de l'ECMA, tels que «Array», sont assez inoffensifs et utiles si vous le faites correctement et que vous testez pour éviter de casser les méthodes existantes. Restez certainement à l'écart de l'objet et réfléchissez bien avant de jouer avec la fonction, cependant.

Si vous partagez du code entre beaucoup de personnes / auteurs ou que vous traitez avec des incertitudes DOM, il est généralement préférable de créer des objets de l'adaptateur / wrapper avec une nouvelle méthode d'usine à utiliser dans un schéma d'héritage. P>

Dans ce cas, j'ai écrit document.CreateExtel pour créer des éléments DOM enveloppés dont les propriétés accessibles sont toutes disponibles via prototype. p>

Utilisation des éléments suivants, votre "Superclass" pour DIVS serait HTMLEXTTelement ( Dans ce cas mondialement disponible - EW, mais c'est juste un exemple). Toutes les références aux propriétés disponibles de l'instance HTMLElement d'origine vivent dans le prototype du wrapper. Remarque: certaines vieilles propriétés à savoir ne peuvent pas être transmises sous forme de références ni même accessibles sans jeter des erreurs (génial), ce qui est ce que l'essai / attrape est pour. P>

Vous pouvez normaliser les propriétés courantes en ajoutant une logique à mettre propriétés manquantes ou normalisées correctement après que la boucle enveloppe les propriétés disponibles, mais je vous quitterai cela. P>

Maintenant pour l'amour de Pete, n'utilisez jamais mon code pour écrire un certain cascade 16- fois la sottise héritage et ensuite mettre en œuvre dans certaines bibliothèques ironiquement populaires, nous sommes tous obligés de traiter ou je vais vous chasser et citera fort "des motifs de conception" à vous tout en jetant des fruits pourris. P>

//Implementation just like document.createElement()
//document.createExtEl('div').tagName === 'DIV'

document.createExtEl = ( function(){  //returns a function below

            var htmlTags = ['div','a'], //... add all the element tags you care to make extendable here
            constructorMap = {},
            i = htmlTags.length;

            while(i--){
                thisTag = htmlTags[i].toLowerCase();
                constructorMap[ thisTag ] = function(){
                    var elObj = document.createElement(thisTag),
                    thisProto = this.constructor.prototype,
                    constructorName = 'HTMLExt' + thisTag.charAt(0).toUpperCase() + thisTag.slice(1) + 'Element';

                    alert(constructorName);

                    window[constructorName] = this.constructor; //adds a global reference you can access the new constructor from.

                    for(var x in elObj){ try{ thisProto[x] = elObj[x]; } catch(e){} }
                }
            }

            //all of the above  executes once and returned function accesses via closure
            return function(tagName){
                return new constructorMap[tagName.toLowerCase()]();
            }



    } )()

    //Now in the case of a superclass/constructor for div, you could use HTMLExtDivElement globally


0 commentaires

1
votes

en 2020, vous pouvez facilement créer un élément personnalisé en étendant des éléments HTML.

class AppDrawer extends HTMLElement {...}
window.customElements.define('app-drawer', AppDrawer);

// Or use an anonymous class if you don't want a named constructor in current scope.
window.customElements.define('app-drawer', class extends HTMLElement {...});


0 commentaires