본문 바로가기
공부일지/Javascript

Clone_Coding. Google (Like_a_Google)

by 곰인간 2023. 4. 8.

구글 클론 코딩 세미 완성본??

https://likeagoogle.netlify.app/


구글 클론 코딩을 해보았다.

레이아웃은 간단했다.

하지만 평소 css를 홀대했던 나는 크게 디였다..

최근에 많은 것을 배웠다.

레이아웃은 그냥 잡는게 아니라 섹션별로 구분하는게 내가 보기에도 편하다는 것을.


# HEADER

<header>

    <div class="container-menu">
        <div class="left-menu">
            <a href="javascript:void(0);">Google 정보</a>
            <a href="javascript:void(0);">스토어</a>
        </div>
        <div class="right-menu">
            <a href="javascript:void(0);">Gamil</a>
            <a href="javascript:void(0);">이미지</a>
            <div class="apps-menu">
                    <div class="apps-button">
                        <span class="material-icons" title="Google 앱">apps</span>
                    </div>
                <div class="apps-dropdown">
			<!--여기에 아주 많은 a태그가 주르륵 달려 있었지만 편의상 생략했습니다.-->
                    </div>
                        <div class="etc">
                            <button>기타 Google 앱 및 제품</button>
                        </div>
                  </div>
                <button class="logIn">로그인</button>
             </div>
        </div>
    </div>

   </header>

지금와서 생각해보니 apps-dropdown에 들어가는 a 태그 들을 ul태그로 묶어서 했을걸 그랬나 싶네요.

css부분은 필요한 부분만 작성하고 생략하겠습니다! (너무 길어..)

.container-menu .right-menu .apps-menu .apps-dropdown {
    position: absolute;
    background-color: white;
    border: 1px solid #ccc;
    padding: 10px;
    box-shadow: 0 2px 6px rgba(116, 114, 114, 0.8);
    overflow: auto;
    min-width: 301px;
    max-height: 448px;
    right: 0;
    z-index: 8;
    border-radius: 8px;
    top: 50px;
    visibility: hidden;
  }
  .container-menu .right-menu .apps-menu .apps-dropdown.show {
    visibility: visible;
  }

드롭다운 메뉴의 구성 css만 꺼내왔습니다.

apps-dropdown선택자에 초창기는 visibility가 아닌 display: none;을 사용하여 보이지않게 하였음.

그리고 자바스크립트에서 클릭 이벤트를 이용해서 드롭다운메뉴 style에 직접적으로 display를 전환 시켰음.

const appsButton = document.querySelector('.apps-button');
const appsDropdown = document.querySelector('.apps-dropdown');

appsButton.addEventListener('click', () => {
  if (appsDropdown.style.display === 'block') {
    appsDropdown.style.display = 'none';
  } else {
    appsDropdown.style.display = 'block';
  }
});

document.addEventListener("click", function (e) {
  if (!appsButton.contains(e.target)) {
    appsDropdown.style.display = 'none';
  }
})

 

위 코드는 제가 처음 작성한 코드입니다.

보시면 위에 함수는 화살표 함수 해놓고,

밑에는 그렇게 안함..

또, 밑에 리팩토링을 거친 코드와 다르게

css선택자를 이용한게 아니라 드롭다운 구성 메뉴에

바로 스타일로 display속성을 우겨 넣음.

이벤트 버블링 때문에 드롭다운 메뉴 내부를 클릭해도 드롭다운 메뉴가 사라지게 됨.

코드 줄 수는 짧은데 뭔가 더 지저분하고 보기 어려워 보입니다..

/* appsDropdown */
const appsButton = document.querySelector('.apps-button');
const appsDropdown = document.querySelector('.apps-dropdown');

appsButton.addEventListener('click', e => {
  e.stopPropagation();
  if(appsDropdown.classList.contains('show')) {
    hide();
  } else {
    show();
  }
});

appsDropdown.addEventListener('click', e => {
  e.stopPropagation();
})

window.addEventListener('click', hide);

function show () {
  appsDropdown.classList.add('show');
};
function hide () {
  appsDropdown.classList.remove('show');
}

위에 자바스크립트 코드는 1차 리팩토링을 거쳐서

css에 show라는 선택자를 classList를 통해서

드롭다운 구성 메뉴에 추가하거나 제거하게 하였고,

이벤트 버블링도 처리했고,

콜백함수도 보기 좋게 정리하고,

화살표 함수로 정리도 했습니다.


# LOGO

<!-- Google-Logo -->
   <section class="logo-container">

    <div class="img-box">
        <img src="images/googlelogo_color_272x92dp.png" alt="">
    </div>

   </section>

로고 부분에 css로 작업을 했지만 생략하겠습니다.

신경써야할 부분은 container 부분에 flex요소를 사용하였고,

flex-shrink요소에 0의 값을 줘서 화면이 줄어도 같이 줄어들지 않게 하였다 정도?

높낮이에 따라 최고 높이와 최소 높이를 줬다 정도?


# SEARCH

   <!-- Search-Bar -->
   <section class="search-container">

    <form action="https://www.google.com/search" role="search" method="get">
        <div class="search-room">
            <div class="search-box">
                <div class="icon-box">
                    <div class="search-icons">
                        <i class="fa-solid fa-magnifying-glass searchI"></i>
                    </div>
                    <div class="search-bar box">
                        <input name="q" type="search" class="search-bar">
                    </div>
                    <div class="search-right">
                        <div class="key-bd"><i class="fa-regular fa-keyboard"></i></div>
                        <div class="mic"><i class="fa-solid fa-microphone-lines"></i> </div>
                        <div class="camera"><i class="fa-solid fa-camera"></i></div>
                    </div>
                </div>
            </div>
            <div class="btn-group">
                <center>
                    <input type="submit" value="Google 검색" class="btn submit" />
                    <input type="button" value="I’m Feeling Lucky" class="btn doodle"/>
                </center>
            </div>
        </div>
    </form>

   </section>

