• Hallo liebe Userinnen und User,

    nach bereits längeren Planungen und Vorbereitungen sind wir nun von vBulletin auf Xenforo umgestiegen. Die Umstellung musste leider aufgrund der Serverprobleme der letzten Tage notgedrungen vorverlegt werden. Das neue Forum ist soweit voll funktionsfähig, allerdings sind noch nicht alle der gewohnten Funktionen vorhanden. Nach Möglichkeit werden wir sie in den nächsten Wochen nachrüsten. Dafür sollte es nun einige der Probleme lösen, die wir in den letzten Tagen, Wochen und Monaten hatten. Auch der Server ist nun potenter als bei unserem alten Hoster, wodurch wir nun langfristig den Tank mit Bytes vollgetankt haben.

    Anfangs mag die neue Boardsoftware etwas ungewohnt sein, aber man findet sich recht schnell ein. Wir wissen, dass ihr alle Gewohnheitstiere seid, aber gebt dem neuen Board eine Chance.
    Sollte etwas der neuen oder auch gewohnten Funktionen unklar sein, könnt ihr den "Wo issn da der Button zu"-Thread im Feedback nutzen. Bugs meldet ihr bitte im Bugtracker, es wird sicher welche geben die uns noch nicht aufgefallen sind. Ich werde das dann versuchen, halbwegs im Startbeitrag übersichtlich zu halten, was an Arbeit noch aussteht.

    Neu ist, dass die Boardsoftware deutlich besser für Mobiltelefone und diverse Endgeräte geeignet ist und nun auch im mobilen Style alle Funktionen verfügbar sind. Am Desktop findet ihr oben rechts sowohl den Umschalter zwischen hellem und dunklem Style. Am Handy ist der Hell-/Dunkelschalter am Ende der Seite. Damit sollte zukünftig jeder sein Board so konfigurieren können, wie es ihm am liebsten ist.


    Die restlichen Funktionen sollten eigentlich soweit wie gewohnt funktionieren. Einfach mal ein wenig damit spielen oder bei Unklarheiten im Thread nachfragen. Viel Spaß im ngb 2.0.

[JS] eventlistener lassen sich nicht entfernen

nietaL

NGBler

Registriert
8 Sep. 2013
Beiträge
231
Ort
Exilgullianer
Mit einem Doppelklick auf ein Bild (HTML Z.5) wird ein Zoom ausgeführt und ein eventlistener hinzugefügt (JS Z.52), der darauf achtet, ob eine Pfeiltaste gedrückt wird, um das gezoomte Bild zu verschieben (JS Z.56).

Wird wieder doppelt geklickt, soll der eventlistener wieder gelöscht werden (JS Z. 35).

Der Ein- und Auszoomen sowie das Umhersliden auf der Karte funktioniert, wie es soll. Leider entfernt er nicht den Eventlistener und jedesmal wenn ich einmal hineinzoome, wird ein weiterer Listener hinzugefügt und somit auch jede Pfeiltaste 2, 3, 4, 5mal ausgewertet. Somit wird bei jedem Zoomen das Sliden schneller.

Könnt ihr mir sagen, warum er den listener nicht entfernt?

Austesten könnt ihr es hier: http://ouraltis.de/experiment

Liebe Grüße!

PS: Bitte nicht über die Unordnung schimpfen. Es ist ein Sandkasten.




[src=javascript]
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script language="jscript" type="text/javascript">


function mouse_pos()
{
$("#karte").mousemove(function(event){
relX = event.pageX - $("#karte").offset().left;
relY = event.pageY - $("#karte").offset().top;
});
}

