Javascript 如何将Jonatas Walker的计时器转换为JS类或jQuery插件

Javascript 如何将Jonatas Walker的计时器转换为JS类或jQuery插件,javascript,object,timepicker,Javascript,Object,Timepicker,我是来自的时间选择器的粉丝,但无法让它在动态创建输入元素的项目中工作。问题似乎是这个时间选择器需要存储构造函数返回的对象。理想情况下,timepicker应该像jQueryUI中的datepicker一样工作。因此,我尝试变得聪明,在创建jQuery插件之前,我尝试创建如下javascript类: function MyTimePicker(inputelement) { // store the timepicker object this.mytime

我是来自的时间选择器的粉丝,但无法让它在动态创建输入元素的项目中工作。问题似乎是这个时间选择器需要存储构造函数返回的对象。理想情况下,timepicker应该像jQueryUI中的datepicker一样工作。因此,我尝试变得聪明,在创建jQuery插件之前,我尝试创建如下javascript类:

    function MyTimePicker(inputelement) {
        // store the timepicker object
        this.mytimepicker = new TimePicker(inputelement);
        // show picked time in the element
        this.mytimepicker.on('change', function (evt) {
            var value = (evt.hour || '00') + ':' + (evt.minute || '00');
            evt.element.value = value;
        });
    }
并在三个输入元素上使用它:

    var dummy1;
    var dummy2;
    var dummy3;
    window.onload = function () {
        dummy1 = new MyTimePicker(jQuery('#time2').get(0));
        dummy2 = new MyTimePicker(jQuery('#time3').get(0));
        dummy3 = new MyTimePicker(jQuery('#time4').get(0));
    };
它不起作用。单击每个输入元素时会出现时间选择器弹出窗口,但不会调用onchange事件,因此拾取的时间不会显示在输入元素中

要么是因为没有足够的Javascript对象经验,要么是因为没有使用这个时间选择器

更新:我用一个合适的原型改进了我的代码,以下是完整的代码,完全独立使用:

    <!DOCTYPE html>
    <html>
    <head>
        <title>Timepicker class, standalone, by Jonatas Walker</title>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script>
        <!--  source: https://github.com/jonataswalker/timepicker.js SO: https://stackoverflow.com/a/36758501/1845672 -->
        <link href="//cdn.jsdelivr.net/timepicker.js/latest/timepicker.min.css" rel="stylesheet">
        <script src="//cdn.jsdelivr.net/timepicker.js/latest/timepicker.min.js"></script>
    </head>
    <body>
        <div id="arrayoftimes">
            <input id="time2" type="time" placeholder="Time HH:MM"><br />
            <input id="time3" type="time" placeholder="Time HH:MM"><br />
            <input id="time4" type="time" placeholder="Time HH:MM"><br />
        </div>
        <script>
            // Javascript Class. this disturbs the above reference application of TimePicker. It probably is not re-entrant.
            //constructor
            function MyTimePicker(selector) {
                this.mytimepicker;
                this.init(selector);
            }
            //prototype
            MyTimePicker.prototype = {
                init: function (selector) {
                    var inputelement = jQuery(selector).get(0);
                    this.mytimepicker = new TimePicker(inputelement);
                    // show picked time in the element
                    this.mytimepicker.on('change', function (evt) {
                        var value = (evt.hour || '00') + ':' + (evt.minute || '00');
                        evt.element.value = value;
                    });
                }
            };
        </script>
        <script>
            var dummy1;
            var dummy2;
            var dummy3;
            window.onload = function () {
                dummy1 = new MyTimePicker('#time2');
                dummy2 = new MyTimePicker('#time3');
                dummy3 = new MyTimePicker('#time4');
            };
        </script>
    </body>
    </html>
现在第一个输入元素工作正常,但拾取的时间值进入所有三个输入元素。其他两个输入确实显示时间选择器对话框,但拾取的值不显示

在Firebug控制台中,在第一次拾取后,我在timepicker.js中看到两个错误:TypeError:active未定义

不知何故,这是否表明计时器内部代码不是可重入的

还是我在使用面向对象的javascript时出错了

更新:


我很确定timepicker.js中有一个bug。我一找到它就会在这里报告。

在gforce301帮助我阅读文档的情况下,我找到了这个解决方案,将时间选择器变成了jQuery插件。此代码具有测试代码,是独立的,并包含用于选择或取消选择计时器输入的复选框

该插件位于此代码的末尾

工作:您可以使用时间选择器添加更多输入。通过选择更多复选框来测试这一点

不工作:不能从输入中删除时间选择器。如果取消选中复选框,相关输入将不会列在传递给setTarget方法的新目标列表中,但时间选择器会继续处理取消选中的输入

<!DOCTYPE html>
<html>
    <head>
        <title>Test of Timepicker class, standalone, by Jonatas Walker</title>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script>
        <!--  source: https://github.com/jonataswalker/timepicker.js SO: https://stackoverflow.com/a/36758501/1845672 -->
        <link href="http://cdn.jsdelivr.net/timepicker.js/latest/timepicker.min.css" rel="stylesheet">
        <script src="http://cdn.jsdelivr.net/timepicker.js/latest/timepicker.min.js"></script>
        <style>
            .timepicker {background-color: yellow;}
        </style>
    </head>
    <body>
        <div id="arrayoftimes">
            Time 1
            <input type="checkbox" onclick="settimeclass(this, '#time1')" />
            <input id="time1" type="text" placeholder="Time HH:MM"/>
            <br />
            Time 2
            <input type="checkbox" onclick="settimeclass(this, '#time2')" />
            <input id="time2" type="text" placeholder="Time HH:MM"/>
            <br />
            Time 3
            <input type="checkbox" onclick="settimeclass(this, '#time3')" />
            <input id="time3" type="text" placeholder="Time HH:MM"/>
            <br />
            <br />
            ID's with timepicker: <span id='msg'></span>
        </div>
        <script> //this code is specific for this particular page
            // at page load, uncheck all checkboxes
            $('input:checkbox').prop('checked', false);
            $('input:text').val('');
            // when (un)checking a checkbox, adjust the timepicker class on each time input
            function settimeclass(self, id){
                if ($(self).prop('checked')){
                    $(id).addClass('timepicker');
                }else{
                    $(id).removeClass('timepicker');
                }
                // apply the new jquery plugin for the timepicker
                $('.timepicker').timepicker();
            }
        </script>
        <script> // this code could be moved to a library
            // jquery plugin for Jonatas's timepicker
            (function ( $ ) {
                // create time picker object
                var _timepickerobj = new TimePicker([]);//([...], {lang:'en', theme:'dark'});
                // attach event for formatting the time
                _timepickerobj.on('change', function(evt) {              
                  var value = (evt.hour || '00') + ':' + (evt.minute || '00');
                  evt.element.value = value;
                });
                // set timepicker target to jquery selector
                $.fn.timepicker = function() {
                    var sel_array = this.toArray();
                    //_timepickerobj.target = [];// no effect
                    _timepickerobj.setTarget(sel_array);
                    // debugging: list time input id's with timepicker
                    var sel_ids = $.map(sel_array ,function(sel) {return sel.id;});
                    $('#msg').text(sel_ids);
                    return this;
                }
            }( jQuery ));
        </script>
    </body>
</html>

这个插件对于我的项目来说已经足够好了,但是如果有人能够改进,例如从输入中删除一个时间选择器,那就太好了。

有了gforce301帮助我阅读文档,我找到了这个解决方案,把时间选择器变成了jQuery插件。此代码具有测试代码,是独立的,并包含用于选择或取消选择计时器输入的复选框

该插件位于此代码的末尾

工作:您可以使用时间选择器添加更多输入。通过选择更多复选框来测试这一点

不工作:不能从输入中删除时间选择器。如果取消选中复选框,相关输入将不会列在传递给setTarget方法的新目标列表中,但时间选择器会继续处理取消选中的输入

<!DOCTYPE html>
<html>
    <head>
        <title>Test of Timepicker class, standalone, by Jonatas Walker</title>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script>
        <!--  source: https://github.com/jonataswalker/timepicker.js SO: https://stackoverflow.com/a/36758501/1845672 -->
        <link href="http://cdn.jsdelivr.net/timepicker.js/latest/timepicker.min.css" rel="stylesheet">
        <script src="http://cdn.jsdelivr.net/timepicker.js/latest/timepicker.min.js"></script>
        <style>
            .timepicker {background-color: yellow;}
        </style>
    </head>
    <body>
        <div id="arrayoftimes">
            Time 1
            <input type="checkbox" onclick="settimeclass(this, '#time1')" />
            <input id="time1" type="text" placeholder="Time HH:MM"/>
            <br />
            Time 2
            <input type="checkbox" onclick="settimeclass(this, '#time2')" />
            <input id="time2" type="text" placeholder="Time HH:MM"/>
            <br />
            Time 3
            <input type="checkbox" onclick="settimeclass(this, '#time3')" />
            <input id="time3" type="text" placeholder="Time HH:MM"/>
            <br />
            <br />
            ID's with timepicker: <span id='msg'></span>
        </div>
        <script> //this code is specific for this particular page
            // at page load, uncheck all checkboxes
            $('input:checkbox').prop('checked', false);
            $('input:text').val('');
            // when (un)checking a checkbox, adjust the timepicker class on each time input
            function settimeclass(self, id){
                if ($(self).prop('checked')){
                    $(id).addClass('timepicker');
                }else{
                    $(id).removeClass('timepicker');
                }
                // apply the new jquery plugin for the timepicker
                $('.timepicker').timepicker();
            }
        </script>
        <script> // this code could be moved to a library
            // jquery plugin for Jonatas's timepicker
            (function ( $ ) {
                // create time picker object
                var _timepickerobj = new TimePicker([]);//([...], {lang:'en', theme:'dark'});
                // attach event for formatting the time
                _timepickerobj.on('change', function(evt) {              
                  var value = (evt.hour || '00') + ':' + (evt.minute || '00');
                  evt.element.value = value;
                });
                // set timepicker target to jquery selector
                $.fn.timepicker = function() {
                    var sel_array = this.toArray();
                    //_timepickerobj.target = [];// no effect
                    _timepickerobj.setTarget(sel_array);
                    // debugging: list time input id's with timepicker
                    var sel_ids = $.map(sel_array ,function(sel) {return sel.id;});
                    $('#msg').text(sel_ids);
                    return this;
                }
            }( jQuery ));
        </script>
    </body>
</html>

这个插件对于我的项目来说已经足够好了,但是如果有人能够改进,例如从输入中删除一个时间选择器,那就太好了。

改变这个:新建MyTimePickerjQuery'time2'。get0;为此:新建MyTimePickerjQuery'time2'[0];工作此外,您没有从MyTimePicker返回任何内容,因此此分配dummy1=newMyTimePickerjQuery'time2'.get0;其他的都将包含undefined@gforce301当时间选择器弹出窗口出现时,window.onload中的内容可以工作。但是阅读JS对象会告诉我,我可能需要将this.mytimepicker.on内容移动到原型中。然而,由于这并不是一个真正的方法,这让我感到困惑,它并不是一个bug;时间选择器应该只实例化一次。如果有多个字段,它希望您将要附加到的字段的所有ID作为数组同时传递。所以,这并不完全是一个bug,但它不喜欢被多次创建。@gforce301你说得对!它确实在文档中,我试过了。但是,使用新的id列表第二次调用构造函数,即使将返回值存储在同一个变量中,对我来说也不起作用。或者有一个析构函数,或者其他什么东西可以用时间选择器重新开始?你正在寻找。查看文档,似乎可以替换timepicker附加到的元素;为此:新建MyTimePickerjQuery'time2'[0];工作此外,您没有从MyTimePicker返回任何内容,因此此分配dummy1=newMyTimePickerjQuery'time2'.get0;其他的都将包含undefined@gforce301当时间选择器弹出窗口出现时,window.onload中的内容可以工作。但是阅读JS对象会告诉我,我可能需要将this.mytimepicker.on内容移动到原型中。然而,由于这并不是一个真正的方法,这让我感到困惑,它并不是一个bug;时间选择器应该只实例化一次。它希望您在传递数组i的同时传递要将其附加到的字段的所有ID
f有倍数。所以,这并不完全是一个bug,但它不喜欢被多次创建。@gforce301你说得对!它确实在文档中,我试过了。但是,使用新的id列表第二次调用构造函数,即使将返回值存储在同一个变量中,对我来说也不起作用。或者有一个析构函数,或者其他什么东西可以用时间选择器重新开始?你正在寻找。查看文档,您似乎可以替换时间选择器所连接的元素。