48

与えられた:

<body>
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <a xlink:href="url"></a>
    </svg>
</body>

HTML DOM を使用したり、属性の内容によって SVG 内のリンクを選択し.querySelector()たりすることは可能ですか?.querySelectorAll()xlink:href

これは機能します:

document.querySelector('a')                    // <a xlink:href="url"/>

これらはしません:

document.querySelector('[href="url"]')         // null
document.querySelector('[xlink:href="url"]')   // Error: not a valid selector
document.querySelector('[xlink\:href="url"]')  // Error: not a valid selector
document.querySelector('[xlink\\:href="url"]') // null

その属性セレクターを記述して、それを「見る」ようにする方法はありxlink:hrefますか?

4

3 に答える 3

56

クエリ セレクターは名前空間を処理できますが、注意が必要です。

  1. CSS セレクターで名前空間を指定するための構文は、html とは異なります。

  2. xlinkquerySelector API には、名前空間プレフィックス ( など) を実際の名前空間 ( など)に割り当てるメソッドはありません"http://www.w3.org/1999/xlink"

最初の点として、CSS 仕様の関連部分では、名前空間を指定しない(デフォルト)、特定の名前空間を指定する、または任意の名前空間を指定することができます。

@namespace foo "http://www.example.com";
[foo|att=val] { color: blue }
[*|att] { color: yellow }
[|att] { color: green }
[att] { color: green }

最初のルールは、値が「val」attの「http://www.example.com 」名前空間の属性を持つ要素のみに一致します。

att2 番目のルールは、属性の名前空間に関係なく (名前空間なしを含む)、属性を持つ要素のみに一致します。

att最後の 2 つのルールは同等であり、属性が名前空間にない属性を持つ要素のみに一致します。

塗りつぶしスタイル (デフォルト、ホバー、およびアクティブ) に注意して、このフィドルを参照してください:
https://jsfiddle.net/eg43L/

@namespaceセレクター API は CSS セレクター構文を採用していますが、名前空間を定義するための規則に相当するものはありません。その結果、名前空間を持つセレクターは無効になります、ワイルドカード名前空間トークンは有効です

解決する必要がある名前空間プレフィックスがセレクターのグループに含まれている場合、実装は SYNTAX_ERR 例外を発生させる必要があります ([DOM-LEVEL-3-CORE]、セクション 1.4)。

この仕様は、任意の名前空間プレフィックスの解決をサポートしていません。ただし、名前空間プレフィックス解決メカニズムのサポートは、この仕様の将来のバージョンに含めることを検討する場合があります。

|div名前空間コンポーネントが空の名前空間を表す空 (例: )、または任意の名前空間を表すアスタリスク (例: ) でない場合、名前空間プレフィックスを解決する必要があり*|divます。アスタリスクまたは空の名前空間プレフィックスは解決する必要がないため、セレクターで名前空間構文をサポートする実装はこれらをサポートする必要があります。

(太字追加)

今度はコンソール出力に注意して、もう一度フィドルをチェックしてください。このコマンドdocument.querySelector('[*|href="#url"]')は、必要な要素を返します。

最後の警告: MDNによると、IE8 は CSS 名前空間をサポートしていないため、これは機能しない可能性があります。


2015 年 1 月 31 日更新:

@ Netsi1964 がコメントで指摘したように、HTML は XML 名前空間をサポートしていないため、これは HTML 5 ドキュメントのカスタム名前空間属性では機能しません。(スタンドアロンの SVG または XHTML を含むその他の XML ドキュメントで機能します。)

HTML5 パーサーが次のような属性に遭遇すると、data:myAttribute="value"それを属性名の単一の文字列として扱います:。さらに混乱させるために、文字列を自動的に小文字にします。

これらquerySelectorの属性を選択するにはdata:、属性文字列の一部として を含める必要があります。ただし、:は CSS セレクターで特別な意味を持つため、文字でエスケープする必要があります\。また、セレクターの一部として を渡す必要があるため、JavaScript で \エスケープする必要があります。

したがって、成功した呼び出しは次のようになります。

document.querySelector('[data\\:myattribute="value"]');

物事をもう少し論理的にするために、属性名にはすべて小文字を使用することをお勧めします。HTML 5 パーサーはとにかくそれらを変換するからです。Blink/Webkit ブラウザーは、渡すセレクターを自動的に小文字にしますがquerySelector、これは実際には非常に問題のあるバグです (つまり、大文字と小文字が混在するタグ名を持つ SVG 要素を選択することはできません)。

しかし、同じ解決策は次の場合にも機能しxlink:hrefますか? いいえ!HTML 5 パーサーxlink:hrefは SVG マークアップを認識し、名前空間属性として正しく解析します。

これは、追加のテストを含む更新されたフィドルです。ここでも、コンソール出力を見て結果を確認します。Chrome 40、Firefox 35、IE 11 でテスト済み。動作の唯一の違いは、Chrome が大文字と小文字が混在するセレクターに一致することです。

于 2014-04-13T20:13:05.027 に答える
12

[*|href]hrefは htmlと svgの両方に一致しxlink:href、 を使用:not([href])して html を除外しhrefます。

document.querySelectorAll('[*|href]:not([href])')

クロームでテスト済み

于 2016-10-10T07:57:35.130 に答える
7

残念ながら違います。

querySelectorは XML 名前空間を処理しないため、これを簡単に行う方法はありません。ただし、XPathクエリを使用することはできます。

var result = document.evaluate(
    // Search for all nodes with an href attribute in the xlink namespace.
    '//*[@xlink:href="url"]',
    document,
    function(prefix){
        return {
            xlink: "http://www.w3.org/1999/xlink"
        }[prefix] || null;
    },
    XPathResult.ORDERED_NODE_ITERATOR_TYPE
);

var element = result.iterateNext();

を持たない IE など、完全なクロスブラウザー サポートが必要な場合は、wicked-good-xpathdocument.evaluateでポリフィルできます。

もちろん、使用状況によっては、これを行う方が簡単な場合があります (これは IE で動作すると思います)。

var element = Array.prototype.filter.call(document.querySelectorAll('a'),
    function(el){
    return el.getAttributeNS('http://www.w3.org/1999/xlink', 'href') === 'url';
})[0] || null;
于 2014-04-12T18:30:27.570 に答える