如何创建一个事件,当单击 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>
我有一个容器,我在其中动态创建了 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>