使用没有 JQuery 的响应式图像映射

Using Responsive Image Map with no JQuery

我最近一直在想如何制作响应式图像地图。听起来不可能,但我确实找到了方法 http://home.comcast.net/~urbanjost/IMG/resizeimg.html

看源码就知道了。这没有附加 JQuery 或 Ruby,或者人们推荐的任何插件。

但是,当我尝试在我的代码中实现这个 JS 时,它就是不起作用。找了一天一夜也没找到。

原代码如下:

JS:

GLOBAL_COUNT = 0;
GLOBAL_AREAS = new Array();
GLOBAL_WIDTH = 1;

function scaleXY(elementid, scale) {
  // avoid problems with 0 scales and image becoming so small it does not change size 
  // I think something breaks in firefox(1) when you shrink so much that all values in an coords= become 0
  // I think something breaks in iexplore(1) when you shrink so much that all values in an coords= become 0

  myscale = Math.max(0, scale);
  oldwidth = document.getElementById(elementid).width
  oldheight = document.getElementById(elementid).height
  newwidth = Math.round(Math.max(oldwidth * myscale, 1));
  newheight = Math.round(Math.max(oldheight * myscale, 1));

  if(oldwidth == newwidth) newwidth =+ 1;
  if(oldheight == newheight) newheight =+ 1;

  document.getElementById(elementid).width = newwidth;
  document.getElementById(elementid).height = newheight;
  scaleArea();
}

//     Assuming one image map in document.
//     Assuming coordinates are comma-delimited in AREA COORDS= string.
//     Assuming the same zoom factor for the height as for the width of the image.

function getglobal() { // place original AREA coordinate strings into a global array, called at load
  var arrayAreas = document.body.getElementsByTagName("AREA");
  GLOBAL_WIDTH = document.getElementById("myimage").width; // get original width
  for(var i = 0; i < arrayAreas.length; i++) {
    GLOBAL_AREAS[i]= arrayAreas[i].coords;
  }
  GLOBAL_COUNT++;
}

function scaleArea() {   // using values stored at load, recalculate new values for the current size
  var arrayAreas = document.body.getElementsByTagName("AREA");
  for(var i = 0; i < arrayAreas.length; i++) {
    ii = i+1;
    rescale = document.getElementById("myimage").width/GLOBAL_WIDTH ;
    sarray = GLOBAL_AREAS[i].split(","); // convert coordinates to a numeric array assuming comma-delimited values
    var rarray =new Array();
    for(var j = 0; j < sarray.length; j++) {
      rarray[j] = parseInt(sarray[j])*rescale; // rescale the values
      rarray[j] = Math.round(rarray[j]);
    } //alert( "GLOBAL " + GLOBAL_AREAS[i] + ":" + sarray.length + " SPLIT=" + sarray +rarray.length);  
    arrayAreas[i].coords = rarray.join(","); // put the values back into a string
  }
  showArea();
}

HTML:

<body onload="getglobal();" >
  <form>
    <input type="button" onclick="scaleXY('myimage',1.0/1.13);" value="scaled smaller" />
    <input type="button" onclick="scaleXY('myimage',1.13);" value="scaled bigger" />
  </form>
  <div>
    <img id="myimage" src="hcopy.gif" alt="Round buttons" usemap="#circles" height="839" width="586" />
    <map id="circles" name="circles" >
      <area target="_blank" title="CYAN AREA" alt="CYAN" shape="circle" coords="50,50,20" href="#CYAN" />
      <area target="_blank" title="BLUE AREA" alt="BLUE" shape="circle" coords="25,25,20" href="#BLUE" />
      <area target="_blank" title="RED AREA" alt="RED" shape="circle" coords="25,75,20" href="#RED" />
      <area target="_blank" title="MAGENTA AREA" alt="MAGENTA" shape="circle" coords="75,25,20" href="#MAGENTA" />
      <area target="_blank" title="GREEN AREA" alt="GREEN" shape="circle" coords="75,75,20" href="#GREEN" />
      <area target="_blank" title="YELLOW AREA" alt="YELLOW" shape="rect" coords="0,0,100,100" href="#YELLOW" />
     </map>
   </div>
<body>

同样,我没有编写此代码。我很难理解它。但是最大的问题是当我尝试将这段代码应用到我的图像时,它停止工作了。

代码:

HTML:

<form onload="getglobal()">
   <input type="button" onclick="scaleImageDown()" value="scaled smaller" />
   <input type="button" onclick="scaleImageUp()" value="scaled bigger" />
</form>
  <div>
    <img src="http://www.astro-galaxy.com/sys_files/sys_view/CL1296246121697.jpg" usemap="#circles" id="myimage" width="839" height"586" >
    <map name="circles" id="circles">
    <area shape="circle" coords="-264,320,442" href="" title="Sun">
    <area shape="circle" coords="244,79,13" href="" title="Mercury">
    <area shape="circle" coords="307,122,24" href="" title="Venus">
    <area shape="circle" coords="382,187,29" href="" title="Earth">
    <area shape="circle" coords="414,149,14" href="" title="The Moon">
    <area shape="circle" coords="432,232,16" href="" title="Mars">
    <area shape="circle" coords="408,249,8" href="" title="Deimos">
    <area shape="circle" coords="456,217,8" href="" title="Phobos">
    <area shape="rect" coords="413,261,486,292" href="" title="Asteroids">
    <area shape="circle" coords="563,337,85" href="" title="Jupiter">
    <area shape="circle" coords="430,421,14" href="" title="Europa">
    <area shape="circle" coords="463,395,18" href="" title="Ganymede">
    <area shape="circle" coords="653,245,17" href="" title="Callisto">
    <area shape="circle" coords="690,220,13" href="" title="Io">
    <area shape="circle" coords="668,431,41" href="" title="Saturn">
    <area shape="circle" coords="727,397,11" href="" title="Titan">
    <area shape="circle" coords="734,487,21" href="" title="Uranus">
    <area shape="circle" coords="684,525,10" href="" title="Umbriel">
    <area shape="circle" coords="702,512,10" href="" title="Miranda">
    <area shape="circle" coords="769,460,10" href="" title="Ariel">
    <area shape="circle" coords="785,445,10" href="" title="Titania">
    <area shape="circle" coords="802,430,10" href="" title="Oberon">
    <area shape="circle" coords="784,536,27" href="" title="Neptune">
    <area shape="circle" coords="757,565,10" href="" title="Triton">
    <area shape="circle" coords="816,574,10" href="" title="Pluto">
  </map>
