前面的话

  我们可以通过计算样式来读取伪元素的样式信息,但是却无法使用javascript来直接操作伪元素,本文以一个需求解决为例,详细介绍脚本化伪元素的6种方法

需求说明

  【1】为id=box的div元素添加content="前缀"的:before伪元素

  【2】为已经添加:before伪元素的div元素删除伪元素

   [注意]由于IE7-浏览器不支持:before伪元素,所以该需求兼容到IE8

添加伪元素

动态样式

  可以采用动态样式的方法,动态生成<style>标签及相关的伪元素样式内容

  由于IE8-浏览器将<style>标签当作特殊的节点,不允许访问其子节点及设置innerHTML属性,需要使用CSSStyleSheet对象的cssText属性来实现兼容

<div id="box">测试文字</div>
<button id="btn">添加伪元素</button>
<script>
//添加伪元素
function loadStyles(str){
//设置标记,防止重复添加
loadStyles.mark = 'load';
var style = document.createElement("style");
style.type = "text/css";
try{
style.innerHTML = str;
}catch(ex){
//IE8-浏览器兼容
style.styleSheet.cssText = str;
}
var head = document.getElementsByTagName('head')[0];
head.appendChild(style);
}
btn.onclick = function(){
//当样式表没有添加过时,添加
if(loadStyles.mark != 'load'){
loadStyles("#box:before{content:'前缀';color: red;}");
}
}
</script>

添加自带伪元素的类名

  在处理大量CSS样式时,一般采用脚本化CSS类的方法。而添加伪元素,也可以使用类似的技术。把伪元素的样式挂在一个新类名上,然后把元素的className设置为新类名

<style>
.add:before{content: "前缀";color: blue;}
</style> <div id="box">测试文字</div>
<button id="btn">添加伪元素</button>
<script>
btn.onclick = function(){
box.className = 'add';
}
</script>

利用setAttribute()方法实现自定义伪元素内容

  若使用方法二,无法自定义伪元素的内容,拓展性不高

  伪元素的content属性非常强大,它的值可以有以下选择,关于content属性的详细信息移步至此

content:<string>|<uri>|attr(<identifier>)

  使用content属性中的attr()值配合setAttribute()方法就可以实现自定义伪元素的内容

  IE8-浏览器需要在元素特性中出现data-beforeData(设置为空字符串即可),才有效果;其他浏览器无此问题

<style>
#box:before{content: attr(data-beforeData);color: red;}
</style> <!--为了兼容IE8-,需要在元素特性中设置 data-beforeData=""-->
<div id="box" data-beforeData="">测试文字</div>
<button id="btn">添加伪元素</button>
<script>
btn.onclick = function(){
box.setAttribute('data-beforeData','前缀');
}
</script>

dataset

  HTML5新增了dateset数据集特性,将元素特性和对象属性联系在了一起

  [注意]IE10-浏览器不支持

  如果不考虑兼容,同样可以实现dateset来实现,但是由于dataset的解释规则,元素特性的值不可以出现大写,需要进行局部修改

  经测试,IE11浏览器不支持使用dateset动态修改伪元素

<style>
#box:before{content: attr(data-before);color: red;}
</style> <div id="box">测试文字</div>
<button id="btn">添加伪元素</button>
<script>
btn.onclick = function(){
box.dataset.before = '前缀';
}
</script>

通过CSSRule对象添加样式

  虽然伪元素的样式无法通过操作行间样式来直接添加,但是可以通过CSSRule对象通过操作内部样式表实现

  如果存在内部样式表,即存在<style>标签,则直接在<style>标签中添加样式;否则先新建<style>标签,再添加样式

<div id="box">测试文字</div>
<button id="btn">添加伪元素</button>
<script>
//作为存在<style>标签的标记,1表示存在,0表示不存在
var mark = 0;
var tags = document.getElementsByTagName('*');
function addStyle(obj){
var str = '#box:before{content:"前缀";color: pink;}';
var sheet = obj.sheet || obj.styleSheet;
var rules = sheet.cssRules|| sheet.rules;
for(var i = 0,len = rules.length; i < len; i++){
//如果已经设置了:before伪元素的样式,就不再重复添加
if(/:before/.test(rules[i].selectorText)){
//obj.mark表示是否设置了:before伪元素的样式,1为已设置,0为未设置
obj.mark = 1;
break;
}
}
//如果未设置伪元素样式
if(!obj.mark){
if(sheet.insertRule){
sheet.insertRule('#box:before{content:"前缀";color:green;}',0);
}else{
sheet.addRule('#box:before','content:"前缀";color:green;',0);
}
}
}
btn.onclick = function(){
for(var i = 0; i < tags.length; i++){
if(tags[i].nodeName == 'STYLE'){
mark = 1;
//添加伪元素
addStyle(tags[i]);
break;
}
}
if(!mark){
//新建<style>标签
var ele = document.createElement('style');
document.getElementsByTagName('head')[0].appendChild(ele);
//添加伪元素
addStyle(ele);
}
}
</script>

删除伪元素

  相比于新增伪元素来说,删除伪元素要困难一些。因为<style>元素中可能还有许多其他的样式,所以只能通过覆盖或删除指定样式来实现

空样式覆盖

  使用优先级更高的:before伪元素的空样式来覆盖原有样式

<style>
#box:before{content:"前缀";color:green;}
.remove:before{content:""!important;}
</style> <div id="box">测试文字</div>
<button id="btn">删除伪元素</button>
<script>
btn.onclick = function(){
box.className = 'remove';
}
</script>

通过CSSRule对象删除指定

  通过selectorText找出CSSRule对象中的:before伪元素的CSS规则

  [注意]在IE8浏览器中,:before伪元素选择器文本会自动将冒号置为单冒号,而其他浏览器会自动将冒号置为双冒号

  然后使用deleteRule()方法或removeRule()方法删除指定样式