function zoom()
{

gebiete = ['gebiet1'];


if(document.getElementById('karteninhalt').style.width == '3388px')
{
document.getElementById('karteninhalt').style.top = '0px';
document.getElementById('karteninhalt').style.left = '0px';
document.getElementById('karteninhalt').style.width = '1150px';
document.getElementById('karteninhalt').style.height = '950px';

gebiete.forEach(function(element)
{
document.getElementById(element).style.width = (parseInt(document.getElementById(element).style.width.split('px')) / 2)+'px';
document.getElementById(element).style.height = (parseInt(document.getElementById(element).style.height.split('px')) / 2)+'px';
document.getElementById(element).style.top = (parseInt(document.getElementById(element).style.top.split('px')) / 2)+'px';
document.getElementById(element).style.left = (parseInt(document.getElementById(element).style.left.split('px')) / 2)+'px';
});

document.removeEventListener("keydown", slide);
}
else
{
document.getElementById('karteninhalt').style.top = -(relY*2)+'px';
document.getElementById('karteninhalt').style.left = -(relX*2)+'px';
document.getElementById('karteninhalt').style.width = '3388px';
document.getElementById('karteninhalt').style.height = '2799px';

gebiete.forEach(function(element)
{
document.getElementById(element).style.width = (parseInt(document.getElementById(element).style.width.split('px')) * 2)+'px';
document.getElementById(element).style.height = (parseInt(document.getElementById(element).style.height.split('px')) * 2)+'px';
document.getElementById(element).style.top = (parseInt(document.getElementById(element).style.top.split('px')) * 2)+'px';
document.getElementById(element).style.left = (parseInt(document.getElementById(element).style.left.split('px')) * 2)+'px';
});

document.addEventListener("keydown", slide);
}


function slide (event)
{
event.preventDefault();

if (event.keyCode == 39 && document.getElementById('karteninhalt').style.width == '3388px')
{
var bild_left_srg = document.getElementById('karteninhalt').style.left;
var bild_left_val = bild_left_srg.split('px');
var bild_left_new = parseInt(bild_left_val) - 300;
if (bild_left_new < -2250) {bild_left_new = -2250;}
document.getElementById('karteninhalt').style.left = bild_left_new + 'px';
}
if (event.keyCode == 37 && document.getElementById('karteninhalt').style.width == '3388px')
{
var bild_left_srg = document.getElementById('karteninhalt').style.left;
var bild_left_val = bild_left_srg.split('px');
var bild_left_new = parseInt(bild_left_val) + 300;
if (bild_left_new > 0) {bild_left_new = 0;}
document.getElementById('karteninhalt').style.left = bild_left_new + 'px';
}
if (event.keyCode == 38 && document.getElementById('karteninhalt').style.width == '3388px')
{
var bild_top_srg = document.getElementById('karteninhalt').style.top;
var bild_top_val = bild_top_srg.split('px');
var bild_top_new = parseInt(bild_top_val) + 300;
if (bild_top_new > 0) {bild_top_new = 0;}
document.getElementById('karteninhalt').style.top = bild_top_new + 'px';
}
if (event.keyCode == 40 && document.getElementById('karteninhalt').style.width == '3388px')
{
var bild_top_srg = document.getElementById('karteninhalt').style.top;
var bild_top_val = bild_top_srg.split('px');
var bild_top_new = parseInt(bild_top_val) - 300;
if (bild_top_new < -1850) {bild_top_new = -1850;}
document.getElementById('karteninhalt').style.top = bild_top_new + 'px';
}
};
}




</script>
[/src]


[src=html4strict]

<body background="tisch_6.jpg">

<div id="karte" onMouseOver="mouse_pos();" onDblClick="zoom();" style="position: absolute; width: 1150px; height: 950px; z-index: 3; overflow: hidden; left: 396px; top: 168px; transform: rotate(-3deg);">



<div id="rahmen" style="position:absolute; background-image:url(rahmen.png); height:950px; width: 1150px; left:0px; top:0px; background-size: contain; z-index:3;"></div>
<div id="struktur" style="position:absolute; background-image:url(struktur.png); height:874px; width: 1074px; left:38px; top:38px; background-size: contain; z-index:2; opacity:0.2"></div>


<div id="karteninhalt" style="position:absolute; width: 1150px; height: 950px; left:0px; top:0px; transition: 0.7s; z-index:1;">



<div id="gebiet1" style="position: absolute; left: 314px; top: 252px; width: 59px; height: 50px; transition: 0.7s; background-image:url(tile.png); background-size: contain; background-repeat: no-repeat; "></div>

<img src="karte_hg.jpg" width="100%" height="100%" />


</div>
</div>

[/src]
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.561
Das sieht wirklich top aus, aber dein Code... :D

Mal drei Vorschläge, vorzugsweise den letzten?

[src=javascript]
// Simple

function zoom() {
// Sollte nicht fehlschlagen wenn nichts gesetzt ist.
document.removeEventListener("keydown", slide);

if (condition == true) {
// Und wieder neu binden
document.addEventListener("keydown", slide);

// Code
}
}

