0
我想動態渲染一些SVG與knockoutJS。換句話說,ajax響應會返回有效的SVG,並且我希望svgweb動態顯示它。使用SVGWeb與KnockoutJS - 動態添加SVG
注意 - 這個問題被寫與回答回答自己的問題功能,這樣我就可以有希望救下的人一個小時左右的搜索。
我想動態渲染一些SVG與knockoutJS。換句話說,ajax響應會返回有效的SVG,並且我希望svgweb動態顯示它。使用SVGWeb與KnockoutJS - 動態添加SVG
注意 - 這個問題被寫與回答回答自己的問題功能,這樣我就可以有希望救下的人一個小時左右的搜索。
如this answer描述,您需要使用appendChild方法svgweb自曝。請注意,它接受實際的節點,而不僅僅是文本。
爲了使事情變得簡單,您可以去掉任何從您的ajax響應中傳出的<xml>
或<doctype>
節點。然後,包裝用jQuery剝離文本之後,結果的第0節點應該是可以傳遞給appendChild
下面的淘汰賽擴展包裝了這個功能有效的SVG節點。
ko.bindingHandlers.renderSvg = {
init: renderSvg,
update: renderSvg
};
function renderSvg(element, valueAccessor, allBindingsAccessor, viewModel) {
var rawVal = valueAccessor();
var svgText = ko.utils.unwrapObservable(rawVal);
if (!svgText) {
element.innerHTML = '';
} else {
//clear out previous content
element.innerHTML = '';
//strip out any `<xml>` or <!doctype> tags that come over
if (svgText.indexOf('<svg') > 0){
svgText = svgText.substr(svgText.indexOf('<svg'));
}
window.svgweb.appendChild($(svgText)[0], element);
}
};
當然,被稱爲有:
<div data-bind="renderSvg: mySvgField"></div>
編輯
原來包裝是SVG字符串使用jQuery,並試圖追加的結果會引起問題。我發現的修補程序是用jQuery包裝父級$ svg,然後使用jQuery遍歷所有子級。天真的1級搜索對我來說已經足夠了。顯然更復雜的用例需要遞歸搜索。更新後的代碼如下。
function renderSvg(element, valueAccessor, allBindingsAccessor, viewModel) {
var rawVal = valueAccessor();
var svgText = ko.utils.unwrapObservable(rawVal);
if (!svgText) {
element.innerHTML = '';
} else {
element.innerHTML = '';
if (svgText.indexOf('<svg') > 0){
svgText = svgText.substr(svgText.indexOf('<svg'));
}
if (!$.browser.msie || $.browser.version > 8){
//normal browsers
window.svgweb.appendChild($(svgText)[0], element);
} else {
//IE 8
var $svg = $(svgText);
var svg = document.createElementNS(svgns, 'svg');
svg.setAttribute('width', $svg.attr('width'));
svg.setAttribute('height', $svg.attr('height'));
$.each($svg.children(), function(i, el){
var path = document.createElementNS(svgns, el.tagName);
for (var i = 0, allAttributes = el.attributes, len = allAttributes.length; i < len; i++){
path.setAttribute(allAttributes.item(i).nodeName, allAttributes.item(i).nodeValue);
}
svg.appendChild(path);
});
window.svgweb.appendChild(svg, element);
}
}
}