尝试用纯 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();
最佳答案
首先,让我们看看如何轻松支持多个选项。一个常见的解决方案是让您的构造函数接受一个“配置”对象,而不是简单的字符串或数字参数。考虑改用这种形式:
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.options 而不是 。这是上面的代码,扩展了更多选项:this.bcolor .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 到 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";
...
}
}
希望这足以让您使用。
对此的变体(Object.extend 模式 和针对 undefined 的测试)在整个位于 JavaScript 中,并被 jQuery 和许多其他库大量使用。如果您遵循与他们相同的基本设计,那么您将成为很好的伙伴。
关于javascript - 为 vanilla javascript 插件进行默认设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42627218/
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问