绿叶清舟 发表于 2024-8-31 20:26

马黑黑 发表于 2024-8-31 20:22
手机里的也是古董的

那就得卸了重新装了

马黑黑 发表于 2024-8-31 20:52

绿叶清舟 发表于 2024-8-31 20:26
那就得卸了重新装了
留着做个纪念。加装一个Edge什么的

马黑黑 发表于 2024-8-31 20:55

<style>
.artbox { position: relative; }
.artbox > p { position: relative; margin: 10px 0; font: normal 18px / 26px sans-serif; }
.artbox mark { color: black; background: lightblue; padding: 2px 4px; }
.textRed { color: red; }
.textMid { text-align: center; }
.showDiv { position: relative; }
</style>

<div class="artbox">
        <h2 class="textMid">第二十六讲:学一点点JS(六)JS操作CSS变量</h2>
        <p>CSS变量是自定义的CSS属性,它有一个高大上的名称叫级联变量,称之为CSS变量更为通俗易懂。CSS变量主要用来解决两个层面的问题,一是基于CSS代码。考虑一下如下情形:当一大堆的属性设置都会用到相同的值,我们就可以给它们设置一个变量值,各属性通过变量名使用此变量值,日后想修改这一系列属性值时,只需修改被引用的变量值,非常方便。再考虑一下另一种情形:通过作用于特定属性的若干个变量来构建一种页面风格,可以同时创建几个风格,风格切换时只需仅需改变变量名,是不是也很高效?二是基于JS,这是本讲要讨论的课题,当然,正式探讨它之前,我们先来认真梳理一下CSS变量。</p>
        <p>任何CSS属性的值都可以使用CSS变量来表示。CSS变量分两个步骤实现:第一步是声明变量被给变量赋值,格式为 <mark>--变量名: 变量值</mark>,双连接符 <mark>--</mark> 是变量名的前缀,其后紧跟一个变量名称,加上小角冒号之后就可以给变量名进行赋值,例如,<mark>--color: red;</mark>,这里,<mark>--color</mark> 是变量名,相当于一个CSS属性,实际上就是一个自定义的CSS属性,赋值方法和其他CSS属性的做法一样,都是用键值对的方式完成,完了需要用小角分号 <mark>;</mark> 收尾;第二步是在需要用到CSS变量值的属性中引用变量,使用关键字 <mark>var</mark> 来完成,格式为 <mark>属性名: var(--变量名);</mark>,例如,<mark>color: var(--color);</mark> 表示前景色 <span class="textRed">color</span> 属性使用变量 <span class="textRed">--color</span> 定义的颜色值。以下示例,通过 <span class="textRed">--color</span> 和 <span class="textRed">--bg</span> 声明前景色和背景色变量,再在 <span class="textRed">color</span> 和 <span class="textRed">background</span> 属性中分别使用两个变量赋值:</p>

<div class="hE"><pre id="pre1">
&lt;style&gt;
.cDiv1 {
        --color: green;
        --bg: lightgray;
        width: 400px;
        height: 80px;
        color: var(--color);
        background: var(--bg);
        padding: 10px;
}
&lt;/style&gt;

&lt;div class="cDiv1"&gt;通过CSS变量设置元素的前景色和背景色&lt;/div&gt;
</pre></div>

        <p><button id="btn1" type="button" value="1">点击查看效果</button></p>
        <div id="sbox1" class="showDiv"></div>

        <p>这样,动态修改盒子的前景色、背景色时,我们可以不用去一一操作元素的对应CSS属性,只需改变对应的CSS变量值就能达到目的,这对大批量动态修改元素的特定属性值特别有用。下面的代码在上述代码基础上使用JS来动态操作盒子的前景色和背景色两个CSS变量,为了便于操作,CSS使用id选择器、盒子使用id标识属性:</p>
       
<div class="hE"><pre id="pre2">
&lt;style&gt;
#cDiv2 {
        --color: green;
        --bg: lightgray;
        width: 400px;
        height: 80px;
        color: var(--color);
        background: var(--bg);
        padding: 10px;
}
&lt;/style&gt;

&lt;div id="cDiv2"&gt;点击本div随机改变前景色和背景色&lt;/div&gt;

