Изменение значений свойств класса CSS на лету с помощью JavaScript / jQuery - PullRequest
51 голосов
/ 19 августа 2011

Я столкнулся с уникальной ситуацией, которую до сих пор не смог найти решение для: динамического присвоения значения стилю CSS. Я знаю, как использовать jQuery для присвоения ширине, высоте и т. Д. Элементу, но я пытаюсь на самом деле изменить значение, определенное в таблице стилей, чтобы динамически создаваемое значение можно было назначить нескольким элементам.

То, что я строю, представляет собой слайд-шоу изображений, которые занимают весь видовой экран, пересчитывая свойства ширины, высоты и левого размера изображения при изменении размера, так что изображение всегда центрируется, предпочитая ширину по высоте, за исключением случаев, когда область просмотра выше чем это широко (изменение размера не перезагружает страницу, только вызывает функцию, чтобы изменить размер изображения).

Я успешно смог заставить его работать на одном изображении, и теперь я пытаюсь определить наилучший способ присвоить эти значения свойств всем изображениям в слайд-шоу, не задавая эти три вещи индивидуально для каждого изображения. ,

Мой вопрос:

Можно ли изменять значения свойств в классе на лету? Я уверен, что ответ там, я, вероятно, просто не использую правильную терминологию в моих поисках. Надеюсь, я хорошо описал проблему. ТИА.

Ответы [ 14 ]

28 голосов
/ 19 августа 2011

Вопреки некоторым ответам здесь, редактирование самой таблицы стилей с помощью Javascript не только возможно, но и повышает производительность.Простое выполнение $('.myclass').css('color: red') приведет к циклу прохождения каждого элемента, соответствующего селектору, и индивидуальной настройке атрибута стиля.Это действительно неэффективно, и если у вас есть сотни элементов, это вызовет проблемы.

Изменение классов на предметах - лучшая идея, но вы все еще страдаете от той же проблемы, что вы меняете атрибутна N предметов, которых может быть большое количество.Лучшим решением может быть изменение класса одного родительского элемента или небольшого количества родителей, а затем попадание в целевые элементы с помощью «Каскада» в css.Это подходит в большинстве ситуаций, но не во всех.

Иногда вам нужно изменить CSS многих элементов на что-то динамическое, или нет хорошего способа сделать это, ударив по небольшому количеству родителей.Изменение самой таблицы стилей или добавление небольшой новой для переопределения существующего CSS - чрезвычайно эффективный способ изменить отображение элементов.Вы взаимодействуете с DOM только в одном месте, и браузер может действительно эффективно развертывать эти изменения.

jss - это одна библиотека, которая помогает упростить непосредственное редактирование таблицы стилей из JavaScript..

22 голосов
/ 27 октября 2013

Демо , IE demo

Вы можете использовать следующую функцию:

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);
};

Особенности :

  • Функция написана на vanilla-js, поэтому она имеет лучшую производительность, чем альтернативы jQuery
  • Одна таблица стилей создается после первойвызовите setStyle, поэтому, если вы его не вызовете, он не создаст никакой таблицы стилей.
  • Эта же таблица стилей повторно используется для следующих вызовов setStyle
  • Функциявернуть ссылку на узел, связанный с добавленной вами связкой CSS.Если вы снова вызовете функцию с этим узлом в качестве второго аргумента, он заменит старый CSS новым.

Пример

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

Поддержка браузера

По крайней мере, он работает на IE9, FF3, Chrome 1, Safari 4, Opera 10.5.

Также есть версия IE, который работает как в современных браузерах, так и в старых версиях IE!(Работает на IE8 и IE7, но может привести к сбою IE6).

18 голосов
/ 27 октября 2013

Хороший вопрос.У многих ответов здесь было решение, прямо противоречащее тому, что вы спрашивали

«Я знаю, как использовать jQuery для присвоения ширине, высоте и т. Д. Элементу, но я пытаюсь сделать это на самом делеизмените значение, определенное в таблице стилей, чтобы динамически создаваемое значение можно было назначить нескольким элементам.
"

