Onclick mit variabler function belegen

TIMS_Ralf

Erfahrenes Mitglied
Hallo allseits!

Folgendes Problem: Ich möchte nen HTML-Tag flexibel mit einerJS-function belegen.

Sofern die Function bekannt ist, ist es kein Problem - läuft:
Javascript:
// MeinDIV ist als Objekt definiert, die Funktion Ttp(...) funzt
function Ttp(...)
{...} // funzt

function ab_gehts(a,b,c)
{...} // funzt auch

MeinDIV.onmouseover = function() { Ttp(2,yBtnLHdL[5],0,0,this,0,0,0,'$Ttp') };
MeinDIV.onclick = function() { ab_gehts(1,2,3) };

Soweit - so gut... funzt ja.

Nun soll das onclick-Event aber flexibel mit einer beliebigen Funktion belegt werden - da komm isch nett weiter:
Im Code soll die Funktion "ab_gehts(a,b,c)" die mit onclick ausgeführt werden soll, als Variable ( oder sonst wie...? ) vorher definiert werden und dann später bei MeinDIV.onclick belegt werden.
Mal seeeehr stark vereinfacht und nur prinzipiell dargelegt:

Javascript:
var meineFunktion = ab_gehts(1,2,3);

MeinDIV.onclick = function() { meineFunktion };

Ich denke, Ihr wißt, was ich meine ;-)

Danke Euch schon mal!
Gruß Ralf
 

Sempervivum

Erfahrenes Mitglied
Ich denke, ich verstehe schon was Du meinst. Du kannst ja zunächst mal direkt dem onclick eine Funktionsreferenz zuweisen:
Code:
MeinDIV.onclick = meineFunktion;
Dabei gilt jedoch die Einschränkung dass dieser Funktion standardmäßig das Event übergeben wird und nichts anderes. Wenn Du andere Parameter übergeben willst, muss Du dein ab_gehts innerhalb einer weiteren Funktion aufrufen:
Code:
const meineFunktion2 = function(event) {
    ab_gehts(1, 2, 3);
}
Diese kannst Du dann dem onclick zuweisen:
Code:
MeinDIV.onclick = meineFunktion2;
 
Zuletzt bearbeitet:

Sempervivum

Erfahrenes Mitglied
Ich hatte da noch einen Fehler drin und habe diesen jetzt korrigiert. Wenn Du morgen neu lädst, solltest Du die (hoffentlich) richtige Funktion sehen.
 

TIMS_Ralf

Erfahrenes Mitglied
Hi Sempervivum,

Ja, so funzt es natürlich. Die Funktion ab_gehts() wäre damit aber immer noch statisch in einer Konstante hinterlegt. Sie müsste aber variabel sein. Hatte es "schematisch" so vorgesehen:

Habe ein Array, welches die Paramter für ein Script enthält. Mit den Paramtern werden u.a. CSS-Befehle gesetzt (Position, Breite, Höhe...), aber eben auch Parameter für untergeordnete Funktionen.

Die Parameter für 3 DIV-Buttons:
Array[0] - [4] ... Status, CSS...
Array[5]: Parameter für MouseOver-Funktion
Array[6]: Parameter für MouseOut-Funktion
Array[7]: Parameter für MouseClick-Funktion - mal mit "???" markiert:

Javascript:
_yXBx = new Array();
  _yXBx[0] = new Object();
//...
// 0=Zeigen 0/1, 1=Bottom, 2=Left, 3=Breite, 4=Höhe, 5=MOvr, 6=MOut, 7=MClick
  _yXBx[0]['ButtonLeft'] = [ 1, -31, 32, 120, 0, 200, 5, ???];
  _yXBx[0]['ButtonMiddle'] = [ 1, -31, 'nix', 140, 0, 201, 5, ???];
  _yXBx[0]['ButtonRigth'] = [ 1, -50, 20, 120, 0, 202, 5, ??? ];
// ...

Das Hauptscript entscheidet, ob das Event des mittleren DIV-Buttons belegt werden soll ( > 0 ? ). Wenn ja, wird das Event mit einer function belegt, dazu deren Parameter aus dem Array ausgelesen. Bei Array[5] und [6]... kein Problem: Die Funktion ist bekannt, die Parameter können ausgelesen und gesetzt werden.

Bei Array[7] sinds aber kein Parameter, sondern es muß eine variable Funtion sein ( im Code mal mit yBtnM[7] "symbolisiert", hier also die function ab_gehts(a,b,c) angegeben werden ):

Javascript:
// ....
if(yBtnM[5] > 0) BtnM.onmouseover = function() { Ttp(2,yBtnM[5],0,0,this,0,0,0,'$Ttp') };
if(yBtnM[6] > 0) BtnM.onmouseout  = function() { CTtp(yBtnM[6],2,0,0,'$CTtp') };
if(yBtnM[7] > 0) BtnM.onclick = yBtnM[7];   // Hier hakt's natürlich
//...

Der Eintrag von yBtnM[7] muß nun als VARIABLE Funktion irgendwie / irgendwo vartiabel deklariert werden.

In einem weiteren Schritt, müßten dann die Variablen für ab_gehts(a,b,c); noch ausgelesen und in die Funktion für das ONCLICK-Event eingetragen werden - auch aus dem Array _yXBx auslesen...

Ist wohl etwas knifflig, hab schon alles mögliche probiert - kriegs nett hin...
 
