在 Knockout 样式绑定中使用 CSS3 变量

Posted

技术标签:

【中文标题】在 Knockout 样式绑定中使用 CSS3 变量【英文标题】:Using CSS3 Variables in Knockout Style Binding 【发布时间】:2018-12-24 10:06:47 【问题描述】:

我正在尝试使用淘汰赛的style binding 将CSS3 variables 添加到一些div 元素中,然后在我们的CSS 中使用这些元素来计算最终样式。

例子:

var viewModel = function ViewModel() 
  this.randomColor = ko.computed(function() 
    // Random color thanks to @paul_irish
    return "#" + Math.floor(Math.random() * 16777215).toString(16);
  );
();

ko.applyBindings(viewModel);
h2 
  /* default fall-back color: */
  --random-colour: #666;
  color: var(--random-colour);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<h2 data-bind="style: '--random-colour': randomColor">This should receive a random text color.</h2>

http://jsfiddle.net/tujhxdmc/5/

我希望它在样式标签中应用 css 变量,但它似乎只是被忽略了。周围的绑定和使用标准 CSS 属性的绑定都按预期工作,所以我确定这是 CSS 变量的问题。

Knockout's documentation 状态:

如果您想应用字体粗细或文本装饰样式,或名称不是合法 javascript 标识符的任何其他样式(例如,因为它包含连字符),您必须使用该样式的 JavaScript 名称.例如,

不要写 font-weight: someValue ;写 fontWeight: someValue

但这不适用于 CSS 变量(必须以双连字符开头)。

如何在 Knockout 的样式绑定中使用 CSS 变量?

【问题讨论】:

查看源代码,如果没有拉取请求,我认为这不会以任何漂亮的方式得到支持:defaultBindings/style.js。 这似乎是驼峰样式属性的行,但看起来-- 会被正则表达式吃掉。 ..我不太喜欢那个样子 我在 GitHub 上提出了一个问题来跟踪它。你可以在这里找到它:Cannot bind to custom CSS property variables #2400。也许更好的方法会来自那个问题。 【参考方案1】:

现在看来,如果不增强 Knockout,这将是不可能的。

考虑一下现在如何在源代码中操作样式绑定: knockout/src/binding/defaultBindings/style.js 。

尤其是这一行:

 element.style[styleName] = styleValue;

无论何时运行,styleName 将是 CSS 变量 "--random-colour"

但是,您不能通过element.style["--random-colour"] 设置样式。你必须通过style.setProperty()

同时考虑这个问题:Accessing a CSS custom property (aka CSS variable) through JavaScript


如果您现在需要此功能,可以加载淘汰库脚本,然后覆盖 ko.bindingHandlers['style'].update 函数以使用将使用 setProperty() 的版本:

ko.bindingHandlers['style'] = 
    'update': function (element, valueAccessor) 
        var value = ko.utils.unwrapObservable(valueAccessor() || );
        ko.utils.objectForEach(value, function(styleName, styleValue) 
            styleValue = ko.utils.unwrapObservable(styleValue);

            if (styleValue === null || styleValue === undefined || styleValue === false) 
                // Empty string removes the value, whereas null/undefined have no effect
                styleValue = "";
            

            if(styleName.substring(0, 2) === "--")
                element.style.setProperty(styleName, styleValue);
             else 
                element.style[styleName] = styleValue;
            
        );
    
;

我在 KnockOut GitHub 上添加了一个问题,以防其他更好的响应来自那里:Cannot bind to custom CSS property variables #2400。

【讨论】:

你不需要 fork Knockout 来添加绑定处理程序。 @MichaelBest 您能否添加如何作为答案?如果您可以覆盖默认行为,我同意分叉是多余的。 在包含 Knockout 库之后,在上面包含您的代码。然后,您将用您自己的替换 style 绑定处理程序。 @MichaelBest 你说得对,这是一个更好的临时解决方案。

以上是关于在 Knockout 样式绑定中使用 CSS3 变量的主要内容,如果未能解决你的问题,请参考以下文章

带有 Knockout 下拉列表问题的边界半径

在 Knockout.js 中异步应用绑定

用于在 url 中查找部分字符串的 Knockout.js 数据绑定

在 Knockout 中绑定多个 PartialView

knockout 多值绑定

使用 jQuery Mobile 进行 Knockout 模板绑定