Programing

자바 스크립트에서 CSS 규칙 세트 변경

lottogame 2020. 12. 26. 09:27
반응형

자바 스크립트에서 CSS 규칙 세트 변경


CSS 규칙 세트를 동적으로 변경할 수 있습니까 (예 : 사용자가 위젯을 클릭 할 때 CSS 규칙 세트를 변경하는 일부 JS)

이 특정 CSS 규칙 세트는 페이지의 많은 요소 (클래스 선택기를 통해)에 적용되며 사용자가 위젯을 클릭 할 때이를 수정하여 클래스 가있는 모든 요소가 변경 되도록하고 싶습니다 .


할 수 있지만 다소 번거 롭습니다. 이를 수행하는 방법에 대한 가장 좋은 참조는 다음 기사입니다. Totally Pwn CSS with Javascript ( 웹 아카이브 링크 ).

Firefox 및 IE에서 작동하도록 관리했습니다. Chrome에서는 할 수 없었지만 DOM 메서드를 지원하는 것으로 보입니다.ricosrealm 은 Chrome에서도 작동 한다고 보고합니다.


이것은 Javascript가있는 Totally Pwn CSS를 기반으로 한 최신 버전입니다. ES6입니다.

function getCSSRule(ruleName) {
    ruleName = ruleName.toLowerCase();
    var result = null;
    var find = Array.prototype.find;

    find.call(document.styleSheets, styleSheet => {
        result = find.call(styleSheet.cssRules, cssRule => {
            return cssRule instanceof CSSStyleRule 
                && cssRule.selectorText.toLowerCase() == ruleName;
        });
        return result != null;
    });
    return result;
}

이 함수는 다음과 같이 사용할 수있는 CSSStyleRule을 반환합니다.

var header = getCSSRule('#header');
header.style.backgroundColor = 'red';

또한 document.styleSheets 는 CSSStylesSheets 객체의 참조를 나열합니다. 페이지의 특정 sytleSheet에 액세스하는 다른 방법 은 html 코드 스타일 또는 링크 요소에 ID할당하고 document.getElementById ( 'my-style'). sheet를 사용하여 자바 스크립트로 가져 오는 것입니다 . 다음은 몇 가지 유용한 방법입니다.

주요 브라우저 및 IE9 + : insertRule (), deleteRule (), removeProperty ().

주요 브라우저, Firefox? 및 IE9 + : setProperty ().

<stye id="my-style" ...
....
var myStyle = document.getElementById('my-style').sheet
myStyle.insertRule('#header { background: red; }', 0);

동적으로 생성 된 스타일을 저장하기 위해 새로운 스타일 요소를 동적으로 생성하는 것도 가능합니다. 충돌을 피하는 방법이되어야한다고 생각합니다.


슬프게도 JS로 스타일 시트를 편집하기위한 API는 브라우저간에 일관성이 없습니다. 유이 스타일 시트 유틸리티 당신은 그냥 사용할 수 있도록 시도는 이러한 차이를 발라합니다. YUI 자체를 사용하지 않으려는 경우 소스 코드살펴보고 작동 방식을 파악할 수도 있습니다.


@ alex-gyoshev 주석의 링크를 통해 코드를 시도했지만 작동하지 않습니다.

  1. Chrome의 Google 글꼴을 사용하는 CSS 규칙에서 실패합니다.
  2. FireFox 보안 검사에서 실패합니다.

그래서 약간 변경했지만 delete필요하지 않았기 때문에 기능을 삭제 했습니다. IE 11, FireFox 32, Chrome 37 및 Opera 26에서 확인했습니다.

function getCSSRule(ruleName) { // Return requested style object
  ruleName = ruleName.toLowerCase(); // Convert test string to lower case.
  var styleSheet;
  var i, ii;
  var cssRule = false; // Initialize cssRule. 
  var cssRules;
  if (document.styleSheets) { // If browser can play with stylesheets
    for (i = 0; i < document.styleSheets.length; i++) { // For each stylesheet
      styleSheet = document.styleSheets[i];
      if (!styleSheet.href) {
        if (styleSheet.cssRules) { // Browser uses cssRules?
          cssRules = styleSheet.cssRules; // Yes --Mozilla Style
        } else { // Browser usses rules?
          cssRules = styleSheet.rules; // Yes IE style. 
        } // End IE check.
        if (cssRules) {
          for (ii = 0; ii < cssRules.length; ii++) {
            cssRule = cssRules[ii];
            if (cssRule) { // If we found a rule...
              // console.log(cssRule);
              if (cssRule.selectorText) {
                console.log(cssRule.selectorText);
                if (cssRule.selectorText.toLowerCase() == ruleName) { //  match ruleName?
                  return cssRule; // return the style object.
                }
              }
            }
          }
        }
      }
    }
  }
  return false; // we found NOTHING!
}

