css 使用JavaScript高效应用样式(最佳实践?)

qyswt5oh  于 2023-01-27  发布在  Java
关注(0)|答案(4)|浏览(165)

我正在为Greasemonkey/Tampermonkey编写用户脚本(并在此过程中学习JS)。这是一个讨论论坛(/bulletin board),其中每个帖子根据一些标准被分配六种可能的样式之一,帖子包含带有用户名的div,带有时间戳的div,带有头像和用户信息的div,以及用于内容本身的div(其可以包括或可以不包括引用DIV)。
为了简单起见,我们将这些样式命名为redbluegreenyellowblackwhite。(* 注意:不仅仅是颜色--每种风格都有自己独特的"一切"价值,甚至边距、填充和其他布局。*)
然后,通过调用样式更改函数(例如makeRed(post)makeGreen(post))来设置每个帖子的样式。
然后,这些函数中的每一个看起来都像这样:

const makeRed = post => {
    let author = post.querySelector(".author");
    author.style.fontSize = "...";
    author.style.fontFamily = "...";
    author.style.backgroundColor = "...";
    author.style.padding = "...";
    author.style.borderRadius = "...";
    author.style.margin = "...";
    author.style.flex = "...";
    // ...

    let date = post.querySelector(".date");
    date.style.fontFamily = "...";
    date.style.fontSize = "...";
    date.style.color = "...";
    date.style.margin = "...";
    date.style.flex = "...";
    // ...

    let avatarInfo = post.querySelector(".infoBox");
    avatarInfo.style.backgroundColor = "...";
    avatarInfo.style.fontSize = "...";
    // ...

    let content = post.querySelector(".content");
    content.style.borderColor = "...";
    content.style.backgroundImage = "...";
    // ...

    let quote = content.querySelector(".quote");
    if (quote) {
        // Lots of quote styling here
    } else {
        // Lots of quote-less styling here
    }
}

这些函数中的每一个都以类似的方式包含了明显更多的代码行,我只是将它们从这个问题中删除以节省一些空间。
所以,对于这个问题:

    • 有没有什么方法可以写得更简洁/优雅?**

我想很难避免每个样式属性都有一行,但至少在CSS中它看起来更好一点,IMO。创建一个CSS文件并以某种方式用JavaScript导入它是否是一个更好的实践(如何?),或者这一长串*element*.style.*property* = "..."实际上是要走的路?或者有更好的方法吗?你会怎么做?
另外,我是JS的新手,所以如果你有任何其他的建议(与我的代码有关或没有),请让我知道!
非常感谢!:-)
编辑:
我被要求包含HTML结构。一个典型的帖子是这样的:

<div class="post">
  <div class="author">Author McAuthorson</div>
  <div class="date">2021.01.10 01:23</div>
  <div class="infoBox">
    <div class="avatar"><img src="..." /></div>
    <div class="userinfo">User info here</div>
  </div>
  <div class="content">
    <div class="quote">Some quote by some guy here</div>
    Some original text by McAuthorson here.
  </div>   
</div>
plicqrtu

plicqrtu1#

一种方法是使用CSS注入并向您希望更改的元素添加/删除类。
下面是一个例子

const makeRed = post => post.classList.add('red')

const css = `
 .red > .author {
    background: red;
    font-weight: bold;
 }
 .red > .date {
    font-weight: bold;
 }
`

// inject the style first
document.head.insertAdjacentHTML("beforeend", `<style>${css}</style>`)

// call the func. to add the class then
setTimeout(() => makeRed(document.querySelector("#test")), 1000)
<div class="post" id="test">
  <div class="author">Author McAuthorson</div>
  <div class="date">2021.01.10 01:23</div>
  <div class="infoBox">
    <div class="avatar"><img src="..." /></div>
    <div class="userinfo">User info here</div>
  </div>
  <div class="content">
    <div class="quote">Some quote by some guy here</div>
    Some original text by McAuthorson here.
  </div>
</div>
k0pti3hp

k0pti3hp2#

您可以动态创建CSS并注入它,如下所示:

function addStyle(styleString) {
    const style = document.createElement('style');
    style.textContent = styleString;
    document.head.append(style);
}

addStyle(`
    .red .author {
        font-size: 12px;
        font-family: 'Times New Roman', Times, serif;
        background-color: red;
        padding: 10px;
        border-radius: 5px;
        margin: 10px;
        flex: 1;
    }

    .red .date{
        font-family: "...";
        font-size: "...";
        color: "...";
        margin: "...";
        flex: "...";
    }

    .red ...{
        ...
    }
    /* similarly for other colors */

    .blue {
        color: blue;
    }
`);

