简体   繁体   English

设置内部样式或操作内部样式的正确方法<style> sheet with JavaScript/jQuery

[英]The right way to set an internal style or to manipulate the internal <style> sheet with JavaScript/jQuery

Let say I have this external "style.css" sheet: 假设我有这个外部的“ style.css”表:

p.class1 {
    background-color: blue;
}

And my HTML content is this: 我的HTML内容是这样的:

<head>
    <link rel="stylesheet" type="text/css" href="style.css" />
    <style>
        p.class1 {
            background-color: red;
        }
        p.class2 {
            background-color: green;
        }
    </style>
</head>
<body>
    <p class="class1">This is the first paragraph..</p>
    <p class="class2">This is the second paragraph..</p>
</body>

For full source code example, visit this link! 有关完整的源代码示例, 请访问此链接! When I try this .css() code: 当我尝试此.css()代码时:

$('p.class1').css("background-color", "green");

It will set the p.class1 's background-color inline, like: 它将设置p.class1background-color内联,例如:

<p class="class1" style="background-color: rgb(0, 255, 0);">

When I unset it with .css("background-color", "") , the inline style will be gone and the background will set back to red internally. 当我使用.css("background-color", "")取消设置时,内联样式将消失,背景将在内部重新设置为red What I want is to set the internal p.class1 style to "" or to remove it when I unset, so the background will become blue externally.. Is there a right way to manipulate the internal <style> ? 我想要的是将内部p.class1样式设置为""或者在取消设置时将其删除,因此背景在外部将变为blue 。是否有正确的方法来处理内部<style>

Keep note, I don't want to remove the internal <style> element to perform the external p.class1 style if it will also affect the style for p.class2 or any attempt that will affect the style of the other in that element. 请注意,如果它也会影响p.class2的样式或任何会影响该元素中其他样式的尝试,则我不想删除内部的<style>元素以执行外部p.class1样式。

It is possible, but you will need to use CSSOM to manipulate the style sheet. 可以,但是您将需要使用CSSOM来处理样式表。 This is not a jQuery thing, per se, though jQuery can help in the first stages. 从本质上讲,这并不是jQuery,尽管jQuery在最初阶段可以提供帮助。

The first step is getting to the internal <style> element in the DOM . 第一步是进入DOM中的内部<style>元素 The easiest way to do that would be to set an id attribute on it in your HTML and then use document.getElementById() to grab the element on the JavaScript side, but any method that can pick out that individual element will work. 最简单的方法是在HTML中为其设置id属性,然后使用document.getElementById()来获取JavaScript端的元素,但是任何可以挑选出该单独元素的方法都可以使用。 Assuming you use an id , the HTML might look like this: 假设您使用id ,则HTML可能如下所示:

<style id="internalStylesheet">
    p.class1 {
        background-color: red;
    }
    p.class2 {
        background-color: green;
    }
</style>

...and then in the JavaScript side... ...然后在JavaScript方面...

var styleElem = document.getElementById('internalStylesheet');

Note that if you use jQuery to do this, you need the actual element, not the jQuery collection returned by jQuery() . 请注意,如果使用jQuery来执行此操作,则需要实际的元素, 而不是 jQuery()返回的jQuery集合。

Once you have the element, you can get into the CSSOM side through its .styleSheet property. 有了元素后,就可以通过其.styleSheet属性进入CSSOM端。 Once you're in the stylesheet, the next step is to find the exact rule you want . 进入样式表后, 下一步就是找到所需的确切规则 CSS rules don't have unique IDs like DOM nodes can, so your only option is to search the list: CSS规则不像DOM节点那样具有唯一的ID,因此您唯一的选择是搜索列表:

var desiredRule = null;
for (var i = 0; i < styleElem.styleSheet.cssRules.length; i += 1) {
    if (styleElem.styleSheet.cssRules[i].selectorText === "p.class1") {
        desiredRule = styleElem.styleSheet.cssRules[i];
        break;
    }
}

Keeping a reference to the rule you want is a good idea if you will have to change it many times. 如果您需要多次更改,则保持引用您想要的规则是一个好主意。 That way you won't have to repeat this search process every time you want to change the rule. 这样,您就不必每次想更改规则时都重复此搜索过程。

Once you have the rule you want, manipulating the rule is a lot like manipulating inline styles . 有了所需的规则后, 操作规则就非常类似于操作内联样式 For actually removing properties on the rule, I recommend something like this: 为了实际删除规则上的属性,我建议类似以下内容:

desiredRule.removeProperty("background-color");

