developer tip

jQuery를 사용하여 :: before 및 :: after와 같은 CSS 의사 요소 선택 및 조작

copycodes 2020. 9. 28. 09:21
반응형

jQuery를 사용하여 :: before 및 :: after와 같은 CSS 의사 요소 선택 및 조작


jQuery를 사용하여 ::before::after(및 세미콜론이 하나있는 이전 버전)과 같은 CSS 의사 요소를 선택 / 조작하는 방법이 있습니까?

예를 들어, 내 스타일 시트에는 다음 규칙이 있습니다.

.span::after{ content:'foo' }

jQuery를 사용하여 'foo'를 'bar'로 어떻게 변경할 수 있습니까?


데이터 속성이있는 의사 요소에 콘텐츠를 전달한 다음 jQuery를 사용하여이를 조작 할 수도 있습니다.

HTML에서 :

<span>foo</span>

jQuery에서 :

$('span').hover(function(){
    $(this).attr('data-content','bar');
});

CSS에서 :

span:after {
    content: attr(data-content) ' any other text you may want';
}

'다른 텍스트'가 표시되지 않도록하려면 다음과 같이 seucolega의 솔루션과 결합 할 수 있습니다.

HTML에서 :

<span>foo</span>

jQuery에서 :

$('span').hover(function(){
    $(this).addClass('change').attr('data-content','bar');
});

CSS에서 :

span.change:after {
    content: attr(data-content) ' any other text you may want';
}

이것은 jQuery가 할 수있는 다른 모든 것들과 함께 대답 할 수있는 간단한 질문이라고 생각할 것입니다. 불행히도 문제는 기술적 인 문제로 귀결됩니다 . css : after 및 : before 규칙은 DOM의 일부가 아니므로 jQuery의 DOM 메소드를 사용하여 변경할 수 없습니다.

있습니다 자바 스크립트 및 / 또는 CSS 해결 방법을 사용하여 이러한 요소를 조작하는 방법; 사용하는 것은 정확한 요구 사항에 따라 다릅니다.


"최상의"접근 방식으로 널리 간주되는 것부터 시작하겠습니다.

1) 미리 정해진 클래스 추가 / 제거

이 접근 방식에서는 CSS에 다른 :after또는 :before스타일 로 클래스를 이미 생성했습니다 . 이 "새"클래스를 나중에 스타일 시트에 배치하여 다음을 재정의하는지 확인하십시오.

p:before {
    content: "foo";
}
p.special:before {
    content: "bar";
}

그런 다음 jQuery (또는 바닐라 JavaScript)를 사용하여이 클래스를 쉽게 추가하거나 제거 할 수 있습니다.

$('p').on('click', function() {
    $(this).toggleClass('special');
});

    $('p').on('click', function() {
      $(this).toggleClass('special');
    });
p:before {
  content: "foo";
  color: red;
  cursor: pointer;
}
p.special:before {
  content: "bar";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<p>This is a paragraph.</p>
<p>This is another paragraph.</p>

  • 장점 : jQuery로 구현하기 쉽습니다. 한 번에 여러 스타일을 빠르게 변경합니다. 우려 사항 분리 (HTML에서 CSS와 JS 분리)를 시행합니다.
  • 단점 : CSS는 내용 때문에, 미리 작성해야 :before하거나 :after완전히 동적이지

2) 문서의 스타일 시트에 직접 새 스타일 추가

그것은 포함하여 문서 스타일 시트에 직접 스타일을 추가 자바 스크립트를 사용하는 것이 가능 :after하고 :before스타일. jQuery는 편리한 단축키를 제공하지 않지만 다행히 JS는 그렇게 복잡하지 않습니다.

var str = "bar";
document.styleSheets[0].addRule('p.special:before','content: "'+str+'";');

