首页 > 解决方案 > 世界数组javascript的地图

问题描述

我有一个世界的 SVG 地图,其元素由以下结构组成


  <path
     inkscape:connector-curvature="0"
     id="AF"
     data-name="Afghanistan"
     data-id="AF"
     d="m 1369.9,333.8 -5.4,0 -3.8,-0.5 -2.5,2.9 -2.1,0.7 -1.5,1.3 -2.6,-2.1 -1,-5.4 -1.6,-0.3 0,-2 -3.2,-1.5 -1.7,2.3 0.2,2.6 -0.6,0.9 -3.2,-0.1 -0.9,3 -2.1,-1.3 -3.3,2.1 -1.8,-0.8 -4.3,-1.4 -2.9,0 -1.6,-0.2 -2.9,-1.7 -0.3,2.3 -4.1,1.2 0.1,5.2 -2.5,2 -4,0.9 -0.4,3 -3.9,0.8 -5.9,-2.4 -0.5,8 -0.5,4.7 2.5,0.9 -1.6,3.5 2.7,5.1 1.1,4 4.3,1.1 1.1,4 -3.9,5.8 9.6,3.2 5.3,-0.9 3.3,0.8 0.9,-1.4 3.8,0.5 6.6,-2.6 -0.8,-5.4 2.3,-3.6 4,0 0.2,-1.7 4,-0.9 2.1,0.6 1.7,-1.8 -1.1,-3.8 1.5,-3.8 3,-1.6 -3,-4.2 5.1,0.2 0.9,-2.3 -0.8,-2.5 2,-2.7 -1.4,-3.2 -1.9,-2.8 2.4,-2.8 5.3,-1.3 5.8,-0.8 2.4,-1.2 2.8,-0.7 -1.4,-1.9 z"
     style="fill:#f2f2f2;fill-rule:evenodd" />

我正在尝试这样做,以便当我单击一个随机生成的国家/地区时,如果用户第一次正确单击它,该国家/地区将变为白色,并且将询问另一个随机生成的国家/地区。(当用户单击正确的国家/地区时,我需要尝试让它随机工作,目前它仅在我刷新页面时才有效)。

我有一个功能可以将颜色更改为白色,但它不依赖于被问到的问题。开发这种依赖关系是我卡住的地方。

function onClickHandler(elem){
   var country_id = elem.id
   var colour = "#ffffff";
   elem.style.fill = colour;
}

正在使用的点击功能:

<path
     inkscape:connector-curvature="0"
     id="Algeria"
     onmouseover="displayName('Algeria')"
     onclick="onClickHandler(this)"

我想到的一种可能的解决方案是,在地图的每一块上制作一些不可见的文本框,然后测试数组项是否与单击的文本框匹配?但我不确定如何在代码中实现它。也许我可以将每个路径标签包装在另一个标签中并定位那种类型的标签?以下是我到目前为止所做的:

var items = Array("Afghanistan", "Algeria", "Australia", "Ecuador", "Bahrain", "Bhutan");

function shuffle(array){
   var currentIndex = array.length, temporaryValue, randomIndex;
   while(0 !== currentIndex){
      randomIndex = Math.floor(Math.random() * currentIndex);
      currentIndex -= 1;
      temporaryValue = array[currentIndex];
      array[currentIndex] = array[randomIndex];
      array[randomIndex] = temporaryValue;
   }

   return array;
}

function nextQuestion(){
   items = shuffle(items);
   objQ = items[0];
   return objQ;

}


var e; //event
var i; //index counter

// Aim to try and put hidden text box on each answer and if the array matches the clicked area highlight it white.

function checkAnswer(){
   for(i = 0; i < items.length; i++){
       if(document.getElementById('ansfield').value  == onClickHandler(this)){
         onClickHandler(this).fill = "white";    
// don't think this is correct. 
//Trying to get it to turn the country 
//with the matched name to the array white.  
//Probably need some sort of onclick event...
}
   }
}

标签: javascriptarrays

解决方案


这似乎与您的其他问题有关?:Getting an SVG map to change color on click