&lt;script&gt;
/* 函数 :生成两个hsl颜色 */
create2HueColors = () =&gt; {
        var a = Math.round(Math.random() * 360); /* 变量 a : 获取 0~360 之间的随机整数 */
        var b = (a + 150) % 360; /* 变量 b :与 a 拉开150度的距离(取360的余数保证hue合理) */
        /* 返回存储两个hsl颜色的对象 */
        return {
                c1: `hsl(${a}, 100%, 50%)`,
                c2: `hsl(${b}, 100%, 50%)`,
        };
};
/* div盒子点击事件 */
cDiv2.onclick = () =&gt; {
        var color = create2HueColors();
        cDiv2.style.setProperty('--color', color.c1);
        cDiv2.style.setProperty('--bg', color.c2);
};
&lt;/script&gt;
</pre></div>

        <p><button id="btn2" type="button" value="2">点击查看效果</button></p>
        <div id="sbox2" class="showDiv"></div>

        <p>代码中的函数 create2HueColors() 生成两个色域范围不沾边的色相值以便让前景色和背景色拉开区间,该函数返回一个对象,对象里记录所生成的两组 hsl 颜色,记作 c1 和 c2。div的点击事件是我们要看的重点:首先声明一个变量 color,通过调用函数 create2HueColors() 给它赋值;接着,使用JS内置的 <span class="textRed">setProperty()</span> 方法改变CSS属性,要改变的是CSS变量 --color 和 --bg,它们的值都是从JS变量 color 中获取,一个是 color.c1,另一个是 color.c2,这是调用事先编写好的生成两个色相值的函数 create2HueColors() 所返回的值。<span class="textRed">setProperty()</span> 方法我们在上一讲中介绍过,它用来给CSS属性赋值,CSS变量本质上是一个自定义的CSS属性,所以自然而然可以使用它来改变变量值。</p>
        <p>我们还可以为上例既有CSS属性如宽高等的属性值设置CSS变量,一切凭需要进行设计。做音画帖最需要的是操纵CSS关键帧动画,当有较多的元素都运行不同的关键帧动画,如何统一管理这些动画的运行与暂停就是我们必须解决的问题,这个时候,CSS变量就能派上用场,我们可以设置一个 --state 变量,用以表示动画运行属性即 animation 属性的运行(running)或暂停(paused)这两种状态,然后根据 --state 属性的上一个属性值来决定下一个属性值,两个值来回轮换,以此达成操控动画的播放与暂停。试看如下例子,演示后可点击div切换动画运行状态:</p>

<div class="hE"><pre id="pre3">
&lt;style&gt;
#cDiv3 {
        --state: running;
        margin: 30px;
        width: 60px;
        height: 60px;
        background: olive;
        animation: rot 6s linear infinite var(--state);
}
@keyframes rot { to { transform: rotate(360deg); } }
&lt;/style&gt;

&lt;div id="cDiv3" title="点击切换动画状态"&gt;&lt;/div&gt;

&lt;script&gt;
/* div盒子点击事件 */
cDiv3.onclick = () =&gt; {
        var currentState = window.getComputedStyle(cDiv3).getPropertyValue('--state');
        cDiv3.style.setProperty('--state', currentState === 'running' ? 'paused' : 'running');
};
&lt;/script&gt;
</pre></div>

        <p><button id="btn3" type="button" value="3">点击查看效果</button></p>
        <div id="sbox3" class="showDiv"></div>

        <p>CSS代码的重点是,#cDiv3 选择器通过 animation 属性运行关键帧动画 rot,并使用 --state 变量来控制运行状态,--state 的初始值是 running,这意味着动画一开始就运行。JS代码共两行,第一行是获取当前的 --state 变量值,使用的是JS内置的API接口 <mark>window.getComputedStyle(元素)</mark>,它会返回一系列的值,我们仅取其CSS属性值 <mark>getPropertyValue(属性)</mark>,示例要操作的元素是 cDiv3,要获取的属性值是自定义CSS变量属性 --state;第二行,用 setProperty() 方法给 --state 变量赋值,赋值过程使用三元运算判断当前动画运行状态 currentState 的值,若为 running,则令其改为 paused,反之,令其改为 running,这样,单击元素就可以让div在动画运行状态与暂停状态间来回切换。 </p>
        <p>通过 <mark>window.getComputedStyle(元素).getPropertyValue(属性)</mark> 方法获得指定元素的指定属性的值是个聪明的做法,不过在音画帖中,我们通过音频基于JS的 paused 暂停属性来决定关键帧动画、视频等的播放或暂停,这在前面的章节中介绍过,这里再详细讲一讲。以下示例,在上一个示例的基础上,① 加入音频标签,并通过音频标签的 <span class="textRed">oncanplay</span> 可以播放、<span class="textRed">onplaying</span> 正在开始播放、<span class="textRed">onpause</span> 暂停这三个事件一同运行一个预设的自定义函数,以此来管控CSS关键帧动画的运行与暂停所依托的CSS变量 --state 的属性值;② 以div元素的伪元素 ::before 模拟播放器,剥夺宿主元素的点击交互功能,将点击操作权限交由伪元素接管。试看代码和演示效果:</p>

