jQuery插件-深度选项修改
jQuery Plugin - Deep option modification
我目前正在工作的插件设置变量是相当深(3-4级在某些地方)。遵循普遍接受的jQuery插件模式,我实现了一种简单的方法,让用户可以使用以下符号动态修改设置:
$('#element').plugin('option', 'option_name', 'new_value');
下面的代码类似于我现在使用的选项方法。
option: function (option, value) {
if (typeof (option) === 'string') {
if (value === undefined) return settings[option];
if(typeof(value) === 'object')
$.extend(true, settings[option], value);
else
settings[option] = value;
}
return this;
}
现在考虑我有一个像这样的设置变量:
var settings = {
opt: false,
another: {
deep: true
}
};
如果我想更改deep
设置,我必须使用以下符号:
$('#element').plugin('option', 'another', { deep: false });
然而,因为在实践中我的设置可以是3-4级深,我觉得下面的符号会更有用:
$('#element').plugin('option', 'another.deep', false);
然而,我不确定这是否可行,也不知道如何去做。作为第一次尝试,我试图"遍历"到有问题的选项并设置它,但是如果我设置遍历变量,它不会设置它在原始设置变量中引用的内容。
option: function (option, value) {
if (typeof (option) === 'string') {
if (value === undefined) return settings[option];
var levels = option.split('.'),
opt = settings[levels[0]];
for(var i = 1; i < levels.length; ++i)
opt = opt[levels[i]];
if(typeof(value) === 'object')
$.extend(true, opt, value);
else
opt = value;
}
return this;
}
换一种说法:通过在遍历之后设置opt
,它在settings
变量中实际引用的设置在代码运行后保持不变。
编辑
作为第二次尝试,我可以使用eval()
这样做:
option: function (option, value) {
if (typeof (option) === 'string') {
var levels = option.split('.'),
last = levels[levels.length - 1];
levels.length -= 1;
if (value === undefined) return eval('settings.' + levels.join('.'))[last];
if(typeof(value) === 'object')
$.extend(true, eval('settings.' + levels.join('.'))[last], value);
else
eval('settings.' + levels.join('.'))[last] = value;
}
return this;
}
但是我真的很想看看是否有人能告诉我一种方法来不使用eval。因为它是一个用户输入字符串,我宁愿不运行eval()
,因为它可以是任何东西。或者让我知道我是否偏执,这应该不会引起任何问题。
您在这里遇到的问题归结为指向对象的变量和指向其他类型(如字符串)的变量之间的差异。2个变量可以指向同一个Object
,但不能指向同一个String
:
var a = { foo: 'bar' };
var b = 'bar';
var a2 = a;
var b2 = b;
a2.foo = 'hello world';
b2 = 'hello world';
console.log(a.foo); // 'hello world'
console.log(b); // 'bar'
在循环的最后一次迭代之前,您的遍历代码工作得很好,此时opt
是一个变量,在对象settings.opt.another
中包含与deep
相同的值。相反,缩短循环并使用levels
的最后一个元素作为key
,如
var settings = {
another: {
deep: true
}
};
var levels = 'another.deep'.split('.')
, opt = settings;
// leave the last element
var i = levels.length-1;
while(i--){
opt = opt[levels.shift()];
}
// save the last element in the array and use it as a key
var k = levels.shift();
opt[k] = 'foobar'; // settings.another.deep is also 'foobar'
在此阶段,opt
是指向与settings.another
相同的Object
的指针,k
是值为'deep'
String
。使用eval而不是遍历如何?
var settings = {
opt: false,
another: {
deep: true,
}
};
var x = "settings.another";
eval(x).deep = false;
alert(settings.another.deep);
内置的jQuery $().extend()
不完全是你需要的吗?
*注意true
的第一个参数的第二个方法签名执行深度合并…
相关文章:
- 在浏览器操作中修改当前选项卡的URL的TLD
- 如何获取dom修改的选择框的当前所选选项
- 修改选择选项中的选定特性
- 修改 ng 选项
- 根据 if / else 语句修改设置“选项”值
- 如何使用 Greasemonkey 修改现有按钮的点击以打开新选项卡
- 根据选择选项修改元素
- 修改googlechrome扩展以删除选项卡
- DIV的显示和隐藏选项(需要修改)
- 如何防止用户修改绑定到html控件的javascript变量的值(使用任何web浏览器的调试器选项)
- 如何检查选择的选项它已被修改
- JavaScript:如何修改<选项>
- Fancybox-修改javascript以添加选项
- 如何修改代码-弹出窗口,其他关闭选项
- 链接到bootstrap选项卡,无需修改"标签
- 在Angular中,当一个选项被下拉菜单选中时,如何修改一个对象
- 修改电子浏览器窗口选项而不重新创建窗口
- jQuery插件-深度选项修改
- 修改网站默认选项卡功能
- 如何修改选定的选项文本&在下一个选项之后恢复文本