2015-02-22 16 views
8

Czy istnieje sposób na łańcuchowe łączenie interfejsu API klasy HTML5?łańcuchowanie interfejsu API klasy HTML5 bez (Jquery)

to nie będzie działać

var sidebar = document.querySelector("#sidebar"); 

sidebar.classList.toggle("active").classList.remove("hover") 

podczas gdy to będzie działać

var sidebar = document.querySelector("#sidebar"); 

sidebar.classList.toggle("active"); 
sidebar.classList.remove("hover") 

UWAGA: NO jquery proszę

+1

można napisać własną funkcję, która działa jak jQuery. – SLaks

+0

Lub może całkowicie uniknąć łączenia. –

+1

http://jsfiddle.net/7f8ud2s0/ – undefined

Odpowiedz

9

Można tworzyć chainability za pomocą małego przedmiotu z metodami chainable:

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; } 
    }; 

} 

Następnie można łańcuch do syta:

classList(elt).remove('foo').add('bar').toggle('baz') 
2

łańcuchowym do pracy, metoda musi zwrócić obiekt, który z którym chcesz się połączyć. Ponieważ metody .classList nie zwracają ani obiektu classList, ani obiektu DOM, nie można natywnie połączyć się z nimi.

Można oczywiście napisać własne metody i zwrócić im odpowiedni obiekt, a tym samym ponownie wprowadzić funkcjonalność w sposób łańcuchowy, ale musielibyśmy umieścić je na prototypie systemu, aby móc używaj ich tak łatwo.

Bez reimplementing metod chainable, można skrócić kod nieco:

(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"); 
:

var sidebarList = document.querySelector("#sidebar").classList; 

sidebarList.toggle("active"); 
sidebarList.remove("hover"); 

Jeśli chcesz dodać metody chainable na rzeczywistych obiektach HTML5, można to zrobić

Demo robocze: http://jsfiddle.net/jfriend00/t6w4aj0w/


Albo, jeśli chcesz interfejs .classList typu, można to zrobić:

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"); 

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


FYI, ponieważ obie te opcje łańcucha rzeczywistego elementu DOM (w przeciwieństwie do metoda torazaburo, która prowadzi łańcuch do niestandardowego obiektu), możesz dodać metodę/właściwość elementu DOM na końcu: w następujący sposób:

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

Lub, można zrobić coś takiego:

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

@Tambo - Twoje pytanie o "sposób na połączenie HTML5 ClassList API", które nie jest tym, co faktycznie zaakceptowałeś. Tworzy globalną funkcję własnego tworzenia, która może łączyć łańcuchy - nie łączy się z klasycznym interfejsem API klasy HTML5. Najwyraźniej właśnie tego chcesz, ale w uczciwości nie jest to, o co prosiłeś. W każdym razie dodałem dwa różne sposoby łączenia, jeśli sobie tego życzysz. – jfriend00

0

Jeśli tylko obsługiwać nowoczesnych przeglądarek, łańcuchowym jest jednym z nielicznych zalet jQuery wciąż trzyma przed wanilii JavaScript, ale to nie powinno cię powstrzymać. Tak, jak zasugerowano wyżej @ jfriend00, możesz stworzyć własne metody dodawania/usuwania/przełączania, które można powiązać, zwracając po prostu obiekt this.

Oto one:

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; 
} 

W twoim przypadku byś następnie zastosować je tak:

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

notatkę o nazewnictwo.Sugerowałbym, żeby nie używać po prostu addClass i removeClass, ponieważ mogą one kolidować z własnymi metodami jQuery, a ktoś czytający kod pomyliłby je z metodami jQuery. Tutaj dodałem C, które oznacza Chaining, ale możesz nazwać to czymś bardziej znaczącym dla ciebie.

Edytuj: Dodałem czek, aby upewnić się, że nasze metody nie zostały wcześniej zdefiniowane, aby uniknąć przesłonięcia. Zmieniłem także nazwę klasy klasy z cssClass na htmlClass, ponieważ jest to bardziej poprawne (html ma klasy, css ma selektory).

+0

Ciekawe, dlaczego zdecydowałeś się nazwać parametry "klasami". To jednoosobowe imię, prawda? (Chociaż niektóre przeglądarki najwyraźniej obsługują variadicity.) –

+0

Kod mógł zostać refaktoryzowany, aby w rzeczywistości obsługiwać wiele klas przez 'tablicę', ale masz rację, obsługa przeglądarki dla wielu klas nie jest w 100% ([IE jest zwykle winowajca] (http://caniuse.com/#feat=classlist)), więc poprawiłem kod, aby uniknąć nieporozumień. Funkcje i tak mogą być powiązane. Dziękuję za uwagę. –

Powiązane problemy