英文:
How to use the mouseover and mouseout events to change background color of all of the generated divs/grid-items
问题
我正在完成"etch-a-sketch"挑战,作为TOP课程的一部分。我已成功使用JS DOM操控和CSS网格创建了一个16x16的网格。问题的第二部分是使每个单独的网格项/单元在悬停时更改背景颜色。我选择使用JS的mouseover事件监听器,但也在搜索信息时看到了CSS的:hover选择器作为一个可行的选项。
我创建了两个函数"overing"和"outing",用于在悬停时更改网格项的背景颜色,使用"mouseover"事件监听器。这些函数只在第一个生成的单元/网格项上有效。请问如何使"overing"和"outing"函数在所有网格项上工作?仅第1个网格项有效
英文:
I am completing the "etch-a-sketch" challenge as part of TOP curriculum. I have successfully created a 16 x 16 grid utilizing JS DOM manipulation and CSS grid. The second part of my problem is to make each individual grid-item/cell change background color on hover. I chose to use JS with the mouseover Eventlistener, but also saw the CSS: hover Selector as a viable option when googling for information.
I have created 2 functions overing
and outing
to change the background color of the grid-item on hover using the "mouseover" event listener. The functions only work on the first generated cell/grid-item. May someone please explain how I can get my overing and outing functions to work on all grid-items.only 1st grid-item working
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
//Function and call to generate 16x16 grid of divs.
document.getElementById("container");
function makeGrid(rows, cols) {
container.style.setProperty('--grid-rows', rows)
container.style.setProperty('--grid-cols', cols)
for (c = 0; c < (rows * cols); c++) {
let cell = document.createElement("div");
cell.innerText = (c + 1);
container.appendChild(cell).className = "grid-item";
};
};
makeGrid(16, 16);
//Function to change background color of individual "grid-item" on hover.
document.querySelector('.grid-item').addEventListener('mouseover', overing);
document.querySelector('.grid-item').addEventListener('mouseout', outing);
function overing(ev) {
ev.currentTarget.style.backgroundColor = 'red';
console.log('mouseenter div');
}
function outing(ev) {
ev.currentTarget.style.backgroundColor = 'white';
console.log('mouseleave div');
}
<!-- language: lang-css -->
:root {
--grid-cols: 1;
--grid-rows: 1;
}
#container {
display: grid;
grid-gap: 1em;
grid-template-columns: repeat(var(--grid-cols), 1fr);
grid-template-rows: repeat(var(--grid-rows), 1fr);
}
.grid-item {
padding: 1em;
border: 1px solid black;
text-align: center;
}
<!-- language: lang-html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sketch-Book</title>
<link rel="stylesheet" type="text/css" href="etchStyles.css" />
</head>
<body>
<div id="container">
</div>
</body>
<script type="text/javascript" src="etchScript.js"></script>
</html>
<!-- end snippet -->
答案1
得分: 4
@Titus 是对的。但由于您正在使用JavaScript创建每个DOM节点,您可以利用这一点在创建时附加事件侦听器。例如:
const overing = (ev) => {
ev.currentTarget.style.backgroundColor = 'red';
};
const outing = (ev) => {
ev.currentTarget.style.backgroundColor = 'white';
}
const makeGrid = (rows, cols) => {
container.style.setProperty('--grid-rows', rows)
container.style.setProperty('--grid-cols', cols)
for (c = 0; c < (rows * cols); c++) {
let cell = document.createElement("div");
cell.innerText = (c + 1);
cell.classList.add('grid-item');
// 在此处附加事件侦听器,因为您有对DOM节点的引用
cell.addEventListener("mouseover", overing);
cell.addEventListener("mouseout", outing);
container.appendChild(cell);
};
};
makeGrid(16, 16);
此代码段演示了如何在创建每个DOM节点时附加事件侦听器,以便在鼠标悬停和移出时更改背景颜色。
英文:
@Titus is right. But since you are using javascript to create each DOM node, you can exploit this fact to attach event listeners at creation time. Ex:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const overing = (ev) => {
ev.currentTarget.style.backgroundColor = 'red';
//console.log('mouseenter div');
};
const outing = (ev) => {
ev.currentTarget.style.backgroundColor = 'white';
//console.log('mouseleave div');
}
const makeGrid = (rows, cols) => {
container.style.setProperty('--grid-rows', rows)
container.style.setProperty('--grid-cols', cols)
for (c = 0; c < (rows * cols); c++) {
let cell = document.createElement("div");
cell.innerText = (c + 1);
cell.classList.add('grid-item');
// attach listeners here since you have a reference to the DOM node
cell.addEventListener("mouseover", overing);
cell.addEventListener("mouseout", outing);
container.appendChild(cell);
};
};
makeGrid(16, 16);
<!-- language: lang-css -->
section {
--grid-cols: 1;
--grid-rows: 1;
}
#container {
display: grid;
grid-gap: 1em;
grid-template-columns: repeat(var(--grid-cols), 1fr);
grid-template-rows: repeat(var(--grid-rows), 1fr);
}
.grid-item {
padding: 1em;
border: 1px solid black;
text-align: center;
}
.grid-item:hover {
cursor: pointer;
}
<!-- language: lang-html -->
<section>
<div id="container">
</div>
</section>
<!-- end snippet -->
答案2
得分: 2
你可以使用CSS的:hover
伪类,这里有一个3x3网格的示例:
.grid {
display: grid;
grid-template: repeat(3, 30vh) / repeat(3, 30vw);
background-color: white;
height: 94vh;
width: 94vw;
grid-row-gap: 1vh;
grid-column-gap: 1vw;
}
.grid_element {
display: flex;
height: 100%;
width: 100%;
background-color: gray;
}
.grid_element:hover {
background-color: red;
}
<div class="grid">
<div class="grid_element"></div>
<div class="grid_element"></div>
<div class="grid_element"></div>
<div class="grid_element"></div>
<div class="grid_element"></div>
<div class="grid_element"></div>
<div class="grid_element"></div>
<div class="grid_element"></div>
<div class="grid_element"></div>
</div>
英文:
You could use css :hover
, here is an example with a 3x3 grid:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
.grid {
display: grid;
grid-template: repeat(3, 30vh) / repeat(3, 30vw);
background-color: white;
height: 94vh;
width: 94vw;
grid-row-gap:1vh;
grid-column-gap:1vw;
}
.grid_element {
display: flex;
height: 100%;
width: 100%;
background-color: gray;
}
.grid_element:hover {
background-color: red;
}
<!-- language: lang-html -->
<div class="grid">
<div class="grid_element"></div>
<div class="grid_element"></div>
<div class="grid_element"></div>
<div class="grid_element"></div>
<div class="grid_element"></div>
<div class="grid_element"></div>
<div class="grid_element"></div>
<div class="grid_element"></div>
<div class="grid_element"></div>
</div>
<!-- end snippet -->
答案3
得分: 1
所有现代浏览器都支持模板引用:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template,因此我们可以使用它来代替手动创建元素,这样我们的代码可以更小 - 尤其是如果您要为每个“单元格”添加更多内容,如一组跨度、div 等。
您可以确定要添加事件处理程序,但您可以在创建它们的相同循环中添加它们。
注意:可能需要创建一个新的 DIV,用于在命中 DOM 之前将所有新项目附加到它,但我将把这个练习留给您,因为它超出了问题的范围。
function makeGrid(rows, cols) {
const container = document.getElementById("container");
const template = document.getElementById("grid-cell-template");
for (let c = 0; c < (rows * cols); c++) {
const cloneCell = template.content.cloneNode(true);
const newItem = cloneCell.querySelector(".grid-item");
newItem.textContent = (c + 1);
newItem.addEventListener('mouseenter', mouseEnterEventHandler);
newItem.addEventListener('mouseleave', mouseLeaveEventHandler);
newItem.addEventListener('mouseover', mouseOverEventHandler);
container.appendChild(newItem);
}
}
makeGrid(16, 16);
function mouseEnterEventHandler(event) {
event.currentTarget.style.backgroundColor = '#FF000022';
}
function mouseLeaveEventHandler(event) {
event.currentTarget.style.backgroundColor = '#FFFFFF';
event.target.style.borderColor = "#000000";
}
function mouseOverEventHandler(event) {
event.target.style.borderColor = "#00FF00";
}
body {
font-size: 16px;
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--grid-cols: 16;
--grid-rows: 16;
}
#container {
display: grid;
grid-gap: 0.5em;
grid-template-columns: repeat(var(--grid-cols), 1fr);
grid-template-rows: repeat(var(--grid-rows), 1fr);
}
.grid-item {
padding: 1em;
border: 1px solid #000000;
text-align: center;
}
<body>
<div id="container">
</div>
<template id="grid-cell-template">
<div class="grid-item"></div>
</template>
</body>
以上为您提供的代码部分的翻译。
英文:
All modern browsers support template ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template so lets' use that instead of manually creating an element so out code can be smaller - especially if you add more content to each "cell" such as a set of spans, divs etc.
You can determine what you want for event handlers but you can add those right in the same loop when creating them.
NOTE: Probably want to create a new DIV just to append all the NEW items to before hitting the DOM and appending them all at once but I will leave that exercise to you as outside the question scope.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
function makeGrid(rows, cols) {
const container = document.getElementById("container");
const template = document.getElementById("grid-cell-template");
for (let c = 0; c < (rows * cols); c++) {
const cloneCell = template.content.cloneNode(true);
const newItem = cloneCell.querySelector(".grid-item");
newItem.textContent = (c + 1);
newItem.addEventListener('mouseenter', mouseEnterEventHandler);
newItem.addEventListener('mouseleave', mouseLeaveEventHandler);
newItem.addEventListener('mouseover', mouseOverEventHandler);
container.appendChild(newItem);
}
}
makeGrid(16, 16);
function mouseEnterEventHandler(event) {
event.currentTarget.style.backgroundColor = '#FF000022';
}
function mouseLeaveEventHandler(event) {
event.currentTarget.style.backgroundColor = '#FFFFFF';
event.target.style.borderColor = "#000000";
}
function mouseOverEventHandler(event) {
event.target.style.borderColor = "#00FF00";
}
<!-- language: lang-css -->
body {
font-size: 16px;
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--grid-cols: 16;
--grid-rows: 16;
}
#container {
display: grid;
grid-gap: 0.5em;
grid-template-columns: repeat(var(--grid-cols), 1fr);
grid-template-rows: repeat(var(--grid-rows), 1fr);
}
.grid-item {
padding: 1em;
border: 1px solid #000000;
text-align: center;
}
<!-- language: lang-html -->
<body>
<div id="container">
</div>
<template id="grid-cell-template">
<div class="grid-item"></div>
</template>
</body>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论