Zuletzt bearbeitet:

Andreas-B

Grünschnabel
Hallo TIMS_Ralf,

ich würde dir gerne helfen, doch ich verstehe irgendwie nicht was genau du willst.

Du schreibst:
Nun soll das onclick-Event aber flexibel mit einer beliebigen Funktion belegt werden [...]
Was bedeutet denn "flexibel mit einer beliebigen Funktion"? Was ist denn an Sempervivums Lösung
Javascript:
MeinDIV.onclick = meineFunktion2;
noch zu statisch?

um eine Funktion aufzurufen, muss sie vorher immer irgendwo deklariert werden.

Vielleicht kannst du ein wenig über deinen usecase des Scripts innerhalb deiner Webseite berichten dann können wir dir auch bessere Tips für die Umsetzung deines Vorhabens geben.

Grüße
Andreas
 

Sempervivum

Erfahrenes Mitglied
doch ich verstehe irgendwie nicht was genau du willst.
Geht mir genau so. Möglicher Weise ist dein Ziel, Parameter, die außerhalb des Klick-Handlers ermittelt werden, an diesen zu übergeben, und Du scheiterst daran, dass der Parameter in Form des Events hart festgelegt ist. Wenn das zutrifft, könnte man es lösen, indem man die Parameter als data-Attribute beim Button ablegt, dann hat man auch im Eventhandler Zugriff darauf:
Code:
deinButton.dataset.param1 = param1;
deinButton.dataset.param2 = param2;
// wobei die beiden Parameter zuvor ermittelt wurden

deinButton.addEventListener('click', event => {
    const target = event.target;
    const param1 = target.dataset.param1;
    const param2 = target.dataset.param2;
    // jetzt stehen dir die beiden Parameter zur Verfügung
});
 

TIMS_Ralf

Erfahrenes Mitglied
Ich habe die Sache nun anders gelöst, wenn auch weniger elegant, sondern eher "Holzhammer"... aber funktioniert ;-)

Der "usecase":
Das soll ein "modales Fenster" (DIV-Layer) werden, das sich über einer WEB-site öffnet, und u.a. Buttons mit weiterführenden Funktionen enthält. Die Optik und Inhalte des Fensters, sowie dessen weiterführende Funktionen sollen durch den Kunden selbständig gepflegt, gestaltet und ausgestattet werden können.

Es gibt nur einen HTML-Code für das modale Fenster für alle Kunden-Domains, wovon aber beliebig viele Fenster (DIV-Layer) je WEB-Domain geöffnet werden können. Deswegen muß eben auch alles variabel sein, da jedes Fenster eigene, weiterführende Funktionen auf Buttons haben muß, aber alles in den einen HTML-Code des Layers passen muß.

Lösung:
- Ich generiere mit einer externen JS-Funktion einen HTML-Code der DIV-Buttons
- Dabei werden gewünschte Funktion und Parameter der DIV-Buttons und seinen Events dynamisch generiert,
- Der dynamisch generierte HTML-Code jedes Buttons enthält dann die Events je nach Bedarf.
- Dieser generierte HTML-Code der Buttons wird nachträglich mit $('#'+XBxLayer).prepend(htmlBtnM); in die WEB-Seite bzw. in den Layer geschrieben, in dem die Buttons stehen müssen.

Damit müssen die Buttons (deren Events) nicht schon vorher definiert und deren Parameter ausgelesen sein, sondern können nachträglich und komplett rein geschrieben werden.
Ist sicherlich nicht die eleganteste Lösung.... aber funzt und erfüllt alle Anforderungen.

Danke Euch beiden!
 
Zuletzt bearbeitet:

Andreas-B

Grünschnabel
Ich denke jetzt versteh' ich worum es geht.

Du könntest die Konfiguration in einem Objekt ablegen und dann der Funktion mit apply (oder über destructuring in ES6) die Parameter übergeben.

So könnte das aussehen:
Javascript:
const config = {
    style: {
        top: -31,
        bottom: 32,
        left: 120,
        width: 200,
        height: 0,
    },
    events: {
        mouseOver: function () { Ttp(2, yBtnM[5], 0, 0, this, 0, 0, 0, '$Ttp') },
        mouseOut: function () { CTtp(yBtnM[6], 2, 0, 0, '$CTtp') },
        onclick: [1, 2, 3]
    }
}

clickButton.onclick = function (evt) {
    ab_gehts.apply(null, [evt].concat(config.events.onclick)) // ES5
    ab_gehts(evt, ...config.events.onclick) // ES6
}

Die Konfiguration könntest du in einem Formular eintragen lassen und serialisiert als JSON abspeichern.

Hast du dir sowas vorgestellt?

edit:
die Apply Funktion hatte das evt Objekt als Kontext übergeben,
dadurch waren die Aufrufe von ES5 und ES6 verschieden.
 
Zuletzt bearbeitet:

TIMS_Ralf

Erfahrenes Mitglied
Oh WOW... da hat sich aber jemand Mühe gegeben!

Ich schau da ab Montag drüber - muß ich erst verstehen ;-)
Vorab: Was sind "ES5" und "ES6" ?

JSON wäre nicht notwendig, aber ne super Idee! Habe meine Lizenzierung selbst programmiert. Bisher alles gut :-D

Schönes, langes und gesundes Wochenende Euch und allen erstmal!
 

Neue Beiträge