Prototype.js - własne selektory
By dodać własny selektor w jQuery autorzy jak zwykle poszli na rękę (wg mnie porządnie na nią nadepneli) i dali do tego specjalną metodę. Cztery argumenty, z czego dwa są tablicami... po co?
$.expr[':'].mySelector = function(objNode, intStackIndex, arrProperties, arrNodeStack) {
// implementacja selektora
};
W prototypie implementacja jest prostsza i można z powodzeniem korzystać z dokumentacji Sizzle, z tą różnicą, że w dokumentacji piszą Sizzle.foo, a w prototype pisać pełną ścieżkę gdzie Sizzle się znajduje Prototype.Selector.engine.selectors.foo. Dla jasności - dotyczy nas Extension Api.
Kamil na swoim blogu w ramach przykładu tworzył pseudoselektor :external, wykonującego co następuje:
- Tylko obiekty a lub link
- z atrybutem rel="external"
- z wpisanym atrybutem href
- prowadzące do zewnętrznej domeny
Więc, by stworzyć dla prototype taki pseudoselektor trzeba dodać do Sizzle filtr sprawdzający czy element spełnia nasze warunki.
Prototype.Selector.engine.selectors.filters.external = function(elem) {
return elem.tagName.match(/^a|link$/i) && elem.href && elem.rel.match(/external/i) && elem.href.search(window.location.hostname) === -1;
};
Była definicja i wywołanie mające wykonać usuń wszystkie linki zewnętrzne, które prowadzą do Twittera lub Google+:
$$('a:external[href*=plus.google.com]', 'a:external[href*=twitter.com]').invoke('remove');
Jeśli trzeba zrobić selektor bardziej rozbudowany, można z powodzeniem korzystać z normalnej składni prototype, obiekt przekazywany do filtra jest już rozszerzony.
Przykładowo, pseudoselektor :visible, który zwraca widoczne elementy. Gdzie widoczne należy rozumieć jako znajdujące się obecnie w oknie przeglądarki i nie będące w jakiś sposób ukryte.
Prototype.Selector.engine.selectors.filters.visible = function(elem) {
if(elem.style.display == 'none' || elem.style.visibility == 'hidden' || elem.style.opacity == 0) {
return false;
}
var view = [document.viewport.getDimensions ['width'], document.viewport.getDimensions ['height']];
var offsets = document.viewport.getScrollOffsets ;
var pos = elem.viewportOffset ;
if(pos[0] >= offsets[0] && pos[0] <= offsets[0]+view[0] && pos[1] >= offsets[1] && pos[1] <= offsets[1]+view[1]) {
return true;
}
return false;
};
I na koniec ciekawostka - jeśli nie podoba ci się Sizzle w prototype.js - można bez problemu wymienić mechanizm selektorów na inny.
> I na koniec ciekawostka - jeśli nie podoba ci się Sizzle w prototype.js - można bez problemu wymienić mechanizm selektorów na inny.
OdpowiedzCiekawsza opcja, to w ogóle wywalenie tego silnika. Korzystanie w JS z zaawansowanych selektorów, to mocny bezsens, podstawowe da się wesprzeć w 50 liniach JS, a jakoś nie powstała wciąż żadna lekka biblioteka (D|B)OM-owa. Ciągle tylko (poza Zepto) te toporne, wszystko robiące potwory. Jeden większy od drugiego. A ja przez ponad 4 lata skorzystałem może z 50% API Prototype'a. W jQuery wyszłoby pewnie jeszcze mniej. I jeszcze to bezsensowne wsparcie dla archaicznych przeglądarek. Oczywiście czasami jest potrzeba ich wspierania. Ale coraz więcej projektów nie ma takiej potrzeby, a ciągle widzę "IE6+" i mnie skręca.
BTW. przeraźliwie małego fonta tu użyłeś. Tak ze 2px do góry by się przydały, bo musiałem dwa razy dać ctrl++
OdpowiedzArial 12px mały? ;) (wcześniej była 11)
Odpowiedz@Piotrek
OdpowiedzNa dobrą sprawę to można całkowicie olać jakąkolwiek bibliotekę, jeśli nie potrzebujemy wspierać starszych przeglądarek i chcemy korzystać wyłącznie z selektorów zaproponowanych przez W3C (http://www.w3.org/TR/selectors-api/) - wystarczy querySelectorAll, o czym pewnie wiesz. Choć nawet i tutaj można wykrywać querySelectorAll i w razie potrzeby dynamicznie ładować Sizzle, więc nie dziwię się, że jeszcze nie powstała dodatkowa biblioteka :P
Michał, już to chyba pisałem - ładnie to rozwiązali w Prototype. Niemniej jQuery, mimo brzydkiego API w tym przypadku, nadrabia w innych miejscach :-) Poza tym kwestia przyzwyczajenia - jeden woli jQuery, inny Prototype. Nie widzę jakichś szczególnie powodów, dla których miałbym przerzucać się na Prototype - co oferuje Prototype, czego nie ma jQuery? :)
Odpowiem niegrzecznie - co ma jQuery czego nie ma prototype.
OdpowiedzBo czego nie ma jQuery, można zobaczyć choćby w dokumentacji.
Musiałbym znać obie biblioteki w doskonałym stopniu, a niestety na prototype nigdy nie starcza mi czasu - mówiąc więc najogólniej, nie mam co się wypowiadać w temacie :) Mi jednak jQuery wystarcza w zupełności.
Odpowiedz