이벤트에 따라 특정 영역을 보여주고 보여주지 않는 효과는

display 속성으로 하면 매우 간단하다.

하지만 동적으로 생성되는 영역은, 특히 가로 크기가 영역이 없어지면서 디자인이 뭉개지는 경우가 발생한다.

 

그럴때는 visibility를 이용하여 display: none 과 비슷한 효과를 주면 된다.

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .sub {position:absolute; visibility: hidden; left: -10000px;}
        .sub.active {visibility: visible; left: 0px;}
    </style>
    <script>
        function show(num) {
            document.querySelector('.active').classList.remove('active');
            document.querySelector('#div'+num).classList.add('active');
        }
    </script>
</head>
<body>
    
    <div>
        header
    </div>
    <div>
        <button onclick="show(1)">div1</button>
        <button onclick="show(2)">div2</button>
        <button onclick="show(3)">div3</button>
    </div>
    <div>
        <div id="div1" class="sub active">111111111111111111111111<br>111111111111111111111111<br>111111111111111111111111<br>111111111111111111111111<br>111111111111111111111111<br>111111111111111111111111<br>111111111111111111111111<br>111111111111111111111111<br>111111111111111111111111<br>111111111111111111111111<br>111111111111111111111111<br>111111111111111111111111<br></div>
        <div id="div2" class="sub">22222222222222222222222</div>
        <div id="div3" class="sub">3333333333333333333333333</div>
    </div>

</body>
</html>

 

목표 엘리먼트에 position: absolute를 주면

목표 엘리먼트가 모두 겹치게 된다.

이때 목표 엘리먼트들을 모두 visibility: hidden 으로하고

특정 목표 엘리먼트만 visibility: visible을 설정하면 된다.

 

 

자바스크립트에서 날짜 관련 핸들링은 항상 어렵다.

 

월단위로 데이터를 검색하는 경우 검색 조건 통제를 위한 자바스크립트로 월단위를 더하는 방식을 알아본다.

 

// 한자리면 0붙이기

function pad(n) {

    return n < 10 ? '0'+n : ''+n

}

// 월 더하기
function addMonth(d, n) {
    d.setMonth(d.getMonth() + n);
    return d.getFullYear() + '/' + pad(d.getMonth()+1) + '/' + pad(d.getDate());    
}

// 실행

console.log(addMonth(new Date('2022/01/01'), 1)); // '2022/02/01'

console.log(addMonth(new Date('2022/01/15'), 1)); // '2022/02/15'

console.log(addMonth(new Date('2022/01/31'), 1)); // '2022/03/03' ??????????????

 

이는 자바스크립트에서 setMonth 함수로 월을 셋팅하면 일은 그대로고 월만 변경 되기 때문에

2022/02/31 이 된다. 2월은 28일 까지 있으므로 자바스크립트 자체에서 2월28일에서 3일을 더해 3월3일이 되는 것이다.

이에 대한 예외 처리를 해줘야 한다.

// 1자리면 0 붙이기

function pad(n) {
    return n < 10 ? '0'+n : ''+n
}

// 윤년인지여부
function isLeapYear(year) {
    return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)); 
}

