繁体   English   中英

jQuery插件多个实例

[英]jquery plugin multiple instances

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

 (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)); 
 <!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> 

我可以通过删除以前的上下事件click事件处理程序,然后重新应用新的click事件处理程序来解决该问题。 这是通过改变来实现的

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

$(this.up).off('click').on('click', $.proxy(this.changeValue, this, '+', element));

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

感谢所有的建议!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM