使用 JavaScript / jQuery 动态修改 CSS 类属性值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7125453/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 00:57:31  来源:igfitidea点击:

Modifying CSS class property values on the fly with JavaScript / jQuery

javascriptjquerycssdynamicproperties

提问by JPN

I've run into a unique situation that I have so far been unable to find a solution for: dynamically assigning a value to a CSS style. I know how to use jQuery to assign width, height, etc. to an element, but what I'm trying to do is actually change the value defined in the stylesheet so that the dynamically-created value can be assigned to multiple elements.

我遇到了一种独特的情况,到目前为止我无法找到解决方案:动态地为 CSS 样式分配一个值。我知道如何使用 jQuery 为元素分配宽度、高度等,但我真正想做的是更改样式表中定义的值,以便可以将动态创建的值分配给多个元素。

What I'm building is a slideshow of images that occupy the full viewport, recalculating the image's width, height, and left properties on resize so that the image is always centered, favors width over height, except when the viewport is taller than it is wide (resizing does not reload the page, just fires a function to resize the image).

我正在构建的是一个占据整个视口的图像幻灯片,在调整大小时重新计算图像的宽度、高度和左属性,以便图像始终居中,优先于宽度而不是高度,除非视口高于它宽(调整大小不会重新加载页面,只会触发一个函数来调整图像大小)。

I have successfully been able to get it to work on one image, and now I'm trying to determine the best way to assign those property values to all images in the slideshow without having to specify those three things individually for every image.

我已经成功地让它在一张图像上工作,现在我正在尝试确定将这些属性值分配给幻灯片中的所有图像的最佳方法,而不必为每个图像单独指定这三项内容。

My Question:

我的问题:

Can the values of properties in a class be modified on the fly? I'm sure the answer is out there, I'm probably just not using the correct terminology in my searches. Hope I did a good job of describing the problem. TIA.

可以动态修改类中的属性值吗?我确定答案就在那里,我可能只是在搜索中没有使用正确的术语。希望我在描述问题方面做得很好。TIA。

回答by JPN

Contrary to some of the answers here, editing the stylesheet itself with Javascript is not only possible, but higher performance. Simply doing $('.myclass').css('color: red')will end up looping through every item matching the selector and individually setting the style attribute. This is really inefficient and if you have hundreds of elements, it's going to cause problems.

与这里的一些答案相反,使用 Javascript 编辑样式表本身不仅是可能的,而且性能更高。简单地执行$('.myclass').css('color: red')将最终遍历与选择器匹配的每个项目并单独设置样式属性。这真的是低效的,如果你有数百个元素,就会导致问题。

Changing classes on the items is a better idea, but you still suffer from the same problem in that you're changing an attribute on N items, which could be a large number. A better solution might be to change the class on one single parent item or a small number of parents and then hit the target items using the "Cascade" in css. This serves in most situations, but not all.

更改项目的类是一个更好的主意,但您仍然会遇到同样的问题,因为您正在更改 N 个项目的属性,这可能是一个很大的数字。更好的解决方案可能是更改单个父项或少数父项的类,然后使用 css 中的“级联”命中目标项。这适用于大多数情况,但不是全部。

Sometimes you need to change the CSS of a lot of items to something dynamic, or there's no good way for you to do so by hitting a small number of parents. Changing the stylesheet itself, or adding a small new one to override the existing css is an extremely efficient way to change the display of items. You're only interacting with the DOM in one spot and the browser can handle deploying those changes really efficiently.

有时您需要将很多项的 CSS 更改为动态的,或者通过点击少数父项没有什么好的方法可以做到这一点。更改样式表本身,或添加一个小的新样式来覆盖现有的 css,是一种非常有效的更改项目显示的方法。您只在一处与 DOM 交互,浏览器可以真正有效地处理部署这些更改。

jssis one library that helps make it easier to directly edit the stylesheet from javascript.

jss是一个库,它有助于更​​轻松地直接从 javascript 编辑样式表。

回答by Oriol

Demo, IE demo

演示,IE 演示

You could use the following function:

您可以使用以下功能:

function setStyle(cssText) {
    var sheet = document.createElement('style');
    sheet.type = 'text/css';
    /* Optional */ window.customSheet = sheet;
    (document.head || document.getElementsByTagName('head')[0]).appendChild(sheet);
    return (setStyle = function(cssText, node) {
        if(!node || node.parentNode !== sheet)
            return sheet.appendChild(document.createTextNode(cssText));
        node.nodeValue = cssText;
        return node;
    })(cssText);
};

Features:

