2017-03-06 88 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