nam: <form> und name="wert"

Hallo

In einem JavaScript möchte ich verschiedenen HTML-Elementen zusätzliche Attribute zuordnen, die später wieder von einem Script ausgelesen werden, jedoch keinen Einfluss auf die Darstellung haben:

  
	//pseudo-code:  
	DOMElement.<attributname> = 'value';  

Wenn nun das DOMElement ein FORM-Element ist, dass ein INPUT-Element als Kind hat, welches wiederum ein NAME-Attribut hat, dessen Wert == dem <attributname> ist, kommt es in Firefox und IE zum Konflikt:

  
	<form action="#" method="post">  
		<input type="text" name="<attributname>"></input>  
	</form>  

DOMElement.<attributname> ist in diesem Fall nicht NULL, sondern ein HTMLInputElement, bei dem die Zuseisung (=) nicht erlaubt ist.

Wie kann ich das verhindern?

Erschwerend kommt hinzu, dass es sich um eine JavaScript-Bibliothek handelt. Ich habe also weder die Kontrolle über den HTML-Code, noch kann ich voraussagen, welche strings als <attributname> nicht in Frage kommen.

Dank und Gruss,
nam

  1. Mahlzeit nam,

    //pseudo-code:
    DOMElement.<attributname> = 'value';

      
    Hast Du mal <http://de.selfhtml.org/javascript/objekte/node.htm#set_attribute@title=setAttribute()> ausprobiert (beachte dabei das "Beachten Sie", da der IE nicht unbedingt immer alles richtig macht)?  
      
      
    MfG,  
    EKKi  
    
    -- 
    sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
    
  2. Wie kann ich das verhindern?

    DOMElement.asdf.<attributname> = 'value'; z.B.

    1. Hi

      DOMElement.asdf.<attributname> = 'value'; z.B.

      Ach, da hätte ich eigentlich auch selber drauf kommen können!

      Vielen Dank und schöne Ostern.

  3. Wenn nun das DOMElement ein FORM-Element ist, dass ein INPUT-Element als Kind hat, welches wiederum ein NAME-Attribut hat, dessen Wert == dem <attributname> ist, kommt es in Firefox und IE zum Konflikt:

    Hast du mal versucht document.forms.elements zu benutzen?

    Struppi.

  4. Wenn nun das DOMElement ein FORM-Element ist, dass ein INPUT-Element als Kind hat, welches wiederum ein NAME-Attribut hat, dessen Wert == dem <attributname> ist, kommt es in Firefox und IE zum Konflikt

    Es gibt noch viele weitere Fälle, in denen du Konflikte auslöst, wenn du einfach Objekteigenschaften setzt. Verwende zumindest einen sehr kryptischen Namespace, der garantiert nicht nochmal verwendet wird:

    element.__myFooNamespace123 = {
       name : "wert"
    };

    Erschwerend kommt hinzu, dass es sich um eine JavaScript-Bibliothek handelt.

    Dann lass es besser gleich bleiben, Daten an den Elementen zu speichern.
    jQuerys data() macht das meines Wissens so, dass es dem Element eine ID zuweist (sofern nicht der Browser mit uniqueID eine liefert) und dann in einem gekapselten Hash unter dieser ID die tatsächlichen Daten in einem weiteren Hash speichert.

    Mathias

    1. Hi

      jQuerys data() macht das meines Wissens so, dass es dem Element eine ID zuweist (sofern nicht der Browser mit uniqueID eine liefert) und dann in einem gekapselten Hash unter dieser ID die tatsächlichen Daten in einem weiteren Hash speichert.

      Ein interessanter Hinweis. Mein IQ ist ziemlich am Anschlag, wenn es darum geht, fremden Code zu lesen. Aber so wie ich das verstanden habe, speichert auch jQuery ein so genanntes (oder einen so genannten?) "expando" im Element ab, worüber dann auf den Cache mit den Daten zugegriffen wird:

        
      var expando = "jQuery" + now(), uuid = 0, windowData = {};  
      jQuery.extend({  
      	cache: {},  
      	data: function( elem, name, data ) {  
      		elem = elem == window ? windowData : elem;  
      		var id = elem[ expando ];  
        
      		// Compute a unique ID for the element  
      		if ( !id )  
      			id = elem[ expando ] = ++uuid;  
        
      		// Only generate the data cache if we're  
      		// trying to access or manipulate it  
      		if ( name && !jQuery.cache[ id ] )  
      			jQuery.cache[ id ] = {};  
        
      		// Prevent overriding the named cache with undefined values  
      		if ( data !== undefined )  
      			jQuery.cache[ id ][ name ] = data;  
        
      		// Return the named cache data, or the ID for the element  
      		return name ? jQuery.cache[ id ][ name ] : id;  
      	},  
      	//[...]  
      });  
      
      

      Ich habe es nach bozo20'2 Rat nun so gelöst:

        
      //pseudo-code:  
          DOMElement.__mySpecialExpandoSettings = {};  
          DOMElement. __mySpecialExpandoSettings.<attributname1> = "value";  
          DOMElement. __mySpecialExpandoSettings.<attributname2> = 42;  
      
      

      Ich sehe nicht ein, was der Umweg über den Cache (in jQuery) bringt.

      1. Ich sehe nicht ein, was der Umweg über den Cache (in jQuery) bringt.

        Na, wie gesagt, man hat die Daten selbst zentral gespeichert anstatt am Element. Ans Element hängt man nur eine ID. Das hat z.B. den Grund der einfacheren Speicherverwaltung. Einerseits gehen die Daten nicht unter, wenn das Element gelöscht wird (kann Vor- und Nachteile haben), andererseits kann (und muss) man den zentralen Speicher beim unload am besten selbst dem Garbage Collector anheimstellen. Und man vermeidet zirkuläre Referenzen. Beides hilft, Memory-Leaks zu vermeiden.

        Mathias

        1. Hi molily

          Danke für deine Hinweise.
          Habe es so gelöst:

            
          var Expando = function () {  
          	var container = {};  
          	var uuid_t = "HyphenatorExpando_";  
          	var uuid_i = 0;  
          	function uuid () {  
          		return uuid_t+(uuid_i++);  
          	}  
          	return {  
          		getDataForElem : function (elem) {  
          			return container[elem.id];  
          		},  
          		setDataForElem : function (elem, data) {  
          			var id ;  
          			if (elem.id && elem.id !== '') {  
          				id = elem.id;  
          			} else {  
          				do {  
          					id = uuid();  
          				} while (document.getElementById(id))  
          				elem.id = id;  
          			}  
          			if (!container[id]) {  
          				container[id] = data;  
          			} else {  
          				for (var key in data) {  
          					if (data.hasOwnProperty(key)) {  
          						container[id][key] = data[key];  
          					}  
          				}  
          			}  
          		},  
          		  
          	};  
          }();  
          
          

          Woher weiss ich aber, wenn ein Element gelöscht wird?

          1. Und das ganze noch ohne Fehler :-/

              
            var Expando = (function () {  
                var container = {};  
                var uuid_t = "Expando_";  
                var uuid_i = 0;  
                function uuid () {  
                    return uuid_t+(uuid_i++);  
                }  
                return {  
                    getDataForElem : function (elem) {  
                        return container[elem.id];  
                    },  
                    setDataForElem : function (elem, data) {  
                        var id;  
                        if (elem.id && elem.id !== '') {  
                            id = elem.id;  
                        } else {  
                            do {  
                                id = uuid();  
                            } while (document.getElementById(id));  
                            elem.id = id;  
                        }  
                        if (!container[id]) {  
                            container[id] = data;  
                        } else {  
                            for (var key in data) {  
                                if (data.hasOwnProperty(key)) {  
                                    container[id][key] = data[key];  
                                }  
                            }  
                        }  
                    }  
                };  
            })();