addEventListener mit Funktionsangabe mit Parameter
Beat
- javascript
Hallo
Folgende Funktionen sind in einer init Phase des Scriptes, mit dem Ziel einen onclick Eventhandler zu realisieren.
Wichtig ist dabei, dass ich der Funktion Parameter überweisen will.
1.Version.
o.onclick = display( o,'target');
Dies funktioniert, hat aber den Schönheitsfehler, dass in der initphase die Funktion ausgeführt wird.
2.Version
o.addEventListener("click", display( o,'target'), false);
Gleiches unschönes Verhalten, aber Firefox wirft zudem noch eine Exception.
Frage: Wie kann ich einen EventListener setzen, ohne dass die Funktion ausgeführt wird, wobei ich aber Übergabe-Parameter definieren kann?
mfg Beat
Hallo Beat,
o.onclick = display( o,'target');
versuch es mal mit
o.onclick = function() {display( o,'target');}
Den Parameter "o" kannst du weglassen, da du im Eventhandler mit this auf das auslösende Element zugreifen kannst.
Gruß, Jürgen
o.onclick = display( o,'target');
versuch es mal mit
o.onclick = function() {display( o,'target');}
Das hat schon mal geklappt.
Den Parameter "o" kannst du weglassen, da du im Eventhandler mit this auf das auslösende Element zugreifen kannst.
Diese Variante läuft noch nicht.
Danke.
mfg Beat
Hallo Beat,
Den Parameter "o" kannst du weglassen, da du im Eventhandler mit this auf das auslösende Element zugreifen kannst.
Diese Variante läuft noch nicht.
dann zeig mal, was du versucht hast.
Gruß, Jürgen
Den Parameter "o" kannst du weglassen, da du im Eventhandler mit this auf das auslösende Element zugreifen kannst.
Diese Variante läuft noch nicht.
dann zeig mal, was du versucht hast.
Also: ich habe eine init Phase.
In dieser muss ich Werte definieren, die ich später manipulieren kann.
Da das js file später der konstanteste teil bleibt, habe ich relativ viel veränderliche CSS Dinge hier dirn.
function init(){
var o;
o = document.getElementById('catalogue');
...
// das war das thema
o = document.getElementById('tb_k');
o.style.backgroundColor = colors.button_bg_active;
o.style.borderColor = colors.button_border_active;
o.onclick = function(){ display(o, 'catalogue') };
// hier versuche ich gerade etwas neues
o = document.getElementById('catlabel');
o.onmousedown = function(){moveobject(o, 'catalogue' ) };
}
// Und nun die Funktion display
// Sie hat jetzt noch überflüssige variablen
function display(starter, target){
// alert (this) ergibt "Object Window"
var s = starter;
var t = document.getElementById(target);
//alert(s + t);
if( t.style.display == "none" ){
t.style.display = "block" ;
s.style.backgroundColor = colors.button_bg_active;
s.style.borderColor = colors.button_border_active;
}
else{
t.style.display = "none";
s.style.backgroundColor = colors.button_bg;
s.style.borderColor = colors.button_border;
}
}
Wenn ich "this" abrufe, erhalte ich das Window Objekt. Ist also nicht brauchbar.
PS: ich weiss es sieht unschön aus, Styles zu manipulieren. Werde wahrscheinlich später die Classe ändern.
mfg Beat
Es ging im Prinzip nur um diesen Aufruf:
o.onclick = function(){ display(o, 'catalogue') };
Hier kannst du statt dem o this schreiben:
o.onclick = function(){ display(this, 'catalogue') };
Macht aber letztlich keinen Unterschied.
Struppi.
Es ging im Prinzip nur um diesen Aufruf:
o.onclick = function(){ display(o, 'catalogue') };
Hier kannst du statt dem o this schreiben:
o.onclick = function(){ display(this, 'catalogue') };
Macht aber letztlich keinen Unterschied.
Ja danke.
Ich dachte halt, dass ich in der funktion dann mit this Zugriff auf das übergebene Objekt erhalte.
Btw:
Immer wenn ich etwas schreibe, plagt mich der Gedanke wegen einer sauberen Namensgebung, die ich später noch verstehe.
Von Namenskonflikten mit built in Objekten mal ganz zu schweigen.
Jetzt habe ich Funktionen, wo ein Element am Ort X Eigenschaften eines Elementes am Ort Y steuert.
Ich habe mir 'starter' und 'target' überlegt.
target scheint mir aber ein schlechter name, da dies ja effektiv als Objekt existiert.
Wie geht man in JS damit um? In Perl ist das ja alles klar.
mfg Beat
Hallo,
Ich habe mir 'starter' und 'target' überlegt.
target scheint mir aber ein schlechter name, da dies ja effektiv als Objekt existiert.
Wie geht man in JS damit um? In Perl ist das ja alles klar.
Ich sehe da kein Problem. Was soll target denn sein? target existiert lediglich als Eigenschaft des Event-Objektes. In keiner Zeile deines Codes arbeitest du mit dem Event-Objekt. target als lokale Variable existiert nur, weil du sie eingeführt hast, nicht davon unabhängig. Überschneidungen gibt es nicht.
Worüber du dir Gedanken machen solltest, ist, dass du das Element mit der ID catalogue über getElementById ansprichst und dann als Referenz vorliegen hast (in der Variable o). Anstatt aber diese Referenz in der Event-Handler-Funktion zu nutzen, überschreibst du die Referenz mit etwas anderem und übergibst dann den String "catalogue". Der wird später sowieso wieder an getElementById weitergegeben. Das ist doppelt gemoppelt und vermeidbar.
var elem1 = document.getElementById("bla");
var elem2 = document.getElementById("blub");
elem2.onclick = function () { display(this, elem1) };
Mathias
Ich sehe da kein Problem. Was soll target denn sein? target existiert lediglich als Eigenschaft des Event-Objektes. In keiner Zeile deines Codes arbeitest du mit dem Event-Objekt. target als lokale Variable existiert nur, weil du sie eingeführt hast, nicht davon unabhängig. Überschneidungen gibt es nicht.
OK. var my_var und my_func(var1, var2){} erzeugen lokale Variablen. Das ist mir klar.
Worüber du dir Gedanken machen solltest, ist, dass du das Element mit der ID catalogue über getElementById ansprichst und dann als Referenz vorliegen hast (in der Variable o). Anstatt aber diese Referenz in der Event-Handler-Funktion zu nutzen, überschreibst du die Referenz mit etwas anderem und übergibst dann den String "catalogue". Der wird später sowieso wieder an getElementById weitergegeben. Das ist doppelt gemoppelt und vermeidbar.
Das ist mir klar geworden, als ich den nächsten Eventhändler initialisieren wollte.
Es sind eben Referenzen und nicht einfach Variablen mit denen ich in JS zu tun habe.
Ich habe mir jetzt ein globales Object geschaffen, in welchem ich die Elemente, mit welchen ich ja dann immer wieder hantiere speichere:
var gui = new Object;
und dann in der Initialisierung:
function init(){
gui.cat = document.getElementById('catalogue'); // das äussere Katalog-Element
...
gui.tbk = document.getElementById('tb_k'); // Toolbar-Button Katalog ein/aus
...
Ich muss dann im Weiteren auch nicht mehr document.getElementById rufen.
Ich sehe nur gleich auf den ersten Blick, wie wichtig Dokumentation im Script wird.
mfg Beat
Am Tag, wo ich sage, ich finde JS toll, da bin ich definitiv hinüber.
Hier mein aktuelles Problem.
Ich will eine Box bewegen.
Also ein Vorgang von
Bewegen kann ich es, aber, ich schaffe es nicht, 'mousemove' zu canceln.
Hier mein Code, den ich gebastelt habe.
gui.catl = document.getElementById('catlabel'); // Katalog Label
gui.catl.onmousedown = function(evt){
var offx = evt.pageX - gui.cat.offsetLeft;
//dies zeigt keine Wirkung
gui.catl.onmouseup = function(evt){
gui.catl.removeEventHandler("mousemove", foo, false);
}
//dieser Teil geht
gui.catl.onmousemove = function foo (evt){
gui.cat.style.left = evt.pageX - offx + "px";
}
};
Damits keine Irritation gibt: gui.catl ist ein inneres Element als Ausläser, während die Position des äusseren Elements gui.cat verändert wird.
Vielleicht weiss wer wie man das macht.
mfg Beat
Hallo Beat,
Bewegen kann ich es, aber, ich schaffe es nicht, 'mousemove' zu canceln.
versuch mal XXX.onmousemove = null:
Gruß, Jürgen
Bewegen kann ich es, aber, ich schaffe es nicht, 'mousemove' zu canceln.
versuch mal
XXX.onmousemove = null:
OK ich habe jetzt so relisiert:
gui.catl = document.getElementById('catlabel'); // Katalog Label
// neu eingefügt
gui.catl.onmouseup = function(evt){
gui.catl.onmousemove = null;
}
// geändert
gui.catl.onmousedown = function(evt){
var offx = evt.pageX - gui.cat.offsetLeft;
var offy = evt.pageY - gui.cat.offsetTop;
gui.catl.onmousemove = function foo (evt){
gui.cat.style.left = evt.pageX - offx + "px";
gui.cat.style.top = evt.pageY - offy + "px";
}
};
Das funktioniert.
Ist aber im Verhalten nicht ganz optimal, besonders in der Vertikalen, wenn die Maus sich schneller bewegt, als der Bereich mitzieht.
mein HTML sieht so aus
<div id=cat>
<h4 id=catl>Sensitives Label</h4>
...
</div>
Entweder ich mach den Algorythmus schneller, oder ich vergrössere den Bereich, oder versuche die Events move und up auf dem document Object zu setzen.
Erste Versuche waren hier nicht gleich erfolgreich.
vielen Dank
mfg Beat
Hallo Beat,
... oder versuche die Events move und up auf dem document Object zu setzen.
ich habe den mousemove auf document gelegt, den up habe ich auf dem Element gelassen. Siehe z.B. mein MausOMeter
Gruß, Jürgen
... oder versuche die Events move und up auf dem document Object zu setzen.
ich habe den mousemove auf document gelegt, den up habe ich auf dem Element gelassen. Siehe z.B. mein MausOMeter
Ich erlaube mir http://www.j-berkemeier.de/Drag_n_Drop.js zu studieren
document.onmousemove ist entschieden besser.
Ich musste auch noch paxeX zu clientX ändern, weil man sonst, falls man scrollt, das Objekt aus dem Screenbereich schubst.
Der Code sieht jetzt so aus.
//
gui.catl = document.getElementById('catlabel'); // Katalog Label
gui.catl.onmouseup = function(evt){
document.onmousemove = null;
}
gui.catl.onmousedown = function(evt){
var offx = evt.clientX - gui.cat.offsetLeft;
var offy = evt.clientY - gui.cat.offsetTop;
document.onmousemove = function foo (evt){
gui.cat.style.left = evt.clientX - offx + "px";
gui.cat.style.top = evt.clientY - offy + "px";
// über diesen Sinn muss ich noch studieren
// evt.cancelBubble = true;
// evt.returnValue = false;
}
};
//
Meine nächste Aufgabe wird dann sein, das etwas zu verallgemeinern.
mfg Beat
// über diesen Sinn muss ich noch studieren
// evt.cancelBubble = true;
// evt.returnValue = false;
Nimm mal ein Bild und verschiebe das im Firefox (zusätzlich sollte in der Seite noch Text vorhanden sein), dann siehst du das Problem. Um das zu lösen brauchst du am Ende der onmousemove Funktion folgenden Code:
if(evt && evt.preventDefault) evt.preventDefault()
return false;
Struppi.
// über diesen Sinn muss ich noch studieren
// evt.cancelBubble = true;
// evt.returnValue = false;Nimm mal ein Bild und verschiebe das im Firefox (zusätzlich sollte in der Seite noch Text vorhanden sein), dann siehst du das Problem. Um das zu lösen brauchst du am Ende der onmousemove Funktion folgenden Code:
if(evt && evt.preventDefault) evt.preventDefault()
return false;
Hallo Struppi
Hier meine testergebnisse.
Ich habe mit meinem ursprünglichen Code ein <img> zu behandeln versucht.
Das Verhalten zeigt sich wie folgt:
onmousedown initiert. Aber solange ich die Mouse drücke und sie bewege, bewegt sich das Bild nicht. erst wenn ich die Maus loslasse stottert das Bild nach.
Nun habe ich den Code minimal erweitert wie folgt.
~~~javascript
gui.cat.onmouseup = function(evt){
document.onmousemove = null;
}
gui.cat.onmousedown = function(evt){
// Dein Tipp
if(evt && evt.preventDefault) evt.preventDefault();
// kein Unterschied in der Wirkung mit oder ohne...
// evt.returnValue = false;
var offx = evt.clientX - gui.cat.offsetLeft;
var offy = evt.clientY - gui.cat.offsetTop;
document.onmousemove = function foo (evt){
gui.cat.style.left = evt.clientX - offx + "px";
gui.cat.style.top = evt.clientY - offy + "px";
}
};
So ergibt sich das normale Verhalten.
Jedoch ist mir im Moment gänzlich schleierhaft, was abgeht.
// evt.returnValue = false;
erweist sich hier als unnötig.
Übrigens ist dein Hinweis auf eine Umgebung mit Text hier nicht ganz schlüssig, weil das zu bewegende Objekt sowieso position fixed oder absolute haben muss.
Ich frage mich, ob es mit dem Typ inline-replaced Element zusammenhängt.
Ein text mit einem Formular hingegen hat nicht den dem <im> ähnlichen Fehler gezeigt.
Danke mal für den Tipp.
mfg Beat
Hier meine testergebnisse.
Ich habe mit meinem ursprünglichen Code ein <img> zu behandeln versucht.
Das Verhalten zeigt sich wie folgt:
onmousedown initiert. Aber solange ich die Mouse drücke und sie bewege, bewegt sich das Bild nicht. erst wenn ich die Maus loslasse stottert das Bild nach.
Genau, und deshalb preventDefault und return false
gui.cat.onmousedown = function(evt){
// Dein Tipp
if(evt && evt.preventDefault) evt.preventDefault();
// kein Unterschied in der Wirkung mit oder ohne...
// evt.returnValue = false;
var offx = evt.clientX - gui.cat.offsetLeft;
var offy = evt.clientY - gui.cat.offsetTop;
document.onmousemove = function foo (evt){
gui.cat.style.left = evt.clientX - offx + "px";
gui.cat.style.top = evt.clientY - offy + "px";
}
hier:
if(evt.preventDefault) evt.preventDefault()
return false;
Das return false ist noch wichtig.
Übrigens ist dein Hinweis auf eine Umgebung mit Text hier nicht ganz schlüssig, weil das zu bewegende Objekt sowieso position fixed oder absolute haben muss.
Das Problem ist, wenn du kein return false hast, wird der Text markiert beim Draggen.
Struppi.
Hallo Struppi,
if(evt && evt.preventDefault) evt.preventDefault()
was passiert eigentlich ohne diese Zeile? Mein DnD-Script läuft eigentlich ganz gut ohne. Aber ich wüsste schon gerne, welche "Leiche" ich da noch im Keller liegen habe.
Gruß, Jürgen
if(evt && evt.preventDefault) evt.preventDefault()
> was passiert eigentlich ohne diese Zeile? Mein DnD-Script läuft eigentlich ganz gut ohne. Aber ich wüsste schon gerne, welche "Leiche" ich da noch im Keller liegen habe.
Praktisch ist es so dass bei einem <img> der onmousedown und der onmousemove miteinander kollidieren. Das ist seltsamerweise nur bei <img>, aber nicht bei einem <input> (in einem Formular) oder 'normalen' Elementen.
Irgendwie muss der onmousedown abgeschaltet werden, damit onmousemove wirkt.
Aber der Hintergrund würde mich auch interessieren.
mfg Beat
--
Woran ich arbeite:
[X-Torah](http://www.elcappuccino.ch/cgi/tok.pl?extern=1-pub-com3306-1)
><o(((°> ><o(((°>
<°)))o>< ><o(((°>o
was passiert eigentlich ohne diese Zeile? Mein DnD-Script läuft eigentlich ganz gut ohne. Aber ich wüsste schon gerne, welche "Leiche" ich da noch im Keller liegen habe.
Das Problem sind Bilder, die lassen sich ohne diese Zeile, bzw. ohne return false nicht im Firefox ziehen.
Struppi.
Hallo Struppi,
Das Problem sind Bilder, die lassen sich ohne diese Zeile, bzw. ohne return false nicht im Firefox ziehen.
das "return false
" habe ich natürlich drin, aber mit oder ohne ".preventDefault()
" habe ich noch keinen Unterschied bemerkt.
Gruß, Jürgen
das "
return false
" habe ich natürlich drin, aber mit oder ohne ".preventDefault()
" habe ich noch keinen Unterschied bemerkt.
Hmmm? Aktuell kann ich das auch nicht mehr nachvollziehen.
Ich kann mich aber dran erinnern, dass ich kurz vorm verzweifeln war, weil meine Drag&Drop Skripte bei Bildern im FF immer hakten. Aber selbst mit einer alten Mozilla Version tun sie es jetzt nicht mehr. Es scheint als ob dieser Aufruf überflüssig ist.
Struppi.
Hallo,
das "
return false
" habe ich natürlich drin, aber mit oder ohne ".preventDefault()
" habe ich noch keinen Unterschied bemerkt.
Hm, verstehe ich dich jetzt falsch?
return false sollte dasselbe machen wie preventDefault, preventDefault ist lediglich Standard.
Im IE sind mit einige Fälle in Erinnerung, wo return false nicht ausreichte und man das eigentlich redundante e.returnValue = false brauchte. Wie das bei Firefox und Co. ist, weiß ich nicht, im Prinzip sollte return false genau das machen, was preventDefault macht, nämlich die Standardreaktion auf das Ereignis unterdrücken.
Mathias
Hallo molily,
ich habe das gerade noch einmal getestet: FF, Safari und Opera (alle unter WinXP) benötigen am Ende des mousedown-Handlers entweder ein "return false;
" oder ein "e.preventDefault();
" damit Drag and Drop funktioniert. Der IE tut es auch ohne, benötigt aber im mousemove-Handler ein "return false;
". Ich beende in meinem Drag and Drop-Script einfach alle Mouseevent-Handler mit "return false;
".
Gruß, Jürgen