// 해당년월의 말일 구하기
function getLastDate(year, month) {
    return [31, (isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
}

// 월 더하기
function addMonth(d, n) {
    var date = d.getDate();
    d.setDate(1); // 1일로 설정
    d.setMonth(d.getMonth() + n); // 개월수 더하기
    //d.setDate(d.getDate() - 1); 
    return d.getFullYear() + '/' + pad(d.getMonth()+1) + '/' + pad(Math.min(date, getLastDate(d.getYear(), d.getMonth())));    
}
// 실행
console.log(addMonth(new Date('2022/01/01'), 1)); // '2022/02/01'
console.log(addMonth(new Date('2022/01/15'), 1)); // '2022/02/15'

console.log(addMonth(new Date('2022/01/31'), 1)); // '2022/02/28'

제대로 나오는거 같다.

iframe 안의 콘텐츠 높이에 따라서 iframe의 높이를 조절하는 방식이다.

 

자식에서 자신의 iframe을 선택하는 것은

window.frameElement 로 접근할수 있다.

window.frameElement.height 는 아이프레임의 높이.

document.querySelector("body").clientHeight + 20 자식 body 영역의 높이에 적당한 높이를 더하여 부모 아이프레임 높이를 조절하면 된다.

 

parent.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <title>Parent</title>
</head>
<body>
    <div>
        <iframe src="./child.html"></iframe>
    </div>
</body>
</html>

 

child.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <title>Child</title>
    <script>
        window.onload = function() {
            window.frameElement.height = document.querySelector("body").clientHeight + 20;
        }
    </script>
</head>
<body>
    <div id="content">
        자식 입니다.<br>
        자식 입니다.<br>
        자식 입니다.<br>
        자식 입니다.<br>
        자식 입니다.<br>
        자식 입니다.<br>
        자식 입니다.<br>
        자식 입니다.<br>
        자식 입니다.<br>
        자식 입니다.<br>
        자식 입니다.<br>
        자식 입니다.<br>
        자식 입니다.<br>
    </div>
</body>
</html>

 

주민번호 형식 : 123456-1234567

 

1. 정규식으로 숫자6자리, 대쉬, 숫자7자리 체크

2. 주민번호 체크 로직으로 체크

주민번호 첫자리부터 12번째 자리까지 순서대로 

2,3,4,5,6,7,8,9,2,3,4,5 를 한자리씩 곱해서 모두 더한다.

모두 더한값을 11로 나누어 나머지를 구한다.

11에서 나머지를 뺀 값이 주민번호의 마지막 번호와 같으면 유효하다.

ex) sum = 1*2 + 2*3 + 3*4 + 4*5 + 5*6 + 6*7 + 1*8 + 2*9 + 3*2 + 4*3 + 5*4 + 6*5 = 206

나머지 = 206 % 11 = 8

값 = 11 - 8 = 3

주민번호 마지막은 7이므로 유효하지 않음.

 

// 주민번호 체크
function isResidentRegNoValid(residentRegNo) {
	var re = /^[0-9]{6}-[0-9]{7}$/;
	if (!re.test(String(residentRegNo).toLowerCase())) {
		return false;
	}

	var regNos = residentRegNo.replace('-', '').split('');
	var checkNos = [2,3,4,5,6,7,8,9,2,3,4,5];
	var sum = 0;
	for (var i = 0; i < checkNos.length; i++) {
		sum = sum + (checkNos[i] * Number(regNos[i]));
	}
	return ((11 - (sum % 11)) % 10) == Number(regNos[12]);
}

 

 

 

 

 

angular, primeng - p-overlayPanel 위치가 정상적이지 않을때

 

<div #overlayTarget>

    <button type="text" pButton label="Basic" (click)="op.toggle($event)"></button>

</div>
<p-overlayPanel #op [appendTo]="overlayTarget">
    <ng-template pTemplate>
        레이어 내용입니다.
    </ng-template>
</p-overlayPanel>

 

appendTo 속성에 타겟을 설정해 주면 된다.

 

 

익스플로러11에서

primeng p-fieldset 사용시

레이어팝업처럼 본문 넓이보다 넓이가 작은 레이어에서

p-fieldset 사용시 팝업보다 width가 커지는 문제가 발생

 

css 파일에 아래의 속성 추가하여 해결

 

fieldset {
    width: intrinsic;
}

angular, ie11에서 SCRIPT1002: 구문 오류 polyfills.js (25944,5) 오류로 흰 화면만 나오는 에러

ie11에서 아래와 같이 흰 화면과 

원인은 

.browserslistrc 파일에 있는 browserslist 에서 IE11이 지원 안되게 설정되어서 생긴 문제이다.

 

last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major versions
last 2 iOS major versions
Firefox ESR
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.

 

not IE 11에서 not 을 삭제하고 다시 빌드한다.

 

이래도 안되는 경우는 tsconfig.json 의

compilerOptions 의 "target": "es2015", 에서

es2015 를 es5로 변경하고 빌드 한다.

 

 

 

 

크롬 브라우저의 한글 폰트 문제로 크롬에서만 특정 영역의 높이가 다르게 나오는 문제가 있었습니다.

 

크롬에서만 특정 css 스타일을 적용하는 방법을 찾아보니

css hack 으로 다음과 같은 방법이 있네요.

 

<html>
	<head>
		<title></title>
		<style>
			.test {
				background-color: red;
				height: 100px;
				color: white;
			}
			@media screen and (-webkit-min-device-pixel-ratio:0){
				.test {
					background-color: blue;
				}
			}
		</style>
	</head>
	<body>
		<div class="test">test</div>
	</body>
</html>

 

배경색을 익스플로러와 크롬을 다르게 적용한 예.

test라는 클래스에 기본으로 높이 100px에 배경을 빨간색으로 적용했습니다.

여기에 아래와 같은 스타일을 적용하면

 

@media screen and (-webkit-min-device-pixel-ratio:0){ 
  .test { 
    background-color: blue; 
  } 
}

크롬 브라우저에서만 배경색이 파란색으로 표시됩니다.

 

-webkit-이라는 prefix가 webkit 베이스 브라우저를 구별하는 prefix입니다.

vendor prefix라고 불리우는 이 기능은 브라우저 벤더의 특정 기능을 구분하기 위한 것으로 보면 됩니다.

종류는 아래와 같습니다.

 

  • -webkit- (Chrome, Safari, newer versions of Opera, almost all iOS browsers (including Firefox for iOS); basically, any WebKit based browser)
  • -moz- (Firefox)
  • -o- (Old, pre-WebKit, versions of Opera)
  • -ms- (Internet Explorer and Microsoft Edge)

@media

screen : 미디어 타입이 화면(screen)이라는 의미

-webkit-min-device-pixel-ratio:0 : 단말기의 화소와 실제 화면의 pixel간의 비율이 0 이상이면, -webkit- prefix 로 크롬이나 모바일 브라우저에 적용

앵귤러 라우터 학습 중 

TS1206: Decorators are not valid here. 라는 에러에 봉착했다.

 

@NgModule 부분이 빨간색으로 표시되면서

컴파일 이후 에러가 발생했다.

데코레이터이 위치가 잘못되었다는 것이다.

아래는 에러나는 소스이다.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { LayoutComponent } from './layout/layout/layout.component';

import { RouterModule, Routes, Router } from '@angular/router';
import { TempListComponent } from './page/temp-list/temp-list.component';
import { TempDetailComponent } from './page/temp-detail/temp-detail.component';
import { IndexComponent } from './page/index/index.component';
@NgModule({
  declarations: [
    AppComponent,
    LayoutComponent,
    IndexComponent,
    TempListComponent,
    TempDetailComponent
  ],
  imports: [
    RouterModule.forRoot(appRoutes),
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
const appRoutes: Routes = [
  {path: '', redirectTo: 'index', pathMatch: 'full'},
  {path: 'index', component: IndexComponent},
  {path: 'temp',
    children: [
      {path: '', component: TempListComponent},
      {path: ':id', component: TempDetailComponent},
    ]
  },
];
export class AppModule {}

 

ERROR in src/app/app.module.ts(11,1): error TS1206: Decorators are not valid here.

 

이는 데코레이터에 대한 이해가 부족해서 생긴 에러이다.

라우터 설정 값을 추가하면서 데코레이터 아래에 클래스 선언부 위, 두 중간에 삽입해서 생긴 문제이다.

데코레이터는 클래스의 역할을 정의하고 메타데이터를 정의하는데 사용된다.

따라서 decorator와 class는 붙어 있어야 된다.

 

아래와 같이 router 설정을 위로 이동하면 해결이 되는 문제다.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { LayoutComponent } from './layout/layout/layout.component';

import { RouterModule, Routes, Router } from '@angular/router';
import { TempListComponent } from './page/temp-list/temp-list.component';
import { TempDetailComponent } from './page/temp-detail/temp-detail.component';
import { IndexComponent } from './page/index/index.component';
const appRoutes: Routes = [
  {path: '', redirectTo: 'index', pathMatch: 'full'},
  {path: 'index', component: IndexComponent},
  {path: 'temp',
    children: [
      {path: '', component: TempListComponent},
      {path: ':id', component: TempDetailComponent},
    ]
  },
];
@NgModule({
  declarations: [
    AppComponent,
    LayoutComponent,
    IndexComponent,
    TempListComponent,
    TempDetailComponent
  ],
  imports: [
    RouterModule.forRoot(appRoutes),
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}


 

 

 

 

 

앵귤러에서 기본 포트는 4200입니다.

로컬에서 개발중이라면 

http://localhost:4200 으로 서비스 됩니다.

 

그런데 프로젝트를 2개를 동시에 작업중이거나

테스트용 프로젝트를 동시에 사용하면 4200 포트를 동시에 사용할 수 없으니

포트를 변경해야 하는 경우가 있습니다.

 

포트 변경 방법은 2가지가 있습니다.

1. 실행 단계에서 포트 설정

2. 설정파일에서 포트 설정

 

1. 실행 단계에서 포트 설정은 angular로 서버 시작시 포트 옵션을 설정합니다.

ng serve --port 4201 

와 같이 실행하면 4001번 포트로 실행됩니다.

 

2. 설정파일에서 포트 설정

4200번 기본 port를 변경하고자 한다면 

프로젝트 루트에 위치한

angular.json 파일에서 설정을 변경하면 됩니다.

 

architect > serve > options 항목에

"port": 포트번호(숫자)를 추가하면 됩니다.

 

프로젝트 기본 설정에는 해당 항목이 없으므로 추가해 주어야 합니다.

예 ) "port": 4202

 

 

그럼

http://localhost:4202 으로 접근이 가능합니다.

 

+ Recent posts