0

Hi I'm trying to remove all jQuery from my platform one line at a time.

But I'm having some trouble finding a replacement for this

$('[data-attribute="value"]', GenericHTMLElement);

I was hoping it would be something simple like

var div = document.createElement('div');
div.innerHTML = '<div><span data-attribute="value"></span><span data-something-else="1000"></span></div>';
var b = div.childNodes;

var a = b.querySelector('[data-attribute="value"]');

But that's not working either. Does have any suggestions for me?

11
  • Try with document.querySelectorAll('[data-attribute="value"]'); Commented Dec 5, 2017 at 10:47
  • Can you please explain what do you mean by But that's not working either? Commented Dec 5, 2017 at 10:49
  • HTMLElement doesn't have a method called querySelector, use document instead. Also, to select multiple elements, use querySelectorAll. Commented Dec 5, 2017 at 10:49
  • @evolutionxbox developer.mozilla.org/en-US/docs/Web/API/Element/querySelector Commented Dec 5, 2017 at 10:51
  • @evolutionxbox OP is not using HTMLElement, I guess. He is fetching some element and using it. My guess is, HTMLElement is more of geberic name than type Commented Dec 5, 2017 at 10:51

3 Answers 3

1

As commented,

childNodes will give you a list of elements. This list will not have querySelector. If you loop over nodes, you should be able to get it though. But, my suggestion is just do div.querySelector(...)

To be specific, it will be of type NodeList. This is a collection of nodes. So you cannot run querySelector on it. You can either loop over all nodes and do querySelector on them or just so this operation on parent div.

var div = document.createElement('div');
div.innerHTML = '<div><span data-attribute="value">Dummy Text</span><span data-something-else="1000"></span></div>';
var b = div.childNodes;

console.log('Type of childNodes is: ', Object.prototype.toString.call(b))

// getting element using loop over childNodes
for(var i = 0; i<b.length; i++) {
  var el = b[i].querySelector('[data-attribute="value"]');
  el && console.log(el.textContent)
}

// getting element using parent elenent.
var el1 = div.querySelector('[data-attribute="value"]');
console.log(el1.textContent)

Sign up to request clarification or add additional context in comments.

Comments

0

First you need to understand what the first code does. It searches for given selector, limiting it to HTMLElementObject scope. Understanding that we can try to do something similar.

From MSDN example, he is using body element:

var el = document.body.querySelector("style[type='text/css'], style:not([type])");

They have this example with data-attributes, take a look please.

Comments

0

The reason your attempt isn't working is that you're trying to call querySelector on a NodeList, which doesn't have a querySelector method.

If you try it on a single element, it works fine:

function mySelect(selector, el) {
    return el.querySelector(selector);
}

var div = document.createElement('div');
div.innerHTML = '<div><span data-attribute="value"></span><span data-something-else="1000"></span></div>';
var b = div.childNodes[0];

console.log(mySelect('[data-attribute="value"]', b));

But this makes it so that mySelect(selector, el) is nothing more than an alias for el.querySelector(selector).

Presumably, you'd want to be able to evaluate a selector on multiple elements at once, and return multiple results, like jQuery does. In that case, you can do so by making some adjustments:

function flatMap(values, f) {
    return Array.prototype.concat.apply([], values.map(f));
}

function mySelect(selector, els) {
    return flatMap(els.length ? Array.from(els) : [els], function (el) {
        return Array.from(el.querySelectorAll(selector));
    });
}

var div = document.createElement('div');
div.innerHTML = '<div><span data-attribute="value">span 1</span><span data-something-else="1000"></span></div><div><span data-attribute="value">span 2</span></div>';

console.log(mySelect('[data-attribute="value"]', div.childNodes));

console.log(mySelect('[data-attribute="value"]', div.childNodes[0]));

1 Comment

I would not suggest using $ as function name. This can cause conflicts with other libraries.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.