【问题标题】:Js function working with every item in htmlJs函数处理html中的每个项目
【发布时间】:2020-09-24 10:23:45
【问题描述】:

这是我的问题: 我为一个更大的项目编写了这段代码

document.getElementById("swt").onclick = function() {
    if (this.innerText === "Off") {
        this.innerText = "On";
        document.getElementById("light-status").src="assets/img/lighting_filled.svg";
    } else {
        this.innerText = "Off";
        document.getElementById("light-status").src="assets/img/lighting_outline.svg";
    }

    document.getElementById("light-status").classList.toggle("light-on");
    document.getElementById("card-button").classList.toggle("card-on");
}
body {
    margin: 0;
    height: 100%;
    width: 100%;
    background-color: dimgray;
    font-family: 'Josefin Sans', sans-serif;
}

.grid-container {
    display: grid;
    grid-template-columns: minmax(256px, 20%) auto;
    grid-template-rows: auto 64px;
    height: 100vh;
}

.main-space-container {
    grid-column: 2;
    grid-row: 1;
    background-color: rgba(0,0,0,0.7);
    overflow-x: auto;
    overflow-y: hidden;
}

.floor-container, .system-container {
    display: flex;
    justify-content: flex-start;
    padding: 10px;
}

.card-container {
    margin: 10px;
    padding: 10px;
    max-width: 256px;
    max-height: 256px;
}

.card-title {
    font-size: 24px;
    font-weight: 400;
    padding-left: 5px;
    margin-top: 4px;
    margin-bottom: 2px;
    color: rgba(255,255,255,0.87);
}

.button-container {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: repeat(2, 1fr);
}

.card-button {
    margin: 5px;
    height: 96px;
    width: 96px;
    background-color: rgba(50,50,50,0.7);
    border-radius: 8px;
    transition: linear 0.2s;
    cursor: pointer;
}

.card-on {
    background-color: rgba(255,255,255,0.7);
    transition: linear 0.2s;
}

/* .card-button:hover {
    background-color: rgba(255,255,255,0.7);
    transition: linear 0.2s;
} */

.feed-container {
    padding-top: 20px;
}

.feed-text  {
    padding-top: 10px;
    padding-bottom: 10px;
    color: rgba(255,255,255,0.87);
}

/* alternative classes */

.large {
    height: 202px;
    width: 202px;
    border-radius: 8px;
    grid-column: 1 / span 2;
    grid-row: 1 / span 2;
}

.four-tile {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: repeat(2, 1fr);
}

.card-icon {
    grid-column: 1;
    grid-row: 1;
    filter: opacity(0.7);
    width: 75%;
    margin: auto;
}

.percentage {
    grid-column: 2;
    grid-row: 1;
    display: flex;
    justify-content: center;
    align-items: center;
    color: rgba(255,255,255,0.7);
}

.name {
    grid-column: 1 / span 2;
    display: flex;
    justify-content: center;
    align-items: center;
    color: rgba(255,255,255,0.7);
}

.card-on > .name, .card-on > .percentage {
    color: rgba(0,0,0,0.87);
    transition: linear 0.2s;
}