</div>

JS:

GLOBAL_COUNT = 0;
GLOBAL_AREAS = new Array();
GLOBAL_WIDTH = 1;
eid = "myimage";

function scaleImageDown() {
  // avoid problems with 0 scales and image becoming so small it does not change size 
  // I think something breaks in firefox(1) when you shrink so much that all values in an coords= become 0
  // I think something breaks in iexplore(1) when you shrink so much that all values in an coords= become 0
  var myscale = 0.5;
  var oldwidth = document.getElementById(eid).width;
  var oldheight = document.getElementById(eid).height;
  var newwidth = oldwidth * myscale;
  var newheight = oldheight * myscale;

  if(oldwidth == newwidth) {
    newwidth =+ 1
  }

  if(oldheight == newheight) {
    newheight =+ 1
  }

  document.getElementById(eid).width = newwidth;
  document.getElementById(eid).height = newheight;
  scaleArea();
}

function scaleImageUp() {
  var myscale = 2;
  var oldwidth = document.getElementById(eid).width;
  var oldheight = document.getElementById(eid).height;
  var newwidth = oldwidth * myscale;
  var newheight = oldheight * myscale;

  if(oldwidth == newwidth) {
    newwidth =+ 1
  }

  if(oldheight == newheight) {
    newheight =+ 1
  }

  document.getElementById(eid).width = newwidth;
  document.getElementById(eid).height = newheight;
  scaleArea();
}

//     Assuming one image map in document.
//     Assuming coordinates are comma-delimited in AREA COORDS= string.
//     Assuming the same zoom factor for the height as for the width of the image.

function getglobal(){ // place original AREA coordinate strings into a global array, called at load
  var arrayAreas = document.body.getElementsByTagName("area");
  GLOBAL_WIDTH = document.getElementById(eid).width; // get original width
  for(var i = 0; i < arrayAreas.length; i++) {
    GLOBAL_AREAS[i]= arrayAreas[i].coords;
  }
  GLOBAL_COUNT++;
}

function scaleArea() { // using values stored at load, recalculate new values for the current size
  var arrayAreas = document.body.getElementsByTagName("area");
  for(var i = 0; i < arrayAreas.length; i++) {
    var ii = i + 1;
    var rescale = document.getElementById(eid).width/GLOBAL_WIDTH ;
    var sarray = GLOBAL_AREAS[i].split(","); // convert coordinates to a numeric array assuming comma-delimited values
    var rarray = new Array();
    for(var j = 0; j < sarray.length; j++) {
      rarray[j] = parseInt(sarray[j]) * rescale; // rescale the values
      rarray[j] = Math.round(rarray[j]);
    } //alert( "GLOBAL " + GLOBAL_AREAS[i] + ":" + sarray.length + " SPLIT=" + sarray +rarray.length);  
    arrayAreas[i].coords=rarray.join(","); // put the values back into a string
  }
  showArea();
}

如您所见,它们几乎相同。唯一的区别是顶部的 onw 有效,而底部的无效。请帮忙。并感谢您对其工作原理的任何解释(当然,除了基础知识)。谢谢!

<form>元素没有自然发生的 'load' 事件,因此在您的代码版本中不会调用 getglobal()

尝试恢复 <body onload="getglobal();">

或者,找到一些其他方法来调用 getglobal() - 例如响应某些用户事件。

代码如何工作?

首先,HTML 导致 DOM 填充:

  • 一个 <form> 元素包含两个按钮
  • 一个<img>元素
  • 包含多个区域的<map>元素

文档的 <body> 元素附加了 getglobal() 作为其 onload 处理程序,这会导致设置多个全局变量:

  • GLOBAL_WIDTH: <img> 元素的初始宽度。
  • GLOBAL_AREAS:图像地图的初始区域坐标数组,“-264,320,442”等
  • GLOBAL_COUNT: 已设置但未使用。

通过一次设置这些全局变量,每次重新缩放图像及其地图时,要做的事情就会少很多。

通过附加 onclick 处理程序,为两个表单按钮分别指定一个 'click' 操作:

  • "scaled smaller" - onclick="scaleImageDown()"
  • "scaled bigger" - onclick="scaleImageUp()"

两个函数scaleImageDown()scaleImageUp()

  • 将图像重新缩放 0.5 或 2 倍。
  • 遍历 GLOBAL_AREAS 数组并操纵区域节点的 coords 属性,使每个坐标除以或乘以 2。这具有重新缩放整个地图的预期效果.

效用函数 scaleArea() 的存在是为了避免 scaleImageDown()scaleImageUp() 中的代码重复。