var str = "bar";
document.styleSheets[0].addRule('p.special:before', 'content: "' + str + '";');
p:before {
  content: "foo";
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<p class="special">This is a paragraph</p>
<p>This is another paragraph</p>

.addRule()그리고 관련 .insertRule()방법 은 오늘날 상당히 잘 지원됩니다.

변형으로 jQuery를 사용하여 문서에 완전히 새로운 스타일 시트를 추가 할 수도 있지만 필요한 코드는 더 깔끔하지 않습니다.

var str = "bar";
$('<style>p.special:before{content:"'+str+'"}</style>').appendTo('head');

var str = "bar";
$('<style>p.special:before{content:"' + str + '"}</style>').appendTo('head');
p:before {
  content: "foo";
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<p class="special">This is a paragraph</p>
<p>This is another paragraph</p>

값을 추가하는 것뿐만 아니라 값을 "조작"하는 것에 대해 이야기 하는 경우 다른 접근 방식을 사용하여 기존 또는 스타일읽을:after:before 수도 있습니다 .

var str = window.getComputedStyle(document.querySelector('p'), ':before') 
           .getPropertyValue('content');

var str = window.getComputedStyle($('p')[0], ':before').getPropertyValue('content');
console.log(str);

document.styleSheets[0].addRule('p.special:before', 'content: "' + str+str + '";');
p:before {
    content:"foo";
    color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<p class="special">This is a paragraph</p>
<p>This is another paragraph</p>

jQuery document.querySelector('p')$('p')[0]사용할 때 약간 더 짧은 코드로 대체 할 수 있습니다 .

  • 장점 : 모든 문자열을 스타일에 동적으로 삽입 할 수 있습니다.
  • 단점 : 원래 스타일이 변경되지 않고 무시됩니다. 반복적 인 (남용) 사용으로 인해 DOM이 임의로 커질 수 있습니다.

3) 다른 DOM 속성 변경

특정 DOM 속성을 읽기 위해 CSS에서 사용할attr() 수도 있습니다 . ( 브라우저가 지원하는 경우 :before, 그것은 지원 attr()뿐만 아니라. ) 이것을 결합하여 content:몇 가지주의 깊게 준비 CSS, 우리는 (그러나 내용 변경 되지 않은 다른 특성, 마진 또는 색상 등)의 :before:after동적 :

p:before {
    content: attr(data-before);
    color: red;
    cursor: pointer;
}

JS :

$('p').on('click', function () {
    $(this).attr('data-before','bar');
});

$('p').on('click', function () {
    $(this).attr('data-before','bar');
});
p:before {
    content: attr(data-before);
    color: red;
    cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<p>This is a paragraph.</p>
<p>This is another paragraph.</p>

CSS를 미리 준비 할 수없는 경우 두 번째 기술과 결합 할 수 있습니다.

var str = "bar";

document.styleSheets[0].addRule('p:before', 'content: attr(data-before);');

$('p').on('click', function () {
    $(this).attr('data-before', str);
});

var str = "bar";
document.styleSheets[0].addRule('p:before', 'content: attr(data-before) !important;');

$('p').on('click', function() {
  $(this).attr('data-before', str);
});
p:before {
  content: "foo";
  color: red;
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<p>This is a paragraph.</p>
<p>This is another paragraph.</p>

  • 장점 : 끝없는 추가 스타일을 만들지 않습니다 .
  • 단점 : attr CSS에서는 URL이나 RGB 색상이 아닌 콘텐츠 문자열에만 적용 할 수 있습니다.

마치 다른 실제 DOM 요소처럼 CSS를 통해 브라우저에서 렌더링되지만 의사 요소 자체는 DOM의 일부가 아닙니다. 이름에서 알 수 있듯이 의사 요소는 실제 요소가 아니므로 사용할 수 없기 때문입니다. 선택하고 (또는 jQuery를 함께 직접 조작 할 어떤 그 문제에,조차 자바 스크립트 API를 선택기의 API ). 이것은 누구의 스타일 당신이 스크립트를 수정하려는 모든 의사 요소에 적용되며 단지 ::before::after.

CSSOM (think window.getComputedStyle())을 통해서만 런타임에 의사 요소 스타일에 직접 액세스 할 수 있습니다 . 이는 .css()의사 요소도 지원하지 않는 메소드 인 jQuery beyond에 의해 노출 되지 않습니다.

하지만 다음과 같이 항상 다른 방법을 찾을 수 있습니다.

  • 하나 이상의 임의 클래스의 의사 요소에 스타일을 적용한 다음 클래스 간 전환 ( 빠른 예는 seucolega의 답변 참조 )-이것은 간단한 선택기 (의사 요소가 아닌)를 사용하므로 관용적 인 방법입니다. 요소와 요소 상태를 구분하여 사용하려는 방식

  • 문서 스타일 시트를 변경하여 가상 요소에 적용되는 스타일을 조작하는 것은 훨씬 더 해킹입니다.


DOM의 일부가 아니기 때문에 jQuery에서 의사 요소를 선택할 수 없습니다. 그러나 아버지 요소에 특정 클래스를 추가하고 CSS에서 유사 요소를 제어 할 수 있습니다.

jQuery에서 :

<script type="text/javascript">
    $('span').addClass('change');
</script>

CSS에서 :

span.change:after { content: 'bar' }

Christian이 제안한대로 다음을 수행 할 수도 있습니다.

$('head').append("<style>.span::after{ content:'bar' }</style>");

의사 요소를 조작하기 위해 사용자 정의 속성 (CSS 변수라고도 함)의존 할 수도 있습니다 . 우리는 다음과 같은 사양읽을 수 있습니다 .

사용자 정의 속성은 일반 속성이므로 모든 요소에서 선언 할 수 있고, 일반 상속계단식 규칙 으로 해결되고, @media 및 기타 조건부 규칙으로 조건부로 만들 수 있으며, HTML의 스타일 속성 에서 사용할 수 있으며, 읽거나 설정할 수 있습니다. CSSOM 사용

이를 고려할 때 아이디어는 요소 내에서 사용자 정의 속성을 정의하는 것이며 의사 요소는 단순히이를 상속합니다. 따라서 쉽게 수정할 수 있습니다.

1) 인라인 스타일 사용 :

.box:before {
  content:var(--content,"I am a before element");
  color:var(--color, red);
  font-size:25px;
}
<div class="box"></div>
<div class="box" style="--color:blue;--content:'I am a blue element'"></div>
<div class="box" style="--color:black"></div>
<div class="box" style="--color:#f0f;--content:'another element'"></div>

2) CSS 및 클래스 사용

.box:before {
  content:var(--content,"I am a before element");
  color:var(--color, red);
  font-size:25px;
}

.blue {
  --color:blue;
  --content:'I am a blue element';
}
.black {
  --color:black;
}
<div class="box"></div>
<div class="box black" ></div>
<div class="box blue"></div>

3) 자바 스크립트 사용

document.querySelectorAll('.box')[0].style.setProperty("--color", "blue");
document.querySelectorAll('.box')[1].style.setProperty("--content", "'I am another element'");
.box:before {
  content:var(--content,"I am a before element");
  color:var(--color, red);
  font-size:25px;
}
<div class="box"></div>
<div class="box"></div>

4) jQuery 사용

