JavaScript 3/30: CSS变量

JavaScript30 为Wes Bos推出的一项为期30天的挑战,旨在帮助人们用纯JavaScript来实现效果,初学者若想在JS方面快速精进,不妨一试。本题为第三题。

实现效果

本题当实现这样的效果,利用JavaScript及CSS3来改变CSS的值,使得拖动滑块及选中颜色时,可以实时调整图片的内边距(padding)、模糊度(blur)及背景颜色(background),同时标题中JS二字的颜色也随之更改。

页面基础布局

  <h2>Update CSS Variables with
    <span class='hl'>JS</span>
  </h2>

  <div class="controls">
    <label for="spacing">Spacing:</label>
    <input id="spacing" type="range" name="spacing" min="10" max="200" value="10" data-sizing="px">

    <label for="blur">Blur:</label>
    <input id="blur" type="range" name="blur" min="0" max="25" value="10" data-sizing="px">

    <label for="base">Base Color</label>
    <input id="base" type="color" name="base" value="#ffc600">
  </div>

  <img src="DSC01672.jpg">
复制代码

解题思路有两种

一、

  • 获取对应input元素;
  • 创建changeImg动作,获取对应input元素的value值,并赋值给图片的内边距(padding)、模糊度(blur)及背景颜色(background);
  • 为每个input元素添加监听事件,当发生change或是mouseover动作时,触发changeImg动作,即时改变颜色或者滑块值;

查看我的demo代码

二、

  • CSS部分
    • 声明全局CSS变量;
    • 将变量与对应元素<img><hl >关联;
  • JavaScript部分
    • 获取对应input元素;
    • 创建changeImg动作,获取对应input元素参数名及参数值,赋值给对应CSS变量blurspacingcolor
    • 为每个input元素添加监听事件,当发生change或是mouseover动作时,触发changeImg动作,即时改变颜色或者滑块值。

查看我的demo代码

第一种方法代码如下:

CSS部分代码

    body {
      text-align: center;
      background: #193549;
      color: white;
      font-family: 'helvetica neue', sans-serif;
      font-weight: 100;
      font-size: 50px;
    }

    img {
      width: 364.8px;
      height: 547.2px;
    }

    .controls {
      margin-bottom: 50px;
    }

    input {
      width: 100px;
    }
复制代码

JavaScript完整代码:

    const inputs = document.querySelectorAll('.controls input');
    const spacing = document.querySelector('#spacing');
    const blur = document.querySelector('#blur');
    const base = document.querySelector('#base');
    const image = document.querySelector('img');
    const h = document.querySelector('.hl');

    function changeImg() {
      image.style.padding = `${spacing.value}px`;
      image.style.filter = `blur(${blur.value}px)`;
      image.style.background = `${base.value}`;
      h.style.color = `${base.value}`;
    }

    inputs.forEach(input => input.addEventListener('mouseover', changeImg));
    inputs.forEach(input => input.addEventListener('change', changeImg));
复制代码

知识点

  • input标签中type="range",呈现效果为可左右移动的滑动杆,如下所示:
  • 使用querySelectorAll('.controls input')获得的 inputs,可返回一个nodelist,与Array有所区别,但同样可以用forEach遍历。
  • CSS滤镜filter,即图片滤镜,可调整图片特效,常见如模糊度blur(),明暗brightness(),对比度contrast()等,可以一次设置一个滤镜也可以同时设置多个滤镜,具体参考此处

第二种方法代码如下:

CSS部分代码

    :root {
      --spacing: 10px;
      --blur: 10px;
      --base: #ffffff;
    }

    img {
      padding: var(--spacing);
      filter: blur(var(--blur));
      background: var(--base);
      width: 364.8px;
      height: 547.2px;
    }

    .hl {
      color: var(--base);
    }

    body {
      text-align: center;
      background: #193549;
      color: white;
      font-family: 'helvetica neue', sans-serif;
      font-weight: 100;
      font-size: 50px;
    }

    .controls {
      margin-bottom: 50px;
    }

    input {
      width: 100px;
    }
复制代码

JS部分代码

    const inputs = document.querySelectorAll('.controls input');

    function changeImg() {
      const suffix = this.dataset.sizing || '';
      document.documentElement.style.setProperty(`--${this.name}`, this.value + suffix);
    }

    inputs.forEach(input => input.addEventListener('change', changeImg));
    inputs.forEach(input => input.addEventListener('mouseover', changeImg));
复制代码

解题难点

1.如何处理参数值(前两个有单位 px 、第三个没有)
<input type="range" name="blur" min="0" max="25" value="10" data-sizing="px">
<input type="color" name="base" value="#8aa8af">
复制代码

可见前两个input元素中,已设置data-sizing: "px",而只要加上 data- 前缀,我们就可以运用dataset属性来访问所有含有data-的值。在JavaScript中,可以通过dataset.sizing来获取单位。

const suffix = this.dataset.sizing || ''; 
复制代码

表示,针对前两个参数值的单位为'px',针对颜色为空,以防报错。

2.如何用 JavaScript 改变 CSS 属性值?

JavaScript中,document.documentElement 即代表文档根元素。所以要改变全局的 CSS 变量,可以这样写:

document.documentElement.style.setProperty(`--${this.name}`, this.value + suffix);
复制代码

为了更好理解setProperty及联系解题思路一:

style.setProperty('padding', '15px');
/* 等同於 */
style.padding = '15px';
复制代码

实际应用中,前者的做法会更方便带参数进去。

知识点

1.CSS变量

方法二的亮点在于创建了CSS变量,实际上,当我们需要构建大型站点时,使用CSS变量,能避免代码冗余,可重复使用,同时,变量名称本身包含语义信息,使得CSS文件更易。具体使用方法如下:

声明一个全局CSS 变量:
:root {
  --global-color: #666;
  --pane-padding: 5px 42px;
}
复制代码
使用一个全局CSS 变量:
.demo{
   color: var(--global-color);
}
复制代码

其中:root 表示DOM元件的根元素,相当于<html>,常见于声明全局CSS变量。关于CSS变量,若想深入理解,可参阅这里

2.模板字符串

关于模板字符串,其实在第一题就有提到,但值得注意的是,在写法上,是使用反引号``包裹字符串,而非'',记录一笔,不能再犯,以防小哥哥再严肃地批评我!

转载于:https://juejin.im/post/5aaa0ffff265da239f071882

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值