// ODER globale Variable

var isZoomActive = false;

function zoom() {
isZoomActive = !isZoomActive;
isZoomActive ? document.addEventListener("keydown", slide) : document.removeEventListener("keydown", slide);
}

// ODER dataset, data Attribute auf dem Clickziel, bitte zoom(evt/e/evt/ziel....) und das "ziel".target anpassen, verwenden!

function zoom(evt) {
if (evt.target.dataset.zoomActive) {
evt.target.dataset.zoomActive = false;
document.removeEventListener("keydown", slide);
} else {
evt.target.dataset.zoomActive = true;
document.addEventListener("keydown", slide);
}
}[/src]
 
Zuletzt bearbeitet:

nietaL

NGBler

Registriert
8 Sep. 2013
Beiträge
231
Ort
Exilgullianer
  • Thread Starter Thread Starter
  • #3
Hey, danke für deine Antwort. Den Kommentar zum Code verzeihe ich dir :D

Ich habe jetzt einfach mal schnell deine ersten beiden Lösungen ausprobiert. Sie zeigen alle dasselbe verhalten. Es werden endlos eventhandler hinzugefügt, aber keine gelöscht. Ich werde noch wahnsinnig.
Die Debug-Konsole bei Firefox zeigt das auch sehr schön an.

* Strg + Umschalt + S
* Linker Reiter "Inspektor"
* Klick auf das kleine [ev]-Symbol neben dem <html>-Tag

Mit jedem Zoom kommt ein keydown-event dazu.

Vielleicht schaust du mal direkt in den Quelltext hinein? Ich bin mit meinem Latein am Ende. So kompliziert ist der Aufbau ja nun nicht. :m


*edit*

Habe es jetzt hiermit gelöst:
[src=javascript]
document.onkeydown = function(event) {
if (event.keyCode == 38) {
alert("Los geht's");
}
}[/src]

Den Unterschied zwischen dem und nem eventhandler verstehe ich zugegebenermaßen nicht. Zumindest funktioniert dieser einfachere Code jetzt :cool:
 
Zuletzt bearbeitet:

Rakorium-M

NGBler

Registriert
14 Juli 2013
Beiträge
413
Das Problem ist, dass du die Funktion [kw]slide[/kw] innerhalb der Funktion [kw]zoom[/kw] definiert hast - bei jedem Aufruf von zoom() wird eine neue "Funktions-Instanz" erstellt. Das muss so sein, weil du in der inneren Funktion ja Variablen oder Paramter aus der äußeren Funktion benutzen könntest. Das heißt, dass jedes [kw]addEventListener[/kw] und [kw]removeEventListener[/kw] eine neue, einzigartige Funktion bekommt, die zwar das gleiche macht wie alle andern Funktions-Instanzen auch, aber eben nicht gleich ist. removeEventListener versucht also eine Funktion zu entfernen, die er noch nie gesehen hat, und scheitert dabei (lässt alle "anderen" Funktionen aber intakt).

Beispiel:
[src=javascript]function outer(){
function f(){
return 0;
}
return f;
}

outer == outer // => true (weil 2x die gleiche Instanz)
outer() == outer() // => false (jeder Aufruf von outer() erzeugt ein neues f)
var f = outer(); f == f // => true (2x die gleiche Instanz)[/src]

tl;dr: Einfachste Lösung wäre es, deine [kw]slide[/kw]-Funktion einfach außerhalb von [kw]zoom[/kw] zu deklarieren.

Ja, Javascript hat ein ziemlich interessantes "Scoping" (Verhalten bei geschachtelten Funktionen). Lohnt sich aber, sich da mal etwas reinzulesen...
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.561
Das Problem ist, dass du die Funktion [kw]slide[/kw] innerhalb der Funktion [kw]zoom[/kw] definiert hast - [....]

Uh, das hab ich gar nicht gesehen..., jetzt wo du es sagst, sehe ich es auch, bin davon ausgegangen die Funktion ist nicht geschachtelt, war wohl zu früh. :D

Hätte es mal in nen Editor kopieren sollen, dann wäre mir das vielleicht auch aufgefallen... :unknown:

Aber die Erklärung ist top! :)
 
Oben