$('.box').eq(0).css("--color", "blue");
/* the css() function with custom properties works only with a jQuery vesion >= 3.x
   with older version we can use style attribute to set the value. Simply pay
   attention if you already have inline style defined! 
*/
$('.box').eq(1).attr("style","--color:#f0f");
.box:before {
  content:"I am a before element";
  color:var(--color, red);
  font-size:25px;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>


복잡한 값과 함께 사용할 수도 있습니다.

.box {
  --c:"content";
  --b:linear-gradient(red,blue);
  --s:20px;
  --p:0 15px;
}

.box:before {
  content: var(--c);
  background:var(--b);
  color:#fff;
  font-size: calc(2 * var(--s) + 5px);
  padding:var(--p);
}
<div class="box"></div>

당신은 내가 구문 고려하고 있음을 알 수 있습니다 기본값이며, 또한 대체 값이라고합니다.var(--c,value)value

동일한 사양에서 다음을 읽을 수 있습니다.

사용자 정의 속성 값은 var () 함수를 사용하여 다른 속성 값으로 대체 할 수 있습니다. var () 구문은 다음과 같습니다.

var() = var( <custom-property-name> [, <declaration-value> ]? )

함수의 첫 번째 인수는 대체 할 사용자 지정 속성의 이름입니다. 함수의 두 번째 인수 (제공된 경우)는 참조 된 사용자 지정 속성이 유효하지 않은 경우 대체 값으로 사용되는 대체 값 입니다.

그리고 나중에 :

속성 값에서 var ()를 대체하려면 :

  1. var()함수 에 대한 첫 번째 인수로 명명 된 사용자 지정 속성 이 애니메이션으로 오염되어 있고 해당 var()함수가 애니메이션 속성 또는 해당 긴 항목 중 하나에서 사용되는 경우 사용자 지정 속성을이 알고리즘의 나머지 부분에 대한 초기 값이있는 것으로 취급합니다.
  2. var()함수 에 대한 첫 번째 인수로 명명 된 사용자 지정 속성의 값이 초기 값이 아닌 var()경우 해당 사용자 지정 속성의 값으로 함수를 대체합니다 .
  3. 그렇지 않고 var()함수에 두 번째 인수로 폴백 값이있는 경우 함수를 폴백 값으로 var()바꿉니다. var()대체에 참조 가있는 경우에도 대체하십시오.
  4. 그렇지 않으면 var()함수가 포함 된 속성이 계산 된 값 시간에 유효하지 않습니다.

사용자 지정 속성을 설정하지 않거나이를로 설정 initial하거나 잘못된 값을 포함하면 대체 값이 사용됩니다. 를 사용 initial하면 사용자 정의 속성을 기본값으로 재설정하려는 경우 유용 할 수 있습니다.

관련

CSS 사용자 정의 속성 (CSS 변수라고도 함) 내에 상속 값을 저장하는 방법은 무엇입니까?

상자 모델에 대한 CSS 사용자 정의 속성 (변수)


CSS 변수는 관련성이 있다고 생각하는 모든 브라우저 (예 : IE 11)에서 사용 가능하지 않을 수 있습니다. https://caniuse.com/#feat=css-variables


다음은 CSS에 정의 된 : after 및 : before 스타일 속성에 액세스하는 방법입니다.

// Get the color value of .element:before
var color = window.getComputedStyle(
    document.querySelector('.element'), ':before'
).getPropertyValue('color');

// Get the content value of .element:before
var content = window.getComputedStyle(
    document.querySelector('.element'), ':before'
).getPropertyValue('content');

CSS를 통해 :: before 또는 :: after sudo 요소를 완전히 조작하고 싶다면 JS로 할 수 있습니다. 아래를 참조하십시오.

jQuery('head').append('<style id="mystyle" type="text/css"> /* your styles here */ </style>');

<style>스타일이 동적으로 변경되면 요소를 제거하고 다시 추가하는 데 사용할 수있는 ID가 요소에 어떻게 있는지 확인하십시오.

이렇게하면 요소는 JS의 도움으로 CSS를 통해 원하는 방식으로 정확하게 스타일을 지정할 수 있습니다.


작동하지만 그다지 효율적이지 않은 한 가지 방법은 새 콘텐츠가있는 문서에 규칙을 추가하고 클래스와 함께 참조하는 것입니다. 필요한 항목에 따라 클래스는 콘텐츠의 각 값에 대해 고유 한 ID가 필요할 수 있습니다.

$("<style type='text/css'>span.id-after:after{content:bar;}</style>").appendTo($("head"));
$('span').addClass('id-after');

다음은 HTML입니다.

<div class="icon">
  <span class="play">
    ::before
  </span>
</div>

'before'에서 계산 된 스타일은 content: "VERIFY TO WATCH";

다음은이 요소를 구체적으로 참조하기 위해 추가 클래스를 추가 한 다음 스타일 태그 (! important 태그 포함)를 추가하여 sudo 요소의 콘텐츠 값의 CSS를 변경하는 두 줄의 jQuery입니다.

$("span.play:eq(0)").addClass('G');

$('body').append("<style>.G:before{content:'NewText' !important}</style>");


모두 감사합니다! 나는 내가 원하는 것을 할 수 있었다 : D http://jsfiddle.net/Tfc9j/42/ 여기 봐

나는 외부 div의 불투명도가 내부 div의 불투명도와 다르고 클릭 somwewhere로 변경되기를 원했습니다.) 감사합니다!

   $('#ena').on('click', function () {
        $('head').append("<style>#ena:before { opacity:0.3; }</style>");
    });