所以我从这个问题中得到我的答案作为起点,并尝试给出一个最小的可重现示例(https://stackoverflow.com/help/minimal-reproducible-example

使用更多 SVG 路径会更顺畅,因此如果您提供这些路径,我也可以添加它们。

简而言之,会发生什么:

  • 当您单击该按钮时,它会选择一个随机的国家/地区路径并将其名称放入 h4 标记中的 span 中
  • 当您单击一个国家/地区时,如果该国家/地区与 h4 标签中跨度中的国家/地区相同,则将该国家/地区填充为绿色,否则为红色。
  • 当您再次单击该按钮时,循环所有国家/地区路径并将其填充重置为初始灰色

const targetSpan = document.querySelector('#target')
const allPaths = document.querySelectorAll('svg > path');

function displayName(elem){
  console.log(elem.id)
}

allPaths.forEach(elem => elem.addEventListener('click', myFuncHandler));

function myFuncHandler(e){
  const country_id = e.target.id
  const thisCountry = e.target.getAttribute('data-name');
  const colour = thisCountry == targetSpan.innerHTML ? "#004400" : "#8a0000";
  e.target.style.fill = colour;
}

const startButton = document.querySelector('#startButton');
startButton.addEventListener('click', e => {
  const randIndex = Math.floor(Math.random() * (allPaths.length));
  const randCountry = allPaths[randIndex];
  targetSpan.innerHTML = randCountry.getAttribute('data-name');
  allPaths.forEach(elem => elem.style.fill = "#f2f2f2");
});
<button id="startButton">Start Game</button>
<h4>Please click on <span id="target"></span></h4>

<svg viewbox="250 250 1250 1000">
<path
     inkscape:connector-curvature="0"
     id="Algeria"
     onmouseover="displayName(this)"
     data-name="Algeria"
     data-id="DZ"
     d="m 1021,336.9 -3.6,0.4 -2.2,-1.5 -5.6,0 -4.9,2.6 -2.7,-1 -8.7,0.5 -8.9,1.2 -5,2 -3.4,2.6 -5.7,1.2 -5.1,3.5 2,4.1 0.3,3.9 1.8,6.7 1.4,1.4 -1,2.5 -7,1 -2.5,2.4 -3.1,0.5 -0.3,4.7 -6.3,2.5 -2.1,3.2 -4.4,1.7 -5.4,1 -8.9,4.7 -0.1,7.5 0,0.4 -0.1,1.2 20.3,15.5 18.4,13.9 18.6,13.8 1.3,3 3.4,1.8 2.6,1.1 0.1,4 6.1,-0.6 7.8,-2.8 15.8,-12.5 18.6,-12.2 -2.5,-4 -4.3,-2.9 -2.6,1.2 -2,-3.6 -0.2,-2.7 -3.4,-4.7 2.1,-2.6 -0.5,-4 0.6,-3.5 -0.5,-2.9 0.9,-5.2 -0.4,-3 -1.9,-5.6 -2.6,-11.3 -3.4,-2.6 0,-1.5 -4.5,-3.8 -0.6,-4.8 3.2,-3.6 1.1,-5.3 -1,-6.2 1,-3.3 z"
     style="fill:#f2f2f2;fill-rule:evenodd" />     
     
<path
     inkscape:connector-curvature="0"
     id="Afghanistan"
     onmouseover="displayName(this)"
     data-name="Afghanistan"
     data-id="AF"
     d="m 1369.9,333.8 -5.4,0 -3.8,-0.5 -2.5,2.9 -2.1,0.7 -1.5,1.3 -2.6,-2.1 -1,-5.4 -1.6,-0.3 0,-2 -3.2,-1.5 -1.7,2.3 0.2,2.6 -0.6,0.9 -3.2,-0.1 -0.9,3 -2.1,-1.3 -3.3,2.1 -1.8,-0.8 -4.3,-1.4 -2.9,0 -1.6,-0.2 -2.9,-1.7 -0.3,2.3 -4.1,1.2 0.1,5.2 -2.5,2 -4,0.9 -0.4,3 -3.9,0.8 -5.9,-2.4 -0.5,8 -0.5,4.7 2.5,0.9 -1.6,3.5 2.7,5.1 1.1,4 4.3,1.1 1.1,4 -3.9,5.8 9.6,3.2 5.3,-0.9 3.3,0.8 0.9,-1.4 3.8,0.5 6.6,-2.6 -0.8,-5.4 2.3,-3.6 4,0 0.2,-1.7 4,-0.9 2.1,0.6 1.7,-1.8 -1.1,-3.8 1.5,-3.8 3,-1.6 -3,-4.2 5.1,0.2 0.9,-2.3 -0.8,-2.5 2,-2.7 -1.4,-3.2 -1.9,-2.8 2.4,-2.8 5.3,-1.3 5.8,-0.8 2.4,-1.2 2.8,-0.7 -1.4,-1.9 z"
     style="fill:#f2f2f2;fill-rule:evenodd" />     
     
</svg>

演示:

在此处输入图像描述


推荐阅读