深入理解脚本化CSS系列第六篇——脚本化伪元素的6种方法
前面的话
我们可以通过计算样式来读取伪元素的样式信息,但是却无法使用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种方法的更多相关文章
- 深入理解脚本化CSS系列第三篇——脚本化CSS类
前面的话 在实际工作中,我们使用javascript操作CSS样式时,如果要改变大量样式,会使用脚本化CSS类的技术,本文将详细介绍脚本化CSS类 style 我们在改变元素的少部分样式时,一般会直接 ...
- 深入理解脚本化CSS系列第四篇——脚本化样式表
× 目录 [1]CSSStyleSheet [2]CSSRule 前面的话 关于脚本化CSS,查询样式时,查询的是计算样式:设置单个样式时,设置的是行间样式:设置多个样式时,设置的是CSS类名.脚本化 ...
- 深入理解脚本化CSS系列第五篇——动态样式
前面的话 很多时候,DOM操作比较简单明了,因此用javascript生成那些通常原本是HTML代码生成的内容并不麻烦.但由于浏览器充斥着隐藏的陷阱和不兼容问题,处理DOM中的某些部分时要复杂一些,比 ...
- 深入理解DOM事件类型系列第六篇——加载事件
前面的话 提到加载事件,可能想到了window.onload,但实际上,加载事件是一大类事件,本文将详细介绍加载事件 load load事件是最常用的一个事件,当页面完全加载后(包括所有图像.java ...
- 用 CSS 隐藏页面元素的 5 种方法
原文链接:用 CSS 隐藏页面元素的 5 种方法,转载请注明来源! 用 CSS 隐藏页面元素有许多种方法.你可以将 opacity 设为 0.将 visibility 设为 hidden.将 disp ...
- CSS 隐藏页面元素的 几 种方法总结
用 CSS 隐藏页面元素有许多种方法.你可以将 opacity 设为 0.将 visibility 设为 hidden.将 display 设为 none 或者将 position 设为 absolu ...
- CSS魔法堂:一起玩透伪元素和Content属性
前言 继上篇<CSS魔法堂:稍稍深入伪类选择器>记录完伪类后,我自然而然要向伪元素伸出"魔掌"的啦^_^.本文讲讲述伪元素以及功能强大的Contet属性,让我们可以通 ...
- css隐藏元素的几种方法与区别
css隐藏元素的几种方法与区别 一:display:none;隐藏不占位 display 除了不能加入 CSS3 动画豪华大餐之外,基本效果卓越,没什么让人诟病的地方. 二:position:abso ...
- 用css隐藏元素的5种方法
.green { width: 100px; height: 100px; background-color: #a0ee00; text-align: center; float: left; ma ...
随机推荐
- Python excel 库:Openpyxl xlrd 对比 介绍
打算用python做一个写mtk camera driver的自动化工具. 模板选用标准库里面string -> Template 即可 但要重定义替换字符,稍后说明 配置文件纠结几天:cfg, ...
- JS typeof与instanceof的区别
typeof 与 instanceof 通常是用来判断一个变量的类型,二者有如下区别: typeof: 判断一个变量的类型,返回值是字符串形式,返回结果有如下几种: number,boolean,st ...
- JavaScript 中string方法
注意:JavaScript的字符串是不可变的(immutable),String类定义的方法不能改变原来字符串内容,例如String.toUpperCase()这样的方法,返回的是全新的字符串,而不是 ...
- VS调式显示问题
调式时,发现与以前的显示不太一样,虽然也能看到结果,但不是很方便,后来网上查找到与VS中的一个文件被修改有关. 找个别人安装过的VS2005,替换Common7\Packages\Debugger\a ...
- 《一个操作系统的实现》学习笔记(一) bochs源码安装及配置
前言:本机环境ubuntu 14.04 bochs 2.4.5 一.下载 官网 http://bochs.sourceforge.net/ 二.安装 1.将下载好的压缩包解压并进入该目录 .tar.g ...
- redhat6 yum源配置
第一次接触redhat系统,安装软件时,发现没有ubuntu的apt-get包管理器,自带的yum包管理器又什么都找不到,网上搜了好久,终于把yum配置好了,感谢博主们- 使用redhat系统自带的y ...
- [IOS]使用了cocoapods 抱错Pods was rejected as an implicit dependency for ‘libPods.a’ because its architectures ......
Pods was rejected as an implicit dependency for ‘libPods.a’ because its architectures ‘i386’ didn’t ...
- git学习笔记一
一.概念理解 1.理解工作区和暂存区以及版本库 工作区我理解就是我们创建的程序所在的文件夹,比如test文件夹.其中有个.git文件,这个就是版本库,其中版本库中有个区域叫暂存区或叫索引. 截自廖雪峰 ...
- bootstarp3 支持ie8
http://blog.csdn.net/hyb3280660/article/details/51850832 想要bootstarp3 支持ie8? 引入 <!-- 存放全局css/js - ...
- linux进程管理(上)
程序和进程的区别: 1.程序是一种静态资源 程序启动产生进程 2.程序与进程无一一对应原则 进程是动态的一个过程 父进程和子进程在前面提过 前台进程:执行命令时只能等待的进程为前台进程也叫异步进程 ...