focus-within封装组件必不可少的css伪类

focus-within封装组件必不可少的css伪类

从一开始还真没怎么关注到这个属性,直到最近在封装自己的组件库,在使用过程中有很多困扰我的地方。比如我封装一个按钮或者checkbox这种组件,在点击的时候给上一个状态,再点击其余地方的时候这个状态取消,第一想法我就是用input这个标签有方法,获取焦点focus,blur用这个不就可以完美的通过控制class然后来实现效果了吗,这个方法确实可以一开始我也是这么做的,但是组件库越来越多的时候我就觉得很麻烦了,每个组件我都需要去添加很多state显示classname,工作量就越来越大,代码也不简洁看起来很重。

每个组件需要这种焦点的我都是这样写的是不是觉得很重,这个地方不是我写焦点的地方只是差不多的实现。

		<input
		   ref={actionRef}
            placeholder={placeholder}
            type={inputType}
            value={text}
            onChange={(e) => {
              e.target.value = e.target.value.substring(
                0,
                maxLength ? maxLength : e.target.value.length,
              );
              setTextSize(e.target.value.length);
              setText(e.target.value);
              onChange?.(actionRef);
            }}
            onBlur={(e) => {
              if (disabled) return;
              setIsClass(false);
              onBlur?.(e);
            }}
            onFocus={() => {
              setIsClass(true);
            }}
            onKeyDown={(e) => {
              if (e.keyCode === 13) {
                props.onPressEnter?.();
              }
            }}
            disabled={disabled}
          />

偶然发现focus-within
太香了,只要是Input获取了焦点不管是父级多少只要使用了这个伪类,子集input只要获取了焦点,父节点也可以使用这个伪类来写一些焦点的样式,这样就大大节省了我组件库代码量了省去了很多的变量。

当用户在一个表单中输入时,我们可以使用传统方式 来改变父级元素的样式,以提供焦点可见性和用户反馈。

<style>
  .form {
    margin-bottom: 20px;
  }

  .form.with-focus {
    background-color: lightblue;
    border: 2px solid blue;
  }
</style>

<div class="form">
  <label for="name">姓名:</label>
  <input type="text" id="name" placeholder="请输入姓名">
</div>

<div class="form">
  <label for="email">邮箱:</label>
  <input type="email" id="email" placeholder="请输入邮箱">
</div>

<div class="form">
  <label for="message">留言:</label>
  <textarea id="message" placeholder="请输入留言"></textarea>
</div>

<script>
  const forms = document.querySelectorAll('.form');

  forms.forEach((form) => {
    const input = form.querySelector('input, textarea');

    input.addEventListener('focus', () => {
      form.classList.add('with-focus');
    });

    input.addEventListener('blur', () => {
      form.classList.remove('with-focus');
    });
  });
</script>

在上述例子中,每个表单项包含一个 <label> 元素和一个 <input><textarea> 元素。通过 JavaScript,我们监听每个表单项内部输入框的 focusblur 事件,并在焦点获得时为父级的 .form 添加 with-focus 类,使其应用样式变化。当焦点失去时,移除该类,恢复默认样式。

下面是一个使用 focus-within 的例子:

<style>
  .form {
    margin-bottom: 20px;
  }

  .form:focus-within {
    background-color: lightblue;
    border: 2px solid blue;
  }
</style>

<div class="form">
  <label for="name">姓名:</label>
  <input type="text" id="name" placeholder="请输入姓名">
</div>

<div class="form">
  <label for="email">邮箱:</label>
  <input type="email" id="email" placeholder="请输入邮箱">
</div>

<div class="form">
  <label for="message">留言:</label>
  <textarea id="message" placeholder="请输入留言"></textarea>
</div>

<script>
  const forms = document.querySelectorAll('.form');

  forms.forEach((form) => {
    const input = form.querySelector('input, textarea');

  });
</script>

使用伪类很轻松就能实现刚刚的功能。不需要再去维护其余的变量和多余的classname。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值