$('#duop').on('click', function (e) {

        $('head').append("<style>#ena:before { opacity:0.8; }</style>");

     e.stopPropagation(); 
    });

#ena{
    width:300px;
    height:300px;
    border:1px black solid;
    position:relative;
}
#duo{
    opacity:1;
    position:absolute;
    top:50px;
  width:300px;
    height:100px;
      background-color:white;
}
#ena:before {
    content: attr(data-before);
    color: white;
    cursor: pointer;
    position: absolute;
    background-color:red;
    opacity:0.9;
    width:100%;
    height:100%;
}


<div id="ena">
    <div id="duo">
        <p>ena p</p>
        <p id="duop">duoyyyyyyyyyyyyyy p</p>

    </div>   


</div>

이것은 실제 사용을 위해 작성하지 않았으므로 실용적이지 않습니다.

css = {
before: function(elem,attr){ 

if($("#cust_style") !== undefined){ 
$("body").append("<style> " + elem + ":before {"  + attr +  "} </style>"); 
} else {
 $("#cust_style").remove();
$("body").append("<style> " + elem + ":before {"  + attr +  "} </style>"); 
}

}, after: function(elem,attr){
if($("#cust_style") !== undefined){ 
$("body").append("<style> " + elem + ":after {"  + attr +  "} </style>"); 

} else { $("#cust_style").remove();
$("body").append("<style> " + elem + ":after {"  + attr +  "} </style>"); 
}
}
}

이것은 현재 추가 / 또는 Pseudo 요소 뒤에 대상 요소에 영향을 미칠 필요한 속성을 포함하는 Style 요소를 추가합니다.

이것은 다음과 같이 사용할 수 있습니다.

css.after("someElement"," content: 'Test'; position: 'absolute'; ") // editing / adding styles to :after

css.before( ... ); // to affect the before pseudo element.

as after : and before : 유사 요소는 DOM을 통해 직접 액세스 할 수 없으며 현재 CSS의 특정 값을 자유롭게 편집 할 수 없습니다.

내 방식은 단지 예일 뿐이며 연습에 좋지 않습니다. 자신의 트릭을 수정하여 실제 사용에 맞게 수정할 수 있습니다.

