使用 JavaScript 动态应用 CSS

Posted

技术标签:

【中文标题】使用 JavaScript 动态应用 CSS【英文标题】:Apply CSS dynamically with JavaScript 【发布时间】:2016-06-08 10:11:17 【问题描述】:

使用 JavaScript 将样式动态(即样式的值在运行时创建)应用于 HTML 元素的好方法是什么?

我正在寻找一种将 javascript 小部件(JS、CSS 和标记)打包到单个组件(基本上是一个对象)中的方法。这个想法是让组件封装样式(因此用户有一个很好的 API 来修改它,而不是直接修改 CSS 并间接应用更改的更紧密耦合的方法)。问题是单个 API 调用可能意味着对多个样式元素的更改。

我这样做的方法是构建 CSS 并将style 属性设置为适当的元素(很可能使用 ID 来避免将更改应用于标记的其他区域)。这是一个好的解决方案吗?有没有更好的方法?

【问题讨论】:

我会用 JS 创建 css 规则,内联样式解决方案意味着当您需要对一组元素进行更改时,您必须更改所有样式属性。 【参考方案1】:

使用 Jquery

使用 css() 函数将样式应用于传递包含样式的对象的现有元素:

var styles = 
  backgroundColor : "#ddd",
  fontWeight: ""
;
$("#myId").css(styles);

您也可以同时应用一种样式:

$("#myId").css("border-color", "#FFFFFF");

原版JS:

var myDiv = document.getElementById("#myId");
myDiv.setAttribute("style", "border-color:#FFFFFF;");

使用 Css:

您还可以使用单独的 css 文件,其中包含类中所需的不同样式,并根据您向元素添加或删除这些类的上下文。

在您的 css 文件中,您可以拥有类似

的类
.myClass 
    background-color: red;


.myOtherClass 
    background-color: blue;

再次使用jquery,向元素添加或删除类,可以使用

$("#myDiv").addClass('myClass');

$("#myDiv").removeClass('myClass');

我认为这是一种更简洁的方式,因为它将您的风格与逻辑分开。但是如果你的 css 的值取决于服务器返回的值,那么这个解决方案可能很难应用。

【讨论】:

酷,我喜欢这个。但是,我想避免使用预定义的 CSS,因为它需要用户知道小部件的内部结构,这会破坏封装。谢谢! 在 vanila js 中有没有等价的 addClass 和 removeClass 方法? 好的。我在这里找到了我的问题的答案。 developeracademy.io/blog/…【参考方案2】:

我这样做的方法是构造 CSS 并将 style 属性设置为适当的元素。例如:

var div = document.createElement('div');
div.setAttribute("style", "color: blue, margin-top:5px");
document.body.appendChild(div);

此代码将创建一个样式为color: blue, margin-top:5px 的新div 元素并将其附加到页面。

【讨论】:

"我的做法是构建 CSS 并将样式属性设置为适当的元素" 我宁愿使用 DOM 元素的style 属性而不是setAttribute(),类似于:div.style = 'color: blue, margin-top:5px' 这些不都一样吗? OP 是关于“这是一个好的解决方案吗?有更好的方法吗?”不是如何添加内联样式。 Mozilla 声明“设置样式请注意,不应通过将字符串直接分配给样式属性来设置样式(如 elt.style = "color: blue;" ),因为它被认为是读取-只是因为 style 属性返回一个 CSSStyleDeclaration 对象,它也是只读的。” -developer.mozilla.org/en-US/docs/Web/API/htmlElement/style【参考方案3】:

使用 Vanilla JS 你可以做这样的事情。

如果你想将一个名为 animateCSS 类 添加到一个 ID 为 circle 的元素中,可以这样做。

var circle = document.getElementById("circle");
circle.classList.add('animate');

您可以像这样删除类。

circle.classList.remove('animate');

【讨论】:

请记住糟糕的 IE 支持。 developer.mozilla.org/en-US/docs/Web/API/Element/classList【参考方案4】:

由于您还询问是否有更好的方法并且您构建了一个组件,我建议您使用前端 javascript 框架构建这样一个组件,因为它们使动态样式非常容易开箱即用 以Vuejs、Reactjs为例

`      
import React, Component from 'react'
import styled from 'styled-jss'
const Circle = styled('div')(
  position: 'absolute',
  width: 50,
  height: 50,
  borderRadius: '50%',
  background: (props) => (
    /* Generates a random or based on props color */
  ),
  transform: (props) => (
    /* Generates a random or based on props transform for  positioning */
  )
)
class Demo extends Component 
  componentDidMount() 
    this.tick()
  
  tick = () => 
    requestAnimationFrame(() => 
      this.setState(/* Some new state */, this.tick)
    )
  
  render() 
    return (
      <div>
        [...Array(amount)].map(() => <Circle />)
      </div>
    )
  

`

【讨论】:

【参考方案5】:

我可能会误解您的问题,但听起来您要求的是简单的架构模式。您想要一些能让使用您的小部件的人更轻松地将其更改为他们的规格的东西吗?

如果是这种情况,那么我不知道有什么特殊模式可以在不使用 CSS 的情况下做到这一点。

我可以告诉你,我发现最容易使用的“小部件”确实有单独的 CSS 文件。我发现根据我的需要修改它们相当简单。我认为这是因为将 CSS 与 HTML 和 Javascript 结合使用的结构已经是一种不错的简单模式。我不知道还有什么更好的,尤其是考虑到人们已经非常熟悉 HTML/CSS 关系。

【讨论】:

问题的思路是用 JS 创建可以相互独立的组件。虽然您所说的 HTML 和 CSS 是标准的绝对正确,但这更多是关于以增强内聚和减少耦合的方式包装事物。像这样打包,小部件的用户不需要知道为了构造小部件而做了什么样式,这有一个额外的好处是他们不需要知道多个 API 来与之交互。 我想你想使用 .attr('style', '...') 或 .css('width, etc', '0px,etc..") 然后。

以上是关于使用 JavaScript 动态应用 CSS的主要内容,如果未能解决你的问题,请参考以下文章

动态 Javascript 源数据 - DataTable

如何在 JavaScript 中动态创建 CSS 类并应用?

使用 javascript/jquery 动态调整画布窗口的大小?

如何在 react js 中动态生成 javascript 文件?

如何使用动态目录中的 webpack 要求 JavaScript

多个动态音频播放器应用于 HTML/JavaScript 中的字典