TodoList-userInfo(js, css)

hyukoยท2023๋…„ 3์›” 30์ผ
0

TodoList - userInfo

๐Ÿ˜ฝ ์•ž์„œ ํ–ˆ๋˜ userInfo์˜ css ์™€ js ์ž‘๋™๋“ค์„ ํ™•์ธํ•˜๊ณ 
sidebar๋ฅผ ํ•˜๋Ÿฌ ๊ฐ€๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

.main-container {
    margin: 10px auto;
    width: 550px;
    height: 100%;
}

.main-hidden {
    display: none;
}

.main-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;

}

.main-title {
    margin: 20px 0px 0px 20px;
    font-size: 36px;
}

.info-photo {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;

    margin-top: 20px;
    width: 100%;
    height: 300px;

    overflow: hidden;
    cursor: pointer;
}

.info-photo:hover {
    opacity: 0.8;
}

.photo-file {
    display: none;  
}

.info-photo img {
    width: 100%;
}

.change-nav {
    position: absolute;
    bottom: 3px;
    right: 3px;
    
    display: none;

    border-radius: 5px;
    padding: 5px;

    background-color: #121212bb;
    color: #f0f0f0;
    font-size: 12px;
}

.info-photo:hover .change-nav {
    display: block;
}

.info-main {
    margin-top: 30px;
    padding: 20px;
}

.info-title {
    font-size: 20px;
    margin-bottom: 10px;
    cursor: default;

}

.button-hidden {
    display: none;
}

.info-detail {
    display: flex;
    justify-content: space-between;
    margin-bottom: 20px;
}

.detail-left, .detail-right {
    width: 48%;

}

.info-input-container {
    display: flex;
    flex-direction: column;

    width: 100%;
}

.info-input-container label {
    font-weight: 600;
    margin-bottom: 5px;
}

.info-input {
    margin-bottom: 10px;
    border-bottom: 1px solid #dbdbdb;
    width: 100%;

    background-color: #f0f0f0;
}


.introduce-input {
    border-bottom: 1px solid #dbdbdb;
    width: 100%;
    height: 100px;
    resize: none;

    background-color: #f0f0f0;
}

.info-input:disabled, .introduce-input:disabled {
    background-color: #fff;
}

์ด์ œ ์•Œ์•„๋ณผ ๊ฒƒ์€ javascript๋ฅผ ํ†ตํ•œ ์ œ์–ด์ด๋‹ค.

์ด userInfo์—์„œ์˜ ๊ธฐ๋Šฅ์€ photo๋ฅผ ๋ฐ”๊ฟ€ ๋•Œ ํด๋ฆญ๋˜๋Š” ๊ฒƒ๊ณผ
์ด๋ฏธ์ง€๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒƒ ๊ทธ๋ฆฌ๊ณ  ์•„๋ž˜์˜ ์ •๋ณด๋“ค์„ ์ˆ˜์ • ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ
์ˆ˜์ •์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ๊ฒƒ ์ •๋„๋˜๊ฒ ๋‹ค.

์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด์„œ ๋ถ„์„ํ•ด๋ณด์ž


// ์ตœ๋Œ€ํ•œ ์ฝ”๋“œ๋ฅผ ์žฌํ™œ์šฉ ํ•˜๊ณ  ์ ‘๊ทผ์„ ์ธ์Šคํ„ด์Šค๋ฅผ ์ด์šฉํ•ด์•ผ๋งŒ ์ ‘๊ทผ
// ๊ฐ€๋Šฅํ•˜๋„๋ก ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ์ œ์ž‘ํ•  ์˜ˆ์ •์ด๋‹ค

class InformationEvent {
    static #instance = null;
    static getInstance() {
        if(this.#instance == null){
            this.#instance = new InformationEvent();
        }
        return this.#instance;
    }

	// ์‚ฌ์ง„์„ ํด๋ฆญ ํ–ˆ์„ ๋•Œ input์ด ํด๋ฆญ๋˜๋„๋ก ์„ค์ •ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

    addEventPhotoChangeClick() {
        const infoPhoto = document.querySelector('.info-photo');
        infoPhoto.onclick = () => {
            const photoFile = document.querySelector('.photo-file');
            photoFile.click();
        }
    }

