Изменение атрибутов svg с помощью javascript не влияет
Я пытаюсь изменить тег svg с помощью javascript, чтобы сделать его изменяемым по размеру, но мои изменения не влияют. Причина, по которой мне нужно сделать это, заключается в том, что этот тег визуализируется библиотекой, которую я не могу изменить, и, похоже, мой единственный выбор - изменить svg с помощью javascript.
Я знаю, что тег, созданный этим script, корректен, так как я могу скопировать тег в новый html-документ и он будет работать (я включил его в примерный код), поэтому мне кажется, что мне нужно каким-то образом заставить svg признать, что он был изменен (или другим способом изменить svg).
Вот HTML-страница, которая показывает мою проблему:
<html>
<head>
<script src="http://code.jquery.com/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var svg = $('#testsvg').find('svg')[0];
var w = svg.getAttribute('width').replace('px', '');
var h = svg.getAttribute('height').replace('px', '');
svg.removeAttribute('width');
svg.removeAttribute('height');
svg.setAttribute('viewbox', '0 0 ' + w + ' ' + h);
svg.setAttribute('preserveaspectratio', 'xminymin meet')
$(svg)
.css('width', '100%')
.css('height', '100%')
.css('background-color', 'white');
});
</script>
</head>
<body style="background-color: #333;">
<div style="width: 80%; height: 40%;">
<svg id="resultsvg" xmlns="http://www.w3.org/2000/svg" version="1.1" style="width: 100%; height: 100%; background-color: white; " viewbox="0 0 100 100" preserveaspectratio="xminymin meet">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="2" fill="red"></circle>
</svg>
</div>
<div id="testsvg" style="width: 80%; height: 40%;">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100px" height="100px">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="2" fill="red" />
</svg>
</div>
</body>
</html>
Ответы
Ответ 1
SVG чувствителен к регистру, поэтому
svg.setAttribute('viewbox', '0 0 ' + w + ' ' + h);
svg.setAttribute('preserveaspectratio', 'xminymin meet')
следует записать
svg.setAttribute('viewbox', '0 0 ' + w + ' ' + h);
svg.setAttribute('preserveaspectratio', 'xminymin meet')
ширина и высота элемента <svg>
- это атрибуты, а не стили (в отличие от html), поэтому вы должны использовать setAttribute('width', '100%')
, а не .css('width', '100%')
Ответ 2
jQuery
преобразовать имя атрибута в нижний регистр; например, вместо установки атрибута viewBox
, он установит viewBox
. К сожалению, имена атрибутов элемента SVG (XML-диалект) чувствительны к регистру.
Если вы хотите последовательно использовать jQuery, вы можете использовать $.attrHooks
для обработки атрибутов, чувствительных к регистру:
['preserveAspectRatio', 'viewBox'].forEach(function(k) {
// jQuery converts the attribute name to lowercase before
// looking for the hook.
$.attrHooks[k.toLowerCase()] = {
set: function(el, value) {
if (value) {
el.setAttribute(k, value);
} else {
el.removeAttribute(k, value);
}
return true;
},
get: function(el) {
return el.getAttribute(k);
},
};
});
$(document).ready(function() {
var svg = $('#testsvg');
var w = svg.attr('width').replace('px', '');
var h = svg.attr('height').replace('px', '');
svg.attr({
width: '100%',
height: '100%',
viewBox: [0, 0, w, h].join(' '),
preserveAspectRatio: 'xMidYMid meet'
})
});
Обратите внимание, что el.attr('viewBox', null)
не удался; ваш установщик крюка не будет вызван. Вместо этого вы должны использовать el.removeAttr('viewBox')
или el.attr('viewBox', false)
.
Для другого атрибута, такого как stroke, я бы поместил их в таблицу стилей.
svg {
background-color: white;
}
circle {
fill: red;
stroke: black;
stroke-width: 1px;
}
Если вам нужно добавить/переключить класс, чтобы изменить стиль для определенных элементов, вам нужно использовать jQuery 1.12+ или jquery 2.2 +.