Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

plain js to select element by attribute name starts with

Context :

  • HTML

     <div ng-me=""></div>
     <div ng-you=""></div>
      <p ng-you=""></p>
    

I want to select all elements which has attribute name starts with ng-.


Using jQuery , the following links are the closest threads to this issue :

  1. jQuery - How to select value by attribute name starts with .

  2. How to remove all Attributes by attribute name starts with .

However ,the first uses jQuery , and the second resolves removing issue of already selected elements NOT selection .

I try this :

document.querySelectorAll('[ng-*]')

And it does not work , but rather, it throws error.

like image 991
Abdennour TOUMI Avatar asked Sep 08 '16 08:09

Abdennour TOUMI


People also ask

How do I select an element by attribute name?

To select elements by an attribute name, pass a selector with the attribute's name to the querySelectorAll() method, e.g. document. querySelectorAll('[title]') . The querySelectorAll method will return a collection of the elements that have the provided attribute set.

How do I use a name attribute in querySelector?

Use the querySelector() method to get an element by a name attribute, e.g. document. querySelector('[name="first_name"]') . The method returns the first element in the DOM that matches the provided selector. If no element matches the selector, null is returned.

Which selects elements that have the specified attribute with a value beginning exactly with a given string?

attributeStartsWith selector Description: Selects elements that have the specified attribute with a value beginning exactly with a given string.


2 Answers

Here I use querySelectorAll to get all objects that I want to check.

Then I look at the attributes collection of each returned object

ES6+

const attrStartsWith = (sel,str) => [...document.querySelectorAll(sel)]
  .filter(ele => [...ele.attributes]
    .filter(({name}) => name.startsWith(str))
    .length>0
  )

console.log(attrStartsWith("*","ng")); // all
console.log(attrStartsWith("div","ng")); // divs
<div ng-a="a">a</div>
<div ng-b="b">b</div>
<p ng-c="c">c</p>

ES5 and lower

function attrStartsWith(sel,str) {
  var el = document.querySelectorAll(sel), res=[];
  
  for (var i = 0, n=el.length; i < n; i++){
    for (var j=0;j<el[i].attributes.length;j++) {
      if (el[i].attributes[j].name.indexOf(str)==0) {
        res.push(el[i]); 
      }
    }
  }
  return res;
}
console.log(attrStartsWith("*","ng")); // all
console.log(attrStartsWith("div","ng")); // divs
<div ng-a="a">a</div>
<div ng-b="b">b</div>
<p ng-c="c">c</p>
like image 138
mplungjan Avatar answered Oct 02 '22 04:10

mplungjan


ES6 solution :

const attrStartsWith = (prefix) =>
  Array.from(document.querySelectorAll('*'))
   .filter(
      (e) => Array.from(e.attributes).filter(
        ({name, value}) => name.startsWith(prefix)).length
   )

Then :

attrStartsWith('ng-') // return an array of HTML elements which  have attributes name starts with "ng-"

versions of 2017-12-02

const queryByAttrNameStartsWith = (contextualSelector = '*') => {
  const elements = Array.from(document.querySelectorAll(contextualSelector));
  return (prefix) =>
    elements.filter(e =>
      Array.from(e.attributes).find(({ name, value }) =>
        name.startsWith(prefix)
      )
    );
};
//then
queryByAttrNameStartsWith('*')('data-'); // all elements that have attribute name that starts with 'data-'
queryByAttrNameStartsWith('div')('ng-'); // ony DIV elements that have attribute name that starts with 'ng-'
//.. so on

or :

NodeList.prototype.filterByAttrNameStartsWith = function(prefix) {
  return Array.from(this).filter(e =>
    Array.from(e.attributes).find(({ name, value }) => name.startsWith(prefix))
  );
};
//then
document.querySelectorAll('*')
 .filterByAttrNameStartsWith('data-'); // all elements that have attribute name that starts with 'data-'
document.querySelectorAll('div')
 .filterByAttrNameStartsWith('ng-'); // ony DIV elements that have attribute name that starts with 'ng-'
//.. so on
like image 44
Abdennour TOUMI Avatar answered Oct 02 '22 04:10

Abdennour TOUMI