重新计算imagemap区域坐标时出错

时间:2017-06-26 14:34:25

标签: javascript html imagemap

我正在编写一个脚本,重新计算imagemap中区域属性的坐标。首次加载页面时,会初始化该功能,以便区域的坐标可以调整到用户浏览器的宽度。一切顺利的第一时间。

我在window元素上添加了一个'resize'事件监听器。该函数触发(与init函数相同),并按预期调整坐标。这样才行。但是有一个问题;每当我调整窗口大小时,我都会收到下面可以看到的错误(首次触发时,错误不会发生。)

错误:

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();

有没有人在调整resize事件时触发init函数会出现什么问题?我一直在寻找一段时间的解决方案......但没有成功。

提前致谢!

1 个答案:

答案 0 :(得分:1)

恕我直言,问题在于您正在config.allAreas初始化start(),但您始终在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数组的长度。

此外,这可以解释你的陈述&#34;奇怪的是,这个功能第一次完美无缺,并且#34;。

config.areaCoords = [];函数中的start()之类的作业可以解决问题。