	// ์‚ฌ์ง„์ด ํด๋ฆญ๋˜์–ด input์ด ์—ด๋ฆฌ๊ณ  ์‚ฌ์ง„์ด ๋ณ€๊ฒฝ ๋ฌ์„ ๊ฒฝ์šฐ ์•„๋ž˜์˜ ๊ธฐ๋Šฅ์ด ์ง„ํ–‰๋œ๋‹ค.

    addEventPhotoChange() {
        const photoFile = document.querySelector('.photo-file');
        photoFile.onchange = () => {
            
          	// ์•„๋ž˜์˜ FileService ๋˜ํ•œ ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ์ œ์ž‘๋˜์–ด ์žˆ๋‹ค.
            FileService.getInstance().changePhoto();
        }
    }
    
	// information์˜ edit ๋ฒ„ํŠผ์ด ํด๋ฆญ๋˜์—ˆ์„ ๊ฒฝ์šฐ 
    addEventInformationEdit() {
        this.addEventAboutMeModifyClick();
        this.addEventAboutMeSaveClick();
    }
    
	// introduction์˜ edit์ด ํด๋ฆญ๋˜์—ˆ์„ ๊ฒฝ์šฐ
    addEventIntrodutionEdit() {
        this.addEventSelfIntroductionModifyClick();
        this.addEventSelfIntroductionSaveClick();
    }
    
	// ํ•ด๋‹น ํ•จ์ˆ˜๋Š” click ํ•œ ๋ฒ„ํŠผ์ด ์ˆ˜์ •๋ฒ„ํŠผ์ธ์ง€ ์ˆ˜์ •์™„๋ฃŒํ›„ ์ €์žฅ ๋ฒ„ํŠผ์ธ์ง€ ๊ตฌ๋ณ„ํ•ด์„œ ์ž‘๋™์„ ํ•˜๋Š” ๊ฒƒ์„ ์ •์˜ ํ•ด๋†“์•˜๋‹ค.
    addEventAboutMeModifyClick() {
        const aboutMeModifyButton = document.querySelector('.m-aboutme');
        aboutMeModifyButton.onclick = () => {
            const aboutMeSaveButton = document.querySelector('.s-aboutme');
            aboutMeSaveButton.classList.remove('button-hidden');
            aboutMeModifyButton.classList.add('button-hidden');
            
            const infoInputContainers = document.querySelectorAll('.info-input-container');
            infoInputContainers.forEach(infoInputContainer => {
                const infoInput = infoInputContainer.querySelector('.info-input');
                infoInput.disabled = false;
            });
            
        }
    }
    
	// ํ•ด๋‹น ํ•จ์ˆ˜๋Š” save๋ฒ„ํŠผ์ด ํด๋ฆญ ๋˜์—ˆ์„ ๋•Œ ์–ด๋–ค์‹์œผ๋กœ ์ž‘๋™ํ• ์ง€ ์ •์˜ ํ•ด๋†“์€ ํ•จ์ˆ˜ ์ด๋‹ค.
    addEventAboutMeSaveClick() {
        const aboutMeSaveButton = document.querySelector('.s-aboutme');
        aboutMeSaveButton.onclick = () => {
            const aboutMeModifyButton = document.querySelector('.m-aboutme');
            aboutMeModifyButton.classList.remove('button-hidden');
            aboutMeSaveButton.classList.add('button-hidden');
            
            const infoInputContainers = document.querySelectorAll('.info-input-container');
            infoInputContainers.forEach(infoInputContainer => {
                const infoInput = infoInputContainer.querySelector('.info-input');
                infoInput.disabled = true;
            });
        }
    }

    addEventSelfIntroductionModifyClick() {
        const selfIntroductionModifyButton = document.querySelector('.m-introduce');
        selfIntroductionModifyButton.onclick = () => {
            const selfIntroductionSaveButton = document.querySelector('.s-introduce');
            selfIntroductionSaveButton.classList.remove('button-hidden');
            selfIntroductionModifyButton.classList.add('button-hidden');
            
            const introduceInput = document.querySelector('.introduce-input');
            introduceInput.disabled = false;
            
        }
    }
    
