马黑黑 发表于 2022-3-22 07:59

JS读取和改变before与after伪元素的content值

本帖最后由 马黑黑 于 2022-3-22 08:04 编辑

先来再次了解一下伪元素中的两兄弟:before与after。它们都是基于document(DOM)中的元素的,如div、img、p等都可以拥有自己的非document(DOM)伪元素。例如,假设有一个div:

.mama {
    /* ...... */
    position: relative;
}

则如下的 div 盒子可以拥有一对伪元素:

<div id="mama"> ... </div>

伪元素必须事先从CSS中定义,并且必须设定content属性(否则不起作用),content可以设置为空值或任意需要显示的内容:

.mama::before {
    content: '我是老大';
    position: absolute;
    /* ...... */
}

.mama::after {
    content: '我是老二';
    position: absolute;
    /* ...... */
}


正如在上面的简易代码示例中所看到的的,元素及其伪元素我们都写上了定位属性,这是非常好的习惯,因为,元素与伪元素本质上是父子关系,将来如果需要定位伪元素时,position属性的事先设定是腾挪它们的前提条件。

之前讨论过,JS很难操控伪元素,原因是伪元素不在 document(DOM)的序列,就像事业单位里的非在编人员,系统名册上找不到他们。不过,存在的事物与人员不可能没有踪影,元素下的伪元素,设置得当,JS是可以发现它们并操作它们。设置的方法:

第一,伪元素的 content 使用 attr 属性且设定变量:

    content: attr(data-1);
    content: attr(data-2);

上面,老大、老二我们分别给出变量,data-1 和 data-2,这些变量不能写成 data1 和 data2,也不能只单独写一个单词,要有两部分或以上,之间有连接线串起来。riqi-a 和 riqi-b是合法的变量,riqia、riqib是不合法的。

第二,在元素中给 css伪元素 的 attr变量 赋值:

    <div class="mama" data-1="伪元素before(老大)" data-2="伪元素after(老二)">
      妈妈元素
    </div>

这样,运行后,页面上会出现如下字样:

妈妈元素
伪元素before(老大)
伪元素after(老二)

但以上文本是重叠在一块的,需要事先给伪元素做定位,就是设定它们的left与top值。

下面给出相对完整的代码示例:

<style>
.mama {
      position: relative;
      width: 200px;
      height: 200px;
      border: 1px solid silver;
}

.mama::before {
      content: attr(data-1);
      position: absolute;
      border: 1px solid red;
      left: 10%;
      top: 30%;
}

.mama::after {
      content: attr(data-2);
      position: absolute;
      border: 1px solid green;
      left: 10%;
      top: 50%;
}
</style>

<div class="mama" data-1="伪元素before(老大)" data-2="伪元素after(老二)">
      妈妈元素
</div>


至于JS对它们的控制,时间关系,待续。

马黑黑 发表于 2022-3-22 07:59

本帖最后由 马黑黑 于 2022-3-22 12:49 编辑

(接一楼)
现在,JS可以通过 attributes 属性值来获得伪元素的 content 属性的内容了。我们前面讨论过,伪元素使用了类似这样的方式定义content值:先是在 css 中设定 content 值为 attr(data-x),然后在 HTML 的元素代码中加入 data-x="字符串",这样,元素显示的内容就由元素的文本、文元素的文本组成。

其中,CSS里伪元素的 content 值 attr 是内置关键字,它指向 attributes 这个属性,JS将通过元素的 attributes 属性分别获得伪元素老大老二的 content 值。假设元素的操作句柄为 ele,那么,

ele.attributes.value

就是伪元素 ::before 的 content 值,而 ::after 的 content 值则为 ele.attributes.value 。

这里,ele 的 attributes 是复数的,它是多个(两个),所以要用数组下标方式 读取,x 为 1 时是老大的值,为 2 时是老二的值。

下面的JS代码示例建立在一楼的CSS+HTML代码基础上,我们的预设是,单击div盒子,会弹出一个提示窗口,上面的内容就是读取到的两个伪元素的文本内容:

<script>

let ele = document.getElementsByClassName('mama'); //获取盒子操作句柄
//盒子单击事件:匿名函数
ele.onclick = function() {
    //读取伪元素content值并赋值给变量 val_1 和 val_2
      let val_1 = ele.attributes.value,
             val_2 = ele.attributes.value;
      alert('获取伪元素的值如下:\r\n\r\n' + val_1 + '\r\n' + val_2); //显示获取到的信息
}

</script>

上面的代码,我们首次使用 getElementsByClassName(‘名称’) ,这是通过获取类名(ClassName)来得到要操纵的元素,因为可能存在多个同类名的元素,得到的结果是数组形式的,所以要指定数组下标, 表示同类名元素的第一个。而 \r\n 是分行符号,这里不能用 <br> 标签,因为提示窗口不是Dom节点。


马黑黑 发表于 2022-3-22 08:00

本帖最后由 马黑黑 于 2022-3-22 13:45 编辑

(接二楼)
读取伪元素的 content 值算是完成了本帖设定的任务的一半,接下来,我们要完成另一半的任务:改变伪元素的 content 值。

在二楼,我们通过 ele.attributes.value 分别读取了老大老二两个伪元素的 content 里的值,x 的取值不是1就是2,分别对应于老大(before)和老二(after),修改其 content 值,也是通过 ele.attributes.value 来实现,试看以下 ele 元素的单击事件:

<script>


let ele = document.getElementsByClassName('mama');
ele.onclick = function() {
      let val_1 = ele.attributes.value,
             val_2 = ele.attributes.value;
      alert('获取伪元素的值如下:\r\n\r\n' + val_1 + '\r\n' + val_2);
      ele.attributes.value = "我是伪元素老大";
      ele.attributes.value = "我是伪元素老二";
}


</script>


这是在二楼同元素名的匿名函数的基础上加了两句,放在 alert 语句之后。提示窗口弹出来后,单击其上的“确定”按钮,ele 元素上的文本就会按预设的那样改变,改变的部分是伪元素老大和老二的内容。

至此,通过伪元素CSS的 attr 之 content 设定 + HTML的 data-x 之 content 赋值来实现读取、修改伪元素的 content 值,已经大功告成。应该说,我们的工作效率不算太低,但我们能做的远不止于此,不过请先熟悉一二三楼的知识点,然后再期待更加精彩的内容。

马黑黑 发表于 2022-3-22 12:50

(占位3)

马黑黑 发表于 2022-3-22 12:50

(占位4)

马黑黑 发表于 2022-3-22 13:43

(占位5)
页: [1]
查看完整版本: JS读取和改变before与after伪元素的content值