我正在努力将我的简单JavaScript Donut Chart转换为jQuery插件。
这是我的第一个jQuery插件,我可以在几个地方使用一些帮助...
到目前为止我演示的内容:http://jsfiddle.net/jasondavis/qsgqebox/
以下是我到目前为止的JavaScript。
jQuery
jQuery.fn.updatePercentageGraph = function (options) {
var settings = $.extend({
// These are the defaults.
percent: 0,
}, options );
var percent = settings.percent;
if(typeof percent === 'undefined') {
var percent = parseInt(this.data('percent'));
}else{
if(percent === '') {
var percent = parseInt(this.data('percent'));
}else{
var percent = parseInt(percent);
this.attr('data-percent', percent);
}
}
var deg = 360*percent/100;
if (percent > 50) {
this.addClass('gt-50');
}else{
this.removeClass('gt-50');
}
$('.ppc-progress-fill').css('transform','rotate('+ deg +'deg)');
$('.ppc-percents span').html(percent+'%');
};
用法:
$('#project_progress2').updatePercentageGraph(34);
我需要帮助:
1)
它目前要求用户像这样设置HTML:
<div id="project_progress" class="progress-pie-chart" data-percent="40">
<div class="ppc-progress">
<div class="ppc-progress-fill4" style="transform: rotate(136.8deg);"></div>
</div>
<div class="ppc-percents4">
<div class="pcc-percents-wrapper">
<span>40%</span>
</div>
</div>
</div>
我想做的就是把它放在你可以做这样的事情的地方......
<div id="project_progress" class="progress-pie-chart" data-percent="40"></div>
然后jQuery插件会自动创建正确的子节点。
jQuery会自动创建:
<div class="ppc-progress">
<div class="ppc-progress-fill4" style="transform: rotate(136.8deg);"></div>
</div>
<div class="ppc-percents4">
<div class="pcc-percents-wrapper">
<span>40%</span>
</div>
</div>
2)更新一些选择器以允许页面上的多个圆环图
到目前为止插件中的另一个问题是从上面显示的JavaScript底部开始的第3和第4行。它正在调用$('.ppc-progress-fill')
和$('.ppc-percents span')
,这会阻止在页面上使用多个图表,因此需要更新以仅定位当前图表中存在的类。
3)优化以防止每次调用函数时重新创建HTML结构以更新百分比值
如果我将此插件转换为自动生成HTML结构,那么我还需要考虑对其进行优化,以便每次我的代码运行时都不必重复生成该结构。将调用$('#project_progress2').updatePercentageGraph(34);
因为在我将使用它的项目中,这些图表将不断更新百分比值。
或许甚至可能更好的是有一个创建初始图表HTML的函数,然后是第二个可以反复调用的函数,只是处理百分比的更新并且不会尝试重建和一遍又一遍地注入HTML结构!
我提到的这些问题是我目前有点困难的关键领域,可以请一些帮助。
JSFiddle演示:
答案 0 :(得分:2)
您在http://jsfiddle.net/qsgqebox/3/
我不会向你解释所有这些代码。只是想说这是我通常为jQuery编写插件的方式。
(function($) {
'use strict';
var PercentageGraph = function(element) {
// Setup settings
this.settings = $.extend({
percent: element.data('percent') ? element.data('percent') : 0
});
// Store the given element
this.element = element;
// Create the progress bar
this.create();
// Initialization
this.update();
}
PercentageGraph.prototype = {
create: function() {
// Create:
// <div class="ppc-progress">
// <div class="ppc-progress-fill4"></div>
// </div>
this.progress = $('<div />');
this.progress.addClass('ppc-progress');
this.progressFill = $('<div />');
this.progressFill
.addClass('ppc-progress-fill')
.appendTo(this.progress);
// Create:
// <div class="ppc-percents4">
// <div class="pcc-percents-wrapper">
// <span>40%</span>
// </div>
// </div>
this.percents = $('<div />');
this.percents.addClass('ppc-percents');
this.percentsWrapper = $('<div />');
this.percentsWrapper
.addClass('pcc-percents-wrapper')
.appendTo(this.percents);
this.percentsContent = $('<span />');
this.percentsContent
.text(this.settings.percent)
.appendTo(this.percentsWrapper);
// Append everything to the element
this.progress.appendTo(this.element);
this.percents.appendTo(this.element);
},
update: function(p) {
var percent = p ? p : this.settings.percent,
deg = 360 * percent / 100;
if (percent > 50) {
this.element.addClass('gt-50');
} else {
this.element.removeClass('gt-50');
}
this.progressFill.css('transform', 'rotate('+ deg +'deg)');
this.percentsContent.html(percent + '%');
}
}
jQuery.fn.percentageGraph = function() {
return new PercentageGraph(this);
}
})(jQuery);
(function($) {
$(document).ready(function() {
var progress = $('div#project_progress').percentageGraph();
// Handle it
$('.update-button').on('click', function() {
var percent = $(this).data('percent');
// Update it
progress.update(percent);
});
});
})(jQuery);
答案 1 :(得分:2)
1)jQuery部分将自动创建
要解决这一问题,您需要在插件创建时创建HTML结构。
2)更新一些选择器以允许页面上的多个甜甜圈图表
防止使用整页选择器。相反,您可以保留对创建的HTML结构的引用,并仅对此子集起作用。不是整个DOM。
3)优化以防止每次调用函数时重新创建HTML结构以更新百分比值
解决多个实例的常用模式是创建一个包含插件实例的data
属性。如果某个实例已经存在,那么您只需对该实例执行操作,而不是创建新实例。
拥有此实例对于另一个用于向插件添加方法的jQuery模式也很有用。您可以检查传递给插件的参数是否为字符串,然后调用具有该名称的方法。
$('#project_progress').updatePercentageGraph('percent', percent);
您也可以使用不带参数的相同方法获取值:
var percent = $('#project_progress').updatePercentageGraph('percent');
一体化,我会建议这样的事情:
(function ($, undefined) {
'use strict';
function PercentageGraph(element, options) {
this.$percentageGraph = $(element).append(
'<div class="ppc-progress">' +
'<div class="ppc-progress-fill"></div>' +
'</div>' +
'<div class="ppc-percents">' +
'<div class="pcc-percents-wrapper">' +
'<span>0%</span>' +
'</div>' +
'</div>'
);
this.options = $.extend({}, $(element).data(), options);
this._init();
}
PercentageGraph.prototype = {
_init: function () {
this.percent(this.options.percent || 0);
},
_update: function () {
var percent = this.options.percent;
var deg = 360*percent/100;
if (percent > 50) {
this.$percentageGraph.addClass('gt-50');
}else{
this.$percentageGraph.removeClass('gt-50');
}
this.$percentageGraph.find('.ppc-progress-fill').css('transform','rotate('+ deg +'deg)');
this.$percentageGraph.find('.ppc-percents span').html(percent+'%');
},
percent: function (percent) {
// If no parameter, act as a getter. Otherwise act as a setter.
if (percent === undefined) {
return this.options.percent;
} else {
this.options.percent = percent;
this._update();
}
},
}
$.fn.updatePercentageGraph = function (options) {
var args = Array.prototype.slice.call(arguments, 1),
result;
this.each(function () {
var plugin = $(this).data('percentage-graph');
if (!plugin) {
$(this).data('percentage-graph', (plugin = new PercentageGraph(this, options)));
}
var method = typeof options === 'string' ? options : '_init';
result = plugin[method].apply(plugin, args);
// Break the .each iteration if it is a getter, that is, when the method returns something.
return result === undefined;
});
return result || this;
};
}(jQuery));
请参阅demo