0

私はSVGUI要素のライブラリに取り組んでおり、knockout.jsの使用を計画しています。これは、knockout.jsなしで必要なことを実行する非常に基本的なページです。これは、Chrome、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>

次に、knockout.jsテンプレートについて説明します。テンプレート化されたコントロールのインスタンスごとに、一意のIDが必要になるため、対応するグラデーションが適切に参照され、異なるパイプ要素がグラデーションを共有しません。この投稿の助けを借りて、私は次の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が生成され、rectスタイルのfill属性で使用されます。ただし、ブラウザは長方形を表示するときにこのグラデーションを使用しません。

ここで何が問題になっていますか?回避策はありますか?ありがとう!

4

1 に答える 1

0

svgノードのプロパティにネイティブKOバインディングを使用している場合は、「attr」バインディングを使用するのが最適であることがわかりました。そして確かにそれはあなたの問題を解決するようです:http://jsfiddle.net/antishok/UHnA8/1/

(svg要素の'class'プロパティは単純な文字列ではないため、'css'バインディングが適切に機能しないことはわかっています。'style'も機能しない理由はわかりませんが、少なくともattrは常に機能するようです。 )。

于 2012-09-28T05:19:07.357 に答える