2017-03-06 83 views
6

试图在纯javascript中构建简单的工具提示插件。为vanilla javascript插件设置默认设置

在我的代码中,我试着在我的代码中将bcolor设置为默认设置,我认为当我们想要放置多个默认设置时,这不是一个好方法。

那么,我怎样才能使我的香草JavaScript插件的默认设置?

JSFIDDLE

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

回答

12

首先,让我们看看如何轻松支持多个选项。一个常见的解决方案是让你的构造函数接受一个“配置”对象,而不是简单的字符串或数字参数。请考虑使用此表单代替:

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 
}); 

当你需要访问任何的这些选择,你的代码可以简单地使用参考选项对象:例如,而不是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]; 
    } 
    ... 
}; 

undefined值针对typeof甲测试为真仅当值不存在,所以这对环的副本从defaultOptionsoptions的任何值,只要他们不” t已经存在于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"; 
     ... 
    } 
} 

这个希望应该足以让你一起工作。在这个


变化(在Object.extend模式和反对undefined测试)用于各地在JavaScript的地方,并大量使用jQuery和其他图书馆的一大堆。如果你遵循他们所做的相同的基本设计,你将会成为一个非常好的公司。

+0

感谢您的真棒答案!当我没有传递一个值时,为什么它不会从默认选项中获取? >> https://jsfiddle.net/efw8c352/ – Norx

+1

你的例子小提琴根本没有传递任何'选项'对象给构造函数;使用该代码可能会在JavaScript控制台上出现错误!所以默认值不会被分配,因为没有对象可以分配它们。你可以通过传递'new Tooltip(“。box”,{})'(一个空对象)来解决这个问题。或者,您可以添加'options = options || {};'作为构造函数的第一行,它将把一个未定义的(缺少)选项对象变成一个空循环可以分配给的空对象。 –

+0

我明白。感谢您的杰出帮助! – Norx