如何使用 JS 将样式修改为 HTML 元素(使用 CSS 在外部设置样式)?

IT技术 javascript html css
2021-01-30 23:43:10

所以当我点击<p>家庭class标签时,我希望它把颜色改为绿色,但它不起作用,我想知道为什么。点击注册正常(因为 console.log("test") 显示正常),但更改颜色的其余功能将不起作用。这是我的 css、html 和 js 代码(js 代码包含在 HTML 中,所以它不是外部文件或任何东西):

.greyRect {

  height:150px;
  width:1350px;

  background-color: #D3D3D3;


}
h1 {
  text-align: center;
}
h2 {
    text-align: center;
}
.home {



box-sizing: border-box;
width:80px;
height:35px;

line-height: 2;
  position: relative;
left:350;
  color:white;

}
.casinocraps {
  background-color: grey;

box-sizing: border-box;
width:120px;
height:35px;
text-align: center;
line-height: 2;
  position: relative;
left:460;
bottom:50;
  color:white;
}
.tictactoe {
  background-color: grey;
  box-sizing: border-box;
  width:90px;
  height:35px;
  text-align: center;
line-height: 2;
    position: relative;
left:600;
bottom:100;
    color:white;
}
.bingo {
  background-color: grey;
  box-sizing: border-box;
  width:80px;
  height:35px;
  text-align: center;
  line-height: 2;
    position: relative;
  left:700;
  bottom:150;
    color:white;
}
.concentration {
  background-color: grey;
  box-sizing: border-box;
  width:100px;
  height:35px;
  text-align: center;
  line-height: 2;
    position: relative;
  left:800;
  bottom:200;
    color:white;
}
footer {
  text-align: center;
    line-height: 4;
      position: relative;
  top:125;
  right:15;
  height:70px;
  width:1365px;

  background-color: #D3D3D3;
}
.border {
  height: 50px;
  width: 100px;
  border: 4px solid green;
  background-color: #555;
  position: relative;
  top:20;
  left:100;
}
.rectangle {
  height: 50px;
  width: 100px;
  background-color: #555;
  position: relative;
  top:50;
  left:100;
}
<html>
  <head>

    <meta charset="utf-8">

    <title></title>
      <link rel="stylesheet" type="text/css" href="cssForAss4.css">
  </head>
  <body>

<header class="greyRect" >
<h1>Assignment 1</h1>

<h2>Home Page</h2>
<nav>
<p class="home" onclick="selectHome()">
Home
</p>
<p class="casinocraps">

<b>Casino Craps</b>
</p>
<p class="tictactoe">

<b>Tic-Tac-Toe</b>
</p>
<p class="bingo">

<b>Bingo</b>
</p>
<p class="concentration">

<b>Concentration</b>
</p>
</nav>
<div class="border">
</div>
<footer >Footer</footer>

</header>

<script>
function selectHome() {
  console.log("test");

document.getElementsByClassName("home").style += "background-color:green;";


}
</script>
  </body>
</html>

3个回答

其他人建议.getElementsByClassName("home")[0],这是一个可怕的想法。

首先,.getElementsByClassName()返回所有匹配元素的节点列表。如果您只对第一个感兴趣,那么找到那个然后继续扫描更多匹配项然后丢弃除找到的第一个之外的所有匹配项是没有意义的,这就是此代码的作用。

其次,.getElementsByClassName()返回一个“活动”节点列表。这意味着每次您与列表交互时,都会再次搜索整个 DOM 以查找匹配项,确保您在列表中设置了最新的内容。这在动态添加和删除节点的应用程序中很有用,但这些用例并不常见。

仅供参考:.getElementsByTagName(), .getElementsByName(), 并且node.childNodes还返回活动节点列表。

所有这些前面提到的方法都可以追溯到 DOM API 的早期,当时它仍然是 Web 开发的“狂野西部”时代。它们都有二十多年的历史,今天有更好的替代品(即.querySelector(), .querySelectorAll(), .closest())。

