利用javascript获取并修改伪元素的值

虽然标题里写的是伪元素,不过这篇文章主要是说::before::after,其余几个伪元素(::first-letter::first-line::selection等)由于没有content属性,所以本文一笔带过,其实方法是一样的。
伪元素的重点在于一个,虽然它们可以被浏览器渲染引擎识别并正确渲染,然而伪元素本身并不是DOM元素,所以无法被js直接操作——因此任何基于JS直接选取DOM元素的CSS更改方法对伪元素都不起作用。(JQ看似万能,这个问题上是直接就栽了。因为JQ的选择符都是基于DOM元素)关于JS和JQ选择器,可以参考这两篇文档: Selectors API Level 1jQuery Selectors

获取伪元素的属性值

虽然JS里没有可以直接操作伪元素的选择符,然而获取其CSS属性的方法还是有的。

window.getComputedStyle

利用window.getComputedStyle方法选择到伪元素,然后利用getPropertyValue方法获取对应的属性的值。
根据MDN的文档

window.getComputedStyle(element[, pseudoElt]);

此方法包含两个参数,一个是元素本身另一个是元素的伪元素。
js语法实例(完整DEMO在线链接):

var div=document.querySelector(‘div‘);
var fontSize=window.getComputedStyle(div,‘::before‘).getPropertyValue(‘font-size‘);//获取before伪元素的字号大小

关于这个方法,详解可以参考这篇文章:
获取元素CSS值之getComputedStyle方法熟悉


更改伪元素的属性值

window.getComputedStyle方法虽然可以获取到伪元素的属性值,然而根据该方法名字也知道其只能获取CSS样式,并无法更改css属性,那么如果想要用js动态更改伪元素属性值的话,该怎么处理呢?
思路有以下几个:

  1. js更改data-*属性值来更改伪元素的content
  2. 创建多个class,通过切换class来达到改变样式的目的
  3. 利用CSSStyleSheet的insertRule方法来添加样式
  4. 利用内部css样式的高优先级来覆盖外部css

以上实现思路的推荐程度依次递减

利用DOM的data-*属性来更改content的值

data-*是HTML5新增的DOM元素属性,作用大致可以理解为标记。具体用法可以参考MDN的这篇文章.而伪元素的content属性值除了常规赋值外,还有一种特殊的attr()方法来获取。
HTML:

<div class="test" data-text="TEXT" data-color="red"></div>

CSS:

.test::before{
    content: attr(data-text);
}

结果:

TEXT

另外content其实可以多个attr连写,而且attr()内的可以是DOM元素的任意属性(比如class等,甚至非W3C标准属性也支持,不过不推荐这么做)所以很方便凑一些模版文字。像下面这种写法也是完全没问题的。注意用空格连接,不要用"+"号。
EXAM:

.test::before {
  content: ‘我的类是‘ attr(class) ‘想要变成‘ attr(data-color);
}

虽然W3C给attr()赋予了无限可能性,包括color,width等属性在未来都有希望用这个方法更改,然而目前只有content支持该方法,其余的都还是草稿状态,尚未有浏览器支持。之所以把这个方法放在第一位只是因为相比别的实现手法来说,这个方法真的太简单太优雅。



但是如果真的想要改伪元素里的color等元素呢?

更改class来实现伪元素样式的更改

把这个方法放到推荐位第二位估计会被很多人骂我:“卧槽,这么简单又没逼格的办法你竟然放到第二位!太没水平了”。不过再看完后面两种方法后或许你会对这种看法有所改观。
这个方法的优点是简单好用且无兼容性问题。缺点是多了一些其实用处不大的class,很像是jQuery类选择器中毒患者的做法;另外不适合多状态的场景(比如实时改变伪元素文字大小等)。
实现过于简单就不贴代码了。



前面的class切换大法可能让人感觉不痛快,这里来个高大上(伪)点的方法:

利用CSSStyleSheet的insertRule方法来添加样式