구글 검색이 가능하게 하였고,

flex를 이용하여 검색창 내부에 아이콘들을 정렬하고,

화면이 줄어들면 검색창에서 벗어나지 않게 조정함.


# BLANK

<!-- blank Space -->
   <div class="blank"></div>

뭐 말그대로 빈 공간

flex-grow와 flex-shrink를 사용해서 화면의 크기 변화에 반응하도록 하였음.


# FOOTER

 <!-- Footer -->
   <footer class="footer-container">
    <div class="footer-box">
        <div class="footer-item-1">
            대한민국
        </div>
        <div class="footer-item-2">
            <div class="left-item">
                <a href="javascript:void(0);">광고</a>
                <a href="javascript:void(0);">비즈니스</a>
                <a href="javascript:void(0);">검색의 원리</a>
            </div>
            <div class="right-item">
                <a href="javascript:void(0);">개인정보처리방침</a>
                <a href="javascript:void(0);">약관</a>
                <span id="option">
                    <div class="option-item">
                        설정
                    </div>
                    <div class="dropdown-content">
                        <a href="javascript:void(0);">검색 설정</a>
                        <a href="javascript:void(0);">고급검색</a>
                        <a href="javascript:void(0);">Google 검색에 표시되는 데이터</a>
                        <a href="javascript:void(0);">검색 기록</a>
                        <a href="javascript:void(0);">검색 도움말</a>
                        <a href="javascript:void(0);">의견 보내기</a>
                        <div class="dark-mode">
                            <input type="button" value="어두운 테마: 사용 안함" id="change">
                                <span class="material-icons sun">light_mode</span>
                         </div>
                      </div>
                </span>
            </div>
        </div>
    </div>
   </footer>

footer container 안에 footer box를 지정해서

item1번과 item2을 위아래로 나눴습니다.

그리고 item2번에 직관적으로 볼 수 있게,

left-item과 right-item으로 구분하였고,

right-item의 설정은 내부에 여러 contents를 드롭다운 메뉴로 구성했습니다.

그리고 input button을 누르면 다크모드가 동작하게 구성했고, 

다크 모드인지 라이트 모드인지 직관적으로 구분하게 아이콘도 작성.

.footer-container .footer-item-2 .right-item .dropdown-content {
    position: absolute;
    bottom: 48px;
    right: 21px;
    z-index: 1;
    background-color: #ffffff;
    width: 248px;
    visibility: hidden;
}
.footer-container .footer-item-2 .right-item .dropdown-content.show-item {
    visibility: visible;
}

position값을 absolute로 주고,

bottom에서 48px, right에서 21px위치에 자리를 잡게합니다.

그리고 z-index값을 1로 줘서 footer box보다 위에 둡니다.

마지막으로 visibility hidden으로 안보이게 마무리.

/* footer_dropDown */
const drop = document.querySelector('.option-item');
const dropdownContent = document.querySelector('.dropdown-content');

drop.addEventListener('click', e => {
  e.stopPropagation();
  if(dropdownContent.classList.contains('show-item')) {
    footerHide();
  } else {
    footerShow();
  }
});

dropdownContent.addEventListener('click', e => {
  e.stopPropagation();
});

window.addEventListener('click', footerHide);

function footerShow () {
  dropdownContent.classList.add('show-item');
};
function footerHide () {
  dropdownContent.classList.remove('show-item');
};

footer부분도 header부분과 마찬가지로 리팩토링을 거쳤습니다.


# FOOTER > DARK_MODE

/* Dark Mode */
const dark= document.querySelector('.dark-mode');
const body = document.querySelector('body');
const footer = document.querySelector('footer');
const header = document.querySelector('header');
const sun = document.querySelector('.sun');

dark.addEventListener('click', function () {
  const change = document.querySelector('#change');
    if(change.value === '어두운 테마: 사용 안함') {
        add();
        change.value = '어두운 테마: 사용';
        document.querySelector('.material-icons.sun').textContent = 'dark_mode';
    } else {
        remove();
        change.value = '어두운 테마: 사용 안함';
        document.querySelector('.material-icons.sun').textContent = 'light_mode';
    }
});


function add () {
  body.classList.add('body-night');
  footer.classList.add('footer-night')
  header.classList.add('header-night');
};
function remove () {
  body.classList.remove('body-night');
        footer.classList.remove('footer-night');
        header.classList.remove('header-night');
};

다크 모드 동작하는 자바스크립트 코드입니다.

처음엔 input버튼만 동작하게 해서 옆에 이모지 부분을 누르면 제대로 작동하지 않았는데,

리팩토링을 거쳐 div전체에 클릭 이벤트가 동작하게 바꿨습니다.

클릭 이벤트가 동작하면 input의 value가 어두운 테마:사용 일 시에 콜백함수로 add함수를 실행시키고,

input의 value를 어두운 테마: 사용 안함으로 변경 시킵니다.

그리고 다크 모드 아이콘을 라이트 모드 아이콘으로 변경시킵니다.


리팩토링을 한 기념으로 정리글을 썼는데

남들이 보기엔 이게 뭐야라고 하실 수도 있을거 같네요.

css부분을 확 생략해버리니깐 뜬금없는 부분도 있을거 같습니다.

하지만 개인적으로 리팩토링 만족이라고 생각합니다.

수정할 일 있으면 수정 ver업데이트 하겠습니다.

댓글