<style>
#box::before{content:"前缀";color:green;}
</style> <div id="box">测试文字</div>
<button id="btn">删除伪元素</button>
<script>
function deleteStyles(){
var sheet = document.styleSheets[0];
var rules = sheet.cssRules || sheet.rules;
for(var i = 0; i < rules.length; i++){
//找出伪元素
if(/#box:(:)?before/.test(rules[i].selectorText)){
if(sheet.deleteRule){
sheet.deleteRule(i);
//兼容IE8-浏览器
}else{
sheet.removeRule(i);
}
}
}
}
btn.onclick = function(){
deleteStyles();
}
</script>

最后

  脚本化CSS系列终于完结了,基本上把使用javascript操作CSS的内容都囊括了

  【1】脚本化行间样式

  【2】查询计算样式

  【3】脚本化CSS类

  【4】脚本化样式表

  【5】动态样式

  【6】脚本化伪元素

  欢迎交流

深入理解脚本化CSS系列第六篇——脚本化伪元素的6种方法的更多相关文章

  1. 深入理解脚本化CSS系列第三篇——脚本化CSS类

    前面的话 在实际工作中,我们使用javascript操作CSS样式时,如果要改变大量样式,会使用脚本化CSS类的技术,本文将详细介绍脚本化CSS类 style 我们在改变元素的少部分样式时,一般会直接 ...

  2. 深入理解脚本化CSS系列第四篇——脚本化样式表

    × 目录 [1]CSSStyleSheet [2]CSSRule 前面的话 关于脚本化CSS,查询样式时,查询的是计算样式:设置单个样式时,设置的是行间样式:设置多个样式时,设置的是CSS类名.脚本化 ...

  3. 深入理解脚本化CSS系列第五篇——动态样式

    前面的话 很多时候,DOM操作比较简单明了,因此用javascript生成那些通常原本是HTML代码生成的内容并不麻烦.但由于浏览器充斥着隐藏的陷阱和不兼容问题,处理DOM中的某些部分时要复杂一些,比 ...

  4. 深入理解DOM事件类型系列第六篇——加载事件

    前面的话 提到加载事件,可能想到了window.onload,但实际上,加载事件是一大类事件,本文将详细介绍加载事件 load load事件是最常用的一个事件,当页面完全加载后(包括所有图像.java ...

  5. 用 CSS 隐藏页面元素的 5 种方法

    原文链接:用 CSS 隐藏页面元素的 5 种方法,转载请注明来源! 用 CSS 隐藏页面元素有许多种方法.你可以将 opacity 设为 0.将 visibility 设为 hidden.将 disp ...

  6. CSS 隐藏页面元素的 几 种方法总结

    用 CSS 隐藏页面元素有许多种方法.你可以将 opacity 设为 0.将 visibility 设为 hidden.将 display 设为 none 或者将 position 设为 absolu ...

  7. CSS魔法堂:一起玩透伪元素和Content属性

    前言  继上篇<CSS魔法堂:稍稍深入伪类选择器>记录完伪类后,我自然而然要向伪元素伸出"魔掌"的啦^_^.本文讲讲述伪元素以及功能强大的Contet属性,让我们可以通 ...

  8. css隐藏元素的几种方法与区别

    css隐藏元素的几种方法与区别 一:display:none;隐藏不占位 display 除了不能加入 CSS3 动画豪华大餐之外,基本效果卓越,没什么让人诟病的地方. 二:position:abso ...

  9. 用css隐藏元素的5种方法

    .green { width: 100px; height: 100px; background-color: #a0ee00; text-align: center; float: left; ma ...

随机推荐

  1. PHP 分页函数

    如果如下:

  2. SRM 628 DIV2

    250  想想就发现规律了. 500  暴力,括号匹配. 1000 给一个f数组,如果i存在,那么f[i]也得存在,问这样的集合有多少种. 先拓扑一下,dp[i] = mul(dp[son]+1)最后 ...

  3. iDB是如何运转的 一

    郑昀 创建于2015/12/2 最后更新于2015/12/4 关键词:数据库,MySQL,自动化运维,DDL,DML,SQL审核,备份,回滚,Inception,osc 提纲: 普通DBA和文艺DBA ...

  4. nginx android app 慢网络请求超时

    最近遇到了android 在慢网络下面请求服务器报 java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by ...

  5. Struts2的OGNL表达式语言

    一.OGNL的概念 OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者 ...

  6. The Practical Guide to Empathy Maps: 10-Minute User Personas

    That’s where the empathy map comes in. When created correctly, empathy maps serve as the perfect lea ...

  7. EL表达式判断

    今天在做开发时遇到个小问题,就百度一番很快找到答案.这里记一下免得以后到处找... 在项目中显示项目名称时因为名字太长所以影响我的样式问题. 解决办法就是将固定长度之后的用"..." ...

  8. IOS ASI http 框架详解

    本文转自:http://my.oschina.net/sunqichao/blog/75011 ASIHTTPRequest对CFNetwork API进行了封装,并且使用起来非常简单,用Object ...

  9. unity3D学习—坦克大战(一)

    背景介绍 本人一名C#程序员,从事C#开发已经有四年有余了,目前在一家大型公司上班.鉴于公司的业务需要,现在需要学习unity3D游戏开发,好在unity支持C#脚本开发,无形中省下了许多重新学习新语 ...

  10. SQL Server2005清除数据库日志

     SQL2005清空删除日志: 复制代码 代码如下: Backup Log DNName with no_log  '这里的DNName是你要收缩的数据库名,自己注意修改下面的数据库名,我就不再注释了 ...