javascript - 如何将 JSON 字符串转换并执行为带参数的函数?
问题描述
IntersectionObserver 旨在在某些滚动点执行功能。我在回调下的 data-options 属性中给出了这些函数。
现在的问题是,如何触发相应的功能?看起来像这样:
modal ('default-modal');
notify ('subscribe-newsletter', 'bottomLeft');
我的带有 JSON 字符串的 HTML 节点:
<section id="section-90" data-trigger="observer" data-options="{'root':null,'rootMargin':'0px','threshold':[0,0.1,0.2,0.3,0.4,0.7,1],'callbacks':{'modal':[{'id':'default-modal','position':'center'}],'notify':[{'id':'subscribe-newsletter','position':'bottomLeft'},{'id':'become-distributor','position':'bottomRight'}]}}">
格式化的 JSON(仅在这里以获得更好的概述:):
{
"root": "null",
"rootMargin": "0px",
"threshold": [
0,
0.25,
0.5,
0.75,
1
],
"callback": {
"modal": [
{
"id": "default-modal",
"position": "center"
}
],
"notify": [
{
"id": "subscribe-newsletter",
"position": "bottomLeft"
},
{
"id": "become-distributor",
"position": "bottomRight"
}
]
}
}
使用选项解析字符串并过滤回调
let str = target.dataset.options; // options from HTML node
let optStr = str.replace(/'/g, '"');
options = JSON.parse(optStr);
let callbacks = options.callbacks; // store only callbacks
for (const key of Object.keys(callbacks)) {
console.log(key, callbacks[key]);
/*
Output:
modal -> [{"id":"default-modal"}]
notify -> [{"id":"subscribe-newsletter","position":"bottomLeft"},{"id":"become-distributor","position":"bottomRight"}]
*/
}
如何使用输出中的参数调用函数?
modal('default-modal');
notify('subscribe-newsletter', bottomLeft)
解决方案
您可以通过调用以非常hacky 的方式执行此操作,eval()
但强烈建议不要这样做,因为它允许各种 XSS 攻击。将函数列入白名单并显式调用它们会好得多。请参阅下面的示例。
//fake funciton calls
function modal(x) { console.log('fake modal() call', x); }
function notify(a, b) { console.log('fake notify() call', a, b); }
//parse the HTML string
var elem = document.getElementById('section-90');
var optionsStr = elem.getAttribute('data-options').replace(/'/g, '"');
var options = JSON.parse(optionsStr);
//Call the known functions
Object.keys(options.callbacks).forEach(key => {
if (key === "modal") {
modal(options.callbacks.modal[0].id)
} else if (key === "notify") {
notify(options.callbacks.notify[0].id, options.callbacks.notify[1].id)
} else {
throw Error("Unknown function attempted to be called!");
}
});
<section id="section-90" data-trigger="observer" data-options="{'root':null,'rootMargin':'0px','threshold':[0,0.1,0.2,0.3,0.4,0.7,1],'callbacks':{'modal':[{'id':'default-modal','position':'center'}],'notify':[{'id':'subscribe-newsletter','position':'bottomLeft'},{'id':'become-distributor','position':'bottomRight'}]}}">
推荐阅读
- firebase - 在 Firebase 控制台中,时间值意味着什么?
- python - 如何逐元素应用二进制交叉熵,然后在 Keras 中对所有这些损失求和?
- mysql - 如何使用数据文件夹中的数据恢复我的 InnoDB 表?
- c++ - 在 C++ 类中访问 C 风格的回调
- react-native - 使用图像图标反应本机选择器
- sql - SQL - 在 sql 中将数据类型 varchar DD/MM/YYYY 转换为日期格式
- java - 在 Java 中使用的最快和最节省内存的 BZip2 解压缩工具是什么
- regex - 正则表达式不应以字符开头并包含序列
- macos - Safari 对话框未在自动浏览器实例中打开
- asp.net-mvc - 如何将基于位置的订单分配给 WordPress (WooCommerce) 上的特定用户?