One, foreword

Recently listened to the moon shadow teacher to speak JS the most basic three principles, which cited the example 🌰 is very clever. Some of them are previous demos, and after digging deep, I found that there is such a deep door; There are a few things that haven’t been used before, but are actually useful.

The content of teacher Yueyin’s lecture can be found in the gold digging booklet – 10 Days talk about front-end Engineer Advancement [1]. I bought this volume, which is of excellent quality and worth investigating.

Three sets of front-end foundation have their respective roles:

  • HTML is used to structure web pages
  • CSS is used to style web pages
  • JS is used to implement web page interaction

This paper mainly records the development principles of HTML, CSS, JS, which are responsible for their own responsibilities. The example of “dark and light color mode switch” by Yueying teacher is taken as an example. By implementing a demo of manually switching traffic lights, I can experience the process of spicy chicken code becoming elegant.

Ii. Mission objectives

There was a strange traffic light at the intersection. It had only two states: red and green. Unlike normal traffic lights, it has only one light bulb, but it can be both red and green.

This traffic light can only be manually pulled to switch the display of traffic lights.

Specify the brake head (the red end of “📍” is green light up and red light down).

When switching a traffic light, you need to simultaneously switch the text displayed in the middle of the traffic light and the direction of the handbrake in the lower left corner.

The basic HTML structure is as follows:

<div class="traffic">
  <span class="notice">Please pass</span>
</div>

<div class="controller">📍</div>
Copy the code

The corresponding SCSS code is as follows:

html.body {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 10px;
}

.traffic {
  width: 160px;
  height: 160px;
  border-radius: 50%;
  background-color: green;
  display: flex;
  justify-content: center;
  align-items: center;
  .notice {
    color: white;
    font-size: 2rem; }}.controller {
  position: absolute;
  bottom: 8rem;
  right: 3rem;
  font-size: 4rem;
  transition: all ease-out 0.4 s;
  transform-origin: bottom;
  cursor: pointer;
}
Copy the code

The result is shown below.

Third, everyone can think of the implementation plan

It doesn’t take long for us to think of something like this:

  • Bind the tap listening event to the handbrake;
  • When clicking the handbrake, the function in the task objective can be realized by manipulating DOM.

This way is easier to implement.

// Get the element instance
const trafficLight = document.querySelector('.traffic');
const notice = document.querySelector('.notice');
const controller = document.querySelector('.controller');

// Bind the click event
controller.onclick = function () {
  / / green to become red
  if (notice.innerHTML === 'Please pass') {
    trafficLight.style.backgroundColor = 'red';
    notice.innerHTML = 'Please wait';
    controller.style.transform = 'rotatex(180deg)';
  } else {
    / / green to become red
    trafficLight.style.backgroundColor = 'green';
    notice.innerHTML = 'Please pass';
    controller.style.transform = 'rotatex(0deg)'; }};Copy the code

The implementation effect is as follows:

@syyCN
CodePen

This approach uses JS to manipulate the content and style of elements, neither of which is clearly JS’s responsibility.

Element content should be taken care of by HTML, and styling should be taken care of by CSS.

Furthermore, if someone else takes over and maintains the code, there is no guarantee that everyone will be able to read the meaning of the JS actions being executed.

Four, do some of their own responsibility to try

Let HTML take care of the element content, CSS take care of the style, and JS control the class name to achieve the purpose of controlling the display.

Without further ado, let’s start with the code.

<div class="traffic green">
  <span class="notice"></span>
</div>

<div class="controller green">📍</div>
Copy the code
html.body {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 10px;
}

.traffic {
  width: 160px;
  height: 160px;
  border-radius: 50%;
  // background-color: green;
  display: flex;
  justify-content: center;
  align-items: center;
  .notice {
    color: white;
    font-size: 2rem; }}.traffic.green {
  background-color: green;
  .notice::after {
    content: 'Please pass'; }}.traffic.red {
  background-color: red;
  .notice::after {
    content: 'Please wait'; }}.controller {
  position: absolute;
  bottom: 10rem;
  right: 180px;
  font-size: 4rem;
  transition: all ease-out 0.4 s;
  transform-origin: bottom;
  cursor: pointer;
}

.controller.green {
  transform: rotatez(0deg);
}

.controller.red {
  transform: rotatez(180deg);
}
Copy the code
const controller = document.querySelector('.controller');

controller.onclick = function () {
  let trafficLight = document.querySelector('.traffic');
  // Determine whether the current light is green or red, and switch accordingly
  if (trafficLight.classList.contains('green')) {
    trafficLight.classList.remove('green');
    trafficLight.classList.add('red');
    controller.classList.remove('green');
    controller.classList.add('red');
  } else {
    trafficLight.classList.remove('red');
    trafficLight.classList.add('green');
    controller.classList.remove('red');
    controller.classList.add('green'); }};Copy the code