function removeStyles(post) {
    //remove all the colors
    post.classList.remove('red', 'green', 'blue', ...);
}

const makeRed = post => {
    removeStyles(post);
    post.classList.add('red');
}

const makeGreen = post => {
    removeStyles(post);
    post.classList.add('green');
}
<div class="post">
        <div class="author">Author McAuthorson</div>
        <div class="date">2021.01.10 01:23</div>
        <div class="infoBox">
            <div class="avatar"><img src="..." /></div>
            <div class="userinfo">User info here</div>
        </div>
        <div class="content">
            <div class="quote">Some quote by some guy here</div>
            Some original text by McAuthorson here.
        </div>
    </div>
4jb9z9bj

4jb9z9bj3#

基本上,不推荐使用JS操作CSS值,除非整个解决方案依赖于CSS值随JS一起动态变化(即使这样,也有更优雅、更高效的解决方案)。
当使用JS时,你总是需要考虑事情实际上需要运行多长时间,以及它可能会导致什么冲突。使用你的方法,如果你遇到问题(就像你现在这样),你将面临一些繁重的未来开发工作,并且必须改变一些东西,或者如果你的其他操作与此冲突。
正如其他人所说,只需使用CSS最简单的方法是定义6个唯一的CSS类和n个元素之间的共享类(如果需要的话)。然后,当一个帖子提交到您的公告牌上时,BACKEND代码为帖子分配一个类名(或ID,或其他表示此帖子意思为“post-style__variant-1”的内容),它相对于类名(也可以相对于行中的其他内容)。
额外的提示是考虑变量。基本上你的公告栏帖子是静态的,但是公告栏帖子可以有6种不同的样式,因此在这一点上你的公告栏帖子可以有6种基于6个不同类名的变量。如果你建立你的帖子提交系统时考虑到变量,你将来就可以扩展它。对于CSS/SCSS结构,你可以做下面的事情
中央支助系统

.post__variant-1 {
   color: red;
}

.post__variant-2 {
   color: green;
}

.post__variant-3 {
   color: blue;
}

^顺便说一句,不推荐,写起来很糟糕,维护起来也很糟糕。根据你正在学习的东西,我建议你尽快进入SCSS。它会让你的生活轻松很多。例如

.post__variant {

    display: block;

    &-1 {
        @extend .post__variant;

        color: red;
    }

    &-2 {
        @extend .post__variant;

        color: green;
    }

    &-3 {
        @extend .post__variant;

        color: blue;
    }
}

顺便说一下,SCSS是一个预处理器。你在本地编写SCSS,然后运行一个命令,这个命令获取SCSS文件,通过预处理器运行它们,然后预处理器把SCSS作为CSS输出。所以所有的东西都被重写成浏览器理解的语言。所以上面的SCSS会被预处理成

.post__variant, .post__variant-3, .post__variant-2, .post__variant-1 {
  display: block;
}
.post__variant-1 {
  color: red;
}
.post__variant-2 {
  color: green;
}
.post__variant-3 {
  color: blue;
}

希望这一切都是有意义的。我曾经钻研公告牌开发当我开始的时候,这是一个很好的和相当标准的切入点。另外,不要理会任何人叫你出来(或负面批评你),因为你想出了一个解决方案。你的解决方案可能不是最好的,但开发人员总是在学习。一旦你认为你是最好的,就没有其他东西要学了。恭喜你,你已经变成了一个地下室的开发人员,习惯于做那些垃圾的遗留项目,不管你决定和哪家公司合作,他们都会忽视你。你留下来只是为了维护那些垃圾遗留项目。

fquxozlt

fquxozlt4#

您可以使用辅助函数。
[2023年]请参阅此Stackblitz snippet

changeStyle(document.querySelector(".sample"), {
  fontSize: "12px",
  fontFamily: "verdana, arial",
  lineHeight: "15px",
  fontWeight: "bold",
  textAlign: "center",
  backgroundColor: "#fffff0",
  color: "green",
  height: "1.2rem"
});

function changeStyle(forElement, props) {
  Object.entries(props).forEach( ([key, value]) => forElement.style[key] = value);
}
<div class="sample">Sample</div>

或者在注入的自定义css样式表中创建/修改css
一个二个一个一个

相关问题