<div class="hE"><pre id="pre4">
&lt;style&gt;
#cDiv4 {
        --state: running;
        margin: 30px;
        width: 400px;
        height: 200px;
        border: 1px solid gray;
        pointer-events: none; /* 禁用指针交互事件 */
        position: relative;
}
#cDiv4::before {
        content: '';
        position: absolute;
        left: 30px;
        top: 30px;
        width: 60px;
        height: 60px;
        background: olive;
        cursor: pointer; /* 鼠标指针 :手型 */
        pointer-events: auto; /* 接受指针交互事件 */
        animation: rot 6s linear infinite var(--state);
}
@keyframes rot { to { transform: rotate(360deg); } }
&lt;/style&gt;

&lt;div id="cDiv4" title="播放/暂停"&gt;
        &lt;audio id="aud" src="https://music.163.com/song/media/outer/url?id=1446035057" autoplay loop&gt;&lt;/audio&gt;
&lt;/div&gt;

&lt;script&gt;
//联动控制函数 mState
mState = () =&gt; {
        //设置基于cDiv4的 --state 变量值 :如果音频暂停值为 'paused',反之值为 'running'
        cDiv4.style.setProperty('--state', aud.paused ? 'paused' : 'running');
        //设置cDiv4的弹出式标题文本 :用布尔变量变数字去读取数组,后续解释
        cDiv4.title = ['暂停','播放'][+aud.paused];
        //...这里可以加入对视频的控制
};

aud.oncanplay = () =&gt; mState(); //音频可以播放时运行联动函数
aud.onplaying = () =&gt; mState(); //音频正在开始播放时运行联动函数
aud.onpause = () =&gt; mState(); //音频暂停时运行联动函数

//以上三个监听事件可以和在一行写,如下:
//aud.oncanplay = aud.onplaying = aud.onpause = () =&gt; mState();

//cDiv4点击事件 :如果音频暂停则播放它,反之暂停它
cDiv4.onclick = () =&gt; aud.paused ? aud.play() : aud.pause();
&lt;/script&gt;
</pre></div>

        <p><button id="btn4" type="button" value="4">点击查看效果</button></p>
        <div id="sbox4" class="showDiv"></div>

        <p>代码解释:</p>
        <p>(一)CSS代码里,pointer-events 属性是指针交互事件属性,值为 <span class="textRed">none</span> 表示禁用、为 <span class="textRed">auto</span> 表示可用,这样,宿主元素 cDiv4 不接受指针交互,其下子元素会继承这个属性设置,也都不接受指针交互,包括title、指针样式都会失效,因此,作为子元素的伪元素要设置为接受才具备接受点击等交互操作功能。</p>
        <p>(二)JS代码中,伪元素的 <span class="textRed">title</span> 属性值通过宿主元素 cDiv4 传递,尽管宿主元素因为指针交互功能受禁;CSS变量 --state 属性也是通过宿主元素传递。这里请特别注意,父元素的CSS变量可以传递给子元素,前提是子元素不要设置变量值、只能引用变量。上述CSS代码,伪元素的 animation 属性引用了 --state 变量,<span class="textRed">var(--state)</span>,但没有 <mark>--state: running/paused</mark> 这样的赋值,声明与赋值只能有父元素完成,否则就无法通过父元素给子元素传递变量值,JS对 --state 属性的操作就作用不到子元素。</p>
        <p>(三)说一下数组在联动函数中的应用:<mark>cDiv4.title = ['暂停','播放'][+aud.paused];</mark> 这一句,<mark>['暂停','播放']</mark>是一个数组,共两个数组元素,而 <mark>[+aud.paused]</mark> 是读取数组的下标,其值为 <span class="textRed">+aud.paused</span>,aud.paused 是 audio 标签的暂停属性,暂停时为真否则为假,是布尔值,布尔值前面加一个加号 <mark>+</mark> 变为数值,<mark>true</mark> 等于1,<mark>false</mark> 等于0,刚好可以对应我们所设置的数组 <mark>['暂停','播放']</mark>,因此弹出式显示出来的title文本符合我们的要求;该句代码也可以使用三元运算语句改写:<mark>cDiv4.title = aud.paused ? '播放' : '暂停';</mark>。</p>
        <p><span class="textRed">作业</span>:参照本讲最后一个示例,制作一个简单的帖子。要求:① 帖子有背景图、有视频,其中视频设置为圆形、不覆盖整个帖子;② 用伪元素 ::before 和 ::after 做两个音频播放控制器,各自有自己的背景图案,点击任意一个都可以联动控制音乐、CSS动画和视频。</p>

        <p><a href="https://www.huachaowang.com/forum.php?mod=viewthread&tid=77307">返回目录</a></p>