The overall idea is:

  • Predefined HTML structure and display state of each HTML element under different class names;
  • Through JS switch HTML class name, make it match different CSS rules, so as to achieve the purpose of display content switch.

The project preview is as follows, all functions can be realized.

@syyCN
CodePen

Tips:

  • Used in the codePseudo class elementBecause thecontentAttributes only apply to pseudo-class elements;
  • After this modification, the readability of our code has increased, as indicated in JSredAs well asgreenClass name, corresponding to different lamp color;
  • Adding the function of switching animation does not involve JS, only need to change in CSS;
  • Also, if the requirements change and you need to change to “red and yellow”, just change the CSS (if you can live with that)greenThe class name represents yellow 😂).

This allows us to make our code more readable and maintainable, but consider that if we have to switch class names to a large number of elements instead of the two in our demo, the JS code becomes verbose and becomes less readable and maintainable.

Five, “the best design in the world, is no design” — Lei Zong

Listen to the “army” words, such as listen to words ~

The same philosophy ray always talks about applies to the front end as well. The best JS code in the world is no JS code! (Doghead to survive 🐶)

Can such a switch be achieved without JS? The answer, of course, is yes

There is one element in HTML that just happens to do the double-value switch: the checkbox. Selected and unselected, are two states, you can set the corresponding display effect of these two states.

Let’s start by adding a checkbox element to the HTML section.

<div class="traffic">
  <span class="notice">Please pass</span>
</div>

<div class="controller">📍</div>
<input type="checkbox" class="checkbox" />
Copy the code

The effect is as follows:

Next, use CSS to associate the checkbox status with the traffic light status.

html.body {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 10px;
}

.traffic {
  width: 160px;
  height: 160px;
  border-radius: 50%;
  background-color: green;
  display: flex;
  justify-content: center;
  align-items: center;
  .notice:after {
    content: 'Please pass';
    color: white;
    font-size: 2rem; }}.controller {
  position: absolute;
  bottom: 10rem;
  right: 180px;
  font-size: 4rem;
  transition: all ease-out 0.4 s;
  transform-origin: bottom;
  cursor: pointer;
}

#checkbox:checked ~ .traffic {
  background-color: red;
  .notice:after {
    content: 'Please wait'; }}#checkbox:checked ~ .controller {
  transform: rotatez(180deg);
}
Copy the code

Now you can switch the color of the traffic light by clicking the checkbox. But this is still far from our goal, we need to click the button in the lower right corner to switch.

Just change the button element to the label tag and add a for attribute with the id of the checkbox.

<input type="checkbox" id="checkbox" />

<div class="traffic">
  <span class="notice"></span>
</div>

<label class="controller" for="checkbox">📍</label>
Copy the code

Now click the handbrake, also can realize the traffic light switch. Next, we simply add the following code to the end of the CSS section to hide the checkbox element.

#checkbox {
  display: none;
}
Copy the code

The full code is as follows:

<input type="checkbox" id="checkbox" />

<div class="traffic">
  <span class="notice"></span>
</div>

<label class="controller" for="checkbox">📍</label>
Copy the code
html.body {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 10px;
}

.traffic {
  width: 160px;
  height: 160px;
  border-radius: 50%;
  background-color: green;
  display: flex;
  justify-content: center;
  align-items: center;
  .notice:after {
    content: 'Please pass';
    color: white;
    font-size: 2rem; }}.controller {
  position: absolute;
  bottom: 10rem;
  right: 180px;
  font-size: 4rem;
  transition: all ease-out 0.4 s;
  transform-origin: bottom;
  cursor: pointer;
}

#checkbox:checked ~ .traffic {
  background-color: red;
  .notice:after {
    content: 'Please wait'; }}#checkbox:checked ~ .controller {
  transform: rotatez(180deg);
}

#checkbox {
  display: none;
}
Copy the code

In this way, we did not use JS, also realized the function of traffic light switch. This idea can also be applied to other scenarios with dual-value switching requirements, such as dark-light mode switching, LTR or RTL reading order switching, etc.

The advantage of using this approach is that we don’t write JS code, so browser compatibility is better. No JS code, no bugs.

On the downside, compared to the JS version, such schema code is verbose and can be difficult to modify if more complex logic is encountered.

Six, summarized

There is no perfect code, only perfect engineers. In the process of code optimization, our code capability is also improved.

It was my first time to attend bytedance training camp, and I was very honored to hear the courses taught by Yueyin and Li Songfeng, as well as the q&A and communication. The training camp focuses on the basics and the content is substantial. In the future study, I also need to pay more attention to the consolidation of my own foundation.

Thanks for the JS course of Yueying teacher, once again recommend Yueying teacher’s gold digging booklet – front-end engineer advanced 10 days talk.

reference

[1] Nuggets Brochure – 10 days of advanced Front-end Engineers talk