2017-06-26 1 views
0

Ich arbeite an einem Skript, das die Koordinaten der Bereichsattribute in der Imagemap neu berechnet. Wenn die Seite zum ersten Mal geladen wird, wird die Funktion initialisiert, so dass sich die Koordinaten des Bereichs an die Breite des Browsers des Benutzers anpassen. Das erste Mal geht alles gut.Fehler beim Neuberechnen der Imagemap-Bereichskoordinaten

Ich habe einen 'resize' Ereignis-Listener auf dem Fensterelement hinzugefügt. Die Funktion wird ausgelöst (wie die Funktion init) und die Koordinaten werden wie erwartet angepasst. Das klappt also. Aber es gibt ein Problem; Ich erhalte den Fehler, den Sie unten sehen können, wenn ich die Größe des Fensters ändere (der Fehler tritt nicht auf, wenn innit zum ersten Mal ausgelöst wird).

Fehler:

Uncaught TypeError: Cannot set property 'coords' of undefined 
at http://localhost:3000/js/index.js:78697:33 
at Array.forEach (native) 
at Object.resize (http://localhost:3000/js/index.js:78696:23) 
at Object.start (http://localhost:3000/js/index.js:78691:25) 
at Object.init (http://localhost:3000/js/index.js:78679:27) 
at Object.start (http://localhost:3000/js/index.js:78724:27) 
at init (http://localhost:3000/js/index.js:78720:19) 

JavaScript

/* ALL IMPORTANT CONFIG DATA 
------------------------------------------------ */ 
const config = { 
    allMaps: [], 
    actualMap: document.getElementsByTagName('map')[0], 
    allAreas: false, 
    areaCoords: [], 
    vector: false, 
}; 

/* RECALCULATION FUNCTIONALITY 
------------------------------------------------ */ 
const RecalculateImageMap = { 
    init() { 
    /* AUTOMATICALLY UPDATE COORDINATES ON RESIZED WINDOW 
    ------------------------------------------------ */ 
    window.addEventListener('resize', ImageMapSetup.init); 
    if (!config.actualMap.newSize) { 
     RecalculateImageMap.start(); 
    } 
    }, 
    start() { 
    config.allAreas = config.actualMap.getElementsByTagName('area'); 
    config.vector = document.getElementById('interactive_vector'); 
    /* ALL COORDINATES TO ARRAY 
    ------------------------------------------------ */ 
    for (let i = 0; i < config.allAreas.length; i++) { 
     const coords = config.allAreas[i].coords; 
     config.areaCoords.push(coords.replace(/ *, */g, ',').replace(/ +/g, ',')); 
    } 
    RecalculateImageMap.resize(); 
    }, 
    resize() { 
    /* FOR EACH AREA => RESIZE THE COORDINATES 
    ------------------------------------------------ */ 
    config.areaCoords.forEach(function(area, i) { 
     config.allAreas[i].coords = RecalculateImageMap.scale(area); 
    }); 
    }, 
    scale(area) { 
    const allValues = area.split(','); 
    /* CHECK FOR DIFFERENCE IN SCREENSIZE 
    ------------------------------------------------ */ 
    let totalScale = config.vector.width/config.vector.naturalWidth; 
    let newArea = []; 
    /* CHANGE EACH COORDINATE BASED ON THE NEW SCALE (DIFFERENCE SINCE LAST WIDTH) 
    ------------------------------------------------ */ 
    allValues.map(function(coordinate) { 
     let result = Math.round(Number(coordinate) * totalScale); 
     newArea.push(result); 
    }); 
    return newArea; 
    } 
}; 

/* INITIALIZE RESIZING 
------------------------------------------------ */ 
const ImageMapSetup = { 
    init() { 
    ImageMapSetup.start(config.actualMap); 
    }, 
    start(element) { 
    if (element) { 
     RecalculateImageMap.init(element); 
     config.allMaps.push(element); 
    } 
    } 
}; 

ImageMapSetup.init(); 

Sieht jemand, was schief geht, wenn die init-Funktion auf der Resize-Ereignis feuern? Ich suche schon seit einiger Zeit nach einer Lösung. Aber ohne Erfolg.

Vielen Dank im Voraus!

+0

Sie laufen mit 'config.areaCoords.forEach' und Sie greifen auf' config.allAreas [i] .coords' innerhalb der Schleife mit dem Index von 'areaCoords' zu - Sind Sie wirklich sicher, dass der 'i' index überschreitet nie die Anzahl der Elemente in' config.allAreas'? – gus27

+0

@ gus27 danke für deine Antwort! Die Schleife und der Index scheint in Ordnung zu sein, ich habe versucht, +1 und -1 ihnen aber dann gibt es mehr Fehler. Das Seltsame ist, dass die Funktion zum ersten Mal perfekt funktioniert (Die Init beim Laden der Seite). Bei der Größenänderung des Fensters tritt der Fehler auf, während die gleiche Funktion ausgelöst wird, die schon einmal funktioniert hat. –

Antwort

1

IMHO das Problem ist, dass Sie config.allAreas in start() initialisiert wird, aber Sie sind immer coords zu config.areaCoords

start() { 
    config.allAreas = config.actualMap.getElementsByTagName('area'); 
    ... 
    for (let i = 0; i < config.allAreas.length; i++) { 
     const coords = config.allAreas[i].coords; 
     config.areaCoords.push(coords.replace(/ *, */g, ',').replace(/ +/g, ',')); 
    } 

Danach in resize() Sie Schleifen über config.areaCoords, die jetzt viel mehr Elemente als config.allAreas enthält Zugabe:

resize() { 
    /* FOR EACH AREA => RESIZE THE COORDINATES 
    ------------------------------------------------ */ 
    config.areaCoords.forEach(function(area, i) { 
     config.allAreas[i].coords = RecalculateImageMap.scale(area); 
    }); 
    }, 

Also ich nehme an, dass der Fehler hier bei der config.allAreas[i].coords = Zuweisung auftritt, weil i viel g ist größer als die Länge des Arrays config.allAreas.

Außerdem würde dies Ihre Aussage erklären "Das Seltsame ist, dass die Funktion zum ersten Mal perfekt funktioniert".

Eine Aufgabe wie config.areaCoords = []; in der start() Funktion sollte das Problem lösen.

+0

Danke für diese Antwort! Es hat das Problem tatsächlich verursacht, ich habe das nicht bemerkt! –

+0

@ CamilleSébastienNiessen Dafür gibt es einen Code-Review ;-) – gus27