Nor*_*orx 6 javascript plugins object
试图用普通的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();
Run Code Online (Sandbox Code Playgroud)
Sea*_*ema 14
首先,让我们看看如何轻松支持多种选择.对此的一个常见解决方案是让构造函数接受"配置"对象而不是简单的字符串或数字参数.请考虑使用此表单:
var Tooltip = function(selector, options) {
this.targetElement = document.querySelectorAll(selector);
this.options = options;
...
};
var box = new Tooltip(".box", { color: "red" });
Run Code Online (Sandbox Code Playgroud)
请注意,我们不是传递单个值,而是传入包含该单个值的对象.但是该对象可能包含许多配置选项 - 而不仅仅是一个!例如,您可以传入:
var box = new Tooltip(".box", {
backgroundColor: "red",
textColor: "white",
fontSize: 12,
animated: true,
animationSpeed: 1000
});
Run Code Online (Sandbox Code Playgroud)
当您需要访问任何这些选项时,您的代码可以简单地使用对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";
...
}
}
Run Code Online (Sandbox Code Playgroud)
这就是你如何处理多种选择; 但每个的默认值呢?要做到这一点,您需要首先在某处定义默认值:
Tooltip.prototype.defaultOptions = {
backgroundColor: "#FF9",
textColor: "black",
fontSize: 12,
animated: false,
animationSpeed: 1000
};
Run Code Online (Sandbox Code Playgroud)
然后你的构造函数可以旋转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];
}
...
};
Run Code Online (Sandbox Code Playgroud)
仅当值不存在时,针对a typeof的值的测试undefined才为真,因此这个for循环将任何值复制defaultOptions到options,只要它们尚不存在options.它很好且可扩展:只要你添加一个新值defaultOptions,循环就会将它复制到其中options,无论调用者之前传递的是什么.
并且,更重要的是,该for循环实际上jQuery.extend是在幕后进行的:将值从一个对象复制到另一个对象.(jQuery解决方案稍微优雅一点,但我在这里简化了一些事情,以便更明显地发生了什么.)
但是如果你想在某些地方使用默认行为呢?例如,如果您没有定义特定的字体大小,可能只是希望它从父元素或文档继承,而不是将其分配给某些东西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";
...
}
}
Run Code Online (Sandbox Code Playgroud)
希望这对你来说应该足够了.
对此的变化(Object.extend模式和测试反对undefined)在JavaScript中被广泛使用,并且被jQuery和许多其他库大量使用.如果你遵循他们所做的相同基本设计,你将会处于非常好的公司.