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

Posted

技术标签:

【中文标题】如何使用 JS 将样式修改为 HTML 元素(使用 CSS 外部样式)?【英文标题】:How to modify style to HTML elements (styled externally with CSS) using JS? 【发布时间】:2019-07-23 22:14:17 【问题描述】:

所以当我点击家庭类的<p> 标签时,我希望它改变 颜色为绿色,但它不起作用,我知道为什么。点击注册很好 (因为 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>

【问题讨论】:

document.getElementsByClassName("home").style.backgroundColor = "green" 可以参考this document.getElementsByClassName("home") 返回array 如果您不使用内联 javascript,您可以使用 this 值仅对单击的元素进行更改。 【参考方案1】:

其他人建议.getElementsByClassName("home")[0],这是一个糟糕的主意。

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

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

仅供参考:.getElementsByTagName().getElementsByName()node.childNodes 也会返回活动节点列表。

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

如果不需要更新列表,.querySelectorAll() 是您的最佳选择。坦率地说,即使您确实需要更新的节点列表,您最好还是使用.querySelectorAll(),然后在需要更新列表的地方再次手动运行它。

这是一个讨论这个问题的good page,它是这样说的:

如何看待活体?

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


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

document.querySelector(".home");

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

【讨论】:

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

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

正如阿达什所说

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

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

一般来说,如果一个属性有一个像背景颜色这样的连字符,你可以把它转换成驼峰式,即backroundColor

查看MDN - HTMLElement.style

【讨论】:

@AnuragSrivastava .getElementsByClassName() 返回一个“节点列表”,而不是一个数组。 @ScottMarcus 有点跑题了,但是“一个活动节点列表......会损害性能”......?有什么证据吗? AFAIK querySelector(All) 本质上很慢,因为它们正在执行字符串搜索,而 gEBCN 从 DOM 搜索... @Teemu 通常用这种措辞来解释拥有活动节点列表的结果,但实际上,它们的功能不同。 @ScottMarcus 嗯 ...根据您的测试,看起来实时收藏没有用,每次您需要收藏或成员时只需调用 gEBXN 即可达到相同的结果。 @Teemu 我同意。但是,如果您了解 DOM API 如何演变的历史,那是有道理的。 .querySelectorAll() 直到“实时”节点列表方法到位多年后才出现。这些现在已经过时了,不应该真正使用,除了极端用例。这就是为什么你会发现我在 Stack Overflow 上呼吁使用它。 ;)【参考方案3】:

这样做:

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

<p class="home" onclick="selectHome()">
  Home
</p>

【讨论】:

以上是关于如何使用 JS 将样式修改为 HTML 元素(使用 CSS 外部样式)?的主要内容,如果未能解决你的问题,请参考以下文章

HTML JS动态设置CSS样式

JS修改CSS设置的样式

通过JS动态的修改HTML元素的样式和增添标签元素等

原生JS获取HTML样式并修改

js如何修改样式?

web学习记录-JS-12