달성하려는 것에 따라 더 나은 솔루션은 포함하는 요소에 클래스를 변경 / 추가하고 (본문이 할 수 있습니다!) 그에 따라 클래스를 정의하는 것입니다.

.yourclass { color: black }
#wrapper.foo .yourclass { color: red }
#wrapper.bar .yourclass { color: blue }

그런 다음 그냥 사용할 수 있습니다

document.getElementById('wrapper').className='foo';

(또는 선택한 js 프레임 워크의 래퍼) 는 요소가 yourclass무엇이든 클래스로 모든 것을 변경 합니다 wrapper.


스타일 태그에 ID <style id="ssID">를 부여합니다. 누군가가 스타일 태그에 ID를 부여하도록 지시하는 것처럼 스타일 태그에 ID를 부여하면 색인이 무엇인지 궁금해하지 않고 직접 액세스 할 수 있습니다.

// create a hash table
var cssHash = {};

// loop through and populate the hash table
for (let i in (r = ss0.sheet.rules)) {

    // selectorText is the name of the rule - set the value equal to the rule
    cssHash[r[i].selectorText] = r[i];

}

이제 스타일 시트의 모든 항목에 대한 해시 테이블이 있습니다. 일부 값은 정의되지 않지만 관심있는 항목에 대해서는 정의되지 않습니다 .

if you have, for instance, a class called #menuItem and you want to change its color to black, do this

cssHash['#menuItem'].style.color = #000;

that line will set the color of the style of the rule whose index was looked up in the hash table (cssHash) by the name '#menuItem'

more importantly, you probably have several different classes that you want to change all at once kind of like when you switched majors in college

let's say you have four different classes and you want to set all of their background colors to the same value, that some user selected from an input

the color selector tag is <input id="bColor" type="color"> and the class rules you want to change are called #menuItem .homeAddr span and #vacuum:hover

// create a listener for that color selector
bColor.addEventListener('input', function (e) {

  // loop through a split list of the four class names
  '#menuItem .homeAddr span #vacuum:hover'.split(' ').forEach(function (obj) {

    // use the hash table to look up the index of each name
    // and set the background color equal to the color input's value
    cssHash[obj].style.backgroundColor = bColor.value;

  });

}, false); // false added here for the sake of non-brevity

You can edit CLASS in document styleshets as follows

[...document.styleSheets[0].cssRules].find(x=> x.selectorText=='.box')
     .style.background= 'red';

function edit() {
  [...document.styleSheets[0].cssRules].find(x=> x.selectorText=='.box')
    .style.background= 'red';
}
.box {
  margin: 10px;
  padding: 10px;
  background: yellow;
}
<button onclick="edit()" >Click me</button>
<div class="box" >My box 1</div>
<div class="box" >My box 2</div>
<div class="box" >My box 3</div>


While setAttribute is nice, there is a standard way of doing this across most browsers:

htmlElement.className = 'someClass';

To do it over many elements, you will need a cross browser solution:

function getElementsByClassName( className, context, tagName ) {
  context = context || document;
  if ( typeof context.getElementsByClassName === 'function' )
    return context.getElementsByClassName( className );

  if ( typeof context.getElementsByTagName !== 'function' )
    return [];

  var elements = typeof tagName === 'string' ? context.getElementsByTagName( tagName ) :
    context.getElementsByTagName('*'),
  ret = [];
  for ( var i = 0, il = elements.length; i < il; i++ )
    if ( elements[ i ].className.match( className ) )
      ret.push( elements[ i ] );

  return ret;
}

var elements = getElementsByClassName('someClass');

for ( var i = 0, il = elements.length; i < il; i++ )
  elements[ i ].className = 'newClass';

You may want to replace the line:

if ( elements[ i ].className.match( className ) )

With some Regular Expression, but you will have to escape special characters in that case.

ReferenceURL : https://stackoverflow.com/questions/1409225/changing-a-css-rule-set-from-javascript

반응형