0

Is there a way to convert: $("#first").find("input").not("td td input") (http://jsfiddle.net/4K9TG/) ...into a querySelectorAll selector?

(continuing from jQuery: find() children until a certain threshold element is encountered)

Community
  • 1
  • 1
Agamemnus
  • 1,395
  • 4
  • 17
  • 41

2 Answers2

1

not is simply a filter over a collection that satisfies a condition. See if this helps.

var query = function(selector, element) {
  element = element || document;
  return [].slice.call(element.querySelectorAll(selector));
};

var not = function(selector) {
  var exclude = query(selector);
  return function(element) {
    return exclude.indexOf(element) == -1;
  };
};

var inputs = query('#first input').filter(not('td td input'));

Here's a demo: http://jsbin.com/EJAyiSux/1/edit

You can implement most jQuery methods as simple filter and map sequences with higher-order functions, as shown above. After all, jQuery collections are just arrays of elements.

elclanrs
  • 92,861
  • 21
  • 134
  • 171
  • Thanks. It would be more efficient to iterate through the DOM manually, in theory, as otherwise you would be iterating through twice. I was just hoping that there was a way to use querySelectorAll to simply stop searching at a particular tag name (in this case it would be "td"). – Agamemnus Dec 16 '13 at 09:10
  • Well, you could create a function that checks for each element's parent and if it's a `td` twice then filter it out. Don't know what it's most efficient way, but it would definitely look uglier. – elclanrs Dec 16 '13 at 09:12
0

I ended up making a function to do this.

http://jsfiddle.net/4K9TG/2/:

var n = get_elements_until (document.getElementById('first'), 'input', 'td')
console.log (n)

function get_elements_until (parent, tagname_to_search_for, tagname_to_stop_at) {
 var element_list = []
 var stack_current = [parent]
 while (true) {
 var stack_new = []
  for (var s = 0, curlen_s = stack_current.length; s < curlen_s; s++) {
   var children = stack_current[s].childNodes
   for (var i = 0, curlen = children.length; i < curlen; i++) {
    var child = children[i], tagname = child.tagName
    if (typeof tagname == "undefined") continue
    tagname = tagname.toLowerCase ()
    if (tagname == tagname_to_search_for) element_list.push (child)
    if (tagname != tagname_to_stop_at) stack_new.push (child)
   }
  }
  stack_current = stack_new
  if (stack_new.length == 0) break
 }
 return element_list
}
Agamemnus
  • 1,395
  • 4
  • 17
  • 41