그래서 이것과 다른 사람들과 함께 자신의 실험을하십시오!

안부-Adarsh ​​Hegde.


가짜 속성을 만들거나 기존 속성을 사용 하여 의사 요소의 스타일 시트에서 상속 할 수 있습니다.

var switched = false;

// Enable color switching
setInterval(function () {
    var color = switched ? 'red' : 'darkred';
    var element = document.getElementById('arrow');
    element.style.backgroundColor = color;
    
    // Managing pseudo-element's css
    // using inheritance.
    element.style.borderLeftColor = color;
    
    switched = !switched;
}, 1000);
.arrow {
    /* SET FICTIONAL PROPERTY */
    border-left-color:red;
    
    background-color:red;
    width:1em;
    height:1em;
    display:inline-block;
    position:relative;
}
.arrow:after {
    border-top:1em solid transparent;
    border-right:1em solid transparent;
    border-bottom:1em solid transparent;
    border-left:1em solid transparent;
    
    /* INHERIT PROPERTY */
    border-left-color:inherit;
    
    content:"";
    width:0;
    height:0;
    position:absolute;
    left:100%;
    top:-50%;
}
<span id="arrow" class="arrow"></span>

"content"속성에 대해 작동하지 않는 것 같습니다 :(


style헤드에를 추가 할 수 있는데 클래스 나 속성을 추가하는 이유

$('head').append('<style>.span:after{ content:'changed content' }</style>')

나는 항상 다음과 같은 내 자신의 유틸리티 기능을 추가하고 있습니다.

function setPseudoElContent(selector, value) {    
    document.styleSheets[0].addRule(selector, 'content: "' + value + '";');
}

setPseudoElContent('.class::after', 'Hello World!');

또는 ES6 기능 사용 :

const setPseudoElContent = (selector, value) => {    
    document.styleSheets[0].addRule(selector, `content: "${value}";`);
}

setPseudoElContent('.class::after', 'Hello World!');

여기에는 많은 답변이 있지만 수락 된 답변 조차도 :before또는 의 CSS를 조작하는 데 도움이되는 답변은 :after없습니다.

제가 제안하는 방법은 다음과 같습니다. HTML이 다음과 같다고 가정합니다.

<div id="something">Test</div>

그런 다음 CSS에서 : before를 설정하고 다음과 같이 디자인합니다.

#something:before{
   content:"1st";
   font-size:20px;
   color:red;
}
#something{
  content:'1st';
}

content나중에 쉽게 꺼낼 수 있도록 요소 자체 에도 속성을 설정 했습니다. 이제 button클릭하면 : before의 색상을 녹색으로 변경하고 글꼴 크기를 30px로 변경할 수 있습니다. 다음과 같이 달성 할 수 있습니다.

일부 클래스에서 필요한 스타일로 CSS를 정의하십시오 .activeS.

.activeS:before{
   color:green !important;
   font-size:30px !important;
 }

이제 다음과 같이 클래스를 : before 요소에 추가하여 : before 스타일을 변경할 수 있습니다.

<button id="changeBefore">Change</button>
<script>
    $('#changeBefore').click(function(){
        $('#something').addClass('activeS');
    });
</script>

의 콘텐츠를 얻으려면 :before다음과 같이 할 수 있습니다.

<button id="getContent">Get Content</button>
<script>
    $('#getContent').click(function(){
        console.log($('#something').css('content'));//will print '1st'
    });
</script>

궁극적으로 :beforejQuery로 콘텐츠 를 동적으로 변경하려는 경우 다음과 같이 수행 할 수 있습니다.

<button id="changeBefore">Change</button>
<script>
    var newValue = '22';//coming from somewhere
    var add = '<style>#something:before{content:"'+newValue+'"!important;}</style>';
    $('#changeBefore').click(function(){
        $('body').append(add);
    });
</script>

위의 "changeBefore"버튼을 클릭하면의 :before내용이 #something동적 값인 '22'로 변경 됩니다 .

도움이 되길 바랍니다


.css()특정 요소에 사용 하는 것과 같은 css-pseudo 규칙을 추가하기 위해 jQuery 플러그인을 만들었습니다 .

  • 플러그인 코드 및 테스트 케이스는 여기
  • 여기에 간단한 CSS 이미지 팝업으로 사용 사례

용법:

$('body')
  .css({
    backgroundColor: 'white'
  })
  .cssPseudo('after', {
    content: 'attr(title) ", you should try to hover the picture, then click it."',
    position: 'absolute',
    top: 20, left: 20  
  })
  .cssPseudo('hover:after', {
    content: '"Now hover the picture, then click it!"'
  });


 $('.span').attr('data-txt', 'foo');
        $('.span').click(function () {
         $(this).attr('data-txt',"any other text");
        })
