[미니 프로젝트] 25JS Ideas (2 of 27)

Seungrok Yoon (Lethe)·2023년 6월 29일
0
post-thumbnail

Project 2 : CSS Gradient Generator (Hex colors)

(2023.06.29)

기능 개발


기본 마크업 및 스타일 레이아웃

먼저 기본 마크업과 레이아웃을 잡아주었습니다. 결과는 아래와 같습니다. 버튼 그룹은 버튼이 2개만 있어서 css의 :nth-child(1) 가상 클래스로 Generate 버튼 우측의 마진값을 주었습니다. 버튼 두 개 사이의 간격을 주는데 display:flex를 사용하는것은 비효율적이라 생각했기 때문입니다. 버튼이 조금 더 많았다면 display:flex;, gap:10px; 속성을 사용했을 것 같습니다.

기본 마크업이 끝난 직후 모습

기능 요구사항

추가적인 스타일링은 핵심 기능이 완료되고 나서 조정할 예정입니다. 그러면 어떤 기능이 필요한지 나열해볼까요?

  • 유저가 Generate 버튼을 클릭하면, linear-gradient 속성의 변화로 배경화면 색과 텍스트가 변해야 한다
    • linear-gradient 색상은 랜덤으로 조절이 되어야 하며, 각도는 45deg로 고정이다
    • linear-gradient: ~ 텍스트를 버튼 그룹 상단의 span 태그에서 확인할 수 있어야 한다
  • copy 버튼 클릭시, 클립보드에 해당 CSS 속성 문구가 복사되어야 한다

기능 1: 버튼 클릭 시 배경색과 텍스트 변경

먼저 랜덤한 hex color 값을 생성하는 함수를 작성했습니다. 코드상으론 getrandomHexText()입니다.

Math.random 에 2의 16제곱수를 곱하여 0과 2^16 사이의 랜덤한 수를 생성한 후, 정수로 바꿔줍니다.
이후, toString 매서드를 통해 10진수의 정수를 16진수의 텍스트로 변환해주고, 빈 자리에는 0을 채워줌으로써 6자리 hexcolor 코드가 나오게 됩니다.

색상코드 생성 테스트

이후에는 Generate 버튼에 이벤트 리스너를 추가하면서, 이벤트 핸들러 함수에서 배경 색상과 텍스트가 변경되도록 하였습니다. 이벤트 핸들러 함수에서 배경 색상 변경과, 텍스트 변경 로직을 별도의 함수로 추상화하여 가독성을 높였습니다.

기능 2: copy버튼 클릭시, 클립보드로 문구 복사

브라우저 API중에는 클립보드와 상호작용할 수 있는 navigator.clipboard API가 존재합니다.
해당 API에는 writeText() 매서드가 있어 이를 활용하면 원하는 기능을 구현할 수 있을 것 같아 보입니다.

그래서 버튼에 클릭 이벤트가 발생할 시에, 클립보드로 문자열을 복사하는 로직을 작성해 보았습니다.

function copyToClipboard() {
  const text = hexText.textContent;
  navigator.clipboard
    .writeText(text)
    .then((r) => alert('Copied!'))
    .catch((e) => alert('Try again'));
}

copyBtn.addEventListener('click', copyToClipboard);

어라? 그런데 이상합니다. 얼핏 보기에는 맞는 코드 같아 보이는데, then 구문에도, catch 구문에도 아무런 응답이 없습니다. 저는 어떤 잘못을 한 것일까요?

이 과정은 조금 길어서 따로 정리했어요. 아래 링크를 참고해주시면 감사하겠습니다!

링크 - Live Server를 HTTPS 프로토콜 방식으로 사용해보자!

기능 구현 코드

기능구현을 마친 JS 파일은 아래와 같습니다.

const background = document.querySelector('.background');
const hexText = document.querySelector('.hex-text');
const btnContainer = document.querySelector('.btn-container');
const generateBtn = document.querySelector('#generate-btn');
const copyBtn = document.querySelector('#copy-btn');

function genLinearGradientValue(degree, colorFrom, colorTo) {
  return `linear-gradient(${degree}deg, ${colorFrom}, ${colorTo})`;
}

function init() {
  const initialColor = '#000000';
  const styleText = genLinearGradientValue(45, initialColor, initialColor);
  background.style.background = styleText;
  hexText.textContent = `background: ${styleText}`;
}

function getRandomHexText() {
  const randomHex =
    '#' +
    parseInt(Math.random() * 2 ** 16)
      .toString(16)
      .padStart(6, 0);
  return randomHex;
}

function updateBgColor(colorFrom, colorTo) {
  background.style.background = genLinearGradientValue(45, colorFrom, colorTo);
}

function updateHexText(colorFrom, colorTo) {
  const text = `background: ${genLinearGradientValue(45, colorFrom, colorTo)}`;
  hexText.textContent = text;
}

function changeBgToRandomHexColor() {
  const hex1 = getRandomHexText();
  const hex2 = getRandomHexText();
  updateBgColor(hex1, hex2);
  updateHexText(hex1, hex2);
}

function copyToClipboard() {
  const text = hexText.textContent;
  navigator.clipboard
    .writeText(text)
    .then((r) => alert('Copied!'))
    .catch((e) => alert('Try again'));
}

init();
generateBtn.addEventListener('click', changeBgToRandomHexColor);
copyBtn.addEventListener('click', copyToClipboard);

완성된 모습


프로젝트 회고


[HTML] body 태그에 바로 스타일링을 하는 것은 좋은 습관일까?

https://css-tricks.com/html-vs-body-in-css/

