首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >函数DOM和闭包,推迟到文档准备就绪

函数DOM和闭包,推迟到文档准备就绪
EN

Stack Overflow用户
提问于 2017-08-04 10:37:56
回答 1查看 104关注 0票数 0

背景

我正在尝试一些函数式编程和DOM操作。我的目标是在两个值之间切换DOM元素的某些样式。我已经准备好了所有所需的零件,它们都是独立工作的。下面是使用的函数的第一个版本:

代码语言:javascript
复制
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元素:

代码语言:javascript
复制
const pickDomA = () => {/* Code that picks and caches DomNode A*/}
const pickDomB = () => {/* Code that picks and caches DomNode B*/}

那么它们就可以像这样使用了

代码语言:javascript
复制
const toggleThing = toggleStyle(pickDomA(), 'display', '');

问题所在

当我想初始化包含这些函数的模块时,问题就出现了:文档还没有准备好,尝试获取DOM节点将返回null,而一切都将失败。

问题只是在启动时,执行将是很好的,因为这些函数是由UI元素触发的,只有在文档准备就绪之后才能使用。

问题

在文档准备好之前,是否有一种优雅而实用的方法来推迟DOM节点的选择?

我不满意的解决方案

到目前为止,我得到的最好结果是将每个参数访问封装到一个函数中,该函数检查参数是否为函数,如果是,则执行参数并返回值。然后,我要做的就是传递封装为函数的值。

虽然这是可行的,但我觉得它有点脆弱,也有点扭曲。如果不是因为文档初始化,那么一切都会更简单。

看起来是这样的:

代码语言:javascript
复制
 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选择函数的(),一切都会很好:

代码语言:javascript
复制
const toggleThing = toggleStyle(pickDomA, 'display', '');

但同样,我对这个解决方案并不满意。还有更简单的吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-04 11:32:41

天真地,您只需推迟执行需要文档准备好的代码,即pickDomA()pickDomB()之前不应该执行。

这通常是这样做的:

代码语言:javascript
复制
document.addEventListener('DOMContentLoaded', _ => {
    const toggleThing = toggleStyle(pickDomA(), 'display', '');
    // rest of code that depends on toggleThing ...
});

或者,确保使用pickDomA()的脚本放在body标记的末尾:然后DOM就准备好了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45504635

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档