Binding HTML5 class API without (jQuery)

Is there a way to chain the HTML5 class API chain ?.

it won't work

var sidebar = document.querySelector("#sidebar"); sidebar.classList.toggle("active").classList.remove("hover") 

while it will work

 var sidebar = document.querySelector("#sidebar"); sidebar.classList.toggle("active"); sidebar.classList.remove("hover") 

NOTE: NO jquery please

+8
javascript html5
source share
3 answers

You can create a chain using a small object using a chain:

 function classList(elt) { var list = elt.classList; return { toggle: function(c) { list.toggle(c); return this; }, add: function(c) { list.add (c); return this; }, remove: function(c) { list.remove(c); return this; } }; } 

Then you can snap your heart content:

 classList(elt).remove('foo').add('bar').toggle('baz') 
+9
source share

To bind to work, the method must return the object with which you want to bind. Because the .classList methods .classList not return a classList or a DOM, you cannot chain to them.

You could, of course, write your own methods and return the corresponding object to them, and thus re-implement the functionality of the chain, but you would have to put them in a prototype system to be able to use them easily.

Without overriding methods with a chain, you can shorten the code a bit:

 var sidebarList = document.querySelector("#sidebar").classList; sidebarList.toggle("active"); sidebarList.remove("hover"); 

If you want to add binding methods to valid HTML5 objects, you can do this:

 (function() { var p = HTMLElement.prototype; p.clAdd = function(cls) { this.classList.add(cls); return this; }; p.clRemove = function(cls) { this.classList.remove(cls); return this; }; p.clToggle = function(cls) { this.classList.toggle(cls); return this; } })(); // sample use document.querySelector("#sidebar").clAdd("active").clRemove("inactive"); 

Working demo: http://jsfiddle.net/jfriend00/t6w4aj0w/


Or, if you need an interface like .classList , you can do this:

 Object.defineProperty(HTMLElement.prototype, "classListChain", { get: function() { var self = this; return { add: function(cls) { self.classList.add(cls); return self; }, remove: function(cls) { self.classList.remove(cls); return self; }, toggle: function(cls) { self.classList.toggle(cls); return self; } } } }); // sample use document.querySelector("#sidebar").classListChain.add("active").classListChain.remove("inactive"); 

Working demo: http://jsfiddle.net/jfriend00/pxm11vcq/


FYI, because both of these options bind the actual DOM element (unlike the torazaburo method, which binds the user object), you can add the method / property of the DOM element at the end, as in:

 el.classListChain.add("active").style.visibility = "visible"; 

Or you can do something like this:

 var el = document.querySelector("#sidebar").classListChain.add("active"); 
+2
source share

If you only support modern browsers, chaining is one of the rare benefits that jQuery still holds against vanilla JavaScript, but that shouldn't stop you. Like @ jfriend00 suggested above, you can create your own add / remove / toggle methods that you can bind by simply returning the this object.

Here they are:

 Element.prototype.addClassC = Element.prototype.addClassC || function (htmlClass) { this.classList.add(htmlClass); return this; } Element.prototype.removeClassC = Element.prototype.removeClassC || function (htmlClass) { this.classList.remove(htmlClass); return this; } Element.prototype.toggleClassC = Element.prototype.toggleClassC || function (htmlClass) { this.classList.toggle(htmlClass); return this; } 

In your case, then you apply them like this:

 sidebar.toggleClassC('active').removeClassC('hover'); 

Note on naming. I would suggest just using addClass and removeClass , because they might conflict with jQuery's own methods, or someone reading the code would allow them for jQuery methods. Here I added C, which stands for Chaining, but you can call it something more meaningful to you.

Change I added a check to make sure that our methods have not yet been defined before, in order to avoid overriding. I also switched the class variable name from cssClass to htmlClass because it is more correct (html has classes, css has a selector).

0
source share

All Articles