特点

  • The function is written in vanilla-js, so it has better performance than jQuery alternatives
  • One stylesheet is created after the first call to setStyle, so if you don't call it, it won't create any stylesheet.
  • The same stylesheet is reused for the following calls of setStyle
  • The function return a reference to the node associated with the bunch of CSS that you have added. If you call the function again with that node as a second argument, it will replace the old CSS with the new one.
  • 该函数是用 vanilla-js 编写的,因此它比 jQuery 替代品具有更好的性能
  • 第一次调用 后会创建一个样式表setStyle,因此如果您不调用它,它将不会创建任何样式表。
  • 相同的样式表被重用于以下调用 setStyle
  • 该函数返回对与您添加的一堆 CSS 关联的节点的引用。如果您使用该节点作为第二个参数再次调用该函数,它将用新的 CSS 替换旧的 CSS。

Example

例子

var myCSS = setStyle('*{ color:red; }');
setStyle('*{ color:blue; }', myCSS); // Replaces the previous CSS with this one

Browser support

浏览器支持

At least, it works on IE9, FF3, Chrome 1, Safari 4, Opera 10.5.

至少,它适用于 IE9、FF3、Chrome 1、Safari 4、Opera 10.5。

There's also an IE versionwhich works both on modern browsers and old versions of IE! (Works on IE8 and IE7, but can crash IE6).

还有一个IE 版本,可以在现代浏览器和旧版本的 IE 上运行!(适用于 IE8 和 IE7,但可能导致 IE6 崩溃)。

回答by Jace Cotton

Nice question. A lot of the answers here had a solution directly contradicting what you were asking

好问题。这里的很多答案都有一个与您所问的直接矛盾的解决方案

"I know how to use jQuery to assign width, height, etc. to an element, but what I'm trying to do is actually change the value defined in the stylesheet so that the dynamically-created value can be assigned to multiple elements.
"
“我知道如何使用 jQuery 为元素分配宽度、高度等,但我真正想做的是更改样式表中定义的值,以便可以将动态创建的值分配给多个元素。

jQuery .cssstyles elements inline: it doesn't change the physical CSS rule! If you want to do this, I would suggest using a vanilla JavaScript solution:

内联jQuery.css样式元素:它不会改变物理 CSS 规则!如果您想这样做,我建议您使用 vanilla JavaScript 解决方案:

document.styleSheets[0].cssRules[0].cssText = "\
     #myID {
         myRule: myValue;
         myOtherRule: myOtherValue;
     }";

This way, you're setting the stylesheet css rule, not appending an inline style.

这样,您将设置样式表 css 规则,而不是附加内联样式。

Hope this helps!

希望这可以帮助!

回答by Brian Peacock

Like @benvie said, its more efficient to change a style sheet rather than using jQuery.css (which will loop through all of the elements in the set). It is also important not to add a new style to the head every time the function is called because it will create a memory leak and thousands of CSS rules that have to be individually applied by the browser. I would do something like this:

就像@benvie 所说的那样,更改样式表比使用 jQuery.css(它将遍历集合中的所有元素)更有效。同样重要的是不要在每次调用函数时向头部添加新样式,因为它会造成内存泄漏和浏览器必须单独应用的数千条 CSS 规则。我会做这样的事情:

//Add the stylesheet once and store a cached jQuery object
var $style = $("<style type='text/css'>").appendTo('head'); 

function onResize() {
    var css = "\
        .someClass {\
            left:   "+leftVal+";\
            width:  "+widthVal+";\
            height: "+heightVal+";\
        }";

    $style.html(css);
}

This solution will change your styles by modifying the DOM only once per resize. Note that for effective js minification and compression, you probably don't want to pretty-print the css, but I did for clarity.

此解决方案将通过每次调整大小仅修改一次 DOM 来更改您的样式。请注意,为了有效的 js 缩小和压缩,您可能不想漂亮地打印 css,但为了清晰起见,我这样做了。

回答by user2041268

Use jquery to add a style override in the <head>:

使用 jquery 在 中添加样式覆盖<head>

$('<style>.someClass {color: red;} input::-webkit-outer-spin-button: {display: none;}</style>')
.appendTo('head'); 

回答by wopolow

I've got a solution for changing a value in specific CSS class. But it only works if you keep your CSS in the tag. If you just keep a link to your CSS from external files ex.

我有一个更改特定 CSS 类中的值的解决方案。但它只有在您将 CSS 保留在标签中时才有效。如果您只是从外部文件中保留指向 CSS 的链接,例如。

<style src='script.js'></style>

