modal은 보통 body의 맨 마지막에 둡니다.
z-index를 굳이 설정하지 않아도 자연히 맨 위로 올라갈 수 있기 때문이지요.
사용자 지정 CSS 속성 사용하기 (변수) - CSS: Cascading Style Sheets | MDN (mozilla.org)
inline으로 color를 지정해주기보다 variable로 만드는건 어떨까요?
:root {
--button-color: #00bcd4;
}
background: var(--button-color);
@import url('./base.css');
@import url('./contents.css');
@import url('./toggle.css');
@import url('./modal.css');
.modal {
...
transition: opacity 0.2s linear;
}
.lotto-app-button:hover {
opacity: 0.7;
}
css 네이밍도 중요해요. BEM(Block, Element, Modifier) 세 가지 요소로 네이밍을 지읍시다!
css naming convention - BEM (velog.io)
.header__navigation--navi-text {
color: red;
}
위 코드에서 header
는 Block, naviagtion
은 Element, navi-text
는 Modifier가 됩니다.
https://studyingazae.tistory.com/194
px : 반응형 웹 페이지에서 사용을 비추합니다.
em : 상위 요소의 폰트 사이즈를 상속 받습니다.
html{ font-size : 10px; }
div { font-size : 2em; /* 10px의 2배 */ }
li { font-size : 2em; /* 10px의 2배의 2배 */ }
<html> 폰트 10
<div> 폰트 20
<li>폰트 40</li>
</div>
</html>
html{ font-size : 10px; }
div { font-size : 2rem; /* 10px의 2배 */ }
li { font-size : 3rem; /* 10px의 3배 */ }
<html> 폰트 10
<div> 폰트 20
<li>폰트 30</li>
</div>
</html>
각 브라우저마다 다를 수 있는 부분들을 위해 reset을 해보는 건 어떨까요?
제 기억으로는 CDN으로 연결하는 부분들도 있었던 것 같아요.
html,
body,
div,
span,
h1,
h2,
h3,
h4,
h5,
h6,
p,
a,
ol,
ul,
li,
form,
label,
table,
footer,
header,
nav,
button section {
font-size: 100%;
margin: 0;
padding: 0;
box-sizing: border-box;
}
반복🔁을 줄이기 위해 javascript에서 map을 사용해서 그려주면 좋지 않을까요? (template.js
를 만들어 봅시다.)
<form id="user-lotto-form">
<input class="user-lotto-number" type="number" min="1" max="45" />
<input class="user-lotto-number" type="number" min="1" max="45" />
<input class="user-lotto-number" type="number" min="1" max="45" />
<input class="user-lotto-number" type="number" min="1" max="45" />
<input class="user-lotto-number" type="number" min="1" max="45" />
<input class="user-lotto-number" type="number" min="1" max="45" />
<input class="user-bonus-number" type="number" min="1" max="45" />
<button id="user-lotto-result-button" type="submit">결과 확인하기</button>
</form>
new Array(6).map(()=>{
...insertAdjacentHTML('afterbegin',`<input class="user-lotto-number" type="number" min="1" max="45" />`)
})
오호! 시도 자체가 너무 대단하다고 개인적으로 생각합니다.
깔끔하게 모아두면 보기가 더 좋을 것 같아요.
DRY 원칙, 즉 “반복하지 마라(Don’t Repeat Yourself)”라는 말 역시 좋은 소프트웨어 개발 습관의 근원이라 할 만하죠?
“모든 지식 조각은 딱 한 번만 나와야 한다 ”라는 말이기도 합니다.
[Javascript] parseInt()과 Math.floor()의 차이 (velog.io)
양수일 경우는 대부분 비슷하게 동작해요. 하지만... 아래와 같은 경우도 있다는 사실!
Math.floor( "-12.34" ); // -13
parseInt( "-12.34" ); // -12
Math.floor( "12 34 56" ); // NaN
parseInt( "12 34 56" ); // 12
커스텀 이벤트 핸들러를 작성할 수도 있을 것 같아요. 인자가 많아지면 파라미터로 객체를 활용해볼 수 있을 것 같네요.
function registerEvent(target, eventType, callback) {
//...
}
registerEvent(this.winningNumberForm, 'submit', e =>
this.handleWinningNumberFormSubmit(e),
);
이런 방법도 있구나.. 놀랐습니다😲😲
const purchasedMoneyValidator = [
{ test: isZero, errorMsg: ERROR_MESSAGE.ZERO_PURCHASE_MONEY },
{ test: isNotNumber, errorMsg: ERROR_MESSAGE.INVALID_PURCHASE_MONEY_TYPE },
...
]
const validatePurchaseMoney = value => purchasedMoneyValidator.every(({ test, errorMsg }) => {
if (test(value)) throw new Error(errorMsg)
return true
})
init(초기화)는 constructor에서 수행하는 것이 맞습니다.
- 사용자가 무엇을 해야할지 직관적으로
바로 알 수 없다면 개발자의 잘못
이라고 생각합니다
직관적으로 알 수 있는 UI가 먼저이고 그럴 수 없는 경우라면 어떻게 해야할지 구체적이고 상세하게 안내하자!
악의적인 초등학생이 깨트리려고 해도 절대 깨지지 않는 앱을 만들자!
🎯 그 목표를 위해 에러를 더 많이 발생시키고 그에 대한 예외처리를 상세히 기술해서 사용성이 깨지지 않도록 노력합시다!
const controller = new LottoController();
controller.winningLottos = [4,15,25,36,41,27,33];
controller.winningLottos로 Class 내의 변수에 바로 접근(get)해서 수정(set)할 수 있다는 말은 은닉화가 이루어지고 있지 않다는 거죠!
이 테스트를 통과한다면 어지간해선 잘 동작할 것이라고 안심해도 될까?
이 질문을 계속 던져보세요.
원래부터 private method는 테스트할 수 없도록 하는게 객체지향에서의 본래 취지입니다.
"객체 내부 로직에 대해서는 궁금하지 않고 오직 밖으로 드러난 것만 잘 보이면 된다"는 차원이거든요.
'단위테스트'라고 할 때의 '단위'
가 함수 내지 메소드단위일 경우도 있지만, '객체'를 하나의 단위로 인식하는게 일반적입니다.
이 객체(인스턴스)에 대한 테스트는 오직 public method를 통해서만 이뤄지도록 하면 되는 것이에요. public method만으로 기존 테스트를 정상적으로 수행할 수 없다면, 테스트 케이스를 수정하셔야 합니다.