text-shadow를 이용하면 글씨 네온사인 효과를 낼 수 있음.
text-shadow: offset-x / offset-y / blur-radius / color ;
text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 20px #ff0080, 0 0 30px #ff0080, 0 0 40px #ff0080, 0 0 55px #ff0080, 0 0 75px #ff0080;
이런식으로 blur값을 넓혀주면서 여러번 써주면 예쁜 네온사인 효과를 구현할 수 있다.
CRUD는 대부분의 컴퓨터 소프트웨어가 가지는 기본적인 데이터 처리 기능.
"Create, Read, Update, Delete"를 묶어서 일컫는 말임.
-> 생성, 읽기, 갱신, 삭제
function set() {
path.style.stroke = color; // path의 테두리 색상 설정
path.style.strokeWidth = 3; // path의 테두리 굵기 3
path.style.strokeDasharray = path.getTotalLength() + "," + path.getTotalLength();
// 윤곽을 그리는 데 사용되는 대시 및 간격 패턴을 정의하는 표시 속성 // getTotalLength() = > 경로의 총 길이에 대한 사용자 에이전트의 계산된 값을 사용자 단위로 반환
path.style.strokeDashoffset = path.getTotalLength();
// 대시 배열의 렌더링에서 오프셋을 정의하는 표시 속성
window.requestAnimationFrame(draw.bind(this)); // 브라우저에게 수행하기를 원하는 애니메이션을 알리고 다음 리페인트가 진행되기 전에 해당 애니메이션을 업데이트하는 함수를 호출. 리페인트 이전에 실행할 콜백을 인자로 받는다.
}//다음 리페인트에서 그 다음 프레임을 애니메이트하려면 콜백 루틴이 반드시 스스로 requestAnimationFrame()을 호출해야합니다.
function draw() {
if (speed < path.getTotalLength()) {
path.style.strokeDashoffset = path.getTotalLength() - speed;
window.requestAnimationFrame(draw.bind(this));
speed = speed + offset;
} else if (speed > path.getTotalLength()) {
path.style.fill = color;
}
}
//파도 애니메이션 함수
set()함수 끝에 보면 window.requestAnimationFrame(draw.bind(this)); == draw(set())으로 무한루프를 이루게 된다.
*벨로그 공백 있으면 안 나가짐 >> 백틱 세 개 넣어야함. 코드 블럭에서 안 나가져서 30분째 ??? 했음.
아래 코드는 미니프로젝트를 하면서 서버쪽 코드인데, this를 왜 let _this = this로 했는가에 대해 작성한 것임.
let guestBook = {
num: null,
postBox: null,
updateStatus: false,
init: function () {
this.settingList();
this.postBox = $("#postBox");
this.registEvent();
},
registEvent: function () {
let _this = this;
$('#fil').on('keyup', function(){
_this.listFilter();
});
},
// 방명록 붙혀넣기
settingList: function () {
$.ajax({
type: "GET",
url: "/guestBook/list",
data: {},
success: function (response) {
let rows = JSON.parse(response["supports"]);
$("#cards-box").empty();
for (let i = 0; i < rows.length; i++) {
let oid = rows[i]["_id"]["$oid"];
let name = rows[i]["name"];
let conents = rows[i]["contents"];
let temp_html = `<div class="card" id="listCard${oid}">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p class="nick_name">${conents}</p>
<footer class="blockquote-footer">${name}</footer>
</blockquote>
<button onclick="guestBook.openUpdateForm('${oid}')" type="button" class="btn btn-outline-dark">수정</button>
<button onclick="guestBook.deleteGuestBook('${oid}')" type="button" class="btn btn-outline-dark">삭제</button>
</div>
</div>`;
$("#cards-box").append(temp_html);
}
},
});
}
// 방명록 등록함수
,insertGuestBook: function () {
let _this = this;
if (confirm("등록하시겠습니까?")) {
let name = $(this.postBox).find('input[name="guestBookName"]').val();
let contents = $(this.postBox)
.find('textarea[name="guestBookContents"]')
.val();
if (name == "" || typeof name == "undefined") {
alert("닉네임을 입력해주세요");
return false;
}
if (contents == "" || typeof contents == "undefined") {
alert("내용을 작성해주세요");
return false;
}
$.ajax({
type: "POST",
url: "/guestBook/insert",
data: {
guestName: name,
guestContents: contents,
},
success: function (response) {
alert(response["msg"]);
_this.settingList();
window.location.reload();
},
// 일반 함수 안에서의 this는 window를 가르킴, ajax 안에서 this는 insertGuestBook를 가르켜야 함. 하지만 일반 this를 쓰면, 전역 함수로 쓰임.
// .settingList() => get요청. insertGuestBook POST로 받고, .settingList GET으로 페이지로 붙혀줌.
});
}
},
// 방명록 수정 기능
updateGuestBook: function () {
let _this = this;
if (!this.updateStatus) {
if (confirm("변경하시겠습니까?")) {
this.updateStatus = true;
let name = $(this.postBox).find('input[name="guestBookName"]').val();
let contents = $(this.postBox)
.find('textarea[name="guestBookContents"]')
.val();
if (name == "" || typeof name == "undefined") {
alert("닉네임을 입력해주세요");
return false;
}
if (contents == "" || typeof contents == "undefined") {
alert("내용을 작성해주세요");
return false;
}
$.ajax({
type: "POST",
url: "/guestBook/update",
data: {
id: _this.num,
guestName: name,
guestContents: contents,
},
success: function (response) {
alert(response["msg"]);
_this.closeUpdateForm();
_this.settingList();
window.location.reload();
},
});
}
}
},
let _this = this를 설정 안 해주고 일반 this를 해버리면, 최상위 객체인 let guestBook을 가르켜버림.
그래서 let _this = this로 설정해주고 특정 함수값을 가져온다.
*스코프 내부 어디서든 변수 선언은 최상위에 선언된 것 처럼 행동.
스코프? : '범위'라는 뜻. 지역 스코프와 전역 스코프가 있다.
선언은 호이스팅 되지만, 할당은 호이스팅이 안된다.
var name;
console.log(name); // undefined
name='hwuiinn'; // 할당은 여기서 처리된다.
let과 const도 hoisting된다.
console.log(name); // Reference Error
let name='hwuiinn';
-왜 var처럼 동작하지 않고 참조 에러가 나는가?
-> TDZ(Temporal Dead Zone) 때문이다.
*console.log(name); // Temporal Dead Zone
const name = 'hwuiinn'; // 함수 선언 및 할당
console.log(name); // 사용가능
console.log(name); // Temporal Dead Zone
-> let과 const는 TDZ의 영향을 받음.
할당을 하기 전엔 사용할 수 없음. 이는 코드를 예측 가능하게 하고, 잠재적인 버그를 줄일 수 있다.
'호이스팅은 스코프 단위로 진행된다'
let age = 30;
function showAge() {
console.log(age);
}
showAge();
//정상 코드
let age = 30;
function showAge() {
console.log(age);
let age = 20;
}
showAge();
//에러 코드, let age = 20;가 지역 스코프로 호이스팅을 일으킴.
변수의 생성과정
함수 스코프 안에서 var가 선언된다면, 함수 밖에서도 var에 접근 불가함.
=> '유일하게 벗어날 수 없는 스코프 == 함수 스코프'
쉘 스크립트