.card-on > .card-icon {
    filter: invert(87%);
    transition: linear 0.2s;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Project 0</title>
    <link rel="stylesheet" href="assets/css/floor.css">
</head>
<body>

    <div class="grid-container">

        <!-- Start main -->
            <div class="system-container">
                <div class="card-container">
                    <h3 class="card-title">Lights</h3>
                    <div class="button-container">
                        <div class="card-button four-tile" id="card-button">
                            <img class="card-icon" id="light-status" src="assets/img/lighting_outline.svg">
                            <div class="percentage" id="swt">Off</div>
                            <div class="name">GF</div>
                        </div>
                        <div class="card-button four-tile" id="card-button">
                            <img class="card-icon" id="light-status" src="assets/img/lighting_outline.svg">
                            <div class="percentage" id="swt">Off</div>
                            <div class="name">FF</div>
                        </div>
                        <div class="card-button"></div>
                        <div class="card-button four-tile">
                            <img class="card-icon" id="sched-off" src="assets/img/clock_modern_outline.svg">
                            <div class="name">Scheduler</div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <!-- End main -->

    </div>

    <!-- start script section -->

    <script src="assets/vendor/main-card.js"></script>
    
    <!-- end script section -->

</body>
</html>

并且 JS 函数有效,但仅适用于它找到的具有指定 ID 的第一个元素。我知道这是使用getElementById 的预期行为,但我进行了一些搜索,但我找不到使该函数与作为该 ID 的每个元素一起工作的方法。 有人可以帮忙吗?

更新:我以这种方式调整了代码,按照建议添加了一个类(称为 swt)而不是 ID,并在 div 中添加了 data-status="true"(或 false);但它给我一个错误,说 btn[i] 未定义并且 getAttribute 无法使用它,但 btn[i].nodeName 给我“DIV”作为反馈,所以它不是未定义的(或者我理解错误?)

var btn = document.querySelectorAll(".swt");

for (var i = 0; i < btn.length; i++) {
    btn[i].addEventListener("click", function() {
        const state = btn[i].getAttribute("data-status")
        if (state === "true") {
            btn.innerText = "On";
        } else if (state === "false") {
            btn.innerText = "Off";
        } else {
            btn.innerText = "Not Connected";
        }

        btn.parentNode.querySelector("img.light-status").classList.toggle("light-on");
        btn.parentNode.classList.toggle("card-on");
    })
}

【问题讨论】:

  • 是否可以将 jQuery 添加到您的页面?这会让事情变得容易一些。
  • Id 必须是唯一的。
  • 这能回答你的问题吗? Get multiple elements by Id
  • 首先。同一个id 在 HTML 中不得出现多次。是否可以将使用id 的部分更改为class
  • 您不应该有多个具有相同 ID 的元素;您应该为所有应该使用该函数的元素分配一个特定的属性 (data-whatever) 或类,然后使用 document.querySelectorAll() 选择它们并遍历所有返回的元素以添加 onClick 事件处理程序。

标签: javascript html css dom event-handling


【解决方案1】:

试试

 <div class="card-button four-tile" id="card-button">
  <img class="card-icon" class="light-status" src="assets/img/lighting_outline.svg">
  <div class="percentage" class="swt">Off</div>
  <div class="name">GF</div>
</div>

还有 JS

document.querySelectorAll(".card-button .swt").map(btn => {
  btn.onclick = function() {
      const state = btn.getAttribute("data-state")
      if (state === "true") {
          btn.innerText = "On";
          btn.setAttribute("data-state", "false")
          btn.parentNode.querySelector("img.light-status").src="assets/img/lighting_filled.svg";
      } else {
          btn.innerText = "Off";
          btn.setAttribute("data-state", "true")
          btn.parentNode.querySelector("img.light-status").src="assets/img/lighting_outline.svg";
      }
  
      btn.parentNode.querySelector("img.light-status").classList.toggle("light-on");
      btn.parentNode.classList.toggle("card-on");
  }
}

【讨论】:

  • 感谢您的回答,我正在尝试您的解决方案,但我不明白“数据状态”的来源。是我必须输入 html 还是 btn.getAttribute 的标准状态?因为如果我按原样使用它,它在这里不起作用。您还错过了 js 末尾的“)”;)
  • data-* 属性是在 HTML5 中添加的自定义属性。在 HTML4 中,我不知道它是否存在。简单关于数据属性You can read here
  • @ParanoidNemo 对不起。我没有测试。
【解决方案2】:

好的,正如@Tomalak 所暗示的那样,使用 jQuery 解决了,因为我对 JS 无处可去。 这是我的解决方案:

jQuery

$(".swt").click(function() {
var status = $(this).attr("data-status");
if (status === "true") {
    $(this).html("Off");
    $(this).attr("data-status", "false");
    $(this).prev().attr("src", "assets/img/lighting_outline.svg");
    $(this).parent().toggleClass("card-on");
} else if (status === "false") {
    $(this).html("On");
    $(this).attr("data-status", "true");
    $(this).prev().attr("src", "assets/img/lighting_filled.svg");
    $(this).parent().toggleClass("card-on");
} else {
    $(this).html("None")
}
console.log(status)
})

HTML

<div class="card-button four-tile">
    <img class="card-icon light-status" src="assets/img/lighting_outline.svg">
    <div class="percentage swt" data-status="false">Off</div>
    <div class="name">GF</div>
</div>

也许不是很优雅,但现在可以了。仍然有兴趣看看是否有人作为一个优秀的 JS 来解决这个问题,因为为什么不呢,我很乐意学习新的东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-05
    相关资源
    最近更新 更多