使用带有 jquery ui 滑块的淘汰赛 js

Posted

技术标签:

【中文标题】使用带有 jquery ui 滑块的淘汰赛 js【英文标题】:Using knockout js with jquery ui sliders 【发布时间】:2012-10-03 02:16:19 【问题描述】:

我正在尝试确定淘汰赛 js 是否可以很好地解决以下问题:

我有多个要链接到文本框的滑块。

更改文本框时,相应的滑块必须更新为新值,反之亦然。

在更改滑块值或文本框时,需要调用一个函数,该函数使用来自所有文本框的输入来计算结果。

我有我快速而肮脏的 jQuery 解决方案here。

使用knockout js 以更优雅的方式实现相同的结果是否容易?

我想我需要创建一个自定义绑定处理程序,就像它在 jQuery UI datepicker change event not caught by KnockoutJS 中所做的那样

【问题讨论】:

你可以使用这个库:gvas.github.io/knockout-jqueryui/slider.html 【参考方案1】:

这里是一个例子:http://jsfiddle.net/jearles/Dt7Ka/

我使用自定义绑定来集成 jquery-ui 滑块,并使用 Knockout 捕获输入并计算净额。

--

用户界面

<h2>Slider Demo</h2>

Savings: <input data-bind="value: savings, valueUpdate: 'afterkeydown'" />
<div style="margin: 10px" data-bind="slider: savings, sliderOptions: min: 0, max: 100, range: 'min', step: 1"></div>

Spent: <input data-bind="value: spent, valueUpdate: 'afterkeydown'" />
<div style="margin: 10px" data-bind="slider: spent, sliderOptions: min: 0, max: 100, range: 'min', step: 1"></div>

Net: <span data-bind="text: net"></span>

查看模型

ko.bindingHandlers.slider = 
  init: function (element, valueAccessor, allBindingsAccessor) 
    var options = allBindingsAccessor().sliderOptions || ;
    $(element).slider(options);
    $(element).slider(
        "slide": function (event, ui) 
            var observable = valueAccessor();
            observable(ui.value);
        ,
        "change": function (event, ui) 
            var observable = valueAccessor();
            observable(ui.value);
        
    );
    ko.utils.domNodeDisposal.addDisposeCallback(element, function () 
        $(element).slider("destroy");
    );
  ,
  update: function (element, valueAccessor) 
    var value = ko.unwrap(valueAccessor());
    if (isNaN(value)) 
        value = 0;
    
    $(element).slider("value", value);
  
;

var ViewModel = function() 
    var self = this;

    self.savings = ko.observable(10);
    self.spent = ko.observable(5);
    self.net = ko.computed(function() 
        return self.savings() - self.spent();
    );


ko.applyBindings(new ViewModel());

【讨论】:

谢谢!比我的 jQuery sln 更优雅 我看到它还将文本框的输入限制在滑块的范围内......太棒了:) 有没有办法阻止用户输入除数字以外的任何内容?当放置一个字符时,它会输出 NaN 我已经更新了上面的代码和小提琴,以便在更新之前检查数字。如果为 NaN,则将值重置为 0。 谢谢...看起来很棒 - 我的页面有大约 6 个滑块,因此确实改进了它 我发现的另一个错误是,如果滑块的步骤不是 1 组,则您无法输入文本:请参阅 jsfiddle.net/Dt7Ka/11【参考方案2】:

我知道这是几天前的事,但我对 John Earles 代码做了一些调整:

ko.bindingHandlers.slider = 
init: function (element, valueAccessor, allBindingsAccessor) 
    var options = allBindingsAccessor().sliderOptions || ;
    $(element).slider(options);
    ko.utils.registerEventHandler(element, "slidechange", function (event, ui) 
        var observable = valueAccessor();
        observable(ui.value);
    );
    ko.utils.domNodeDisposal.addDisposeCallback(element, function () 
        $(element).slider("destroy");
    );
    ko.utils.registerEventHandler(element, "slide", function (event, ui) 
        var observable = valueAccessor();
        observable(ui.value);
    );
,
update: function (element, valueAccessor, allBindingsAccessor) 
    var value = ko.utils.unwrapObservable(valueAccessor());
    if (isNaN(value)) value = 0;
    $(element).slider("option", allBindingsAccessor().sliderOptions);
    $(element).slider("value", value);

;

这样做的原因是,如果您使用更改的选项(fx 另一个 observable),那么即使您希望它这样做,它也不会影响滑块。

【讨论】:

【参考方案3】:

@John Earles 和@Michael Kire Hansen:感谢您的出色解决方案!

我使用了 Michael Kire Hansen 的高级代码。我将滑块的“max:”选项绑定到 ko.observable,结果发现在这种情况下滑块没有正确更新值。示例:假设滑块处于最大值 25 的值 25 并且您将最大值更改为 100,滑块停留在最右边的位置,表示它处于最大值(但值仍然是 25,而不是 100)。只要向左滑动一点,值就会更新为 99。

解决方案: 在“更新:”部分只需将最后两行切换为:

$(element).slider("option", allBindingsAccessor().sliderOptions);
$(element).slider("value", value);

这首先更改选项,然后更改值,它就像一个魅力。

【讨论】:

【参考方案4】:

非常感谢您的帮助,我需要在我的场景中使用范围滑块,所以这里是 @John Earles 和 @Michael Kire Hansen 的扩展

ko.bindingHandlers.sliderRange = 
init: function (element, valueAccessor, allBindingsAccessor) 
    var options = allBindingsAccessor().sliderOptions || ;
    $(element).slider(options);
    ko.utils.registerEventHandler(element, "slidechange", function (event, ui) 
        var observable = valueAccessor();
        observable.Min(ui.values[0]);
        observable.Max(ui.values[1]);
    );
    ko.utils.domNodeDisposal.addDisposeCallback(element, function () 
        $(element).slider("destroy");
    );
    ko.utils.registerEventHandler(element, "slide", function (event, ui) 
        var observable = valueAccessor();
        observable.Min(ui.values[0]);
        observable.Max(ui.values[1]);
    );
,
update: function (element, valueAccessor, allBindingsAccessor) 
    var value = ko.utils.unwrapObservable(valueAccessor());
    if (isNaN(value.Min())) value.Min(0);
    if (isNaN(value.Max())) value.Max(0);

    $(element).slider("option", allBindingsAccessor().sliderOptions);
    $(element).slider("values", 0, value.Min());
    $(element).slider("values", 1, value.Max());

;

然后是伴随它的 HTML

<div id="slider-range" 
             data-bind="sliderRange:  Min: 0, Max: 100 , 
                                sliderOptions:  
                                    range: true,
                                    min: 0,
                                    max: 100,
                                    step: 10,
                                    values: [0, 100]
                                "></div>

【讨论】:

以上是关于使用带有 jquery ui 滑块的淘汰赛 js的主要内容,如果未能解决你的问题,请参考以下文章

如何限制 jQuery UI 滑块的范围?

如何使用 knockout.js 正确绑定和初始化 jQuery Mobile 范围滑块?

jQuery UI Slider - 最大值(不是滑块的结尾)

如何使范围滑块的左侧与滑块右侧的颜色不同?

JQuery UI 范围滑块值

使用 URL 查询字符串加载页面时 jQuery 设置 UI 滑块