Equivalent to the .filter () method of jQuery or Zepto in pure javascript

5

What is the best way to do the filter method like jQuery or Zepto in pure javascript?

I want to implement this method in my library: link

HTML

<p>Lorem Ipsum</p>
<p class="middle">Lorem Ipsum</p>
<p class="middle">Lorem Ipsum</p>
<p>Lorem Ipsum</p>

JS

$('p').filter('.middle'); // Retorna somente o "p" que tiver a classe "middle"
    
asked by anonymous 12.02.2014 / 14:25

3 answers

2

For your example, you would not even need filter . You can solve it with a single selector:

var elementos = document.querySelectorAll('p.middle');

A simple way to implement filter is to take two sets of elements, and compare all of them together. Certainly there are more efficient ways to implement the function, but this is well didactic:

function filter(selElementos, selFiltro) {
    var els = document.querySelectorAll(selElementos);
    var filtro = document.querySelectorAll(selFiltro);
    var saida = [];
    for(var i=0; i<els.length; i++) {
        for(var j=0; j<filtro.length; j++) {
            if(els[i] == filtro[j]) {
                saida.push(els[i]);
            }
        }
    }
    return saida;
}

Demo no jsfiddle

    
12.02.2014 / 17:47
3

Explanation:

Using pure Javascript you would have to loop through all elements that have the <p> tag using the document.getElementsByTagName() function in your Document, and then store them in an Array for easy iteration between them and then use a repeat loop to check that each of them has the class middle or not, and stores them in another array only those that have, and then you have the Array that you can see in the console with only the elements that have Middle class, as a HTMLCollection which is nothing more than an Array of HTML Elements.

Solution:

Javascript code:

function filter(tagName,classe){
    var aryP = document.getElementsByTagName(tagName);
    var len  = aryP.length;
    var aryPMiddle = [];
    for (var i=0;i < len; i++){
        if (aryP[i].getAttribute('class') == classe){
          aryPMiddle.push(aryP[i]);
        }
    }
    console.log(aryPMiddle);
    return aryPMiddle;
}

Then just run the function:

filter('p','middle');

And you will get the return of:

[p.middle, p.middle]

Functional sample in JSFiddle

- EDIT -

But you want a similar use with .filter() of jQuery in more ways, in addition to getting all the elements with the supplied tag, then I suggest to use this function that you can send a selector any for it in the same way that you use no jQuery:

function filter(selector){
    var aryPMiddle = document.querySelectorAll(selector);
    console.log(aryPMiddle);
    return aryPMiddle;
}

Example usage:

With the following HTML:

<p id="middle">Lorem Ipsum</p>
<p class="middle">Lorem Ipsum</p>
<p class="middle">Lorem Ipsum</p>
<p>Lorem Ipsum</p>

Running:

filter('.middle');

Return:

  

NodeList [p.middle, p.middle]

And running:

filter('#middle');

Return:

  

NodeList [p # middle]

Note: unfortunately in JSFiddle did not work and the reason is still unknown, however if you run in the console of your browser works correctly.

    
12.02.2014 / 14:31
0
var cls = 'middle';
var tag = 'P';

var lista = document.getElementsByTagName(tag);
for (var i = 0; i < lista.length; i++)
{
    if ((' ' + lista[i].className + ' ').indexOf(' ' + cls + ' ') > -1)
    {
        // tratar o elemento com a classe
    }
}
    
12.02.2014 / 14:35