当没有必要保持最新列表时,这.querySelectorAll()是要走的路。坦率地说,即使您确实需要更新的节点列表,您仍然最好.querySelectorAll()在需要更新列表的地方再次手动运行它。

这是一个很好的页面,讨论了这个问题,下面是它要说的内容:

如何考虑活动对象?

活动对象不直观。您可以将其视为延迟评估或惰性评估。访问其结果时,将重新计算活动对象的方法或属性。


但是,在这种情况下,我们甚至不需要节点列表,我们只需要一个节点。正确的解决方案是:

document.querySelector(".home");

.querySelector()扫描文档中与提供的选择器匹配的第一个元素,如果找到,则返回对该单个节点的引用。否则,它返回undefined

@zero298 为什么您认为添加从 DOM 查询中找到的元素创建一个数组并将其放置在节点列表中的额外步骤比仅执行 DOM 查询和创建节点列表要快?
2021-03-17 23:43:10
好的,这清除了我之前发表的评论,但让我感到困惑的是为什么使用Array.from()克隆实时收藏[...document.getElementsByClassName("test")]仍然比querySelectorAll(). 我猜它必须添加实时收集支持代码,然后立即将其拆除。
2021-03-30 23:43:10
很棒的解释。绝对应该在我的回答中建议 querySelector。谢谢指正。
2021-03-31 23:43:10
链接测试无效,因为静态节点列表创建一次,长度为零,然后从未更新,因此访问长度属性会返回错误的值。添加document.querySelectorAll('.test')到每个循环使其getElementsByTagName一些您假设“必须扫描文档”中的实现细节,您不知道。集合可能有一个在修改发生时更新的索引,对于大型集合来说可能querySelectorAll更快,这可能取决于文档中所有节点的索引。
2021-04-04 23:43:10
我在想实时收集代码可能比查找每个 DOM 元素并检查它是否与查询与每个元素匹配并只检查其类的开销更少,因为 querySelectorAll 可以使用更复杂的搜索进行搜索,而不仅仅是类名比较.
2021-04-07 23:43:10

.style 实际上是一个 js 对象,key 对应 css 属性。

正如阿达什所说

document.getElementsByClassName("home")[0].style.backgroundColor = "green"

编辑- 不要这样做。正如 Scott Marcus 所解释的那样,这非常糟糕。绝对应该使用 querySelector('.home') 来获取元素。

通常,如果属性具有像背景颜色这样的连字符,则将其转换为驼峰式大小写,即 backroundColor

查看MDN - HTMLElement.style

@ScottMarcus 有点跑题了,但是“一个活动节点列表......损害了性能”......?某处有证据吗?AFAIKquerySelector(All)本质上很慢,因为它们正在执行字符串搜索,而gEBCN从 DOM 搜索......
2021-03-15 23:43:10
@ScottMarcus 嗯...根据您的测试,看起来实时集合是无用的,只需在gEBXN每次需要集合或其成员时调用 a 即可实现相同的结果
2021-03-16 23:43:10
@Teemu 我同意。但是,如果您了解 DOM API 如何演变的历史,那就说得通了。.querySelectorAll()直到“实时”节点列表方法到位多年后才出现。这些现在已经过时了,不应该真正使用,除非是极端用例。这就是为什么你会发现我在整个 Stack Overflow 上都在呼吁使用它。;)
2021-03-25 23:43:10
@Teemu 通常用这种方式来解释拥有活动节点列表结果,但实际上,它们的功能不同。
2021-03-26 23:43:10
@AnuragSrivastava.getElementsByClassName()返回一个“节点列表”,而不是一个数组。
2021-04-05 23:43:10

像这样做:

function selectHome() {
  document.getElementsByClassName("home")[0].style.backgroundColor = "green";
}
<p class="home" onclick="selectHome()">
  Home
</p>