计算图像地图区域坐标时出错
Error when recalculating imagemap area coordinates
我正在编写一个重新计算图像映射中区域属性坐标的脚本。首次加载页面时,该函数会被初始化,以便该区域的坐标会根据用户浏览器的宽度进行调整。第一次一切顺利。
我在 window 元素上添加了一个 'resize' 事件侦听器。函数触发(与 init 函数相同),坐标按预期调整。这样就可以了。但是有一个问题;每次调整 window 的大小时,我都会不断收到错误消息(错误不会在 innit 第一次触发时发生)。
错误:
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();
有人看到在调整大小事件上触发 init 函数时出了什么问题吗?我一直在寻找解决方案。但是没有成功。
提前致谢!
恕我直言,问题是您在 start()
中初始化 config.allAreas
,但您总是向 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, ','));
}
之后在 resize()
中循环遍历 config.areaCoords
,它现在包含的元素比 config.allAreas
:
多得多
resize() {
/* FOR EACH AREA => RESIZE THE COORDINATES
------------------------------------------------ */
config.areaCoords.forEach(function(area, i) {
config.allAreas[i].coords = RecalculateImageMap.scale(area);
});
},
所以我认为错误发生在 config.allAreas[i].coords =
赋值处,因为 i
比 config.allAreas
数组的长度大得多。
此外,这将解释您的陈述 "The weird thing is that the function works perfect for the first time"。
start()
函数中的 config.areaCoords = [];
这样的赋值应该可以解决问题。
我正在编写一个重新计算图像映射中区域属性坐标的脚本。首次加载页面时,该函数会被初始化,以便该区域的坐标会根据用户浏览器的宽度进行调整。第一次一切顺利。
我在 window 元素上添加了一个 'resize' 事件侦听器。函数触发(与 init 函数相同),坐标按预期调整。这样就可以了。但是有一个问题;每次调整 window 的大小时,我都会不断收到错误消息(错误不会在 innit 第一次触发时发生)。
错误:
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();
有人看到在调整大小事件上触发 init 函数时出了什么问题吗?我一直在寻找解决方案。但是没有成功。
提前致谢!
恕我直言,问题是您在 start()
中初始化 config.allAreas
,但您总是向 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, ','));
}
之后在 resize()
中循环遍历 config.areaCoords
,它现在包含的元素比 config.allAreas
:
resize() {
/* FOR EACH AREA => RESIZE THE COORDINATES
------------------------------------------------ */
config.areaCoords.forEach(function(area, i) {
config.allAreas[i].coords = RecalculateImageMap.scale(area);
});
},
所以我认为错误发生在 config.allAreas[i].coords =
赋值处,因为 i
比 config.allAreas
数组的长度大得多。
此外,这将解释您的陈述 "The weird thing is that the function works perfect for the first time"。
start()
函数中的 config.areaCoords = [];
这样的赋值应该可以解决问题。