Подтвердить что ты не робот

Изменение значений свойств класса CSS "на лету" с помощью JavaScript/jQuery

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

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

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

Мой вопрос:

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

4b9b3361

Ответ 1

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

Изменение классов по элементам является лучшей идеей, но вы по-прежнему страдаете от той же проблемы, что и вы изменяете атрибут на N элементов, что может быть большим числом. Лучшим решением может быть изменение класса на одном родительском элементе или небольшом числе родителей, а затем на целевые объекты, используя "Cascade" в css. Это работает в большинстве ситуаций, но не для всех.

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

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

Ответ 2

Демо, IE демонстрационная

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

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
  • Функция возвращает ссылку на node, связанную с добавленной вами связкой CSS. Если вы снова вызовете функцию с этим node в качестве второго аргумента, она заменит старый 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).

Ответ 3

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

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

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

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

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

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

Ответ 4

Как и @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

С помощью jquery добавьте переопределение стиля в <head>:

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

Ответ 6

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

<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 ('height', '50px'); заключается в том, что когда вы делаете это с помощью метода css jQuery, все элементы, имеющие класс .foo, будут иметь видимый стиль = 'height: 50px' в DOM. Если вы сделаете это по-своему, элементы нетронуты, и единственное, что вы увидите, это class= 'foo'

<сильные > Преимущества

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

Недостатки

  • Только внутренний CSS
  • Вы должны найти определенный тег стиля, который хотите изменить

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

Ответ 7

Вы не можете изменять членов класса 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');

Ответ 8

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

т

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

Ответ 9

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

Ответ 10

YUI 2 и 3 имеет таблицу стилей модулей, которая позволит вам делать именно это (редактировать таблицы стилей "на лету" с помощью javascript). http://yuilibrary.com/yui/docs/stylesheet/. Поэтому я думаю, что это возможно. Это не то же самое, что $( ". Some" ). Css ({...}), но на самом деле изменить/добавить/удалить определение стилей из таблицы стилей, точно так же, как пользователь спросил.

Ответ 11

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

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

С самого начала у меня был файл main.css (индекс 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-loops для поиска правила/свойства, которое вы хотите изменить, а затем переписать все правило на одном листе, но я нашел этот способ более простым для моих нужд.

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

Ответ 12

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

<style>
  /* The bulk of the css rules should go here or in an external css file */
  /* None of these rules will be changed, but may be overridden */
  .aclass { display: inline-block; width: 50px; height: 30px; }
</style>
<style id="style">
  /* Only the rules to be changed should go in this style */
  .bclass { display: inline-block; }
</style>
<script>
  //
  // This is a helper function that returns the named style as an object.
  // This could also be done in other ways.
  // 
  function setStyle() { return document.getElementById( 'style' ); }
</script>
<div id="d1" class="aclass" style="background-color: green;">
  Hi
</div>
<!-- The element to be shown and hidden --> 
<div id="d2" class="aclass bclass" style="background-color: yellow;">
  there
</div>
<div id="d3" class="aclass" style="background-color: lightblue;">
  sailor
</div>
<hr />
<!-- These buttons demonstrate hiding and showing the d3 dive element -->
<button onclick="setStyle().innerHTML = '.bclass { display: none; }';">
  Hide
</button>&nbsp;&nbsp;
<button onclick="setStyle().innerHTML = '.bclass { display: inline-block; }';">
  Show
</button>

Переключая правило bclass во встроенную и именованную таблицу стилей, которая появляется после любых других соответствующих таблиц стилей, в этом случае с правилом aclass, я мог бы обновить только правило css для отображения в одном месте и переопределить его правило aclass, которое также имеет собственное правило отображения.

Красота этой техники заключается в том, что она настолько проста, эффективно одна строка, которая выполняет фактическую работу, она не требует каких-либо библиотек, таких как JQuery или плагинов, и реальной работы по обновлению всех мест где это изменение применяется, выполняется с помощью функциональности ядра браузера css, а не JavaScript. Кроме того, он работает в IE 9 и выше, Chrome, Safari, Opera и всех других браузерах, которые MicroSoft Edge может эмулировать, для настольных компьютеров и планшетов/телефонов.

Ответ 13

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

Ответ 14

Это решение модифицирует Cycne, чтобы использовать синтаксис ES6 и выйти из цикла раньше для внешних таблиц стилей. Это решение не изменяет внешние таблицы стилей

function changeStyle(findSelector, newDeclarations) {
    // Change original css style declaration.
    document.styleSheets.forEach((sheet) => {
      if (sheet.href) return;
      const cssRulesList = sheet.cssRules;
      cssRulesList.forEach((styleRule) => {
        if (styleRule.selectorText === findSelector) {
          Object.keys(newDeclarations).forEach((cssProp) => {
            styleRule.style[cssProp] = newDeclarations[cssProp];
          });
        }
      });
    });
  }

  const styleDeclarations = {
    'width': '200px',
    'height': '400px',
    'color': '#F00'
  };
  changeStyle('.paintBox', styleDeclarations);