首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >jquery插件多实例

jquery插件多实例
EN

Stack Overflow用户
提问于 2015-06-18 06:57:24
回答 1查看 900关注 0票数 0

我正在尝试创建一个简单的jQuery插件,它允许多个“时间选择器”的实例。我过去没有做过太多的JavaScript OOP,所以我认为创建这对我来说是一次很好的学习经历。话虽如此,我似乎无法弄清楚为什么当我改变时间时,所有的实例都会受到影响。这是我在StackOverflow上的第一篇文章,所以请耐心等待。代码如下:

代码语言:javascript
复制
(function($) {

  //Helper functions 
  if (typeof String.prototype.endsWith != 'function') {
    String.prototype.endsWith = function(str) {
      return str.length > 0 && this.substring(this.length - str.length, this.length) === str;
    }
  }

  //Find if area is on the clickable list
  var findOne = function(haystack, arr) {
    return arr.some(function(v) {
      return haystack.indexOf(v) >= 0;
    });
  };

  var Timepicker = function(element, options) {

    this.defaults = {
      now: new Date()
    };
    this.element = $(element);
    this.createTimepicker();
    this.options = $.extend({}, this.defaults, options);
    this.timepicker = $('.wicked-picker'); //The outer portion of the picker
    this.up = $('.wicked-picker__controls__control-up'); //the up control(s)
    this.down = $('.wicked-picker__controls__control-down'); //the down control(s)
    this.hoursElem = $('.wicked-picker__controls__control--hours'); //the hours text
    this.minutesElem = $('.wicked-picker__controls__control--minutes'); //the minutes text
    this.meridiemElem = $('.wicked-picker__controls__control--meridiem'); //the am or pm text
    this.canClick = ['timepicker', this.timepicker.selector.substring(1), this.up.selector.substring(1), this.down.selector.substring(1), this.hoursElem.selector.substring(1), this.minutesElem.selector.substring(1), this.meridiemElem.selector.substring(1)]; //the clickable areas
    this.selectedHour = ((this.defaults.now.getHours() + 11) % 12) + 1; //the default hour
    this.selectedMin = ((this.defaults.now.getMinutes() < 10) ? '0' : '') + this.defaults.now.getMinutes(); //the default minute
    this.selectedMeridiem = (this.defaults.now.getHours > 12) ? 'PM' : 'AM'; //the defaut meridiem
    this.attach(element); //attach events to this element

  };

  $.extend(Timepicker.prototype = {

    showTimepicker: function(element) {
      var timepickerPos = this.element.offset();
      //set time to default time (now)
      this.setText(element);
      //if the timepicker's time differs from the input field's time change it
      if (this.getText(element) !== this.getTime()) {
        var inputTime = this.getText(element).replace(':', '').split(' ');
        var newTime = new Date();
        newTime.setHours(inputTime[0]);
        newTime.setMinutes(inputTime[2]);
        this.setTime(newTime);
      }
      //Positioning
      this.timepicker.css({
        'z-index': this.element.zIndex() + 1,
        position: 'absolute',
        left: timepickerPos.left,
        top: timepickerPos.top + element.target.offsetHeight + 5
      }).show();

      //Time up/down events
      //Most likely the area with issues
      //Needs to know which instance
      $(this.up).on('click', $.proxy(this.changeValue, this, '+', element));
      $(this.down).on('click', $.proxy(this.changeValue, this, '-', element));
    },

    hideTimepicker: function(element) {
      var targetClass = element.target.className.split(' ');
      //Check if area is clickable before hiding
      if (findOne(targetClass, this.canClick) === false) {
        this.timepicker.hide();
      }
    },

    //Create only one timepicker per page
    createTimepicker: function() {
      if ($('.wicked-picker').length === 0)
        $('body').append('<div class="wicked-picker"> <p class="wicked-picker__title">Timepicker</p> <ul class="wicked-picker__controls"> <li class="wicked-picker__controls__control"> <span class="wicked-picker__controls__control-up"></span><span class="wicked-picker__controls__control--hours">00</span><span class="wicked-picker__controls__control-down"></span> </li> <li class="wicked-picker__controls__control"> <span class="wicked-picker__controls__control-up"></span><span class="wicked-picker__controls__control--minutes">00</span><span class="wicked-picker__controls__control-down"></span> </li> <li class="wicked-picker__controls__control"> <span class="wicked-picker__controls__control-up"></span><span class="wicked-picker__controls__control--meridiem">AM</span><span class="wicked-picker__controls__control-down"></span> </li> </ul> </div>');
    },

    //Attach the show and hide picker events
    attach: function(element) {
      $(element).on('focus', $.proxy(this.showTimepicker, this));
      $('body').on('click', $.proxy(this.hideTimepicker, this));
    },

    //set the timepicker's time 
    setTime: function(time) {
      this.setHours(time.getHours());
      this.setMinutes(time.getMinutes());
      this.setMeridiem();
    },

    //get the timepicker's time in the form H : MM : AM || PM
    getTime: function() {
      return [this.getHours + ' : ' + this.getMinutes() + ' ' + this.getMeridiem()];
    },

    //set the timepicker's and input field's hours
    setHours: function(hours) {
      var hour = new Date();
      hour.setHours(hours);
      var hoursText = ((hour.getHours() + 11) % 12) + 1;
      this.hoursElem.text(hoursText);
      this.selectedHour = hoursText;
    },

    //set the timepicker's hours
    getHours: function() {
      var hours = new Date();
      hours.setHours(this.hoursElem.text());
      return hours.getHours();
    },

    //set the timepicker's and input field's minutes
    setMinutes: function(minutes) {
      var minute = new Date();
      minute.setMinutes(minutes);
      var minutesText = minute.getMinutes();
      var min = ((minutesText < 10) ? '0' : '') + minutesText;
      this.minutesElem.text(min);
      this.selectedMin = min;
    },

    //set the timepicker's minutes
    getMinutes: function() {
      var minutes = new Date();
      minutes.setMinutes(this.minutesElem.text());
      var minutesText = minutes.getMinutes();
      return ((minutesText < 10) ? '0' : '') + minutesText;
    },

    //set the timepicker's and input field's meridiem
    setMeridiem: function() {
      var meridiem = this.getMeridiem();
      var newMeridiem = (meridiem === 'PM') ? 'AM' : 'PM';
      this.meridiemElem.text(newMeridiem);
      this.selectedMeridiem = newMeridiem;
    },

    //set the timepicker's meridiem
    getMeridiem: function() {
      return this.meridiemElem.text();
    },

    //change the input field's time based on the arrow selected for each time unit
    //input is the input field to be changed
    //element is the up or down arrow clicked
    //operator is the '+' or '-' sign
    changeValue: function(operator, input, element) {
      var target = (operator === '+') ? element.target.nextSibling : element.target.previousSibling;
      var targetClass = $(target).attr('class');
      if (targetClass.endsWith('hours')) {
        this.setHours(eval(this.getHours() + operator + 1));
      } else if (targetClass.endsWith('minutes')) {
        this.setMinutes(eval(this.getMinutes() + operator + 1));
      } else {
        this.setMeridiem();
      }
      console.log('changed ' + $(input.target).attr('name'));
      this.setText(input);
    },


    //Set the input field's time
    setText: function(input) {
      console.log('set ' + $(input.target).attr('name') + ' to ' + this.selectedHour + ' : ' + this.selectedMin + ' ' + this.selectedMeridiem);
      $(input.target).val(this.selectedHour + ' : ' + this.selectedMin + ' ' + this.selectedMeridiem);
    },

    //Get the input field's time
    getText: function(input) {
      return $(input.target).val();
    }


  });

  //Create timepickers
  $.fn.timepicker = function(options) {
    return this.each(function() {
      new Timepicker(this, options);
    });
  };

}(jQuery));
代码语言:javascript
复制
<!DOCTYPE html>
<html>

<head lang="en">
  <meta charset="UTF-8">
  <title></title>
</head>

<body>
  <input type="text" name="event-start-time" id="event-start-time" class="form-input timepicker grid-5" />
  <input type="text" name="event-end-time" id="event-end-time" class="form-input timepicker grid-5" />
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
  <script>
    $('.timepicker').timepicker({});
  </script>
</body>

</html>

EN

回答 1

Stack Overflow用户

发布于 2015-06-19 01:45:05

通过删除以前的up和down事件单击事件处理程序,然后重新应用新的单击事件处理程序,我能够解决这个问题。这是通过更改

代码语言:javascript
复制
$(this.up).on('click', $.proxy(this.changeValue, this, '+', element));
$(this.down).on('click', $.proxy(this.changeValue, this, '-', element));

代码语言:javascript
复制
$(this.up).off('click').on('click', $.proxy(this.changeValue, this, '+', element));

$(this.down).off('click').on('click', $.proxy(this.changeValue, this, '-', element));

谢谢你所有的建议!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30903872

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档