javascript - 如何让 Knockout.js 为属性设置 namespaceURI?

标签 javascript knockout.js svg

在 svg 中,如果我使用 knockout 为 a 节点设置 xlink:href 属性,属性的命名空间设置不正确,因此 a 在点击时不作为链接。

例如,考虑以下包含两个链接椭圆的 svg。一个是硬编码的 xlink:href 属性,另一个是通过 data-bind 属性通过 knockout 设置的:

<svg width="5cm" height="6cm" viewBox="0 0 5 6" version="1.1" 
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 
  <rect x=".01" y=".01" width="4.98" height="5.98"  
        fill="none" stroke="blue"  stroke-width=".03"/> 
  <a xlink:href="#hardcoded"> 
    <ellipse data-bind="attr: blue" /> 
  </a> 
  <a data-bind="attr: { 'xlink:href': href }"> 
    <ellipse data-bind="attr: red" /> 
  </a> 
</svg>

让 knockout 跑起来很容易:

ko.applyBindings( { 
  blue: { cx:2.5, cy:1.5, rx:2, ry:1, fill:"blue" },
  href: '#foo', 
  red: { cx:2.5, cy:4.5, rx:2, ry:1, fill:"red" },
});

但只有硬编码的链接有效。如果我添加一些代码来查看属性节点的 namespaceURI 值,我可以看到 knockout 设置的 xlink:href 属性有一个 null namespaceURI,而不是硬编码的,后者设置为 http://www.w3.org/1999/xlink.

Array.forEach( document.getElementsByTagName('a'), function(a){
  a.setAttribute('title', 'xlink:href namespaceURI = ' + a.getAttributeNode('xlink:href').namespaceURI);
});

您可以 view all this in a fiddle .

是否有一种简单的方法来告诉 knockout 属性的正确命名空间应该是什么,或者我是否需要编写自定义绑定(bind)?

最佳答案

我的备用解决方案是添加此自定义绑定(bind):

ko.bindingHandlers['attr-ns'] = {
  update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    ko.utils.objectForEach( ko.unwrap( valueAccessor() ), function(name, value){
      var prefixLen = name.indexOf(':');
      var prefix    = name.substr( 0, prefixLen );
      var namespace = prefixLen < 0 ? null : element.lookupNamespaceURI( prefix );

      element.setAttributeNS( namespace, name, ko.unwrap( value ) );
    });
  }
};

并更改模板以使用我定义的 attr-ns 绑定(bind):

<a data-bind="attr-ns: { 'xlink:href': href }">
  <ellipse data-bind="attr: red" />
</a>

这似乎工作正常,但如果没有必要,我宁愿不这样做。更多自定义代码 = 更多可能出错的代码。

您可以 view this solution in a fiddle .

关于javascript - 如何让 Knockout.js 为属性设置 namespaceURI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18083723/

相关文章:

html - 将 img.src 设置为动态 svg 元素

javascript - 是否可以根据复选框的状态为复选框的子项设置样式,而无需在样式化组件中使用三元?

javascript - 如何在 Node.js 中管理内存

javascript - 在范围 CSS 模式下设置 ExtJS 4.2 的正确方法是什么?

javascript - 智能数学正则表达式

jquery - Knockout 和 jQuery 在 IE 8 中冲突?

javascript - Google 图表 - 在 x 和 y 标签上拉伸(stretch)图表

javascript - 如何在svg中动态显示文本

javascript - 修复 "Load unsafe scripts"

html - 使用 knockout js 实现 html5 拖放照片,durandal 2.0