当前位置:  开发笔记 > 编程语言 > 正文

唯一元素ID,即使元素没有

如何解决《唯一元素ID,即使元素没有》经验,为你挑选了4个好方法。

我正在写一个GreaseMonkey脚本,我正在迭代一堆元素.对于每个元素,我需要一个字符串ID,以后我可以用它来引用该元素.元素本身没有id属性,我不能修改原始文档给它一个(虽然我可以在我的脚本中进行DOM更改).我无法在我的脚本中存储引用,因为当我需要它们时,GreaseMonkey脚本本身将超出范围.例如,有没有办法获得浏览器使用的"内部"ID?只有Firefox的解决方案很好; 可以在其他场景中应用的跨浏览器解决方案非常棒.

编辑:

如果GreaseMonkey脚本超出范围,您以后如何引用这些元素?他们GreaseMonkey脚本正在向DOM对象添加事件.我无法将引用存储在数组或其他类似的机制中,因为当事件触发时,数组将会消失,因为GreaseMonkey脚本将超出范围.因此,事件需要某种方式来了解脚本在附加事件时所具有的元素引用.并且所讨论的元素不是它所附着的元素.

你不能只在元素上使用自定义属性吗?是的,但问题在于查找.我不得不求助于遍历所有元素,寻找将自定义属性设置为所需id的元素.那肯定会有用,但在大型文档中它可能非常耗时.我正在寻找浏览器可以执行查找工作的东西.

等等,你能否或不能修改文件?我无法修改源文档,但我可以在脚本中进行DOM更改.我会在问题中澄清一下.

你能不能使用封口?尽管我最初认为他们不会这样做,但Closuses确实有效.见我后来的帖子.

这听起来像是问题的答案:"我可以使用一些内部浏览器ID吗?" 没有."



1> Borgar..:

答案是否定的,没有可以访问的内部ID.Opera和IE(可能是Safari?)支持.sourceIndex(如果DOM有所改变),但Firefox没有这种类型.

您可以通过生成给定节点的Xpath或查找document.getElementsByTagName('*')将始终按源顺序返回元素的节点的索引来模拟源索引.

所有这些当然需要一个完全静态的文件.对DOM的更改将破坏查找.

我不明白的是你如何放松对节点的引用而不是(理论上的)内部id?关闭和分配工作或他们不工作.或者我错过了什么?



2> Jason Buntin..:

你的问题的措辞有点混淆 - 你说你需要一个[你]可以用来引用该元素的字符串ID,"但你"不能在[你的]脚本中存储引用,因为当[你需要它们,GreaseMonkey脚本本身就会超出范围."

如果脚本超出范围,那你以后如何引用它们?!

我将忽略这样一个事实,即我对你所得到的东西感到困惑,并告诉你我经常编写Greasemonkey脚本,并且可以修改我访问的DOM元素,为它们提供ID属性.这是可用于获取临时使用的伪唯一值的代码:

var PseudoGuid = new (function() {
    this.empty = "00000000-0000-0000-0000-000000000000";
    this.GetNew = function() {
        var fourChars = function() {
            return (((1 + Math.random()) * 0x10000)|0).toString(16).substring(1).toUpperCase();
        }
        return (fourChars() + fourChars() + "-" + fourChars() + "-" + fourChars() + "-" + fourChars() + "-" + fourChars() + fourChars() + fourChars());
    };
})();

// usage example:
var tempId = PseudoGuid.GetNew();
someDomElement.id = tempId;

这对我有用,我自己用Greasemonkey脚本测试了它.


更新:闭包是要走的路 - 个人而言,作为一个核心的JavaScript开发人员,我不知道你怎么没有立即想到这些.:)

myDomElement; // some DOM element we want later reference to

someOtherDomElement.addEventListener("click", function(e) {
   // because of the closure, here we have a reference to myDomElement
   doSomething(myDomElement);
}, false);

现在,myDomElement从您的描述中可以看出,其中一个元素已经存在(因为您正在考虑向其中添加ID,或者其他任何内容).

也许如果你发布一个你想要做的事情的例子,它会更容易帮助你,假设没有.



3> Kornel..:

关闭是要走的路.这样你就可以准确地引用那些甚至可以在DOM的一些改组中存活的元素.

那些不知道闭包的例子:

var saved_element = findThatDOMNode();

document.body.onclick = function() 
{
   alert(saved_element); // it's still there!
}

如果你必须将它存储在一个cookie中,那么我建议为它计算XPath(例如,沿着DOM计算前一个兄弟姐妹,直到找到带有ID的元素,你最终会得到类似的东西[@id=foo]/div[4]/p[2]/a).

XPointer是W3C解决该问题的方法.



4> Robert J. Wa..:

更新:闭包确实是答案.所以在摆弄它之后,我想出了为什么闭包最初有问题以及如何修复它.关闭闭包的棘手问题是,在遍历元素时必须小心,不要以所有闭包引用相同的元素结束.例如,这不起作用:

for (var i = 0; i < elements.length; i++) {
    var element = elements[i];
    var button = document.createElement("button");
    button.addEventListener("click", function(ev) {
        // do something with element here
    }, false)
}

但这样做:

var buildListener = function(element) {
    return function(ev) {
        // do something with event here
    };
};

for (var i = 0; i < elements.length; i++) {
    var element = elements[i];
    var button = document.createElement("button");
    button.addEventListener("click", buildListener(element), false)
}

无论如何,我决定不选择一个答案,因为这个问题有两个答案:1)不,你可以使用没有内部ID; 2)你应该使用闭包.所以我只是向第一个人投票说出是否有内部ID或谁建议生成ID,以及提到闭包的人.谢谢您的帮助!

推荐阅读
拾味湖
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有