.span{
}
.span:after{ 
  content: attr(data-txt);
 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class='span'></div>


이 목적으로 내 플러그인을 사용할 수 있습니다.

JQuery :

(function() {
  $.pseudoElements = {
    length: 0
  };

  var setPseudoElement = function(parameters) {
    if (typeof parameters.argument === 'object' || (parameters.argument !== undefined && parameters.property !== undefined)) {
      for (var element of parameters.elements.get()) {
        if (!element.pseudoElements) element.pseudoElements = {
          styleSheet: null,
          before: {
            index: null,
            properties: null
          },
          after: {
            index: null,
            properties: null
          },
          id: null
        };

        var selector = (function() {
          if (element.pseudoElements.id !== null) {
            if (Number(element.getAttribute('data-pe--id')) !== element.pseudoElements.id) element.setAttribute('data-pe--id', element.pseudoElements.id);
            return '[data-pe--id="' + element.pseudoElements.id + '"]::' + parameters.pseudoElement;
          } else {
            var id = $.pseudoElements.length;
            $.pseudoElements.length++

              element.pseudoElements.id = id;
            element.setAttribute('data-pe--id', id);

            return '[data-pe--id="' + id + '"]::' + parameters.pseudoElement;
          };
        })();

        if (!element.pseudoElements.styleSheet) {
          if (document.styleSheets[0]) {
            element.pseudoElements.styleSheet = document.styleSheets[0];
          } else {
            var styleSheet = document.createElement('style');

            document.head.appendChild(styleSheet);
            element.pseudoElements.styleSheet = styleSheet.sheet;
          };
        };

        if (element.pseudoElements[parameters.pseudoElement].properties && element.pseudoElements[parameters.pseudoElement].index) {
          element.pseudoElements.styleSheet.deleteRule(element.pseudoElements[parameters.pseudoElement].index);
        };

        if (typeof parameters.argument === 'object') {
          parameters.argument = $.extend({}, parameters.argument);

          if (!element.pseudoElements[parameters.pseudoElement].properties && !element.pseudoElements[parameters.pseudoElement].index) {
            var newIndex = element.pseudoElements.styleSheet.rules.length || element.pseudoElements.styleSheet.cssRules.length || element.pseudoElements.styleSheet.length;

            element.pseudoElements[parameters.pseudoElement].index = newIndex;
            element.pseudoElements[parameters.pseudoElement].properties = parameters.argument;
          };

          var properties = '';

          for (var property in parameters.argument) {
            if (typeof parameters.argument[property] === 'function')
              element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property]();
            else
              element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property];
          };

          for (var property in element.pseudoElements[parameters.pseudoElement].properties) {
            properties += property + ': ' + element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';
          };

          element.pseudoElements.styleSheet.addRule(selector, properties, element.pseudoElements[parameters.pseudoElement].index);
        } else if (parameters.argument !== undefined && parameters.property !== undefined) {
          if (!element.pseudoElements[parameters.pseudoElement].properties && !element.pseudoElements[parameters.pseudoElement].index) {
            var newIndex = element.pseudoElements.styleSheet.rules.length || element.pseudoElements.styleSheet.cssRules.length || element.pseudoElements.styleSheet.length;

            element.pseudoElements[parameters.pseudoElement].index = newIndex;
            element.pseudoElements[parameters.pseudoElement].properties = {};
          };

          if (typeof parameters.property === 'function')
            element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property();
          else
            element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property;

          var properties = '';

          for (var property in element.pseudoElements[parameters.pseudoElement].properties) {
            properties += property + ': ' + element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';
          };

          element.pseudoElements.styleSheet.addRule(selector, properties, element.pseudoElements[parameters.pseudoElement].index);
        };
      };

      return $(parameters.elements);
    } else if (parameters.argument !== undefined && parameters.property === undefined) {
      var element = $(parameters.elements).get(0);

      var windowStyle = window.getComputedStyle(
        element, '::' + parameters.pseudoElement
      ).getPropertyValue(parameters.argument);

      if (element.pseudoElements) {
        return $(parameters.elements).get(0).pseudoElements[parameters.pseudoElement].properties[parameters.argument] || windowStyle;
      } else {
        return windowStyle || null;
      };
    } else {
      console.error('Invalid values!');
      return false;
    };
  };

  $.fn.cssBefore = function(argument, property) {
    return setPseudoElement({
      elements: this,
      pseudoElement: 'before',
      argument: argument,
      property: property
    });
  };
  $.fn.cssAfter = function(argument, property) {
    return setPseudoElement({
      elements: this,
      pseudoElement: 'after',
      argument: argument,
      property: property
    });
  };
})();