</div>

<script>
var sc = document.createElement('script');
sc.chartset = 'utf-8';
sc.src = 'https://638183.freep.cn/638183/web/js2024/helight.js';
document.body.appendChild(sc);
var runCodes = (str,ele) => {
        let reg = /(<script(.*?)>)(.|\n)*?(<\/script>)/g;
        let js_str, html_str;
        if(str.match(reg) !== null) {
                js_str = str.match(reg);
                html_str = str.replace(js_str, '').trim();
                js_str = js_str.replace(/<[\/]{0,1}script[^>]*>/g,'').trim();
        } else {
                js_str = '';
                html_str = str.trim();
        }
        ele.innerHTML = html_str;
        let myfunc = new Function(js_str);
        myfunc();
};

.forEach((btn,key) => {
        var pres = ,
                outs = ;
        btn.onclick = () => {
                runCodes(pres.innerText, outs);
                btn.disabled = true;
        }
});
</script>

马黑黑 发表于 2024-8-31 20:57

讲义已经写到第29讲

马黑黑 发表于 2024-8-31 20:58

大家好像没有学习热情,似乎是课程有些难度呢,还是我讲的不好?

绿叶清舟 发表于 2024-8-31 21:12

马黑黑 发表于 2024-8-31 20:52
留着做个纪念。加装一个Edge什么的

那不占地方嘛,去搜来装个

绿叶清舟 发表于 2024-8-31 21:13

这么快已经二十六了啊,申请留级行不

马黑黑 发表于 2024-8-31 21:15

绿叶清舟 发表于 2024-8-31 21:13
这么快已经二十六了啊,申请留级行不

也不是不行,现在八九十岁的人参加高考也是很多的

马黑黑 发表于 2024-8-31 21:16

绿叶清舟 发表于 2024-8-31 21:12
那不占地方嘛,去搜来装个

商店里有的是

绿叶清舟 发表于 2024-8-31 21:24

马黑黑 发表于 2024-8-31 21:15
也不是不行,现在八九十岁的人参加高考也是很多的

这个制度真是,也奇怪有人一考就是十几次的也不知道咋想的

马黑黑 发表于 2024-8-31 21:28

绿叶清舟 发表于 2024-8-31 21:24
这个制度真是,也奇怪有人一考就是十几次的也不知道咋想的

想啥不重要,问题是,万一考上了,如果开家长会,怎么办

绿叶清舟 发表于 2024-8-31 21:29

马黑黑 发表于 2024-8-31 21:16
商店里有的是

找到了

马黑黑 发表于 2024-8-31 21:29

绿叶清舟 发表于 2024-8-31 21:29
找到了

装个试试

绿叶清舟 发表于 2024-8-31 21:29

马黑黑 发表于 2024-8-31 21:28
想啥不重要,问题是,万一考上了,如果开家长会,怎么办

带个照片去

马黑黑 发表于 2024-8-31 21:30

绿叶清舟 发表于 2024-8-31 21:29
带个照片去

设个灵堂呀

绿叶清舟 发表于 2024-8-31 21:33

马黑黑 发表于 2024-8-31 21:29
装个试试

已经装上了

马黑黑 发表于 2024-8-31 21:34

绿叶清舟 发表于 2024-8-31 21:33
已经装上了

试用一下,需要点时间熟悉它的操作环境

绿叶清舟 发表于 2024-8-31 21:36

马黑黑 发表于 2024-8-31 21:30
设个灵堂呀

那得把老师吓哭了

马黑黑 发表于 2024-8-31 21:43

绿叶清舟 发表于 2024-8-31 21:36
那得把老师吓哭了

那也不至于,大学老师可不是都是厦大的

绿叶清舟 发表于 2024-8-31 21:45

马黑黑 发表于 2024-8-31 21:34
试用一下,需要点时间熟悉它的操作环境

现在就在手机上了,就是字有点小了
页: 14 15 16 17 18 19 20 21 22 23 [24] 25 26 27 28 29 30 31 32 33
查看完整版本: 小白音画帖教程(完结)