如何使用mouseover和mouseout事件来更改生成的divs/grid-items的背景颜色。

huangapple go评论78阅读模式
英文:

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(&quot;container&quot;);

function makeGrid(rows, cols) {
  container.style.setProperty(&#39;--grid-rows&#39;, rows)
  container.style.setProperty(&#39;--grid-cols&#39;, cols)
  for (c = 0; c &lt; (rows * cols); c++) {
    let cell = document.createElement(&quot;div&quot;);
    cell.innerText = (c + 1);
    container.appendChild(cell).className = &quot;grid-item&quot;;
  };
};
makeGrid(16, 16);
//Function to change background color of individual &quot;grid-item&quot; on hover.
document.querySelector(&#39;.grid-item&#39;).addEventListener(&#39;mouseover&#39;, overing);
document.querySelector(&#39;.grid-item&#39;).addEventListener(&#39;mouseout&#39;, outing);

function overing(ev) {
  ev.currentTarget.style.backgroundColor = &#39;red&#39;;
  console.log(&#39;mouseenter div&#39;);
}

function outing(ev) {
  ev.currentTarget.style.backgroundColor = &#39;white&#39;;
  console.log(&#39;mouseleave div&#39;);
}

<!-- 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 -->

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;

&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
  &lt;title&gt;Sketch-Book&lt;/title&gt;
  &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;etchStyles.css&quot; /&gt;
&lt;/head&gt;

&lt;body&gt;
  &lt;div id=&quot;container&quot;&gt;
  &lt;/div&gt;
&lt;/body&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;etchScript.js&quot;&gt;&lt;/script&gt;

&lt;/html&gt;

<!-- 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) =&gt; {
  ev.currentTarget.style.backgroundColor = &#39;red&#39;;
  //console.log(&#39;mouseenter div&#39;);
};

const outing = (ev) =&gt; {
  ev.currentTarget.style.backgroundColor = &#39;white&#39;;
  //console.log(&#39;mouseleave div&#39;);
}

const makeGrid = (rows, cols) =&gt; {
  container.style.setProperty(&#39;--grid-rows&#39;, rows)
  container.style.setProperty(&#39;--grid-cols&#39;, cols)
  for (c = 0; c &lt; (rows * cols); c++) {
    let cell = document.createElement(&quot;div&quot;);
    cell.innerText = (c + 1);
    cell.classList.add(&#39;grid-item&#39;);
    
    //  attach listeners here since you have a reference to the DOM node
    cell.addEventListener(&quot;mouseover&quot;, overing);
    cell.addEventListener(&quot;mouseout&quot;, 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 -->

&lt;section&gt;
    &lt;div id=&quot;container&quot;&gt;
    &lt;/div&gt;
&lt;/section&gt;

<!-- 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 -->

&lt;div class=&quot;grid&quot;&gt;
  &lt;div class=&quot;grid_element&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;grid_element&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;grid_element&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;grid_element&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;grid_element&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;grid_element&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;grid_element&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;grid_element&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;grid_element&quot;&gt;&lt;/div&gt;
&lt;/div&gt;

<!-- 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(&quot;container&quot;);
  const template = document.getElementById(&quot;grid-cell-template&quot;);
  for (let c = 0; c &lt; (rows * cols); c++) {
    const cloneCell = template.content.cloneNode(true);
    const newItem = cloneCell.querySelector(&quot;.grid-item&quot;);
    newItem.textContent = (c + 1);
    newItem.addEventListener(&#39;mouseenter&#39;, mouseEnterEventHandler);
    newItem.addEventListener(&#39;mouseleave&#39;, mouseLeaveEventHandler);
    newItem.addEventListener(&#39;mouseover&#39;, mouseOverEventHandler);
    container.appendChild(newItem);
  }
}
makeGrid(16, 16);

function mouseEnterEventHandler(event) {
  event.currentTarget.style.backgroundColor = &#39;#FF000022&#39;;
}

function mouseLeaveEventHandler(event) {
  event.currentTarget.style.backgroundColor = &#39;#FFFFFF&#39;;
  event.target.style.borderColor = &quot;#000000&quot;;
}

function mouseOverEventHandler(event) {
  event.target.style.borderColor = &quot;#00FF00&quot;;
}

<!-- 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 -->

&lt;body&gt;
  &lt;div id=&quot;container&quot;&gt;
  &lt;/div&gt;
  &lt;template id=&quot;grid-cell-template&quot;&gt;
  &lt;div class=&quot;grid-item&quot;&gt;&lt;/div&gt;
  &lt;/template&gt;
&lt;/body&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年4月10日 23:18:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/75978353.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定