    addEventSelfIntroductionSaveClick() {
        const selfIntroductionSaveButton = document.querySelector('.s-introduce');
        selfIntroductionSaveButton.onclick = () => {
            const selfIntroductionModifyButton = document.querySelector('.m-introduce');
            selfIntroductionModifyButton.classList.remove('button-hidden');
            selfIntroductionSaveButton.classList.add('button-hidden');
            
            const introduceInput = document.querySelector('.introduce-input');
            introduceInput.disabled = true;
        }
    }
}

class InformationService {
    static #instance = null;
    static getInstance() {
        if(this.#instance == null){
            this.#instance = new InformationService();
        }
        return this.#instance;
    }

	// ํ™”๋ฉด์ด ๋กœ๋“œ๋˜๋Š” ๋™์‹œ์— ์ง„ํ–‰๋˜๋Š” ๋กœ์ง์ด๋‹ค
	// ์šฐ๋ฆฌ๋Š” ๋กœ์ปฌ์Šคํ† ๋ฆฌ์ง€์— ์ •๋ณด๋ฅผ ์ €์žฅํ•˜์—ฌ ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•˜์—ฌ๋„
	// ์ •๋ณด๊ฐ€ ๋‚ ์•„๊ฐ€์ง€ ์•Š๊ฒŒ ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— 
	// ์ตœ์ดˆ์— ๊ฐ’์ด ์—†์„ ๋•Œ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๋ฐ›์•„์˜ฌ์ˆ˜ ์žˆ๊ฒŒ ์•„๋ž˜์˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ
	// ๊ตฌํ˜„ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    loadInfo() {
        this.loadInfoPhoto();
    }

    loadInfoPhoto() {
        const infoPhotoImg = document.querySelector('.info-photo img');
        const infoPhoto = localStorage.getItem('infoPhoto');
        if (infoPhoto== null) {
            infoPhotoImg.src = './images/noimage-760x460.png'
        }else {
            infoPhotoImg.src = infoPhoto;
        }
    }

}

class FileService {
    static #instance = null;
    static getInstance() {
        if(this.#instance == null){
            this.#instance = new FileService();
        }
        return this.#instance;
    }

    changePhoto() {
        const photoForm = document.querySelector('.photo-form');
        const formData = new FormData(photoForm);
        const fileValue = formData.get('file');
        
        if(fileValue.size == 0) {
            return;
        }

        this.showPreview(fileValue);
    }

    showPreview(fileValue) {
        const fileReader = new FileReader();
        
        fileReader.readAsDataURL(fileValue);

        fileReader.onload = (e) => {
            const photoImg = document.querySelector('.info-photo img');
            photoImg.src = e.target.result;
            localStorage.setItem('infoPhoto', photoImg.src);
        }

    }
}



๋งˆ์น˜๋ฉฐ...

js, css ๋ฅผ ๋‹ค๋ฃจ๊ณ  side bar ๊นŒ์ง€ ๊ธฐ๋ก์„ ํ•˜๋ ค ํ–ˆ์œผ๋‚˜ ๋‚ด์šฉ์ด
๊ฝค๋‚˜ ๊ธธ์—ˆ๋˜ ๊ด€๊ณ„๋กœ ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ ๊ธฐ๋ก์„ ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.
์ข€๋” ์ข‹์€ js ๋ฐฉ์‹์ด ์žˆ์„ ๊ฒƒ์ด๊ณ  jquery๋“ฑ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•๋„ ์žˆ๊ฒ ์ง€๋งŒ
์ˆœ์ˆ˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๋ชจ๋“  ๊ฒƒ์„ ์ œ์–ดํ•˜๋Š”๊ฒŒ ๋ชฉํ‘œ์˜€๊ธฐ ๋•Œ๋ฌธ์—
์ฝ”๋“œ๊ฐ€ ๋งŽ์ด ๊ธธ๊ณ  ์ด์ƒํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค!!

profile
๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž ์ค€๋น„์ค‘

0๊ฐœ์˜ ๋Œ“๊ธ€