Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
classList shim
(version: 3)
Optimzing classList shim
Comparing performance of:
myClassList1 vs myClassList2 vs myClassList3 vs myClassList4 vs default
Created:
9 years ago
by:
Registered User
Jump to the latest result
HTML Preparation code:
<div id="test-div" class="class1 class2 class3 class4 class5 class6 class7">My test div</div> <script> ;(function (view) { 'use strict'; var tokenListProp = 'DOMTokenList1', classListProp = 'myClassList1'; if (typeof view === 'undefined') { return; } if (!(tokenListProp in view)) { var arr = []; var inArray = function (array, value) { var i; if (arr.indexOf) { return arr.indexOf.call(array, value); } for (i = 0; i < array.length; i++) { if (array[i] === value) { return i; } } return -1; }; var validateToken = function (token) { var whitespace = /[\u0009\u000A\u000C\u000D\u0020]/; if (token === '' || whitespace.test(token)) { throw new Error('Token must not be empty or contain whitespace.'); } }; var DOMTokenList = function (element, prop) { var inst = this; var i; var values = []; if (element && prop) { inst.element = element; inst.prop = prop; if (element[prop]) { values = element[prop].replace(/^\s+|\s+$/g, '').split(/\s+/); for (i = 0; i < values.length; i++) { inst[i] = values[i]; } } } inst.length = values.length; }; DOMTokenList.prototype = { add: function () { var inst = this; var i; var tokens = arguments; for (i = 0; i < tokens.length; i++) { validateToken(tokens[i]); if (!inst.contains(tokens[i])) { arr.push.call(inst, tokens[i]); } } if (inst.element) { inst.element[inst.prop] = inst; } }, contains: function (token) { validateToken(token); return inArray(this, token) !== -1; }, item: function (index) { return this[index] || null; }, remove: function () { var tokens = arguments; var inst = this; var key; var i; for (i = 0; i < tokens.length; i++) { validateToken(tokens[i]); key = inArray(inst, tokens[i]); if (key !== -1) { arr.splice.call(inst, key, 1); } } if (inst.element) { inst.element[inst.prop] = inst; } }, toggle: function (token, force) { var inst = this; if (inst.contains(token)) { if (force) { return true; } inst.remove(token); return false; } else { if (force === false) { return false; } inst.add(token); return true; } }, toString: function () { return arr.join.call(this, ' '); } }; view[tokenListProp] = DOMTokenList; } if (("document" in view) && ('Element' in view) && !(classListProp in view.document.createElement("_"))) { Object.defineProperty(view.Element.prototype, classListProp, { get: function () { return new view[tokenListProp](this, 'className'); } }); } }(self)); ;(function (view) { 'use strict'; var tokenListProp = 'DOMTokenList2', classListProp = 'myClassList2'; if (typeof view === 'undefined') { return; } if (!(tokenListProp in view)) { var arr = []; var inArray = function (array, value) { var i; if (arr.indexOf) { return arr.indexOf.call(array, value); } for (i = 0; i < array.length; i++) { if (array[i] === value) { return i; } } return -1; }; var validateToken = function (token) { var whitespace = /[\u0009\u000A\u000C\u000D\u0020]/; if (token === '' || whitespace.test(token)) { throw new Error('Token must not be empty or contain whitespace.'); } }; var DOMTokenList = function (element, prop) { var inst = this; var i; var values = []; if (element && prop) { inst.element = element; inst.prop = prop; if (element[prop]) { values = element[prop].replace(/^\s+|\s+$/g, '').split(/\s+/); for (i = 0; i < values.length; i++) { inst[i] = values[i]; } } } inst.length = values.length; }; DOMTokenList.prototype = { add: function () { var inst = this; var i; var tokens = arguments; for (i = 0; i < tokens.length; i++) { validateToken(tokens[i]); if (!inst.contains(tokens[i])) { arr.push.call(inst, tokens[i]); } } if (inst.element) { inst.element[inst.prop] = inst; } }, contains: function (token) { validateToken(token); return inArray(this, token) !== -1; }, item: function (index) { return this[index] || null; }, remove: function () { var tokens = arguments; var inst = this; var key; var i; for (i = 0; i < tokens.length; i++) { validateToken(tokens[i]); key = inArray(inst, tokens[i]); if (key !== -1) { arr.splice.call(inst, key, 1); } } if (inst.element) { inst.element[inst.prop] = inst; } }, toggle: function (token, force) { var inst = this; if (inst.contains(token)) { if (force) { return true; } inst.remove(token); return false; } else { if (force === false) { return false; } inst.add(token); return true; } }, toString: function () { return arr.join.call(this, ' '); } }; view[tokenListProp] = DOMTokenList; } if (("document" in view) && ('Element' in view) && !(classListProp in view.document.createElement("_"))) { Object.defineProperty(view.Element.prototype, classListProp, { get: function () { return new view[tokenListProp](this, 'className'); } }); } }(self)); ;(function (view) { "use strict"; var classListProp = 'myClassList3'; if ((typeof view === 'undefined') || !("document" in view) || !('Element' in view) || (classListProp in document.createElement("_"))) { return; } var protoProp = "prototype" , elemCtrProto = view.Element[protoProp] , objCtr = Object , strTrim = String[protoProp].trim || function () { return this.replace(/^\s+|\s+$/g, ""); } , arrIndexOf = Array[protoProp].indexOf || function (item) { var i = 0 , len = this.length ; for (; i < len; i++) { if (i in this && this[i] === item) { return i; } } return -1; } // Vendors: please allow content code to instantiate DOMExceptions , DOMEx = function (type, message) { this.name = type; this.code = DOMException[type]; this.message = message; } , checkTokenAndGetIndex = function (classList, token) { if (token === "") { throw new DOMEx( "SYNTAX_ERR" , "An invalid or illegal string was specified" ); } if (/\s/.test(token)) { throw new DOMEx( "INVALID_CHARACTER_ERR" , "String contains an invalid character" ); } return arrIndexOf.call(classList, token); } , ClassList = function (elem) { var trimmedClasses = strTrim.call(elem.getAttribute("class") || "") , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [] , i = 0 , len = classes.length ; for (; i < len; i++) { this.push(classes[i]); } this._updateClassName = function () { elem.setAttribute("class", this.toString()); }; } , classListProto = ClassList[protoProp] = [] , classListGetter = function () { return new ClassList(this); } ; // Most DOMException implementations don't allow calling DOMException's toString() // on non-DOMExceptions. Error's toString() is sufficient here. DOMEx[protoProp] = Error[protoProp]; classListProto.item = function (i) { return this[i] || null; }; classListProto.contains = function (token) { token += ""; return checkTokenAndGetIndex(this, token) !== -1; }; classListProto.add = function () { var tokens = arguments , i = 0 , l = tokens.length , token , updated = false ; do { token = tokens[i] + ""; if (checkTokenAndGetIndex(this, token) === -1) { this.push(token); updated = true; } } while (++i < l); if (updated) { this._updateClassName(); } }; classListProto.remove = function () { var tokens = arguments , i = 0 , l = tokens.length , token , updated = false , index ; do { token = tokens[i] + ""; index = checkTokenAndGetIndex(this, token); while (index !== -1) { this.splice(index, 1); updated = true; index = checkTokenAndGetIndex(this, token); } } while (++i < l); if (updated) { this._updateClassName(); } }; classListProto.toggle = function (token, force) { token += ""; var result = this.contains(token) , method = result ? force !== true && "remove" : force !== false && "add" ; if (method) { this[method](token); } if (force === true || force === false) { return force; } else { return !result; } }; classListProto.toString = function () { return this.join(" "); }; if (objCtr.defineProperty) { var classListPropDesc = { get: classListGetter , enumerable: false , configurable: true }; objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); } else if (objCtr[protoProp].__defineGetter__) { elemCtrProto.__defineGetter__(classListProp, classListGetter); } }(self)); ;(function (view) { "use strict"; var classListProp = 'myClassList4'; if ((typeof view === 'undefined') || !("document" in view) || !('Element' in view) || (classListProp in document.createElement("_"))) { return; } var protoProp = "prototype" , elemCtrProto = view.Element[protoProp] , objCtr = Object , strTrim = String[protoProp].trim || function () { return this.replace(/^\s+|\s+$/g, ""); } , arrIndexOf = Array[protoProp].indexOf || function (item) { var i = 0 , len = this.length ; for (; i < len; i++) { if (i in this && this[i] === item) { return i; } } return -1; } // Vendors: please allow content code to instantiate DOMExceptions , DOMEx = function (type, message) { this.name = type; this.code = DOMException[type]; this.message = message; } , checkTokenAndGetIndex = function (classList, token) { if (token === "") { throw new DOMEx( "SYNTAX_ERR" , "An invalid or illegal string was specified" ); } if (/\s/.test(token)) { throw new DOMEx( "INVALID_CHARACTER_ERR" , "String contains an invalid character" ); } return arrIndexOf.call(classList, token); } , ClassList = function (elem) { var trimmedClasses = strTrim.call(elem.getAttribute("class") || "") , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [] , i = 0 , len = classes.length ; for (; i < len; i++) { this.push(classes[i]); } this._updateClassName = function () { elem.setAttribute("class", this.toString()); }; } , classListProto = ClassList[protoProp] = [] , classListGetter = function () { return new ClassList(this); } ; // Most DOMException implementations don't allow calling DOMException's toString() // on non-DOMExceptions. Error's toString() is sufficient here. DOMEx[protoProp] = Error[protoProp]; classListProto.item = function (i) { return this[i] || null; }; classListProto.contains = function (token) { token += ""; return checkTokenAndGetIndex(this, token) !== -1; }; classListProto.add = function () { var tokens = arguments , i = 0 , l = tokens.length , token , updated = false ; do { token = tokens[i] + ""; if (checkTokenAndGetIndex(this, token) === -1) { this.push(token); updated = true; } } while (++i < l); if (updated) { this._updateClassName(); } }; classListProto.remove = function () { var tokens = arguments , i = 0 , l = tokens.length , token , updated = false , index ; do { token = tokens[i] + ""; index = checkTokenAndGetIndex(this, token); while (index !== -1) { this.splice(index, 1); updated = true; index = checkTokenAndGetIndex(this, token); } } while (++i < l); if (updated) { this._updateClassName(); } }; classListProto.toggle = function (token, force) { token += ""; var result = this.contains(token) , method = result ? force !== true && "remove" : force !== false && "add" ; if (method) { this[method](token); } if (force === true || force === false) { return force; } else { return !result; } }; classListProto.toString = function () { return this.join(" "); }; if (objCtr.defineProperty) { var classListPropDesc = { get: classListGetter , enumerable: false , configurable: true }; objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); } else if (objCtr[protoProp].__defineGetter__) { elemCtrProto.__defineGetter__(classListProp, classListGetter); } }(self)); </script>
Script Preparation code:
var mydiv = document.getElementById("test-div"); var test;
Tests:
myClassList1
test = mydiv.myClassList1; test = mydiv.myClassList1;
myClassList2
test = mydiv.myClassList2; test = mydiv.myClassList2;
myClassList3
test = mydiv.myClassList3; test = mydiv.myClassList3;
myClassList4
test = mydiv.myClassList4; test = mydiv.myClassList4;
default
test = mydiv.classList; test = mydiv.classList';
Rendered benchmark preparation results:
Suite status:
<idle, ready to run>
Run tests (5)
Previous results
Fork
Test case name
Result
myClassList1
myClassList2
myClassList3
myClassList4
default
Fastest:
N/A
Slowest:
N/A
Latest run results:
No previous run results
This benchmark does not have any results yet. Be the first one
to run it!
Autogenerated LLM Summary
(model
llama3.2:3b
, generated one year ago):
It looks like you have a JavaScript code snippet and some test cases, but I'll assume you want me to help with the actual analysis. From what I can gather: 1. The code defines a class `classListProto` with several methods: `toggle`, `toString`, and some getter/setter for `classListProp`. 2. There are four individual test cases defined in an array (`individualTestCases`). Each test case has a "Benchmark Definition" string, a "Test Name", and possibly other metadata. 3. The latest benchmark result is shown in the format of multiple objects, each containing various metrics like `RawUAString`, `Browser`, `DevicePlatform`, etc. To help you better, I'd like to ask some clarifying questions: * What is the purpose of this code? Is it a testing framework or an actual implementation? * Can you provide more context about these test cases and what's being measured (e.g., performance, accuracy)? * Are there any specific requirements or constraints for the solution (e.g., optimization, error handling)? Please feel free to add more information if I'm missing something!
Related benchmarks:
className vs. classList v2
classlist vs classname
className vs classList for a new element
toggle classname string vs array vs classList
Comments
Confirm delete:
Do you really want to delete benchmark?