this solution won't work.

此解决方案不起作用。

If your css looks like this for example:

例如,如果您的 css 如下所示:

<style id='style'>
.foo {
height:50px;
}
</style>

You can change a value of the tag using JS/jQuery.

您可以使用 JS/jQuery 更改标签的值。

I've written a function, perhaps it's not the best one but it works. You can improve it if you want.

我写了一个函数,也许它不是最好的,但它有效。如果你愿意,你可以改进它。

function replaceClassProp(cl,prop,val){

if(!cl || !prop || !val){console.error('Wrong function arguments');return false;}


// Select style tag value

var tag = '#style';

    var style = $(tag).text();
    var str = style;

// Find the class you want to change
    var n = str.indexOf('.'+cl);
    str = str.substr(n,str.length);
    n = str.indexOf('}');
    str = str.substr(0,n+1);

    var before = str;

// Find specific property

    n = str.indexOf(prop);
    str = str.substr(n,str.length);
    n = str.indexOf(';');
    str = str.substr(0,n+1);

// Replace the property with values you selected

    var after = before.replace(str,prop+':'+val+';');
    style=style.replace(before,after);

// Submit changes

    $(tag).text(style);

}

Then just change the tag variable into your style tag id and exegute:

然后只需将标签变量更改为您的样式标签 ID 并执行:

replaceClassProp('foo','height','50px');

The difference between this and $('.foo').css('height','50px'); is that when you do it with css method of jQuery, all elements that have .foo class will have visible style='height:50px' in DOM. If you do it my way, elements are untouched and the only thing youll see is class='foo'

这与 $('.foo').css('height','50px'); 的区别;就是当你用 jQuery 的 css 方法来做时,所有具有 .foo 类的元素在 DOM 中都将具有可见的 style='height:50px' 。如果您按照我的方式进行操作,元素将保持不变,您将看到的唯一内容是 class='foo'

Advantages

好处

  • Clear DOM
  • You can modify the property you want without replacing the whole style
  • 清除DOM
  • 你可以修改你想要的属性而不用替换整个样式

Disadvantages

缺点

  • Only internal CSS
  • You have to find specific style tag you want to edit
  • 仅内部 CSS
  • 您必须找到要编辑的特定样式标签

Hope it helps anyhow.

希望它无论如何都有帮助。

回答by Tejs

You can't modify the members of a CSS class on the fly. However, you could introduce a new <style>tag on the page with your new css class implementation, and then switch out the class. Example:

您不能即时修改 CSS 类的成员。但是,您可以<style>使用新的 css 类实现在页面上引入一个新标记,然后切换该类。例子:

Sample.css

.someClass { border: 1px solid black; font-size: 20px; }

You want to change that class entirely, so you create a new style element:

您想完全更改该类,因此您创建了一个新的样式元素:

<style>
   .someClassReplacement { border: 1px solid white; font-size: 14px; }       
</style>

You then do a simple replacement via jQuery:

然后你通过 jQuery 做一个简单的替换:

$('.someClass').removeClass('someClass').addClass('someClassReplacement');

回答by JJ.

Why not just use a .classselector to modify the properties of every object in that class?

为什么不直接使用.class选择器来修改该类中每个对象的属性?

ie:

IE:

$('.myclass').css('color: red;');

$('.myclass').css('color: red;');

回答by Cycne

function changeStyle(findSelector, newRules) {
    // Change original css style declaration.   
    for ( s in document.styleSheets ) {
        var CssRulesStyle = document.styleSheets[s].cssRules;
        for ( x in CssRulesStyle ) {
            if ( CssRulesStyle[x].selectorText == findSelector) {
                for ( cssprop in newRules ) {
                    CssRulesStyle[x].style[cssprop] = newRules[cssprop];
                }

                return true;
            }
        }
    }

    return false;
}

changeStyle('#exact .myStyle .declaration', {'width':'200px', 'height':'400px', 'color':'#F00'});

回答by cancerbero

YUI 2 and 3 has a module stylesheet that will let you do just that (edit stylesheets on the fly with javascript). http://yuilibrary.com/yui/docs/stylesheet/. So I think it is possible. This is not the same as $(".some").css({...}) but really change/add/remove styles definition from stylesheet, just like the user asked.

YUI 2 和 3 有一个模块样式表,可以让您做到这一点(使用 javascript 即时编辑样式表)。http://yuilibrary.com/yui/docs/stylesheet/。所以我认为这是可能的。这与 $(".some").css({...}) 不同,但确实从样式表中更改/添加/删除样式定义,就像用户要求的那样。