【问题标题】:How to store a reference DOM element for later use如何存储引用 DOM 元素以供以后使用
【发布时间】:2019-12-08 01:51:19
【问题描述】:

我在一个网站上,我点击任何元素并对其进行操作

document.addEventListener('click', function(e){
  e.target.innerHTML = `<span style="background: red">${e.target.innerText}</span>`
})

如何存储对我单击的元素的引用?

我想存储对数据库的引用,以便在重新加载页面时,将完全相同的元素包装在 span 标签中。

【问题讨论】:

  • 您是要存储实际元素本身(JS 可以轻松做到这一点,元素可以存储为变量)还是将其序列化为字符串?我觉得如果您将元素作为字符串存储在动态站点的数据库中,那么存储数据的方式会更加优雅/有效;更原子的东西,你可以用它来用服务器端语言或其他东西重建元素。
  • @matthew-e-brown 我正在为自己创建一个突出显示的 chrome 扩展。说我在维基文章上。我突出显示的文本变为红色,并存储在 aa DB 中(我有)。然后,当我刷新同一页面时,我需要查看以前的亮点。
  • 如果不向 DOM 节点添加唯一标识符以在页面重新加载时保持稳定,您将无法做到这一点。这样做的任何其他方法都将非常脆弱。 JavaScript 对 DOM 的引用在页面重新加载时不稳定。在不使用这种解决方案的情况下,可能有更好的方法来做你想做的事。你想解决什么问题?
  • 您可以使用元素选择器来解决页面重新加载问题,但不能保证您将获得相同的元素或任何元素。您无法控制第三方网页。
  • 你不能,但你可以尝试保存选择器,但就像我说的,它可能不会得到相同的元素。请参阅stackoverflow.com/questions/29787964/… 如何获取选择器(例如:来自您的e.target

标签: javascript


【解决方案1】:

没有经过彻底测试,但可以替代Build the querySelector string value of any given node in the DOM中的代码

注意:该代码假定编写良好的 HTML,即唯一 ID - 不幸的是,网络上充满了具有非唯一 ID 的垃圾页面,因此该代码将失败

结果很可能是比上面的代码更长的选择器,但它似乎工作 - 我还没有打破它:p

function getCSSPath(el) {
    const fullPath = [];
    const fn = el => {
        let tagName = el.tagName.toLowerCase();
        let elPath = '';
        if (el.id) {
            elPath += '#' + el.id;
        }
        if (el.classList.length) {
            elPath += '.' + [...el.classList].join('.');
        }
        if (el.parentElement) {
            if (el.previousElementSibling || el.nextElementSibling) {
                let nthChild = 1;
                for (let e = el.previousElementSibling; e; e = e.previousElementSibling, nthChild++);
                tagName += `:nth-child(${nthChild})`;
            }
            fn(el.parentElement);
        }
        fullPath.push(tagName + elPath);
    };
    fn(el);
    return fullPath.join('>');
}

我认为这是上面的更好版本:

function getCSSPath(el) {
    let elPath = el.tagName.toLowerCase();
    if (el.parentElement && (el.previousElementSibling || el.nextElementSibling)) {
        let nthChild = 1;
        for (let e = el.previousElementSibling; e; e = e.previousElementSibling, nthChild++);
        elPath += `:nth-child(${nthChild})`;
    }
    if (el.id) {
        elPath += '#' + el.id;
    }
    if (el.classList.length) {
        elPath += '.' + [...el.classList].join('.');
    }
    return (el.parentElement ? getCSSPath(el.parentElement) + '>' : '') + elPath;
}

【讨论】:

  • 现在我正处于测试阶段,我正在处理这个函数太深的问题。例如在 Reddit 中,输出不会产生任何结果。解决方案是让这个函数不要一直回到html。我正在尝试修改它,但你将如何做到这一点,以便它只有几个层次,比如.gran&gt;.parent&gt;.element - 谢谢
  • ...我将结果切片以获得我需要的getCSSPath(parentEl).split("&gt;").slice(1).slice(-2).join("&gt;") 并且它有效,我只是出于学习目的,您将如何重构函数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-28
  • 2016-03-18
  • 2016-06-26
  • 2012-02-29
  • 2021-10-11
  • 1970-01-01
  • 2021-09-08
相关资源
最近更新 更多