这部分内容和W3C标准牵连比较多,加上较冷门,没多少人关注,个人目前啃不动标准,所以这部分内容不会做深入分析,理解可能也会有问题,望斧正。

CSSStyleSheet是浏览器存放页面内所有css样式表的对象方法(不包括行内样式),每个linkstyle标签都代表一个CSSStyleSheet对象,获取他们可以用document.styleSheets方法。(需要注意的是虽然styleSheets方法返回的结果把link标签引进的外部样式也算进去了,但是非IE浏览器没办法获取到他们的cssRules属性,只有内嵌的style标签内的元素可以被获取到)

document.styleSheets[0].insertRule(‘.test::before{color:green}‘,0)//chrome,firefox等非IE浏览器使用
document.styleSheets[0].addRule(‘.test::before{color:green}‘,0)//IE系列浏览器使用
/* 虽然部分浏览器也可以通过id来指定,‘document.styleSheets.id.insertRule()‘这种写法在chrome和IE下都行得通,但是firefox会返回‘undefined‘,所以建议还是使用index值来获取stylesheet */

.insertRule的语法是stylesheet.insertRule(rule, index),另一个参数是index,意思是在对应的styleSheets里的cssRules样式表中的位置,这个值越大则样式优先级越高,但是值不能超过当前样式表规则(cssRules)长度(CSS中先定义的样式总是会被后定义的覆盖就是这个缘故。),当值小于cssRules长度时,添加的样式规则会插入到index值定义的位置,之前其余的规则依次顺延。

addruleinsertRule方法本质上没区别,只是后者不被IE浏览器识别,所以前者作为浏览器兼容方法存在。(下文为节省篇幅,以insertRule方法指代此两种方法。)

上面的代码看似简单一行,然而却不是每次都有效的。原因有以下几点:

  1. document.styleSheets虽然按照stylelink的顺序返回对应的StyleSheetList,然而第一个如果是link而不是style,前面讲过此时无法获取对应的cssRules,则document.styleSheets[0].cssRulesnullinsertRule方法不起作用。(此情况只针对非IE浏览器,IE浏览器正常,但是定义的早往往意味着被后面的样式覆盖,所以意义不大)
  2. 同上,如果页面内没有内嵌样式的style标签,则insertRule方法也无法发挥作用。
  3. index值不够大的话很有可能会早于css文件开始的定义位置,导致被覆盖。因此有个折衷办法就是给添加的样式增加!important,虽然我个人比较反感这么做。

由此可见此方法的局限性,但是这种方法的优雅之处在于避免了直接写内嵌样式,而是通过css api来做更改。相比下面的方法来说,稍微好点。



但是这种方法好像局限性有点大啊?

HEAD中添加style标签强制覆盖初始属性

这个方法是利用内部css样式的高优先级来覆盖外部css,好处是简单易理解,实现简单。坏处就是吃相太难看,过于粗暴。

var style=document.createElement(‘style‘);
style.innerHTML=".test::before{color:green}";//添加样式内容的话也可以用上面提到过的`insertRule`,相对例子里的硬编码会更优雅点。
document.head.appendChild(style);

看到这里可能有些人反应过来了,其实加style标签这种方法可以是insertRule实现方法的大前提——因为不是所有页面一开始都有内嵌的style样式的。这种方法虽然不是很好,但是有时候却又确确实实是必须的——比如“拖动滑块改变伪元素内文字大小”这个需求。

转载:https://segmentfault.com/a/1190000003711146

原文地址:https://www.cnblogs.com/liangjing-yy/p/9028660.html

时间: 2024-08-29 10:44:53

利用javascript获取并修改伪元素的值的相关文章

JavaScript获取DOM节点HTML元素CSS样式

