我开发了这个简短的脚本,但我想知道制作$ul
,$el
和一些函数的最佳方法是什么? select
私人。目前这些是公共界面的一部分,但我想隐藏这些。换入另一个返回DropDown对象的函数可能吗?这样做的正确方法是什么?代码如下:
namespace = {};
namespace.DropDown = function(el) {
this.$el = $(el)
this.$trigger = this.$el.find(".trigger");
this.$ul = this.$el.find("ul");
this.$li = this.$ul.find("li");
this.$trigger.text(this.$ul.find(".selected").text());
this.$trigger.on("click", $.proxy(this.open, this));
}
namespace.DropDown.prototype.open = function(e) {
e.stopImmediatePropagation();
this.$ul.addClass("open");
// position selected element in the middle
var scrollUp,
panelCenter = this.$ul.scrollTop() + (this.$ul.innerHeight() / 2),
selectedPositionTop = this.$ul.scrollTop() + this.$ul.find(".selected").position().top;
if (selectedPositionTop > panelCenter) {
scrollUp = selectedPositionTop - panelCenter;
this.$ul[0].scrollTop = this.$ul[0].scrollTop + scrollUp;
} else {
scrollUp = panelCenter - selectedPositionTop;
this.$ul[0].scrollTop = this.$ul[0].scrollTop - scrollUp;
}
// position elements whole container (list container)
var triggerTop = this.$trigger.offset().top + (parseInt(this.$trigger.css("padding-top")) || 0) + (parseInt(this.$trigger.css("border-top") || 0)),
t = Math.abs(triggerTop - this.$ul.find(".selected").offset().top);
this.$ul.css("top", -t + "px");
this.$li.one("click", $.proxy(this.select, this));
$(document).one("click", $.proxy(this.close, this));
}
namespace.DropDown.prototype.close = function() {
this.$li.off("click");
this.$ul.removeClass("open");
this.$ul.css("top", "0px");
}
namespace.DropDown.prototype.select = function(e) {
$(document).off("click");
e.stopImmediatePropagation();
this.$li.removeClass("selected");
$(e.target).addClass("selected");
this.$trigger.text(this.$ul.find(".selected").text());
this.close(e);
}
$(function() {
new namespace.DropDown($(".dropdown")[0]);
new namespace.DropDown($(".dropdown")[1]);
new namespace.DropDown($(".dropdown")[2]);
});
编辑:
我设法将它包装到另一个函数中,因此我可以获得属性和函数,例如$ ul,选择关闭protootype并通过关闭进行私有。它确实有效,我可以将对象的内容保密,但这是最好的方法吗?这对我来说似乎过于复杂。另外我敢肯定我不是第一个提出这个问题的人,所以这个模式有名字吗?修改后的代码:
namespace = {};
namespace.DropDown = function(el) {
var $el = $(el),
$trigger = $el.find(".trigger"),
$ul = $el.find("ul"),
$li = $ul.find("li");
DropDown = function() {
$trigger.text($ul.find(".selected").text());
$trigger.on("click", $.proxy(this.open, this));
}
function select(e) {
$(document).off("click");
e.stopImmediatePropagation();
$li.removeClass("selected");
$(e.target).addClass("selected");
$trigger.text($ul.find(".selected").text());
this.close(e);
}
DropDown.prototype.open = function(e) {
e.stopImmediatePropagation();
$ul.addClass("open");
// position selected element in the middle
var scrollUp,
panelCenter = $ul.scrollTop() + ($ul.innerHeight() / 2),
selectedPositionTop = $ul.scrollTop() + $ul.find(".selected").position().top; //- $ul.find(".selected").outerHeight();
if (selectedPositionTop > panelCenter) {
scrollUp = selectedPositionTop - panelCenter;
$ul[0].scrollTop = $ul[0].scrollTop + scrollUp;
} else {
scrollUp = panelCenter - selectedPositionTop;
$ul[0].scrollTop = $ul[0].scrollTop - scrollUp;
}
// position elements whole container (list container)
var triggerTop = $trigger.offset().top + (parseInt($trigger.css("padding-top")) || 0) + (parseInt($trigger.css("border-top") || 0)),
t = Math.abs(triggerTop - $ul.find(".selected").offset().top);
$ul.css("top", -t + "px");
$li.one("click", $.proxy(select, this));
//$ul[0].scrollTop = this.scrollPos;
$(document).one("click", $.proxy(this.close, this));
}
DropDown.prototype.close = function() {
$li.off("click");
$ul.removeClass("open");
$ul.css("top", "0px");
}
return new DropDown();
};
$(function() {
new namespace.DropDown($(".dropdown")[0]);
new namespace.DropDown($(".dropdown")[1]);
new namespace.DropDown($(".dropdown")[2]);
});
编辑2:
我应该知道我希望将方法保留在prototype
而不是通过this.functionname
直接保留在对象本身上。我想避免方法重复,因为如果它们直接附加到this
,就会发生这种情况。出于这个简单的原因,这个问题不重复。
答案 0 :(得分:0)
您可以通过闭包创建私有方法和变量,但另一种可能更简单并创建更流畅/更清晰的读取代码的方法可能是通过约定指定私有/公共。例如:
this._privateVariable = true;
this.publicVariable = true;
使用下划线为私人,没有下划线为公共等.. /编辑感谢HMR
答案 1 :(得分:0)
这是制作公共和私人属性的一般形式
var MyClass = (function(){
var myclass = function(){}
var privateMethod = function(){ return 1; }
myclass.prototype.publicMethod = function(){ return privateMethod() + 1; }
return myclass;
})();
放在myclass或myclass.prototype上的属性将公开。但是,使用var
声明的变量将不会公开,但其他方法仍然可以访问它们。在上面的示例中,publicMethod是唯一可公开使用的方法,但它能够调用privateMethod,因为它们是在同一范围内定义的。
答案 2 :(得分:0)
同样如此:
function SampleClass() {
// private
var _type = 'aClass';
// private
var _dothis = function (action) {
return 'i did this ' + action;
};
return {
// public
type: _type,
// public
dothis: function (action) {
return _dothis(action);
}
};
}