The DOMTokenList and DOMSettableTokenList interfaces (MDN, WHATWG) provide methods for manipulating ordered sets of string tokens represented by space-delimited strings. They are most commonly used in the form of the Element.prototype.classList property, a DOMTokenList which reflects the class
attribute of an associated element.
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');
I'm working on a custom element (HTML5Rocks, W3C Draft) which displays a real-time feed of the activity of specified Stack Overflow users. This list of users is specified in an ids
attribute, and may be updated at any time.
<so-users ids="1114 22656 106224"></so-users>
document.querySelector('so-users').setAttribute('ids', '23354 115866');
Instead of requiring users to manipulate this attribute directly, I would like to have an .ids
property providing a DOMTokenList that they can use instead. Ideally this would be directly associated with the attribute, but an unbound DOMSettableTokenList instance that I have to manually bind would also be fine.
document.querySelector('so-users').ids.add('17174');
Unfortunately, I have been unable to find any way to create a DOMTokenList instance. The definition is not a constructor, and directly creating an object using its prototype results in errors when I call any associated methods:
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
How can I construct a new DOMTokenList
or DOMSettableTokenList
instance?
ids
attribute instead ofclass
attribute ? – Vitrifyclass
attribute for these purpose would conflict with using it for styles. If I specified style classes, then a user could no longer iterate over the tokenlist to find all of the users it's targeting. I'd like to provide a cleaner API for my element by using a distinct attribute, like I generally would when creating custom elements. – Insanitaryelement.dataset
- definingadd
,remove
,contains
functions as toelement.dataset
- instead of attempting to incorporateDOMTokenList
into the implementation. Are the main functions required and attached to theids
attributeadd
,contains
,remove
? – Vitrifyids
to an array? then you can use push/pop/indexOf/etc, which aside from toggle has the same features, and more. or a Set? – Toponym