Note that because of the inefficiences involved in searching the list, I don't recommend you do this unless the rule will affect many elements on the page, and it might have to be changed often . 请注意,由于搜索列表效率低下, 因此不建议您执行此操作,除非该规则会影响页面上的许多元素,并且该规则可能需要经常更改 If that fits your use case, then it can be very fast, especially if you keep cached references to the rules you need to change. 如果适合您的用例,那么它会非常快,尤其是如果您保留对需要更改的规则的引用的缓存。 But this doesn't actually describe many common use cases, and when it doesn't, it's troublesome enough that it could be called premature optimization. 但这实际上并没有描述许多常见的用例,而如果没有,则很麻烦,可以将其称为过早优化。

The only way to have a conflicting external CSS file override the inline <style> element without changing your HTML file at all, based on the code in your question, is by adding the !important hack to your external CSS file: 根据问题中的代码,有冲突的外部CSS文件覆盖内联<style>元素而根本不更改HTML文件的唯一方法是在外部CSS文件中添加!important hack:

p.class1 {
    background-color: blue !important;
}

But this is a hack, is bad, and should not be done, because you are throwing away the "Cascading" part of CSS when you use !important ; 但这是一个hack,很不好,也不应该这样做,因为使用!important时,您将丢弃CSS的“层叠”部分。 instead, you should just remove p.class1 { background-color: red; 相反,您应该只删除p.class1 { background-color: red; from your inline <style> element, or replace its value with blue , since you don't want red to be used. 从您的内联<style>元素中,或将其值替换为blue ,因为您不希望使用red

Instead, you should have your external stylesheet load after the <style> element. 相反,您应该在<style>元素之后加载外部样式表。 This can be done by simply flipping their order: 这可以通过简单地翻转顺序来完成:

<head>
    <style>
        p.class1 {
            background-color: red;
        }
        p.class2 {
            background-color: green;
        }
    </style>
    <link rel="stylesheet" type="text/css" href="style.css" />
</head>

This will override the <style> 's p.class1 value of red with the CSS file's p.class1 value of blue. 这将覆盖<style>p.class1red值和CSS文件的p.class1的蓝色值。

Alternatively, if you add a wrapper/container element around your <p> elements, you can set your external CSS file to have a more specific selector, which would override the less specific selector in the <style> element. 另外,如果在<p>元素周围添加包装器/容器元素,则可以将外部CSS文件设置为具有更具体的选择器,该选择器将覆盖<style>元素中的次要选择器。 Something like: 就像是:

HTML: HTML:

<div class="wrapper">
    <p class="class1">This is the first paragraph..</p>
    <p class="class2">This is the second paragraph..</p>
</div>

CSS: CSS:

.wrapper p.class1 {
    background-color: blue;
}

Since the selector .wrapper p.class1 is more specific than the inline selector p.class1 , it will normally override the inline selector. 由于选择器.wrapper p.class1比内联选择器p.class1更具体,因此它通常会覆盖内联选择器。

Firstly, there is no real difference between the external stylesheet and the internal <style> tag. 首先,外部样式表和内部<style>标记之间没有真正的区别。 The one defined later will take effect. 稍后定义的那个将生效。 I presume you have included your CSS before your <style> , so this part of the CSS will never work: 我假设您在<style>之前包含了CSS,所以CSS的这一部分将永远无法使用:

p.class1 {
    background-color: blue;
}

Secondly, all inline styles will overwrite any CSS, so your jQuery .css() calls will always work. 其次,所有内联样式都将覆盖任何CSS,因此您的jQuery .css()调用将始终有效。 Setting it to an empty string will remove that inline style property, so it will naturally fall back to the lower-priority stylesheets - in your case, 将其设置为空字符串将删除该内联样式属性,因此它自然会退回到优先级较低的样式表-在您的情况下,

<style>
p.class1 {
    background-color: red;
}
...
</style>

Thirdly, no there is no way to manipulate the internal <style> dynamically. 第三,没有办法动态地操作内部<style> So if you want your p.class1 to revert to blue after inline styles are removed, you should either: 因此,如果希望在删除内联样式后将p.class1恢复为蓝色,则应该执行以下任一操作:

  1. Declare your <link href="external.css"> after your <style> , which would then cancel out your p.class1 internal style. <style>之后声明您的<link href="external.css"> <style> ,这将取消您的p.class1内部样式。 (This then begs the question of: why would you want to include that property for it to be cancelled out then?) (然后提出了一个问题:您为什么要包括该属性以使其随后被取消?)

OR 要么

  1. Just use CSS and avoid internal styles. 只需使用CSS并避免使用内部样式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM