w3schools variable tutorial javascripts getelement javascript dom

javascript - variable - Construyendo una instancia DOMTokenList/DOMSettableTokenList



dom javascript tutorial (2)

No puede crear un DOMTokenList o un DOMSettableTokenList directamente. En su lugar, debe usar el atributo de clase para almacenar y recuperar sus datos y tal vez asignar un atributo de ID de su elemento DOM a la propiedad classList.

var element = document.querySelector(''so-users''); element.ids = element.classList;

Puede usar relList de acuerdo con la documentación pero classList es más compatible, el único inconveniente es que puede tener problemas si uno de sus identificadores coincide con un nombre de clase, así que configure un estilo en línea para ocultar el elemento por si acaso.

Para un componente personalizado, la compatibilidad debe ser una preocupación (classList está presente en IE> = 10, Firefox 3.6, Chrome 8, Opera 11.5 y Safari 5.1, consulte http://caniuse.com/#feat=classlist ) por lo que si la compatibilidad está en sus requisitos utilizan la otra solución publicada a continuación.

Si no puede usar clases o classList y / o debe usar el atributo ids, debe implementar una función personalizada de acuerdo con la especificación con las siguientes propiedades como funciones.

  • ít()
  • contiene ()
  • añadir()
  • retirar()
  • palanca()

Este es un ejemplo de implementación de dicha funcionalidad.

var TokenList = function (ids) { ''use strict''; var idsArray = [], self = this, parse = function (id, functionName, cb) { var search = id.toString(); if (search.split('' '').length > 1) { throw new Error("Failed to execute ''" + functionName + "'' on ''TokenList'': The token provided (''" + search + "'') contains HTML space characters, which are not valid in tokens.'');"); } else { cb(search); } }; function triggerAttributeChange() { if (self.tokenChanged && typeof self.tokenChanged === ''function'') { self.tokenChanged(idsArray.toString()); } } if (ids && typeof ids === ''string'') { idsArray = ids.split('' ''); } self.item = function (index) { return idsArray[index]; }; self.contains = function (id) { parse(id, ''contains'', function (search) { return idsArray.indexOf(search) !== -1; }); }; self.add = function (id) { parse(id, ''add'', function (search) { if (idsArray.indexOf(search) === -1) { idsArray.push(search); } triggerAttributeChange(); }); }; self.remove = function (id) { parse(id, ''remove'', function (search) { idsArray = idsArray.filter(function (item) { return item !== id; }); triggerAttributeChange(); }); }; self.toggle = function (id) { parse(id, ''toggle'', function (search) { if (!self.contains(search)) { self.add(search); } else { self.remove(search); } }); }; self.tokenChanged = null; self.toString = function () { var tokens = '''', i; if (idsArray.length > 0) { for (i = 0; i < idsArray.length; i = i + 1) { tokens = tokens + idsArray[i] + '' ''; } tokens = tokens.slice(0, tokens.length - 1); } return tokens; }; };

Establezca una propiedad ''ids'' en su elemento con una nueva instancia de esta función y, finalmente, debe vincular el atributo de destino a la propiedad escuchando los cambios en el elemento y actualizando la propiedad o viceversa. Puedes hacerlo con un observador de mutaciones.

Consulte el evento de activación del cambio de atributo de DOM y https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

var attachTokenList = function (element, prop, initialValues) { ''use strict''; var initValues = initialValues || element.getAttribute(prop), MutationObserver = window.MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver, observer, config, cancelMutation = false; function createTokenList(values) { var tList = new TokenList(values); tList.tokenChanged = function () { element.setAttribute(prop, element[prop].toString()); cancelMutation = true; }; element[prop] = tList; } createTokenList(initValues); observer = new MutationObserver(function (mutation) { var i, mutationrec, newAttr; if (mutation.length > 0 && !cancelMutation) { for (i = 0; i < mutation.length; i = i + 1) { mutationrec = mutation[i]; if (mutationrec.attributeName === prop && element[prop]) { newAttr = element.getAttribute(prop); createTokenList(newAttr); } } } cancelMutation = false; }); config = { attributes: true }; observer.observe(element, config); };

Pruebas para ver si funciona.

<so-users ids="1234 5678"></so-users> <button onclick="clickButton1()">Add 7890</button> <button onclick="clickButton2()">Set to 3456</button> <button onclick="clickButton3()">Add 9876</button>

Dentro de una etiqueta de script

var elem = document.querySelector(''so-users''); attachTokenList(elem, ''ids'') function clickButton1 () { elem.ids.add(''7890''); } function clickButton2 () { elem.setAttribute(''ids'', ''3456''); } function clickButton3 () { elem.ids.add(''9876''); }

Al hacer clic en los botones en secuencia, establezca el atributo ids en ''3456 9876''

Las interfaces DOMTokenList y DOMSettableTokenList ( MDN , WHATWG ) proporcionan métodos para manipular conjuntos ordenados de tokens de cadena representados por cadenas delimitadas por espacios. Se utilizan más comúnmente en la forma de la propiedad Element.prototype.classList, un DOMTokenList que refleja el atributo de class de un elemento asociado.

var div = document.createElement(''div''); div.setAttribute(''class'', ''hello world goodnight moon''); var list = div.classList; console.assert(list.length === 4); console.assert(list[0] === ''hello''); console.assert(list.item(1) === ''world''); console.assert(list.contains(''moon'') === true); console.assert(list.contains(''mars'') === false); list.remove(''world'', ''earth'', ''dirt'', ''sand''); list.add(''hello'', ''mars''); list.toggle(''goodnight''); console.assert(div.getAttribute(''class'') === ''hello moon mars'');

Estoy trabajando en un elemento personalizado ( HTML5Rocks , W3C Draft ) que muestra un feed en tiempo real de la actividad de los usuarios de desbordamiento de pila especificados. Esta lista de usuarios se especifica en un atributo de ids y se puede actualizar en cualquier momento.

<so-users ids="1114 22656 106224"></so-users>

document.querySelector(''so-users'').setAttribute(''ids'', ''23354 115866'');

En lugar de requerir que los usuarios manipulen este atributo directamente, me gustaría tener una propiedad .ids que proporcione un DOMTokenList que puedan usar en su lugar. Idealmente, esto estaría directamente asociado con el atributo, pero una instancia de DOMSettableTokenList no vinculada que tengo que enlazar manualmente también estaría bien.

document.querySelector(''so-users'').ids.add(''17174'');

Desafortunadamente, no he podido encontrar ninguna forma de crear una instancia de DOMTokenList. La definición no es un constructor, y la creación directa de un objeto utilizando su prototipo produce errores cuando llamo a cualquier método asociado:

new DOMTokenList; // TypeError: Illegal constructor new DOMSettableTokenList; // TypeError: Illegal constructor

var list = Object.create(DOMSettableTokenList.prototype, { value: { value: ''hello world'' } }); console.assert(list instanceof DOMTokenList); console.assert(list instanceof DOMSettableTokenList); list.item(0); // TypeError: Illegal invocation

function TokenListConstructor() { this.value = ''hello world''; } TokenListConstructor.prototype = DOMSettableTokenList.prototype; var list = new TokenListConstructor; console.assert(list instanceof DOMTokenList); console.assert(list instanceof DOMSettableTokenList); list.add(''moon''); // TypeError: Illegal invocation

¿Cómo puedo construir una nueva instancia de DOMTokenList o DOMSettableTokenList ?


Utilización de html5rocks.com/en/tutorials/webcomponents/customelements/… enfoque de inicialización de html5rocks.com/en/tutorials/webcomponents/customelements/… , HTMLElement.dataset , intente

var XFooProto = Object.create(HTMLElement.prototype); // 1. Give x-foo a foo() method. XFooProto.contains = function(id) { var data = JSON.parse(this.dataset.ids); return data.some(function(_id) { return id == _id }) }; XFooProto.add = function(id) { var data = JSON.parse(this.dataset.ids); if (!this.contains(id)) { data.push(id); }; return data }; XFooProto.remove = function(id) { var data = JSON.parse(this.dataset.ids); if (this.contains(id)) { for (var _id in data) { if (data[_id] === id) { data.splice(_id, 1) } }; }; return data }; XFooProto.ids = function() { return this.dataset.ids }; // 2. Define a property read-only "bar". // Object.defineProperty(XFooProto, "ids", {value: this}); // 3. Register x-foo''s definition. var XFoo = document.registerElement(''x-foo'', {prototype: XFooProto}); // 4. Instantiate an x-foo. var xfoo = document.createElement(''x-foo''); xfoo.dataset.ids = ''["23354", "115866"]''; // 5. Add it to the page. document.body.appendChild(xfoo); console.log(xfoo.add("123")); // `["23354", "115866", "123"]` console.log(xfoo.remove("123")); // `["23354", "115866"]` console.log(xfoo.contains("123")); // `false` console.log(xfoo.contains("23354")); // `true` console.log(xfoo.ids()); // `["23354", "115866"]` , type : `String` var pre = document.getElementsByTagName("pre")[0] pre.innerText = JSON.stringify(JSON.parse(xfoo.dataset.ids), null, 4);

<pre></pre>