ライブラリを使用せずにquerySelectorAllを使用できない場合に要素を属性で取得しますか?


123
<p data-foo="bar">

どのようにして同等のことを行うことができます

document.querySelectorAll('[data-foo]')

どこquerySelectorAllがあり利用できませんか

少なくともIE7で動作するネイティブソリューションが必要です。IE6は気にしません。


sizzle.js JavaScriptセレクターライブラリをチェックしてください
エポック

1
私がする必要がある唯一の選択はデータ属性ですから、Sizzleのようなセレクターエンジン全体を使わずに、パッチを適用する最も簡単な方法を見つけようとしました。しかし、出典を調べるのは良い点です。BTWのもう1つの優れたセレクターエンジンはgithub.com/ded/qweryです
ryanve

@ryanve、ありがとう私は見ていきましょう:)
エポック

私が使用した実用的なソリューションは、github.com / ryanve / dope / blob / master / dope.jsの「queryAttr」というメソッドにあります
ryanve

7
笑、あなたの質問は私の答えです。したがって、これには別の質問が伴います。どのような状況でquerySelectorAll利用できないのですか? note - I don't care all IE
vzhen 2013

回答:


136

getElementsByTagName( '*')を実行し、「data-foo」属性を持つ要素のみを返す関数を記述できます。

function getAllElementsWithAttribute(attribute)
{
  var matchingElements = [];
  var allElements = document.getElementsByTagName('*');
  for (var i = 0, n = allElements.length; i < n; i++)
  {
    if (allElements[i].getAttribute(attribute) !== null)
    {
      // Element exists with attribute. Add to array.
      matchingElements.push(allElements[i]);
    }
  }
  return matchingElements;
}

そして、

getAllElementsWithAttribute('data-foo');

8
使用すると!= nullのgetAttribute、その値は返すようにするために、古いIEでそれが可能であるため、(上記の私のコメントよりも良い)の理想的な方法ですtypeofです'number'
ryanve

1
document.getElementsByTagName('*')代わりになぜ使用するのdocument.allですか?
ペドロザット2016年

1
値ではなく存在だけを確認したいので、hasAttributeではなくを使用しないでgetAttribute() !== nullください。
rvighne 2016

61

使用する

//find first element with "someAttr" attribute
document.querySelector('[someAttr]')

または

//find all elements with "someAttr" attribute
document.querySelectorAll('[someAttr]') 

属性によって要素を検索します。現在、すべての関連ブラウザー(IE8を含む)でサポートされています。http//caniuse.com/#search=queryselector


2
質問が「IE7少なくとも機能するネイティブソリューションが必要である」と明示的に要求した場合、これにはどのように多くの賛成票がありますか。多分これが交換されなければならないに-それは実際にIE8から開始していても第二に、そのリンクは、IE11でそのサポートが開始さを述べdeveloper.mozilla.org/en-US/docs/Web/API/Element/...それは実際に答えをサポートしていますので。 ..?
Zze

7
すべての賛成投票の理由と、私が回答した理由は、このSOの質問が本当に古いためです。DOM 要素を見つける方法を検索すると、この質問は検索結果の非常に高い場所にあります。彼らは賛成票を探しています。有用性>歴史的正確さ。2つ目は、リンクが正常に機能すること、caniuse.comが古いブラウザを非表示にしていることだけです。「相対使用」に切り替えると、古いブラウザが表示されます。
Pylinux

完璧に働きました。すばやく簡単
Dawson B

それは2020年です。これは今受け入れられた答えになるはずです。
NearHuscarl

44

私は少し遊んで、この大まかな解決策に終わりました:

function getElementsByAttribute(attribute, context) {
  var nodeList = (context || document).getElementsByTagName('*');
  var nodeArray = [];
  var iterator = 0;
  var node = null;

  while (node = nodeList[iterator++]) {
    if (node.hasAttribute(attribute)) nodeArray.push(node);
  }

  return nodeArray;
}

使い方は非常に簡単で、IE8でも機能します。

getElementsByAttribute('data-foo');
// or with parentNode
getElementsByAttribute('data-foo', document);

http://fiddle.jshell.net/9xaxf6jr/

しかし、私は/ を使用することをお勧めします(そして古いブラウザをサポートするにはポリフィルを使用します):querySelectorAll

document.querySelectorAll('[data-foo]');

はい、querySelectorAllの+1。簡単なjsperfテストjsperf.com/custom-vs-selectorall-attributesは、受け入れられた回答よりもはるかに高速であることを示しています...残念ながら、IE 7互換ではありません:(
Sebastien Daniel

11

これを試してみてください

document.querySelector( '[attribute = "value"]')

例:

document.querySelector('[role="button"]')

5

それも機能します:

document.querySelector([attribute="value"]);

そう:

document.querySelector([data-foo="bar"]);

2
これには、実際のquerySelectorの単一引用符がありません。する必要があります: document.querySelector('[data-foo="bar"]');
Brettins

1

これを試してください-上記の答えを少し変更しました:

var getAttributes = function(attribute) {
    var allElements = document.getElementsByTagName('*'),
        allElementsLen = allElements.length,
        curElement,
        i,
        results = [];

    for(i = 0; i < allElementsLen; i += 1) {
        curElement = allElements[i];

        if(curElement.getAttribute(attribute)) {
            results.push(curElement);
        }
    }

    return results;
};

そして、

getAttributes('data-foo');

3
何を変えたのか、そしてその理由は?
Artjom B.

1

@kevinfahyの回答を少し変更し、必要に応じて値で属性を取得できるようにします。

function getElementsByAttributeValue(attribute, value){
  var matchingElements = [];
  var allElements = document.getElementsByTagName('*');
  for (var i = 0, n = allElements.length; i < n; i++) {
    if (allElements[i].getAttribute(attribute) !== null) {
      if (!value || allElements[i].getAttribute(attribute) == value)
        matchingElements.push(allElements[i]);
    }
  }
  return matchingElements;
}

0

ブラウザで使用しない

ブラウザで、を使用しますdocument.querySelect('[attribute-name]')

ただし、ユニットテストを行っており、モックドDOMに不安定なquerySelector実装がある場合は、これでうまくいきます。

これは@kevinfahyの答えです。ES6のファットアロー関数を使用して、HtmlCollectionを配列に変換することにより、おそらく読みやすさを犠牲にしてビットを少し削減しています。

したがって、これはES6トランスパイラーでのみ機能します。また、多くの要素でどれだけのパフォーマンスが得られるかはわかりません。

function getElementsWithAttribute(attribute) {
  return [].slice.call(document.getElementsByTagName('*'))
    .filter(elem => elem.getAttribute(attribute) !== null);
}

そして、特定の値を持つ属性を取得するバリアントがあります

function getElementsWithAttributeValue(attribute, value) {
  return [].slice.call(document.getElementsByTagName('*'))
    .filter(elem => elem.getAttribute(attribute) === value);
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.