body태그에 바로 스타일링을 하는것은 물론 가능합니다. 그렇지만 이것이 반드시 좋다라고는 할 수 없다는 생각이 들었습니다. 특히 SPA 방식의 프로덕트라면 body태그에 직접적으로 스타일을 거는 것은 body 하위의 요소들의 스타일에 제약을 걸 수 있다는 생각이 들었어요.

element.addEventLister() 이벤트 핸들러 콜백함수 - 익명 함수 VS 화살표 함수 ... this... 또 너야?

참고: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

많이 사용하는 매서드이지만, 이벤트 핸들러 함수로서 두 번째 인자로 올 수 있는 값인 자바스크립트 함수 형태별 차이점을 제대로 모르고 사용해왔었습니다. 때로는 기분에 따라, 때로는 손이 가는 대로 콜백함수의 형태를 일반함수, 익명함수, 화살표함수로 분별없이 사용했었는데, 이번에는 각 콜백형태의 특징을 제대로 짚고 넘어가야겠다 생각이 들어 기록해봅니다.

addEventLister()란?

EventTarget 인터페이스의 매서드인 addEventListener()는 이벤트가 타겟(Element, Document, Window, 또는 event를 지원하는 모든 객체)으로 전달이 되었을 때 호출되는 함수를 설정할 때 사용됩니다. addEventListener() 을 통해 Event Listener를 타겟에 등록하게 되는 것입니다. 그렇게 함으로써 해당 타겟은 이벤트 발생을 포착할 수 있게 됩니다. 말 그대로 듣고있는 것으로 비유하면 되겠습니다. 그리고 등록된 이벤트가 발생하면 이벤트 리스너를 등록할 때 함께 인자로 전달한 이벤트리스너 콜백함수를 실행하게 됩니다.

이 매서드는 첫 번쨰 인자로 이벤트의 타입을,
두 번째 인자에는

  • null
  • 자바스크립트 함수
  • 또는 handleEvent()가 구현된 객체
    가 올 수 있습니다. 맨날 자바스크립트 함수만 작성하던 제게는 handleEvent 매서드만 있다면 일반 객체도 올 수 있다는 것을 처음 알았습니다. 조금 부끄럽지만 이제라도 알게 되었으니 나중에 누구한테라도 제대로 설명해줄 수 있겠네요 ㅎㅎ.

그리고 세 번째 인자에는 이 이벤트와 관련하여 추가적인 설정을 추가할 수 있는 옵션객체, 또는 useCapture에 해당하는 boolean값을 받습니다.

제가 궁금했던 것은, 그러면 2번째 인자에 자바스크립트 함수가 오는 경우, 일반함수, 익명함수, 화살표 함수에 따라서 어떤 차이가 있는지에 대한 것이었습니다.

결론은 this 바인딩에 대한 차이였고, 이는 자바스크립트 함수의 특성으로 인한 것이었습니다.

일반함수, 익명함수 - 자체적으로 this를 형성합니다
화살표함수 - 화살표함수를 담고 있는 함수(여기서는 addEventListener)의 this 바인딩을 상속받습니다

[CSS] flex를 사용하지 않고, 여러개의 버튼을 가로로 중앙정렬하고 싶을 때

text-align 속성은 block, 또는 테이블 cell 요소에 주었을 때, inline 속성의 컨텐츠를 정렬할 수 있는 CSS 속성입니다.

저는 Generate, Copy 버튼을 가운데 정렬하고 싶었는데, display:flex 를 사용하지 않고 싶었습니다.
그래서 버튼들을 감싸고 있는 text-align 속성을 통해서 center값을 주었습니다.

//버튼 컨테이너와 버튼 CSS 코드

.btn-container {
  text-align: center;
  :nth-child(1) {
    margin-right: 10px;
  }
}

button {
  padding: 0.5rem;
  user-select: none;
}

text-align: center 적용 결과는 아래와 같습니다.

[CSS] box-shadow 속성 사용법

  1. offset-x | offset-Y | color
  2. offset-x | offset-Y | blur-radius | color
  3. offset-x | offset-Y | blur-radius | spread-raius | color

[CSS] text-shadow 속성을 새로 알게되었습니다

링크 - MDN text shadow

/* offset-x | offset-y | blur-radius | color */
text-shadow: 1px 1px 2px black;

[CSS] 명시도

https://www.w3schools.com/css/css_specificity.asp

명시도가 높은 스타일이 최종적으로 화면에 반영됩니다.

명시도 점수는 다음과 같이 적용됩니다.

  • 인라인 스타일 : 1000점 ex) <h1 style="color: pink;">heading</h1>
  • id : 100점 ex) #textbox
  • class, 가상 클래스, 속성 선택자 : 10점 ex) .test, :active , [href]
  • element, 가상 요소 : 1점 ex) h1, ::after, ::before

또한, 같은 명시도라면, 나중에 적용된 스타일이 최종적으로 반영됩니다.
html 문서의 <style>태그 안의 스타일이, 외부 css 파일의 스타일보다 명시도가 높게 반영됩니다.

[CSS] 속성들의 기본값

CSS 속성들에는 default 값이 있습니다. 한 번 확인해보죠.

참고: https://www.w3schools.com/cssref/css_default_values.php

[CSS] line-height

링크-MDN line-height

line-height 를 사용할 때는 유닛없는 숫자를 사용하는 것이 가장 선호되는 방법이라고 합니다.
가령 아래처럼요.

p{
	line-height: 1.1;
}
profile
안녕하세요 개발자 윤승록입니다. 내 성장을 가시적으로 기록하기 위해 블로그를 운영중입니다.

0개의 댓글