如何使用JavaScript更改伪元素:before的内容值

65

我有一个使用CSS构建的图形,它会在JS的动态更改下进行改变。我使用pseudo元素来显示图表最大值:

.graph:before {
    content:""; //value that want set by JS
    position:absolute;
    top:0;
    left:0;
}

这就是为什么我需要通过JS设置这个值的原因。我尝试了$(".graph:before").css("content", hh);,但没有成功。如何获取那个值?


7
请参考类似的问题:https://dev59.com/J2445IYBdhLWcg3wGWd7 - antyrat
使用jQuery在2016年是可行的。 - Abhay Maurya
内容是一个 String;在2019年中它是:**.style.setProperty('--varname',"${value}");** - Danny '365CSI' Engelman
8个回答

112
我希望以下代码片段能够帮到您,您可以使用CSS attr()函数通过JS指定所需的content值。 下面有两个选项:使用JavaScript或jQuery:

jQuery:

$('.graph').on('click', function () {
    //do something with the callback
    $(this).attr('data-before','anything'); //anything is the 'content' value
});

JavaScript:

var graphElem = document.querySelector('.graph');
graphElem.addEventListener('click', function (event) {
    event.target.setAttribute('data-before', 'anything');
});

CSS:
.graph:before {
    content: attr(data-before); /* value that that refers to CSS 'content' */
    position:absolute;
    top: 0;
    left: 0;
}

@RhysvanderWaerden 所引用的网站指的是 attr() 函数在除了 content 以外的属性上缺乏支持。否则,这个解决方案的支持范围似乎相当广泛(https://www.w3schools.com/cssref/func_attr.asp)。 - JustinStolle
1
你知道如何通过这种方法发送Unicode吗? - godblessstrawberry
2
@godblessstrawberry,我有同样的问题,并在如何使用Unicode上找到了答案,这里提供了示例:<p><a href="#" data-fa-icon="&#xf206;"> Unicode example</a></p> - Jacques
1
这个解决方案非常聪明(在我看来),很好地解决了我的问题,谢谢@santosh-d! - vcoppolecchia
1
非常有帮助的解决方案。 - Payel Dutta
显示剩余2条评论

36

更新 (2018):正如在评论中提到的,现在您可以这样做。

由于伪元素不是DOM的一部分,因此无法通过JavaScript修改它们。 您最好的选择是在CSS中定义另一个带有所需样式的类,然后将其添加到元素中。 由于从您的问题中看来这似乎是不可能的,也许您需要考虑使用真正的DOM元素而不是伪元素。


@JamesAllardice 这似乎是CSS或JS阵营中令人困惑的决定,你知道更多相关背景吗? - tim peterson
2
@timpeterson - 伪元素存在的目的是提供一种访问文档中不可访问信息的方法。它们从未被设计为可以从文档内部进行访问。请查看CSS规范中有关“生成内容”的章节(http://www.w3.org/TR/css3-content/#pseudo-elements)。 - James Allardice
6
有点晚参加这个聚会,但是对于未来的读者,这并不完全正确。你无法直接使用JS修改伪元素,但你可以使用javascript修改元素属性,而伪元素可以“读取”。请查看上面链接的问题:https://dev59.com/J2445IYBdhLWcg3wGWd7 - goldins
“你不能通过JavaScript修改伪元素,因为它们不是DOM的一部分。” 真的吗? - xgqfrms
也许你应该先阅读这篇文章!@james-allardice https://dev59.com/A1cP5IYBdhLWcg3weJ5R#44342130 - xgqfrms
1
这已经不再是真实的情况了。下面的答案证明你是可以的。 - tatsu

31

1
好的解决方案,但似乎无法设置“content”属性。如果有人知道如何做到这一点,请发一个例子。 - TwoFingerRightClick

12
我认为可以使用attr()函数来指定伪元素的内容,以下是一个使用"title"属性的工作示例,但也适用于自定义属性。
document.getElementById('btn_change1').addEventListener("click", function(){
    document.getElementById('test_div').title='Status 1';
});
   
document.getElementById('btn_change2').addEventListener("click", function(){       
    document.getElementById('test_div').title='Status 2';
});
#test_div {
   margin: 4em;
   padding:2em;
   background: blue;
   color: yellow;
}

#test_div:after {
   content:attr(title);
   background: red;
   padding:1em;
}
<button id='btn_change1'>Change div:after to [Status 1]</button>
<button id='btn_change2'>Change div:after to [Status 2]</button>

