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

Jquery mobile 如何使用knockout.js正确绑定和初始化jQuery移动范围滑块?,jquery-mobile,knockout.js,custom-binding,rangeslider,Jquery Mobile,Knockout.js,Custom Binding,Rangeslider,我有一些麻烦,以获得一个JQM范围滑块工作以及淘汰赛。 这是JQM滑块的一个非常基本的html代码: <input type="range" name="quantity-slider" id="quantity-slider" min="0" max="10"> 我在互联网上阅读了其他人的一些帖子,这些帖子也发现了一些与范围滑块的JQM初始化相关的问题(例如这里:和这里:),并提供了一个有效的解决方案,每个都有自己的自定义绑定实现 其中一项建议如下: 到目前为止,一切顺利。之后,

我有一些麻烦,以获得一个JQM范围滑块工作以及淘汰赛。 这是JQM滑块的一个非常基本的html代码:

<input type="range" name="quantity-slider" id="quantity-slider" min="0" max="10">
我在互联网上阅读了其他人的一些帖子,这些帖子也发现了一些与范围滑块的JQM初始化相关的问题(例如这里:和这里:),并提供了一个有效的解决方案,每个都有自己的自定义绑定实现

其中一项建议如下:

到目前为止,一切顺利。之后,我遇到了这个问题:

如果JQM滑块位于第一页,则它可以工作。当JQM滑块位于第二页时,它不再工作

我认为这是一个与这个特殊的JQM小部件和他的DOM操作相关的问题,我可以理解。为了更好地解释这一点,我制作了两个JSFIDLE,其中我只交换了两个JQM页面的顺序:

  • 不工作:第二个JQM页面上的滑块
  • 工作:第一个JQM页面上的滑块
  • 有人能解释一下,哪种方法是初始化JQM滑块的敲除绑定的正确方法?也许有另一种方法可以为JQM滑块编写自定义绑定,或者在pagebeforeshow事件中放置淘汰绑定

    更新: 通过以下更改,滑块将显示正确的值,并与文本输入部分同步:

    $(document).on('pagebeforeshow', '#slider-page', function(){       
        $('#quantity-slider').val(viewModel.quantity());
        $('#quantity-slider').slider('refresh');
    });
    
    但我想知道是否有更好的解决办法


    至少,再加上Varun的定制绑定,它现在对我来说效果非常好

    我遇到了同样的问题。我就是这样解决的。尽管此解决方案在直接使用文本输入编辑值时不会更新可观察值。(我不显示输入文本框,因此此解决方案对我来说就足够了)


    在花了几个小时测试了在网络上发现的关于这个问题的所有变体之后,我最终得到了以下解决方案,也许这有助于其他人腾出时间:

    最终工作小提琴:

    问题是如何将knockout.js和jquerymobile slider与多页面导航集成在一起,我认为这将是最常见的情况之一

    对不起,我不能认为Varun的回答是完全的和令人满意的,但是我必须说,没有<强> Varun的自定义绑定处理< <强> >我就永远不会找到一个工作解决方案。 以下是自定义绑定处理程序slighlty modified:

    /* custom binding handler thanks to Varun http://stackoverflow.com/a/16493161/2308978 */
    ko.bindingHandlers.slider = {
        init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            var value = valueAccessor();
                $(document).on({
                    "mouseup touchend keypress": function (elem) {
                    var sliderVal = $('#' + element.id).val();
                    value(sliderVal);
                }
            }, ".ui-slider");
        }
     };
    
    …以下是页面初始化:

    $(document).on('pagebeforeshow', '#slider-page', function(){
        $('#quantity-slider').val(viewModel.quantity());
        $('#quantity-slider').slider('refresh');
    });
    

    按下enter或tab键后,滑块的文本部分也会同步,因为这是标准的滑块行为。

    在自定义处理程序中,绑定到“更改”事件比绑定到mouseup touchend和keypress更可靠。此外,pagebeforeshow事件也不是必需的。您只需在处理程序中的init期间设置value属性:

    ko.bindingHandlers.slider = {
        init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            var value = valueAccessor();
            $(element).attr("value", value());
                $(document).on({
                    "change": function (elem) {
                    var sliderVal = $('#' + element.id).val();
                    value(sliderVal);
                }
            }, ".ui-slider");
        }
     };
    

    参见示例:

    Hi Varun,非常感谢您分享您的经验和工作。但是当我尝试您的示例时,我总是看到相同的问题,当我转到第二页时,滑块未初始化为4。所以问题是为什么会发生这种情况?我在这里读了你关于这个问题的另一篇文章:对我来说,唯一有效的定制绑定是你的!嗨,Varun,我直接使用ui滑块选择器更改了代码,没有使用c滑块包装器,它也工作得很好。请您更新您的答案,并解释为什么您需要“ko if:is”?如果没有它,它对我也有用。如果你能更好地解释你在这个有争议的问题上的经验,那就太好了。如果条件是模拟稍后添加的控件。在您的情况下,因为您正在导航页面,所以jqm会动态添加控件。我想在没有多个页面的情况下也这样做:)
    /* custom binding handler thanks to Varun http://stackoverflow.com/a/16493161/2308978 */
    ko.bindingHandlers.slider = {
        init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            var value = valueAccessor();
                $(document).on({
                    "mouseup touchend keypress": function (elem) {
                    var sliderVal = $('#' + element.id).val();
                    value(sliderVal);
                }
            }, ".ui-slider");
        }
     };
    
    $(document).on('pagebeforeshow', '#slider-page', function(){
        $('#quantity-slider').val(viewModel.quantity());
        $('#quantity-slider').slider('refresh');
    });
    
    ko.bindingHandlers.slider = {
        init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            var value = valueAccessor();
            $(element).attr("value", value());
                $(document).on({
                    "change": function (elem) {
                    var sliderVal = $('#' + element.id).val();
                    value(sliderVal);
                }
            }, ".ui-slider");
        }
     };