$(function() {
  $('.element').cssBefore('content', '"New before!"');
});
.element {
  width: 480px;
  margin: 0 auto;
  border: 2px solid red;
}

.element::before {
  content: 'Old before!';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

<div class="element"></div>

jQuery.css의 일반 기능과 같이 값을 지정해야합니다.

또한 jQuery.css의 일반 함수 에서처럼 유사 요소 매개 변수의 값을 가져올 수도 있습니다.

console.log( $(element).cssBefore(parameter) );

JS :

(function() {
  document.pseudoElements = {
    length: 0
  };

  var setPseudoElement = function(parameters) {
    if (typeof parameters.argument === 'object' || (parameters.argument !== undefined && parameters.property !== undefined)) {
      if (!parameters.element.pseudoElements) parameters.element.pseudoElements = {
        styleSheet: null,
        before: {
          index: null,
          properties: null
        },
        after: {
          index: null,
          properties: null
        },
        id: null
      };

      var selector = (function() {
        if (parameters.element.pseudoElements.id !== null) {
          if (Number(parameters.element.getAttribute('data-pe--id')) !== parameters.element.pseudoElements.id) parameters.element.setAttribute('data-pe--id', parameters.element.pseudoElements.id);
          return '[data-pe--id="' + parameters.element.pseudoElements.id + '"]::' + parameters.pseudoElement;
        } else {
          var id = document.pseudoElements.length;
          document.pseudoElements.length++

            parameters.element.pseudoElements.id = id;
          parameters.element.setAttribute('data-pe--id', id);

          return '[data-pe--id="' + id + '"]::' + parameters.pseudoElement;
        };
      })();

      if (!parameters.element.pseudoElements.styleSheet) {
        if (document.styleSheets[0]) {
          parameters.element.pseudoElements.styleSheet = document.styleSheets[0];
        } else {
          var styleSheet = document.createElement('style');

          document.head.appendChild(styleSheet);
          parameters.element.pseudoElements.styleSheet = styleSheet.sheet;
        };
      };

      if (parameters.element.pseudoElements[parameters.pseudoElement].properties && parameters.element.pseudoElements[parameters.pseudoElement].index) {
        parameters.element.pseudoElements.styleSheet.deleteRule(parameters.element.pseudoElements[parameters.pseudoElement].index);
      };

      if (typeof parameters.argument === 'object') {
        parameters.argument = (function() {
          var cloneObject = typeof parameters.argument.pop === 'function' ? [] : {};

          for (var property in parameters.argument) {
            cloneObject[property] = parameters.argument[property];
          };

          return cloneObject;
        })();

        if (!parameters.element.pseudoElements[parameters.pseudoElement].properties && !parameters.element.pseudoElements[parameters.pseudoElement].index) {
          var newIndex = parameters.element.pseudoElements.styleSheet.rules.length || parameters.element.pseudoElements.styleSheet.cssRules.length || parameters.element.pseudoElements.styleSheet.length;

          parameters.element.pseudoElements[parameters.pseudoElement].index = newIndex;
          parameters.element.pseudoElements[parameters.pseudoElement].properties = parameters.argument;
        };

        var properties = '';

        for (var property in parameters.argument) {
          if (typeof parameters.argument[property] === 'function')
            parameters.element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property]();
          else
            parameters.element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property];
        };

        for (var property in parameters.element.pseudoElements[parameters.pseudoElement].properties) {
          properties += property + ': ' + parameters.element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';
        };

        parameters.element.pseudoElements.styleSheet.addRule(selector, properties, parameters.element.pseudoElements[parameters.pseudoElement].index);
      } else if (parameters.argument !== undefined && parameters.property !== undefined) {
        if (!parameters.element.pseudoElements[parameters.pseudoElement].properties && !parameters.element.pseudoElements[parameters.pseudoElement].index) {
          var newIndex = parameters.element.pseudoElements.styleSheet.rules.length || parameters.element.pseudoElements.styleSheet.cssRules.length || parameters.element.pseudoElements.styleSheet.length;

          parameters.element.pseudoElements[parameters.pseudoElement].index = newIndex;
          parameters.element.pseudoElements[parameters.pseudoElement].properties = {};
        };

        if (typeof parameters.property === 'function')
          parameters.element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property();
        else
          parameters.element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property;

        var properties = '';

        for (var property in parameters.element.pseudoElements[parameters.pseudoElement].properties) {
          properties += property + ': ' + parameters.element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';
        };

        parameters.element.pseudoElements.styleSheet.addRule(selector, properties, parameters.element.pseudoElements[parameters.pseudoElement].index);
      };
    } else if (parameters.argument !== undefined && parameters.property === undefined) {
      var windowStyle = window.getComputedStyle(
        parameters.element, '::' + parameters.pseudoElement
      ).getPropertyValue(parameters.argument);

      if (parameters.element.pseudoElements) {
        return parameters.element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] || windowStyle;
      } else {
        return windowStyle || null;
      };
    } else {
      console.error('Invalid values!');
      return false;
    };
  };

  Object.defineProperty(Element.prototype, 'styleBefore', {
    enumerable: false,
    value: function(argument, property) {
      return setPseudoElement({
        element: this,
        pseudoElement: 'before',
        argument: argument,
        property: property
      });
    }
  });
  Object.defineProperty(Element.prototype, 'styleAfter', {
    enumerable: false,
    value: function(argument, property) {
      return setPseudoElement({
        element: this,
        pseudoElement: 'after',
        argument: argument,
        property: property
      });
    }
  });
})();

