javascript
  • svg
  • knockout.js
  • 2012-09-28 14 views 0 likes 
    0

    我正在研究SVG UI元素库并计划使用knockout.js。这是一个非常基础的页面,可以在没有knockout.js的情况下完成我所需要的功能,它可以在Chrome,FF,Opera中正常工作。它绘制了一条管道:knockout.js中的唯一元素ID:Chrome OK,FF和Opera失败

    <html> 
    <body> 
        <div width="100px" height="100px"> 
         <svg width='100px' height='100px'> 
          <linearGradient id="gradId" y1='-20%' x1='0%' y2='100%' x2='0%' gradientUnits='objectBoundingBox'> 
          <stop offset='-20%' style="stop-color: #303030"/> 
          <stop offset='40%' style="stop-color: #D0D0D0"/> 
          <stop offset='100%' style="stop-color: #303030"/> 
          </linearGradient> 
          <rect id="myRect" x='0%' y='30%' width='100%' height='40%' /> 
         </svg> 
        </div> 
        <script type="text/javascript"> 
         document.getElementById("myRect").style.fill = "url(#gradId)"; 
         console.log(document.getElementById("myRect").style.fill); 
        </script> 
    </body> 
    </html> 
    

    现在来敲除.js模板。对于模板控件的每个实例,我将需要唯一的id,因此对应的渐变可以正确引用,并且不同的管道元素不共享渐变。从this post一些帮助,我制作了下面的HTML:

    <html> 
    <head> 
        <script type="text/javascript" src="js/knockout-2.1.0.debug.js "></script> 
        <script type="text/javascript"> 
         // knockout code inspired by https://stackoverflow.com/questions/9233176/unique-ids-in-knockout-js-templates 
         ko.bindingHandlers.uniqueId = { 
          init: function (element, valueAccessor) { 
           // Generate new element id 
           element.id = ko.bindingHandlers.uniqueId.prefix + valueAccessor() + ko.bindingHandlers.uniqueId.prefix + (++ko.bindingHandlers.uniqueId.counter); 
           console.log("Element id:" + element.id); 
          }, 
          prefix: "autoId_", 
          counter: 0 
         }; 
    
         ko.bindingHandlers.uniqueStyleFill = { 
          init: function (element, valueAccessor) { 
           // Use recently generated element id in the style.fill value 
           var value = ko.bindingHandlers.uniqueId.prefix + valueAccessor() + ko.bindingHandlers.uniqueId.prefix + ko.bindingHandlers.uniqueId.counter.toString(); 
           element.style.fill = "url(#" + value + ")"; 
           console.log("Binding:" + element.style.fill); 
          } 
         }; 
        </script> 
    </head> 
    <body> 
    <!-- Define ko template plumbing-horizontal-pipe that uses bodyColor and bodyColorLight attributes of the bound object --> 
        <script type="text/html" id="plumbing-horizontal-pipe"> 
         <svg width='100px' height='100px'> 
          <linearGradient data-bind="uniqueId: 'horPipeGrad_'" y1='-20%' x1='0%' y2='100%' x2='0%' gradientUnits='objectBoundingBox'> 
          <stop offset='-20%' data-bind="style: {'stop-color': bodyColor()}"/> 
          <stop offset='40%' data-bind="style: {'stop-color': bodyColorLight()}"/> 
          <stop offset='100%' data-bind="style: {'stop-color': bodyColor()}"/> 
          </linearGradient> 
          <rect x='0%' y='30%' width='100%' height='40%' data-bind="uniqueStyleFill: 'horPipeGrad_'"/> 
         </svg> 
        </script> 
        <div width="100px" height="100px"> 
        <!-- Load ko template defined above, bind 'pipe' --> 
         <svg width="100" height="110" data-bind="template: { name: 'plumbing-horizontal-pipe', data: pipe }" /> 
        </div> 
        <!-- ko view model with one item 'pipe' --> 
        <script type="text/javascript"> 
         function MyViewModel() { 
          this.pipe = { bodyColor: ko.observable("#FF0000"), bodyColorLight: ko.observable("#FFA0A0") }; 
         } 
         var g_vm = new MyViewModel(); 
         // This should make the browser display a red pipe. Works in Chrome, doesn't work in FF and Opera. 
         ko.applyBindings(g_vm); 
        </script> 
    </body> 
    </html> 
    

    它在Chrome中工作正常 - 显示红色的管道。 FF和Opera继续显示黑色矩形,这意味着SVG对象不会拾取渐变。我检查FF日志输出,它看起来完全正常:

    [21:30:08.606] Element id:autoId_horPipeGrad_autoId_1 
    [21:30:08.610] Binding:url("#autoId_horPipeGrad_autoId_1") none 
    

    人们可以看到,产生渐变的ID和为矩形样式填充属性使用。但是,在显示矩形时,浏览器不使用此渐变。

    这里有什么问题?任何解决方法? 谢谢!

    回答

    0

    我发现如果我使用原生KO绑定svg节点属性,最好使用'attr'绑定。 事实上它似乎解决您的问题:http://jsfiddle.net/antishok/UHnA8/1/

    (我知道,“CSS”结合不工作好,因为对SVG元素的“类”属性不是一个简单的字符串不知道为什么“风格'也不起作用,但至少attr似乎始终工作)

    +0

    感谢很多antishok,使用attr而不是风格似乎在FF和Opera工作。 –

    +0

    你可能想接受答案,然后..你不想要低的接受率,是吗? :P – antishok

    +0

    完成。只是熟悉当地的awesomne​​ss米,感谢您的提示。虽然没有足够的因果报应。 –

    相关问题