如何创建一个事件,当单击 div 或其子 <p/> 元素时,在香草 Javascript 中围绕整个 div 创建边框

How to create an event that when a div or it's child <p/> elements clicked create a border around the whole div in vanilla Javascript

我有一个容器,我在其中动态创建了 divs。每个创建的 div 内部都有 2 个 p 元素。我如何在每个创建的 div 中添加一个 onclick 函数,这样当单击 div 或 p 元素时,绿色边框仅出现在整个 div 周围。因为现在如果我单击 p,边框将围绕 p 而不是围绕 div。我必须单击 div 才能获得正确的边框。

此外,当单击 div 时,程序会迭代具有正确答案的对象数组,如果单击的 div 的 id 在数组 code3 值中,我想将其添加到div 绿色边框。如果错误的红色边框。使用我的代码,如果正确答案不止一个,则只有一个正确答案采用绿色边框,而其他正确答案采用红色边框,就像错误答案一样。同样在控制台中,当我单击正确的答案时,会出现国家名称(应该如此),但还会在名称下方出现“错​​误”字样,左侧有一个小数字。我的for循环有问题吗? 我的代码是:

<body>
<div class = "game-panel">
  <div id="neighbours-panel">
    <div class= neighbor id='ARG'>
         <p>AR(Flag symbol)</p>
         <p>Argentina</p> 
    </div>
    <div class= neighbor id='ITA'>
         <p>IT(Flag symbol)</p>
         <p>Italy</p> 
    </div>
    <div class= neighbor id='GRC'>
         <p>GR(Flag symbol)</p>
         <p>Greece</p> 
    </div>
    etc.
    .
    .
    .
   </div>
</div>

//An array of countries:
realNeighbours = [{ "code": "AF", "code3": "AFG", "name": "Afghanistan", "number": "004" },     { "code": "DZ", "code3": "DZA", "name": "Algeria", "number": "012" },     { "code": "AS", "code3": "ASM", "name": "American Samoa", "number": "016" },     { "code": "AD", "code3": "AND", "name": "Andorra", "number": "020" },]

//JS code:
x = document.getElementById("game-panel").childNodes;

x[x.length-1].addEventListener("click", function (e) {
  for(i=0; i<realNeighbours.length; i++){
    if(realNeighbours[i]['code3'].includes(e.target.id)) {
      e.target.style.border = '1px solid green';
      console.log(this.innerHTML);
    } else {
      e.target.style.border = '1px solid red';
      console.log('wrong')
    }
  }
});

您不需要在每次添加时都创建一个 eventListener div,使用事件委托技术

const
    DomParser = new DOMParser()
  , Checked_HTML = str => (DomParser.parseFromString( str, 'text/html')).body.firstChild
  , borderCountries =
      [ { code: 'AR', code3: 'ARG', name: 'Argentina'   } 
      , { code: 'AF', code3: 'AFG', name: 'Afghanistan' } 
      , { code: 'IT', code3: 'ITA', name: 'Italy'       } 
      , { code: 'GR', code3: 'GRC', name: 'Greece'      } 
      ] 
  , realNeighbours = 
    [ { code: 'AF', code3: 'AFG', name: 'Afghanistan',    number: '004' } 
    , { code: 'DZ', code3: 'DZA', name: 'Algeria',        number: '012' } 
    , { code: 'AS', code3: 'ASM', name: 'American Samoa', number: '016' } 
    , { code: 'AD', code3: 'AND', name: 'Andorra',        number: '020' } 
    ] 
  , gamePanel = document.querySelector('div#game-panel') 
  , score = (function ()  // IIFE clossure
    {
    let divCount = 0
      , value    = 0
      ;
    const
        counter  = document.querySelector('#score > span')
      , correct  = +5
      , wrong    = -3
      , obj = 
        { update(bool)
          {
          value +=( bool ? correct : wrong) * divCount
          counter.textContent = value
          }
        , divAdded() { divCount++ }
        }
      ;
    counter.textContent = value  // init  
    return obj
    })()
  ;
gamePanel.onclick = evt =>
  {
  if (!evt.target.matches('div.neighbor, div.neighbor > p') ) return
  let xDiv    = evt.target.closest('div.neighbor')
    , test_c3 = realNeighbours.some(el=>el.code3===xDiv.dataset.code3)

  score.update(test_c3)
 
  xDiv.classList.add( (test_c3 ? 'cl_green' : 'cl_red') )
  }
 
// generate the divs --- (with DOMParser(): personal preference) 
borderCountries.forEach( bc => 
  {
  let newDiv = `
  <div class="neighbor" data-code3="${bc.code3}">
    <p>${bc.code}(Flag symbol)</p>
    <p>${bc.name}</p> 
  </div>`
  gamePanel.appendChild(Checked_HTML(newDiv)) 

  score.divAdded()
  })
div#game-panel > div { border: 3px solid transparent }
div#game-panel > div.cl_red   { border-color: red;}
div#game-panel > div.cl_green { border-color: green;}
<h4 id="score">score <span></span></h4>

<div id="game-panel">
</div>