试图在普通的javascript中构建一个简单的工具提示插件。
在我的代码中,我尝试将bcolor
设置为我的代码中的默认设置,我认为当我们想要设置多个默认设置时,这不是一个好方法。
那么,如何在我的vanilla javascript插件中进行默认设置?
var Tooltip = function(selector, bcolor) {
this.targetElement = document.querySelectorAll(selector);
this.bcolor = bcolor;
if (this.bcolor == null || typeof this.bcolor !== "string") {
this.bcolor = "#333";
}
if (this.targetElement == null) {
console.log("Ooops, error!")
}
return this;
}
Tooltip.prototype.tooltip = function() {
for (var i = 0; i < this.targetElement.length; i++) {
var text = this.targetElement[i].getAttribute("data-tooltip");
this.targetElement[i].style.position = "relative";
var span = document.createElement("span");
this.targetElement[i].appendChild(span);
span.style.position = "absolute";
span.style.top = "-25px";
span.style.left = "-20px";
span.style.padding = "4px"
span.style.borderRadius = "5px";
span.style.backgroundColor = this.bcolor;
span.style.color = "#fff";
span.innerHTML = text;
}
}
var box = new Tooltip(".box", "red");
box.tooltip();
答案 0 :(得分:13)
首先,让我们看看如何轻松支持多个选项。对此的一个常见解决方案是让构造函数接受“配置”对象而不是简单的字符串或数字参数。请考虑使用此表单:
var Tooltip = function(selector, options) {
this.targetElement = document.querySelectorAll(selector);
this.options = options;
...
};
var box = new Tooltip(".box", { color: "red" });
请注意,我们不是传递单个值,而是传入包含该单个值的对象。但是该对象可能包含许多配置选项 - 而不仅仅是一个!例如,您可以传入:
var box = new Tooltip(".box", {
backgroundColor: "red",
textColor: "white",
fontSize: 12,
animated: true,
animationSpeed: 1000
});
当您需要访问任何这些选项时,您的代码只需使用对options对象的引用:例如,您可以使用this.bcolor
而不是this.options.backgroundColor
。这是上面的代码,扩展了一些选项:
Tooltip.prototype.tooltip = function() {
for (var i = 0; i < this.targetElement.length; i++) {
...
span.style.backgroundColor = this.options.backgroundColor;
span.style.color = this.options.textColor;
span.style.fontSize = this.options.fontSize + "px";
...
}
}
这就是你如何处理多种选择;但每个默认值呢?为此,您需要首先在某处定义默认值:
Tooltip.prototype.defaultOptions = {
backgroundColor: "#FF9",
textColor: "black",
fontSize: 12,
animated: false,
animationSpeed: 1000
};
然后你的构造函数可以旋转defaultOptions
,使用它的值来填充提供的options
对象中缺少的“漏洞”:
var Tooltip = function(selector, options) {
this.targetElement = document.querySelectorAll(selector);
this.options = options;
for (var optionName in this.defaultOptions) {
if (typeof this.options[optionName] === 'undefined')
this.options[optionName] = this.defaultOptions[optionName];
}
...
};
typeof
对undefined
的值的测试仅在值不存在时才为真,因此for循环将任何值从defaultOptions
复制到{{1只要options
中不存在它们。它很好且可扩展:只要向options
添加新值,循环就会将其复制到defaultOptions
,无论调用者之前传递的是什么。
而且,更重要的是,options
循环实际上就是for
正在做的所有事情:将值从一个对象复制到另一个对象。 (jQuery解决方案更优雅一点,但我在这里简化了一些事情,以便更明显地发生了什么。)
但是,如果您想在某些地方使用默认行为,该怎么办?例如,如果您没有定义特定的字体大小,可能只是希望它从父元素或文档继承而不是从jQuery.extend
分配给它。
如果你想要那种“不分配 - 除非提供”的行为,上面相同的基本模式可以工作,但是你需要稍微调整一下默认选项,然后在你添加一个条件时'正在应用该选项。考虑这个例子与我上面显示的不同之处:
defaultOptions
这对你来说应该足够了。
此处的变体( // Notice that we specifically leave out fontSize here in the defaults.
Tooltip.prototype.defaultOptions = {
backgroundColor: "#FF9",
textColor: "black",
animated: false,
animationSpeed: 1000
};
Tooltip.prototype.tooltip = function() {
for (var i = 0; i < this.targetElement.length; i++) {
...
span.style.backgroundColor = this.options.backgroundColor;
span.style.color = this.options.textColor;
// Now, we only assign the fontSize if it was provided by the user.
if (typeof this.options.fontSize !== 'undefined')
span.style.fontSize = this.options.fontSize + "px";
...
}
}
模式和针对Object.extend
的测试)在JavaScript中被广泛使用,并且被大量使用通过jQuery和许多其他库。如果你遵循他们所做的相同的基本设计,你将会处于非常好的公司。