JavaScript获取DOM节点HTML元素CSS样式技术 maybe yes 发表于2015-01-10 18:07 原文链接 : http://blog.lmlphp.com/archives/59  来自 : LMLPHP后院 如何使用 JavaScript 获取某个 DOM 节点下 HTML 元素的 CSS 样式值?使用过 JQuery 的童鞋一定都非常的熟悉,Jquery 提供了非常强大的 CSS 方法,可以很方便的设置和获取元素的 style 属性. 某些情况下,我们不能使用 JQ

JQuery获取与设置HTML元素的值value

JQuery获取与设置HTML元素的值value 作者:简明现代魔法图书馆 发布时间:2011-07-07 10:16:13 20481 次阅读 服务器君一共花费了13.221 ms进行了6次数据库查询,努力地为您提供了提供了这个页面. val()方法 此方法类似于JavaScript中的value属性,可以用来设置和获取元索的值.无论元素是文本框,下拉列表还足单选框,它都可以返回元素的值.如果元素为多选,则返回一个包含所有选择的值的数组.先看看下面的效果演示: 欢迎访问简明现代魔法图书馆 简单

jQuery获取表单各元素的值

radio值获取 $("input[type='radio']:checked").val(); 2,设置指定的项为当前选中项 $("input[type='radio']").eq(1).attr("checked",true);//设置第二项为选中项 <input type="text" name="textname" id="text_id" value="&quo

javascript获取数组最后一个元素(三种方法)

JavaScript 获取Array末尾元素 一.JavaScript pop() 方法 pop() 方法用于删除并返回数组的最后一个元素. 注意:pop() 方法将删除 arrayObject 的最后一个元素,把数组长度减 1,并且返回它删除的元素的值.如果数组已经为空,则 pop() 不改变数组,并返回 undefined 值. var arr = new Array("js","JavaScript","jQuery"); var end

利用javascript获取url中的传值并创建页面元素

url传值: 在地址后附加 ?键1=值1&键2=值2&键3=值3... ...(注意:该方法会将参数显示在地址栏中,传入的值应该不影响网站安全和透露网站内部信息) <script type="text/javascript"> //该函数将获取url中的键值组合,并通过传入的键参数返回键所对应的值 function getvl(name) { var reg = new RegExp("(^|\\?|&)" + name + &q

19 01 11 javascript 获取某一种元素(所有的标签) 以及字符串处理的方法

获取元素方法二 可以使用内置对象document上的getElementsByTagName方法来获取页面上的某一种标签,获取的是一个选择集,不是数组,但是可以用下标的方式操作选择集里面的标签元素. 注意 拿出来的是一个数组   所以不能直接进行操作 <script type="text/javascript"> window.onload = function(){ var aLi = document.getElementsByTagName('li'); // aLi

利用JavaScript获取页面文档内容

JavaScript的document对象包含了页面的实际内容,所以利用document对象可以获取页面内容,例如页面标题.各个表单值. 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>js基础</title> 6 7 </head> 8 9 <body> 10

JavaScript获取浏览器窗口、元素、屏幕的大小

在实现页面的某些效果时,我们经常会用到JavaScript去获取浏览器窗口,页面中元素和屏幕的大小,而这三个的大小在不同的浏览器中获取的方式有所不同,所以不得不处理一些兼容性问题. 一.屏幕的大小 首先来看屏幕大小,什么是屏幕大小呢?屏幕大小是指当前所用设备的屏幕的分辨率(浏览器窗口外部显示器的大小),它一般是不变的.它们可以通过JavaScript中的screen对象的属性获取. screen.height:屏幕的像素高度: screen.width:屏幕的像素宽度: screen.avail

JavaScript获取相同id的元素

在servlet里,你可以直接使用 1 String[] property=request.getParameterValues("property");//属性 来获取相同id的属性值.但是在js里,这是行不通的.我们只有采用寻找结点的方式来获取元素.使用这种方法的话,id是否相同对我们来说已经是透明的了. 1 property[0]=$("#property").val(); 2 relation[0]=$("#relation").val(