Можно ли использовать HTML.querySelector () для выбора атрибута xlink в SVG?
дано:
<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 в .querySelector()
или .querySelectorAll()
чтобы выбрать ссылку внутри SVG по содержанию его
3 ответов
селектор запроса can обрабатывать пространства имен, но это становится сложнее, потому что
синтаксис для указания пространств имен в селекторах CSS отличается от html;
API querySelector не имеет никакого метода для назначения префикса пространства имен (например,
xlink
) на соответствующее пространство имен (например,"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 }
первое правило будет соответствовать только элементы с атрибутом
att
в "http://www.example.com "пространство имен со значением "val".второе правило будет соответствовать только элементы с атрибутом
att
независимо от пространства имен атрибута (включая пространство имен).последние два правила эквивалентны и будут соответствовать только элементам с атрибутом
att
где атрибут не в пространстве имен.
см. эту скрипку, обращая внимание на стили заливки (по умолчанию, наведение и активное):
https://jsfiddle.net/eg43L/
API селекторов принимает синтаксис селектора CSS, но не имеет эквивалента @namespace
правила для определения пространства имен. В результате селекторы с пространствами имен недопустимы но маркер пространства имен подстановочных знаков действителен:
если группа селекторов включает префиксы пространства имен, которые необходимо разрешить, реализация должна вызвать исключение SYNTAX_ERR ([DOM-LEVEL-3-CORE], раздел 1.4).
эта спецификация не поддерживает разрешение произвольных префиксов пространства имен. Однако можно рассмотреть возможность поддержки механизма разрешения префикса пространства имен для включения в будущую версию этой спецификации.
префикс пространства имен должен быть разрешен, если компонент пространства имен не пуст (например,
|div
), представляющий пространство имен null или звездочку (например,*|div
), представляющий любое пространство имен. поскольку звездочка или пустой префикс пространства имен не требуется разрешать, реализации, поддерживающие синтаксис пространства имен в селекторах, должны поддерживать их.
(жирный шрифт добавлено)
проверить скрипка опять же, на этот раз обращая внимание на выход консоли. Команда document.querySelector('[*|href="#url"]')
возвращает элемент, который вы хотите.
последнее предупреждение: MDN говорит мне, что IE8 - не поддерживает пространства имен CSS, поэтому это может не работать для них.
2015-01-31 обновления:
как @Netsi1964 указал в комментариях, это не работает для пользовательских атрибутов пространства имен в документах HTML 5, поскольку HTML не поддерживает пространства имен XML. (Он будет работать в автономном SVG или другом XML-документе, включая XHTML.)
когда анализатор 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 соответствует селектору смешанных регистров.
к сожалению, нет.
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, который не имеет document.evaluate
, вы можете polyfill его с злой-хороший-xpath.
конечно, в зависимости от вашего использования, это может быть проще сделать (что, я думаю, будет работать на 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;
[*|href]
будет соответствовать обоим html href
и svg xlink:href
, а затем использовать :not([href])
исключить html href
.
document.querySelectorAll('[*|href]:not([href])')
протестировано в chrome