Domanda

Sto scrivendo uno script GreaseMonkey in cui sto ripetendo un mucchio di elementi. Per ogni elemento, ho bisogno di un ID stringa che posso usare per fare riferimento a quell'elemento in un secondo momento. L'elemento stesso non ha un attributo id e non posso modificare il documento originale per assegnargliene uno (anche se posso apportare modifiche al DOM nel mio script). Non riesco a memorizzare i riferimenti nella mia sceneggiatura perché quando ne ho bisogno, la stessa sceneggiatura GreaseMonkey sarà fuori portata. C'è un modo per arrivare a un "interno" ID utilizzato dal browser, ad esempio? Una soluzione solo per Firefox va bene; una soluzione cross-browser che potrebbe essere applicata in altri scenari sarebbe fantastica.

Modifica:

  • Se lo script GreaseMonkey non rientra nell'ambito, come si fa a fare riferimento agli elementi in un secondo momento? Lo script GreaseMonkey sta aggiungendo eventi agli oggetti DOM. Non riesco a memorizzare i riferimenti in un array o in qualche altro meccanismo simile perché quando l'evento si attiva, l'array sparirà perché lo script GreaseMonkey non sarà più compreso. Quindi l'evento ha bisogno di un modo per conoscere il riferimento dell'elemento che lo script aveva quando l'evento è stato allegato. E l'elemento in questione non è quello a cui è collegato.

  • Non puoi semplicemente utilizzare una proprietà personalizzata sull'elemento? Sì, ma il problema è nella ricerca. Dovrei ricorrere all'iterazione attraverso tutti gli elementi che cercano quello che ha quella proprietà personalizzata impostata sull'ID desiderato. Funzionerebbe, certo, ma in documenti di grandi dimensioni potrebbe richiedere molto tempo. Sto cercando qualcosa in cui il browser può eseguire il grunt di ricerca.

  • Aspetta, puoi o non puoi modificare il documento? Non riesco a modificare il documento di origine, ma posso apportare modifiche al DOM nello script. Chiarirò la domanda.

  • Non puoi usare le chiusure? Le chiusure si sono rivelate efficaci, sebbene inizialmente pensassi che non lo avrebbero fatto. Vedi il mio post successivo.

Sembra la risposta alla domanda: " Esiste un ID browser interno che potrei usare? " è " No. "

È stato utile?

Soluzione 4

AGGIORNAMENTO: Le chiusure sono davvero la risposta. Quindi, dopo averci armeggiato ancora un po ', ho capito perché le chiusure inizialmente erano problematiche e come risolverle. La cosa difficile con una chiusura è che devi stare attento quando si scorre attraverso gli elementi per non finire con tutte le tue chiusure che fanno riferimento allo stesso elemento. Ad esempio, questo non funziona:

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)
}

Ma questo fa:

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)
}

Comunque, ho deciso di non selezionare una risposta perché la domanda aveva due risposte: 1) No, non ci sono ID interni che puoi usare; 2) per questo dovresti usare chiusure. Quindi ho semplicemente valutato le prime persone a dire se c'erano ID interni o che consigliavano di generare ID, oltre a chiunque avesse menzionato chiusure. Grazie per l'aiuto!

Altri suggerimenti

La risposta è no, non esiste un ID interno a cui puoi accedere. Opera e IE (forse Safari?) Supportano .sourceIndex (che cambia se DOM lo fa) ma Firefox non ha nulla di questo tipo.

È possibile simulare l'indice di origine generando Xpath su un determinato nodo o trovando l'indice del nodo da document.getElementsByTagName ('*') che restituirà sempre gli elementi nell'ordine di origine.

Tutto ciò richiede ovviamente un file completamente statico. Le modifiche a DOM interromperanno la ricerca.

Quello che non capisco è come perdere i riferimenti ai nodi ma non agli ID (teorici) interni? Chiusure e incarichi funzionano o no. O mi sto perdendo qualcosa?

La chiusura è la strada da percorrere. In questo modo avrai un riferimento esatto all'elemento che sopravviverà anche a qualche mescolamento di DOM.

Esempio per chi non conosce chiusure:

var saved_element = findThatDOMNode();

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

Se hai dovuto memorizzarlo in un cookie, allora ti consiglio di calcolare XPath per esso (ad esempio, cammina sul DOM contando i fratelli precedenti fino a trovare l'elemento con un ID e finirai con qualcosa come [@ id = foo] / div [4] / p [2] / a ).

XPointer è la soluzione del W3C a questo problema.

Un po 'confuso dal testo della tua domanda: dici che hai bisogno di un ID stringa che [tu] possa usare per fare riferimento a quell'elemento in un secondo momento, " ma che non puoi "archiviare i riferimenti nel [tuo] script perché quando [ne] hai bisogno, lo stesso script GreaseMonkey sarà uscito dal campo di applicazione. "

Se lo script sarà uscito dal campo di applicazione, come si fa a fare riferimento successivamente ?!

Ignorerò il fatto che sono confuso da quello che stai ottenendo e ti dirò che scrivo script Greasemonkey abbastanza spesso e posso modificare gli elementi DOM a cui accedo per dare loro un ID proprietà. Questo è il codice che puoi usare per ottenere un valore pseudo-unico per un uso temporaneo:

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;

Funziona per me, l'ho appena provato in uno script Greasemonkey da solo.


AGGIORNAMENTO: Le chiusure sono la strada da percorrere - personalmente, come sviluppatore JavaScript hard-core, non so come tu non abbia pensato a quelli immediatamente . :)

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);