jQuery .css элементы стилей inline : оно не изменяетсяфизическое правило CSS!Если вы хотите сделать это, я бы предложил использовать ванильное решение JavaScript:

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

Таким образом, вы устанавливаете правило css таблицы стилей, не добавляя встроенный стиль.

Надеюсьэто помогает!

8 голосов
/ 27 октября 2013

Как сказал @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);
}

Это решение изменит ваши стили, изменяя DOM только один раз за изменение размера.Обратите внимание, что для эффективного минимизации и сжатия js вы, вероятно, не хотите печатать css, но я сделал это для ясности.

5 голосов
/ 05 февраля 2013

Используйте jquery для добавления переопределения стиля в <head>:

$('<style>.someClass {color: red;} input::-webkit-outer-spin-button: {display: none;}</style>')
.appendTo('head'); 
4 голосов
/ 18 апреля 2014

У меня есть решение для изменения значения в определенном классе CSS.Но это работает, только если вы держите свой CSS в теге.Если вы просто сохраните ссылку на свой CSS из внешних файлов, напр.

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

это решение не будет работать.

Если ваш CSS выглядит следующим образом:

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

Вы можете изменить значение тега с помощью JS/jQuery.

Я написал функцию, возможно, она не самая лучшая, но она работает.Вы можете улучшить его, если хотите.

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);

}

Затем просто измените переменную тега на свой идентификатор тега стиля и выполните exegute:

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

Разница между этим и $ ('. Foo') .css (' высота», '50px');в том, что когда вы делаете это с помощью метода css jQuery, все элементы, имеющие класс .foo, будут иметь видимый стиль = 'height: 50px' в DOM.Если вы сделаете это по-моему, элементы останутся нетронутыми, и единственное, что вы увидите, это class = 'foo'

Преимущества

  • Очистить DOM
  • Вы можете изменить желаемое свойство без замены всего стиля

Недостатки

  • Только внутренний CSS
  • У вас естьчтобы найти конкретный тег стиля, который вы хотите отредактировать

Надеюсь, это поможет в любом случае.

3 голосов
/ 19 августа 2011

Вы не можете изменять члены класса CSS на лету.Однако вы можете ввести новый тег <style> на странице с вашей новой реализацией класса css, а затем отключить класс.Пример:

Sample.css

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

Вы хотите полностью изменить этот класс, поэтому вы создаете новый элемент стиля:

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

Затем вы делаете простую замену через jQuery:

$('.someClass').removeClass('someClass').addClass('someClassReplacement');
2 голосов
/ 23 июля 2017
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'});
2 голосов
/ 19 августа 2011

Почему бы просто не использовать селектор .class для изменения свойств каждого объекта в этом классе?

, то есть:

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

1 голос
/ 01 декабря 2015

Ладно ... была такая же проблема и исправлена, но решение может быть не для всех.

Если вам известны индексы таблицы стилей и правило, которое вы хотите удалить, попробуйте что-то вроде document.styleSheets[1].deleteRule(0);.

С самого начала у меня был файл main.css (index 0). Затем я создал новый файл js_edit.css (индекс 1), который содержал только одно правило со свойствами, которые я хотел удалить после завершения загрузки страницы (после нескольких других функций JS) .

Теперь, поскольку js_edit.css загружается после main.css , вы можете просто вставить / удалить правила в js_edit.css , как вам угодно, и они переопределите их в main.css .

var x = document.styleSheets[1];
x.insertRule("p { font-size: 2rem; }", x.cssRules.length);

x.cssRules.length возвращает количество правил во второй (индекс 1) таблице стилей, таким образом вставляя новое правило в конце.

Я уверен, что вы можете использовать несколько циклов for для поиска правила / свойства, которое вы хотите изменить, и затем переписать все правило на том же листе, но я нашел этот способ более простым для моих нужд.

http://www.quirksmode.org/dom/w3c_css.html мне очень помогли.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...