Reviving this because I recently remembered something about JavaScript. This depends on how the NodeList is being checked, but..
const singleNode = ((nodeList) => (node) => {
const layer = { // define our specific case
0: { value: node, enumerable: true },
length: { value: 1 },
item: {
value(i) {
return this[+i || 0];
},
enumerable: true,
},
};
return Object.create(nodeList, layer); // put our case on top of true NodeList
})(document.createDocumentFragment().childNodes); // scope a true NodeList
Now, if you do
const list = singleNode(document.body); // for example
list instanceof NodeList; // true
list.constructor === NodeList; // true
and list
has properties length 1
and 0 as your node, as well as anything inherited from NodeList.
If you can't use Object.create
, you could do the same except as a constructor with prototype nodelist
and set this['0'] = node;
, this['length'] = 1;
and create with new
.
ES5 version
var singleNode = (function () {
// make an empty node list to inherit from
var nodelist = document.createDocumentFragment().childNodes;
// return a function to create object formed as desired
return function (node) {
return Object.create(nodelist, {
'0': {value: node, enumerable: true},
'length': {value: 1},
'item': {
"value": function (i) {
return this[+i || 0];
},
enumerable: true
}
}); // return an object pretending to be a NodeList
};
}());