Ora, myDomElement è uno degli elementi che apparentemente, dalla tua descrizione, hai già in giro (dal momento che stavi pensando di aggiungere un ID ad esso, o altro).

Forse se pubblichi un esempio di ciò che stai cercando di fare, sarebbe più facile aiutarti, supponendo che non lo sia.

Se puoi scrivere sul DOM (sono sicuro che puoi). Lo risolverei così:

Avere una funzione restituire o generare un ID:

//(function () {

  var idCounter = new Date().getTime();
  function getId( node ) {
    return (node.id) ? node.id : (node.id = 'tempIdPrefix_' + idCounter++ );
  }

//})();

Usa questo per ottenere gli ID come necessario:

var n = document.getElementById('someid');
getId(n);  // returns "someid"

var n = document.getElementsByTagName('div')[1];
getId(n);  // returns "tempIdPrefix_1224697942198"

In questo modo non devi preoccuparti di come appare l'HTML quando il server te lo passa.

Se non stai modificando il DOM, puoi ottenerli tutti per ordine indicizzato:

( prototipo esempio)

myNodes = document.body.descendants()
alert(document.body.descendants()[1].innerHTML)

È possibile eseguire il ciclo attraverso tutti i nodi e assegnare loro un nome di classe univoco che è possibile selezionare facilmente in seguito.

È possibile impostare l'attributo id su un valore calcolato. C'è una funzione nella libreria dei prototipi che può farlo per te.

http://www.prototypejs.org/api/element/identify

La mia libreria javascript preferita è jQuery. Sfortunatamente jQuery non ha una funzione come identifica. Tuttavia, puoi comunque impostare l'attributo id su un valore che generi da solo.

http://docs.jquery.com/Attributes/attr#keyfn

Ecco uno snippet parziale dai documenti jQuery che imposta l'id per i div in base alla posizione nella pagina:

  $(document).ready(function(){

    $("div").attr("id", function (arr) {
          return "div-id" + arr;
        });
  });

Puoi anche usare pguid (identificatore univoco di pagina) per la generazione di identificatori univoci:

 pguid = b9j.pguid.next() // A unique id (suitable for a DOM element)
                          // is generated
                          // Something like "b9j-pguid-20a9ff-0"
 ...
 pguid = b9j.pguid.next() // Another unique one... "b9j-pguid-20a9ff-1"

 // Build a custom generator
 var sequence = new b9j.pguid.Sequence({ namespace: "frobozz" })
 pguid = sequence.next() "frobozz-c861e1-0"

http://appengine.bravo9.com/b9j/documentation/pguid.html

Usa il mouse e / o le proprietà posizionali dell'elemento per generare un ID univoco.

Puoi generare un identificatore univoco e stabile per un dato nodo in un DOM con la seguente funzione:

function getUniqueKeyForNode (targetNode) {
    const pieces = ['doc'];
    let node = targetNode;

    while (node && node.parentNode) {
        pieces.push(Array.prototype.indexOf.call(node.parentNode.childNodes, node));
        node = node.parentNode
    }

    return pieces.reverse().join('/');
}

Questo creerà identificatori come doc / 0 , doc / 0/0 , doc / 0/1 , doc / 0/1/0 , doc / 0/1/1 per una struttura come questa:

<div>
    <div />
    <div>
        <div />
        <div />
    </div>
</div>

Ci sono anche alcune ottimizzazioni e modifiche che puoi apportare, ad esempio:

  • Nel ciclo while , break quando quel nodo ha un attributo che sai essere unico, ad esempio @id

  • Non reverse () i pezzi , attualmente è lì solo per assomigliare di più alla struttura DOM da cui sono generati gli ID

  • Non includere il primo pezzo doc se non hai bisogno di un identificatore per il nodo del documento

  • Salvare l'identificatore sul nodo in qualche modo e riutilizzare quel valore per i nodi figlio per evitare di dover attraversare di nuovo completamente l'albero.

  • Se stai riscrivendo questi identificatori in XML, usa un altro carattere di concatenazione se l'attributo che stai scrivendo è limitato.

In javascript, è possibile collegare un campo ID personalizzato al nodo

if(node.id) {
  node.myId = node.id;
} else {
  node.myId = createId();
}

// store myId

È un po 'di hack, ma darà a ogni nodo un ID che puoi usare. Naturalmente, document.getElementById () non presterà attenzione ad esso.

Penso di aver appena risolto un problema simile a questo. Tuttavia, sto usando jQuery in un ambiente DOM del browser.

var objA = $ ("selettore per alcuni elementi dom"); var objB = $ (" selettore per qualche altro elemento dom ");

if (objA [0] === objB [0]) {   //GRANDE! i due oggetti puntano esattamente allo stesso nodo dom }

OK, non esiste alcun ID associato automaticamente all'elemento DOM. DOM ha una struttura gerarchica di elementi che è l'informazione principale. Da questo punto di vista, puoi associare i dati agli elementi DOM con jQuery o jQLite. Può risolvere alcuni problemi quando devi associare dati personalizzati agli elementi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top