背景
我正在尝试一些函数式编程和DOM操作。我的目标是在两个值之间切换DOM元素的某些样式。我已经准备好了所有所需的零件,它们都是独立工作的。下面是使用的函数的第一个版本:
const toggleBetween = (...args) => {
let index=0;
const ln = args.length;
return () => {
const val = args[index];
index = (index +1)% ln;
return val;
}
}
export const toggleStyle = (domNode, name: string, value: any) => {
const toggleValue = toggleBetween(domNode.style[name], value);
return () => {
domNode.style[name] = toggleValue();
}
}这两个函数都非常简单。第一个函数将返回一个函数,该函数将在每次调用列表时返回列表上的下一个值,第二个函数将返回一个函数,该函数将在当前值和所提供的值之间切换给定的样式属性。到目前一切尚好。
我还有几个函数可以获取所需的DOM元素:
const pickDomA = () => {/* Code that picks and caches DomNode A*/}
const pickDomB = () => {/* Code that picks and caches DomNode B*/}那么它们就可以像这样使用了
const toggleThing = toggleStyle(pickDomA(), 'display', '');问题所在
当我想初始化包含这些函数的模块时,问题就出现了:文档还没有准备好,尝试获取DOM节点将返回null,而一切都将失败。
问题只是在启动时,执行将是很好的,因为这些函数是由UI元素触发的,只有在文档准备就绪之后才能使用。
问题
在文档准备好之前,是否有一种优雅而实用的方法来推迟DOM节点的选择?
我不满意的解决方案
到目前为止,我得到的最好结果是将每个参数访问封装到一个函数中,该函数检查参数是否为函数,如果是,则执行参数并返回值。然后,我要做的就是传递封装为函数的值。
虽然这是可行的,但我觉得它有点脆弱,也有点扭曲。如果不是因为文档初始化,那么一切都会更简单。
看起来是这样的:
const getValue = (val) => {
if (typeof val === 'function') {
return val();
}
return val;
}
const toggleBetween = (...args) => {
let index=0;
const ln = args.length;
return () => {
const val = args[index];
index = (index +1)% ln;
return getValue(val);
}
}
export const toggleStyle = (domNode, name: string, value: any) => {
const originalValue = memoize(()=> getValue(domNode).style[name]);
const toggleValue = toggleBetween(originalValue , value);
return () => {
getValue(domNode).style[name] = toggleValue();
}
}正如您所看到的,现在每个函数都可以接受一个函数而不是一个值,并执行它以获得值,因此DOM选择被推迟到第一次执行。memoize的原因是因为我只需要第一个提取的值,这意味着原始DOM节点值。
然后,我要做的就是删除DOM选择函数的(),一切都会很好:
const toggleThing = toggleStyle(pickDomA, 'display', '');但同样,我对这个解决方案并不满意。还有更简单的吗?
发布于 2017-08-04 11:32:41
天真地,您只需推迟执行需要文档准备好的代码,即pickDomA()和pickDomB()之前不应该执行。
这通常是这样做的:
document.addEventListener('DOMContentLoaded', _ => {
const toggleThing = toggleStyle(pickDomA(), 'display', '');
// rest of code that depends on toggleThing ...
});或者,确保使用pickDomA()的脚本放在body标记的末尾:然后DOM就准备好了。
https://stackoverflow.com/questions/45504635
复制相似问题