document.querySelector('.element').styleBefore('content', '"New before!"');
.element {
  width: 480px;
  margin: 0 auto;
  border: 2px solid red;
}

.element::before {
  content: 'Old before!';
}
<div class="element"></div>


GitHub : https://github.com/yuri-spivak/managing-the-properties-of-pseudo-elements/


다른 누군가가 전체 스타일 요소를 사용하여 헤드 요소에 추가하는 것에 대해 언급했으며 한 번만 수행하는 경우 나쁘지 않지만 두 번 이상 재설정해야하는 경우 많은 스타일 요소로 끝납니다. 따라서 머리에 빈 스타일 요소를 id로 만들고 다음과 같이 innerHTML을 대체하는 것을 방지합니다.

<style id="pseudo"></style>

그러면 JavaScript는 다음과 같습니다.

var pseudo = document.getElementById("pseudo");

function setHeight() {
    let height = document.getElementById("container").clientHeight;
    pseudo.innerHTML = `.class:before { height: ${height}px; }`
}

setHeight()

이제 제 경우에는 다른 높이를 기준으로 이전 요소의 높이를 설정하는 데 이것이 필요했으며 크기가 조정되면 변경되므로 setHeight()창 크기가 조정될 때마다 실행할 수 있으며 <style>제대로 대체 됩니다.

똑같은 일을하려고 애쓰던 사람에게 도움이되기를 바랍니다.


I에 정의 변수를 사용하여 만들어진 :root내부 CSS수정하는 :after(동일한가 적용되는 :before) 가상 요소는 , 특히 변동 background-colorA는 서식이 가치 anchor에 의해 정의 .sliding-middle-out:hover:after되고 content다른 가치 anchor( #reference다음의) 데모 자바 스크립트를 사용하여 임의의 색을 생성 / jQuery :

HTML

<a href="#" id="changeColor" class="sliding-middle-out" title="Generate a random color">Change link color</a>
<span id="log"></span>
<h6>
  <a href="https://stackoverflow.com/a/52360188/2149425" id="reference" class="sliding-middle-out" target="_blank" title="Stack Overflow topic">Reference</a>
</h6>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/davidmerfield/randomColor/master/randomColor.js"></script>

CSS

:root {
    --anchorsFg: #0DAFA4;
}
a, a:visited, a:focus, a:active {
    text-decoration: none;
    color: var(--anchorsFg);
    outline: 0;
    font-style: italic;

    -webkit-transition: color 250ms ease-in-out;
    -moz-transition: color 250ms ease-in-out;
    -ms-transition: color 250ms ease-in-out;
    -o-transition: color 250ms ease-in-out;
    transition: color 250ms ease-in-out;
}
.sliding-middle-out {
    display: inline-block;
    position: relative;
    padding-bottom: 1px;
}
.sliding-middle-out:after {
    content: '';
    display: block;
    margin: auto;
    height: 1px;
    width: 0px;
    background-color: transparent;

    -webkit-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    -moz-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    -ms-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    -o-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
}
.sliding-middle-out:hover:after {
    width: 100%;
    background-color: var(--anchorsFg);
    outline: 0;
}
#reference {
  margin-top: 20px;
}
.sliding-middle-out:before {
  content: attr(data-content);
  display: attr(data-display);
}

JS / jQuery

var anchorsFg = randomColor();
$( ".sliding-middle-out" ).hover(function(){
    $( ":root" ).css({"--anchorsFg" : anchorsFg});
});

$( "#reference" ).hover(
 function(){
    $(this).attr("data-content", "Hello World!").attr("data-display", "block").html("");
 },
 function(){
    $(this).attr("data-content", "Reference").attr("data-display", "inline").html("");
 }
);

참고 URL : https://stackoverflow.com/questions/5041494/selecting-and-manipulating-css-pseudo-elements-such-as-before-and-after-usin

반응형