<div id='test_div' title='Initial Status'>The element to modify</div>


6

对于仍在寻找解决相同问题的人,可以使用jQuery按以下方式进行操作:

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

这个例子说明了当点击按钮changeBefore时,.graph:before的值将根据其新的动态值而改变。
要更详细地描述如何更改:before: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。您可以按以下方式实现: 在某个类.activeS上定义所需样式的CSS:
.activeS:before{
   color:green !important;
   font-size:30px !important;
 }

现在您可以通过将类添加到: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>

希望它能帮助到你


最佳答案在这里。append(prepend)起作用了,而其他方法(attr、html等)则没有。我确实添加了上面答案中的CSS,这是清除已有内容的最佳方法。 - tatsu
1
谢谢,我很高兴它能帮到你! - Abhay Maurya

1
您可以使用document.styleSheets来修改伪选择器cssRules。
document.styleSheets[0].cssRules[0].style.content = '"111"';

这告诉我们实际上是可以做到的,而不需要使用 content: attr(...)(我几乎会为此点赞),但是应该这样做吗?只有当你希望将 Twitter 个人简介从“Web 应用程序开发者”更改为“一个项目的维护者”时才这样做。 - s3c

1

我曾遇到类似的问题,但是是关于图标的。我需要在HTML5音频播放器中切换播放和暂停图标。

问题在于HTML、CSS和jQuery都会因为使用\符号而对"content"值解释不同,导致图标无法正常显示。

因此,最好的解决方法是删除并重新创建节点。以下是我的代码:

<ul class="list list--buttons">
    <li><a href="#" class="list__link previuos"><i class="fa fa-step-backward"></i></a></li>

    <li><a href="#" class="list__link playpause"><i class="fa fa-play"></i></a></li>

    <li><a href="#" class="list__link next"><i class="fa fa-step-forward"></i></a></li>
</ul>

和脚本

<script type="text/javascript">
            $(
                function(){
                    var aud = $('audio')[0];
                    $('.playpause').on('click', function(e){
                        e.preventDefault();
                    if (aud.paused) {
                        aud.play();
                        /* from play icon to pause icon */
                        $('.playpause .fa-play').remove();
                        $('.playpause').append('<i class="fa fa-pause"></i>');
                    }
                    else {
                        aud.pause();
                        /* from play icon to pause icon */
                        $('.playpause .fa-pause').remove();
                        $('.playpause').append('<i class="fa fa-play"></i>');
                    }

                })
                $('.next').on('click', function(e){
                    e.preventDefault();
                    aud.src = '{$content:audio-file}';
                })
                $('.previuos').on('click', function(e){
                    e.preventDefault();
                    aud.src = '{$content:audio-file}';
                })
                aud.ontimeupdate = function(){
                    $('.progress').css('width', aud.currentTime / aud.duration * 100 + '%')
                }
            })
        </script>

希望它有所帮助!

-1

如果您使用类似于onoffswitch的东西,并且想要使用i18next翻译css内容属性,则可以使用github(i18next Jquery Framework)中的i18next Framework示例,然后使用以下代码扩展该函数:

var before = i18next.t('onoffswitch.before');
var after = i18next.t('onoffswitch.after');
$('.onoffswitch-inner')
    .attr('data-before', before )
    .attr('data-after', after );

而且CSS代码必须是这样的:

.onoffswitch-inner:before {
    content:  attr(data-before);
    padding-left: 10px;
    background-color: #65AFF5; color: #FFFFFF;
}
.onoffswitch-inner:after {
    content:  attr(data-after);
    padding-right: 10px;
    background-color: #EEEEEE; color: #999999;
    text-align: right;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接