The effect

Train of thought

Use checkbox to achieve, tick, untick corresponding open, closed state, use :checked selector to control the style display under the open state.

The key

How do I modify the original checkBox style? Where appearance is used (MDN link). Appearance changes the UI of an element. Note that the appearance attribute of the checkbox is checkbox by default, so we reset the element attribute to None and use CSS as a normal element. Note the prefix.

The implementation code

<! DOCTYPE html><html>
<head>
  <title>Switch implementation</title>
  <style type="text/css">
      .switch {
          width: 57px;
          height: 28px;
          position: relative;
          border: 1px solid #dfdfdf;
          background-color: #DCDFE6;
          box-shadow: #dfdfdf 0 0 0 0 inset;
          border-radius: 20px;
          background-clip: content-box;
          display: inline-block;
          appearance: none;
          -webkit-appearance: none;
          -moz-appearance: none;
          user-select: none;
          outline: none;
      }
      .switch::before {
          content: ' ';
          position: absolute;
          width: 22px;
          height: 22px;
          background-color: #FFFFFF;
          border-radius: 50%;
          left: 2px;
          top: 0;
          bottom: 0;
          margin: auto;
          transition:.3s;
      }
      .switch:checked {
          background-color: #409EFF;
          transition:.6s;
      }
      .switch:checked::before {
          left: 30px;
          transition:.3s;
      }
  </style>
</head>
<body>
    <input type="checkbox" class="switch" checked />
</body>
</html>
Copy the code

Updated version

Simply to achieve the above the switch of the switch effect, we need to switch places, usually is certainly need to request the background to realize data state changes, which realize the disadvantages of it is obvious that I just click on the switch, the switch is closed or open, and not wait until after the request is successful for closed or open, If we reset the switch after the request failed, the interaction would not satisfy the product manager. What we need is to turn the switch on or off only when the request is successful. As a vue user, I can see that the ElementUI library most used under VUe2.0 doesn’t do this either, so we’ll do it ourselves if we have to. To do this we need to give up the checked selector because it causes problems: the checked selector depends on the default behavior of the check box and it can’t be prevented by an event.preventDefault(), so my code looks like this:

<! DOCTYPE html><html>
<head>
	<title>Switch implementation</title>
	<style type="text/css">
        .switch {
            width: 57px;
            height: 28px;
            position: relative;
            border: 1px solid #dfdfdf;
            background-color: #DCDFE6;
            box-shadow: #dfdfdf 0 0 0 0 inset;
            border-radius: 20px;
            background-clip: content-box;
            display: inline-block;
            appearance: none;
            -webkit-appearance: none;
            -moz-appearance: none;
            user-select: none;
            outline: none;
        }
        .switch::before {
            content: ' ';
            position: absolute;
            width: 22px;
            height: 22px;
            background-color: #FFFFFF;
            border-radius: 50%;
            top: 0;
            bottom: 0;
            margin: auto;
        }
        .switch_uncheck::before {
            left: 2px;
            transition:.3s;
        }
        .switch_check {
            background-color: #409EFF;
            transition:.6s;
        }
        .switch_check::before {
            left: 30px;
            transition:.3s;
        }
	</style>
</head>
<body>
	<input type="checkbox" class="switch switch_uncheck" onclick="clickHandle(event)" />
	<script type="text/javascript">
		// Define the initial state of the switch, which is off by default
		let status = false 
		function clickHandle(event) {
			let switchs = document.querySelector('.switch')
			setTimeout(() = > {
				// TODO does the request operation, change the status on success, do not change on failurestatus = ! statusif (status) {
					switchs.classList.add('switch_check')
					switchs.classList.remove('switch_uncheck')}else {
					switchs.classList.remove('switch_check')
					switchs.classList.add('switch_uncheck')}},1000)}</script>
</body>
</html>
Copy the code

The effect



And you can see that when you click on it1sThe delay effect only closes or opens that I usesetTimeoutJust simulating the operation. Of course, we usually need to encapsulate a component, and when we encapsulate a component, it can receive a function, inside the componentpromiseEncapsulate, and then decide whether to turn the switch on or off depending on the success of the request. I only provide ideas here, and I will implement specific component encapsulation in my own VUe3.0 official website demo later.