본문 바로가기

나스 웹스테이션 서브도메인 설정

#나스 #웹스테이션 #서브도메인

  • 웹 서비스 - 생성 - 기본 스크립트 언어 웹사이트 - php선택(그누보드사용할시)

  • 이름 : 서브도메인의 이름 아무거나
  • 설명 : 이름과 동일하게 해도됨(설명이 필요하면 적음)
  • 문서 루트 : 서브도메인에 연결할 폴더
  • HTTP 벡엔드 서버 : Nginx(기능이 적고 빠름), Apache HTTP Server 2.4(기능이 많으며 속도가 느림)

  • 웹 포털 - 생성 - 웹 서비스 포털

  • 서비스 : 웹서비스에서 등록한 서비스 선택
  • 포털 유형 : 이름 기반 그대로 놔둠
  • 호스트 이름 : 서브도메인
  • 나머진 그대로

웹와치 점검

#웹와치 점검 #웹접근성

그누보드 원페이지

#그누보드 #원페이지

  • 루트의 index.php 내용을 하단의 소스로 대체
  • onepage 부분이 관리자페이지의 게시판-내용관리ID

        <?php
        include_once('./_common.php');
        $co_view = sql_fetch(" select co_content, co_mobile_content from {$g5['content_table']} where co_id = 'onepage' ");
        echo $co_view['co_content'];
        ?>
    

유튜브 쇼츠 퍼가기

#유튜브 #쇼츠 #퍼가기 #공유

콘텐츠타이틀

  • https://youtube.com/shorts/AvxIJHWFVpA?si=kLP4UD23eBnR6Ffo
  • 위 주소중 "shorts"을 "watch"로 수정하면 됩니다.
  • https://youtube.com/shorts/AvxIJHWFVpA?si=kLP4UD23eBnR6Ffo

table rowspan 있을대 마우스 hvoer

#table #rowspan #hover


        <!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Rowspan Hover 최종</title>
<style>
  table.table_hover { border-collapse: collapse; width: 60%; }
  table.table_hover td, 
  table.table_hover th { border: 1px solid #ccc; padding: 8px; text-align:center; }
  .td_hover { background: #f8fbff; } /* ✅ 마우스 오버 시 강조 색상 */
</style>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>

<table class="table_hover">
  <tr>
    <td rowspan="2">A</td>
    <td>B1</td>
    <td>C1</td>
  </tr>
  <tr>
    <td>B2</td>
    <td>C2</td>
  </tr>
  <tr>
    <td rowspan="3">D</td>
    <td>E1</td>
    <td>F1</td>
  </tr>
  <tr>
    <td>E2</td>
    <td>F2</td>
  </tr>
  <tr>
    <td>E3</td>
    <td>F3</td>
  </tr>
</table>

<script>
$(function(){
  // ✅ table.table_hover 클래스가 붙은 테이블마다 실행
  $("table.table_hover").each(function(){

      let $table = $(this);   // 현재 테이블 캐싱
      let rowGroups = {};     // { 행 인덱스: [그룹ID, ...] } 형태로 rowspan 그룹 저장

      // 1️⃣ rowspan 그룹을 미리 계산 (테이블 한 번만 스캔)
      $table.find("tr").each(function(rowIndex){
          // 현재 행에서 rowspan이 있는 td를 모두 탐색
          $(this).children("td[rowspan]").each(function(){
              let span = parseInt($(this).attr("rowspan"), 10); // rowspan 개수
              // 유니크한 그룹 ID 생성 (rowIndex + 랜덤값)
              let groupId = "grp-" + rowIndex + "-" + Math.random().toString(36).substr(2,5);
              // rowspan으로 포함되는 모든 행 인덱스에 그룹ID 기록
              for(let i = 0; i < span; i++){
                  (rowGroups[rowIndex + i] ||= []).push(groupId);
              }
          });
      });

      // 2️⃣ hover 이벤트 → 마우스 올렸을 때/벗어났을 때 처리
      $table.find("td").hover(function(){

          // (1) 기존 강조 효과 제거
          $table.find("tr").removeClass("td_hover");

          // (2) 현재 마우스가 올라간 td의 행 인덱스
          let idx = $(this).parent().index();

          // (3) 현재 행이 속한 rowspan 그룹 ID 목록 가져오기
          let groups = rowGroups[idx] || [];

          // (4) 만약 rowspan 그룹에 속해 있다면 → 해당 그룹ID가 포함된 모든 tr 강조
          if(groups.length){
              $table.find("tr").each(function(i){
                  if((rowGroups[i] || []).some(id => groups.includes(id))){
                      $(this).addClass("td_hover");
                  }
              });
          } 
          // (5) rowspan 그룹에 속하지 않는 경우 → 현재 행만 강조
          else {
              $(this).parent().addClass("td_hover");
          }

      // (6) 마우스를 벗어나면 → 전체 강조 제거
      }, function(){
          $table.find("tr").removeClass("td_hover");
      });
  });
});
</script>

</body>
</html>

    

포커스 아웃

#focus #포커스 아웃 #제이쿼리

포커스 아웃시 소스 실행

  • e.relatedTarget을 사용하지 않은 경우 gnb안에서 포커스 이동시 계속 실행함
  • e.relatedTarget을 이용하여 gnb안에 포커스가 아예 없는경우 실행되게 함.

        $('.gnb').on('focusout', function (e) {
            if (!$(this).has(e.relatedTarget).length) {
                console.log('close')
            }
        })

        $('.hd-navi').on('mouseenter', function(){
            console.log('open')
        })
    

css로 이미지 색상변경

#css로 이미지 색상변경


        filter: opacity(0.5) drop-shadow(0 0 0 #000000);
    

아이디로 링크보낼때 좀더 아래로 가게

#href #링크 #아이디 #스크롤

scroll-margin-top

  • href=#aaa 일때 아래로 100px 더 내려감

        a[href="#aaa"] {scroll-margin-top: 100px;}
    

접근성 양식

#웹접근성

테이블 caption

  • 테이블명 테이블 th1/th2/th3 목록

나스 업데이트 용량 문제로 안될때

#나스 #업데이트 #용량 문제

로그파일 용량으로 문제가될 가능성이 있음 아래 순서대로 진행

  • putty 접속
  • 아이디 비번 입력 후 sudo --login 입력(루트권한)
  • df -h 입력으로 /dev/md0 용량 확인(너무 많을경우 업데이트가 안됨)
  • re -r /var/log/* 를 이용해서 로그파일 삭제

외부에서 나스 폴더 공유

#외부 폴더공유 #나스 폴더공유

나스 webdev 이용

  • 나스에서 사용자 등록 후 폴더 권한 부여
  • 외부에서 네트워크 위치 추가
  • https://bodam-e.com:5006/폴더명

REMIX ICON

#remix icon #아이콘 #리믹스 아이콘

사용할때마다 추가 중

아이콘 공식 사이트

https://www.remixicon.com/

remixicon 아이콘


        <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/remixicon/4.5.0/remixicon.min.css' integrity='sha512-T7lIYojLrqj7eBrV1NvUSZplDBi8mFyIEGFGdox8Bic92Col3GVrscbJkL37AJoDmF2iAh81fRpO4XZukI6kbA==' crossorigin='anonymous'/>
    

        font-family:remixicon
    

select 전체선택

#셀렉트 #select #전체선택

select 전체선택


        $('.keyword_all').on('change', function () {
            const siblingCheckboxes = $(this).closest('li').siblings().find('input[type="checkbox"]');
            siblingCheckboxes.prop('checked', $(this).prop('checked'));
        });        
    

기본 게시판 table

#table #게시판

html


        
    <!-- board_list -->
    <div class="board_list board_st01">
        <div class="board_top_info">전체 <span class="red">10</span>건, 현재페이지 <span class="red">1</span>/10 Page</div>
        <table class="tdCenter">
            <caption>게시판 목록</caption>
            <colgroup>
                <col style="width:70px;">
                <col style="width:100%">
                <col style="width:170px;">
                <col style="width:180px;">
            </colgroup>
            <thead>
                <tr>
                    <th scope="col">순번</th>
                    <th scope="col">예약명</th>
                    <th scope="col">업종구분</th>
                    <th scope="col">점검기간</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td aria-label="순번">010</td>
                    <td aria-label="예약명" class="tdLeft"><a href="#">2024년 미용업(종합,일반,피부,손발톱,화장분장) 인터넷 자율점검</a></td>
                    <td aria-label="업종구분">안경업소</td>
                    <td aria-label="점검기간">2025.11.01~2025.11.30</td>
                </tr>
                <tr>
                    <td aria-label="순번">009</td>
                    <td aria-label="예약명" class="tdLeft"><a href="#">2024년 건물위생관리업 인터넷 자율점검</a></td>
                    <td aria-label="업종구분">안전상비의약품판매업</td>
                    <td aria-label="점검기간">2025.11.01~2025.11.30</td>
                </tr>
                <tr>
                    <td aria-label="순번">008</td>
                    <td aria-label="예약명" class="tdLeft"><a href="#">2024 치과기공소 자율점검</a></td>
                    <td aria-label="업종구분">의료기기판매업</td>
                    <td aria-label="점검기간">2025.11.01~2025.11.30</td>
                </tr>
            </tbody>
        </table>
        
        <!-- board_paging -->							
        <div class="board_paging">
            <ul class="pc">
                <li><a href="#"><i class="ri-skip-left-fill"></i><span class="blind">처음으로</span></a></li>
                <li><a href="#"><i class="ri-arrow-drop-left-line"></i><span class="blind">이전으로</span></a></li>
                <li class="active"><a href="#">1</a></li>
                <li><a href="#">2</a></li>
                <li><a href="#">3</a></li>
                <li><a href="#">4</a></li>
                <li><a href="#">5</a></li>
                <li><a href="#">6</a></li>
                <li><a href="#">7</a></li>
                <li><a href="#">8</a></li>
                <li><a href="#">9</a></li>
                <li><a href="#">10</a></li>
                <li><a href="#"><i class="ri-arrow-drop-right-line"></i><span class="blind">다음으로</span></a></li>
                <li><a href="#"><i class="ri-skip-right-fill"></i><span class="blind">마지막으로</span></a></li>
            </ul>
            
            <div class="mo">
                <input type="text" value="8888" class="input_st01">
                <span> / 100</span>
                <a href="#" class="btn_st01">이동</a>
            </div>
        </div>
        <!-- //board_paging -->
            
    </div>
<!-- //board_list -->
    

CSS


        
    /* board_style */
    .board_list.board_st01 {
        --board_color:#6d6d6d;
        --th_background:#f7f7f7;
        --th_color:#2d2d2d;
        --border_color:#dfdfdf;
        --border_top:2px solid #afa190;
        --padding:15px;
        --paging_active:#e57173;
    }
    .board_list .board_top_info {text-align:right;margin-bottom:10px;font-weight:500;}
    .board_list .board_top_info .red {color:#e0383b;}
    .board_list :is(tr, th, td) {box-sizing:border-box;}
    .board_list thead {margin-top:-1px;}
    .board_list table {color:var(--board_color);border-collapse:collapse;width:100%;border-top:var(--border_top);table-layout:fixed;}
    .board_list table caption {position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0 none;overflow:hidden;clip:rect(0, 0, 0, 0);}
    .board_list :is(th, td) {padding:var(--padding);border:1px solid var(--border_color);border-left:none;border-right:none;}
    .board_list thead th {background:var(--th_background);color:var(--th_color);font-weight:600;}
    .board_list td {white-space: nowrap;overflow: hidden;text-overflow: ellipsis;}
    .board_list td a:hover {text-decoration:underline;}
    .board_list .btn_type {display:inline-flex;width:66px !important;height:26px !important;line-height:26px !important;padding:0 5px !important;justify-content:center;font-weight:400;border:none;}
    .board_list .btn_type span {font-size:15px !important;letter-spacing:-0.05em;}
    .board_list .btn_type.open {background:#e57173;color:#fff;}
    .board_list .btn_type.closed {background:#515151;color:#fff;}
    .board_paging {margin:30px 0;}
    .board_paging .mo {display:none;}
    .board_paging ul {display:flex;justify-content:center;align-items:center;gap:5px;}
    .board_paging ul li a {display:flex;justify-content:center;align-items:center;width:40px;height:40px;border:1px solid var(--border_color);font-size:15px;border-radius:2px;}
    .board_paging ul li a:hover {background:#efefef;}
    .board_paging ul li.active a {background:var(--paging_active);border:1px solid var(--paging_active);color:#fff;}
    .board_paging ul li i {font-size:1.5em;}

    @media all and (max-width: 768px) {
        .board_list.board_st01 {
            --padding:10px;
        }
        .board_list :is(colgroup, thead) {display:none;}
        .board_list :is(tr, th, td) {display:block;width:100%;text-align:left !important}
        .board_list td::before {content:attr(aria-label) ':';display:inline-block;margin-right:5px;color:var(--th_color);}
        .board_list tr {border-bottom:1px solid var(--border_color);}
        .board_list td {border:none;}
        .board_list :is(th, td) {padding:0 var(--padding);margin:var(--padding) 0;}
        .board_paging .pc {display:none;}
        .board_paging .mo {display:flex;justify-content:center;align-items:center;gap:10px;}
        .board_paging .mo input {width:60px;text-align:center;}
        .board_paging .mo .btn_type {text-align:center;height:40px !important;line-height:40px !important;}
    }
    

CDN

#cdn

사용할때마다 추가 중

배달의민족 주아체


    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fonts-archive/BMJUA/BMJUA.css" type="text/css"/>
    

        font-family: "BM JUA";
    

Noto Sans (한국어 경량)


        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/noto-sans-kr@0.1.1/styles.min.css" type="text/css"/>
    

        font-family: "Noto Sans Korean";
    

Noto Sans


        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/noto-sans@5.2.10/400.min.css" type="text/css"/>
    

        font-family: "Noto Sans";
    

swiper


        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css"/>
        <script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>
    

remixicon 아이콘


        <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/remixicon/4.5.0/remixicon.min.css' integrity='sha512-T7lIYojLrqj7eBrV1NvUSZplDBi8mFyIEGFGdox8Bic92Col3GVrscbJkL37AJoDmF2iAh81fRpO4XZukI6kbA==' crossorigin='anonymous'/>
    

        font-family:remixicon
    

제이쿼리


        <script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script>
    

이미지맵 반응형


        <script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery-rwdImageMaps/1.6/jquery.rwdImageMaps.min.js"></script>
    

        $("img[usemap]").rwdImageMaps();
    

구글 메터리얼 아이콘


        <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded" rel="stylesheet" />        
    

aos 애니메이션


        <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
        <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
    

로티 애니메이션


        <script src="https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player.js"></script>
    

프리텐다드(pretendard)


        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/pretendard/1.3.9/static/pretendard.css">
    

        font-family:'Pretendard';
    

여분필드 사용법

#그누보드 #여분필드

write.skin.php 에서 입력


        <input type="text" name="wr_1" value="여분필드1">
    

view.skin.php 에서 출력


        <?php echo $view['wr_1']?>
    

자주쓰는 로티

#자주쓰는 로티 #lottie

html


        <div class="flex">
            <label class="lottie_checkbox">
                <input type="checkbox" class="">체크1
            </label>
            <label class="lottie_checkbox">
                <input type="checkbox" class="">체크2
            </label>
            <label class="lottie_checkbox">
                <input type="checkbox" checked class="">체크3
            </label>
        
            
            <label class="lottie_radio">
                <input type="radio" name="typeA" class="">라디오1
            </label>
            
            <label class="lottie_radio">
                <input type="radio" name="typeA" checked class="">라디오2
            </label>
            
            <label class="lottie_radio">
                <input type="radio" name="typeB" class="">라디오1
            </label>
            
            <label class="lottie_radio">
                <input type="radio" name="typeB" class="">라디오2
            </label>
        </div>
    
        <button type="button">
            <lottie-player class="lottie_menu" src="https://lottie.host/37e85c58-88ca-4b7e-a241-3f42fcd7bca4/FmvcD5oN2Q.json"></lottie-player>
        </button>
        <button type="button">
            <lottie-player class="lottie_search" src="https://lottie.host/bb7ee499-afb7-4a03-b3e9-66d53a6a67fa/DjP0vM4EQk.json"></lottie-player>
        </button>
    

script


        $(document).ready(function() {

            // Lottie 플레이어 추가 및 초기화(checkbox, radio)
            function addLottiePlayer(input, src) {
                const lottiePlayer = $('<lottie-player>', {
                  src: src,
                  class: 'lottie_animation',
                });
            
                $(input).before(lottiePlayer);
            
                lottiePlayer.on('load', function() {
                  const lottieInstance = lottiePlayer[0].getLottie();
                  if ($(input).is(':checked')) {
                    lottieInstance.playSegments([10, 30], true);
                  }
                });
              }
                      
            // 동적으로 로티 추가
            $('.lottie_checkbox input').each(function () {
              addLottiePlayer(this, 'https://lottie.host/45afa788-745e-4c70-b4e4-3f370bce0a3e/1w61VXC67a.json');
            });
          
            $('.lottie_radio input').each(function () {
              addLottiePlayer(this, 'https://lottie.host/b2623135-d4b0-445e-ac7d-fdb0d7efcdf6/p4D1TV7cq5.json');
            });
          
            // 상태 변경 시 애니메이션 실행
            $('.lottie_checkbox input, .lottie_radio input').change(function () {
              const isChecked = $(this).is(':checked');
              const lottieInstance = $(this).siblings('lottie-player')[0].getLottie();
          
              // 체크 상태에 따라 애니메이션 실행
              if (isChecked) {
                lottieInstance.playSegments([10, 30], true);
              } else {
                const startFrame = this.type === 'radio' ? 1 : 10;
                lottieInstance.playSegments([startFrame, 0], true);
              }
          
              // 같은 이름의 다른 라디오 버튼 처리
              if ($(this).attr('type') === 'radio') {
                const name = $(this).attr('name');
                // 같은 name을 가진 다른 라디오 버튼 해제
                $('.lottie_radio input[name="' + name + '"]')
                  .not(this)
                  .each(function () {
                    $(this).prop('checked', false); // 다른 버튼 해제
                    const otherLottieInstance = $(this).siblings('lottie-player')[0].getLottie();
                    // 애니메이션 리셋
                    otherLottieInstance.playSegments([1, 0], true); // 해제된 버튼에 대해 애니메이션
                  });
                // 현재 선택된 라디오 버튼에 대해 애니메이션 실행
                lottieInstance.playSegments([10, 30], true);
              }
            });
          
        
        
        
        
          // 로티 호버기능
          function lottie_hover(trigger_selector, target_selector, start_frame, end_frame, speed) {
            const $target_element = $(target_selector);
        
            $target_element.each(function () {
              const lottie_instance = this.getLottie();
        
              function play_animation(start, end) {
                lottie_instance.setSpeed(speed);
                lottie_instance.playSegments([start, end], true);
              }
        
              $(trigger_selector).hover(
                () => play_animation(lottie_instance.currentFrame, end_frame),
                () => play_animation(lottie_instance.currentFrame, start_frame)
              );
            });
          }
        
          // 로티 클릭 기능
          function lottie_click(trigger_selector, target_selector, start_frame = 0, end_frame = 30, speed = 1) {
            const $target_element = $(target_selector);
            let is_clicked = false;
        
            $target_element.each(function () {
              const lottie_instance = this.getLottie();
        
              function play_animation(start, end) {
                lottie_instance.setSpeed(speed);
                lottie_instance.playSegments([start, end], true);
              }
        
              $(trigger_selector).click(() => {
                const current_frame = lottie_instance.currentFrame;
                if (is_clicked) {
                  play_animation(current_frame, start_frame);
                } else {
                  play_animation(current_frame, end_frame);
                }
                is_clicked = !is_clicked;
              });
            });
          }
        
          // 트리거, 타겟, 시작프레임, 끝프레임, 속도
          lottie_hover('nav', 'nav .lottie_dropdown', 0, 30, 5);
          lottie_click('nav', 'nav .lottie_dropdown', 0, 50, 1.5);
    
        });
    

css


        lottie-player {font-size:inherit;}
        .lottie_checkbox,
        .lottie_radio {cursor:pointer;margin:0 0.3em;}
        .lottie_checkbox input,
        .lottie_radio input {display:none;}
        .lottie_checkbox lottie-player {width:3em;height:3em;display:inline-block;vertical-align: top;margin:-0.7em;}
        .lottie_radio lottie-player {width:1.5em;height:1.5em;display:inline-block;vertical-align: top;}
        .lottie_menu {width:3em;height:3em;}
        .lottie_search {width:3em;height:3em;}
    

Lottie

#움직이는 아이콘 #로티 #lottie

로티 공식 사이트

https://lottiefiles.com/

CDN


        <script src="https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player.js"></script>
    

HTML 기본


        <lottie-player 
            src="https://lottie.host/37e85c58-88ca-4b7e-a241-3f42fcd7bca4/FmvcD5oN2Q.json" 
            background="##fff" 
            speed="1" 
            style="width: 300px; height: 300px" 
            loop 
            controls 
            autoplay 
            direction="1" 
            mode="normal"
        >
        </lottie-player>
    
  • src에 json내용을 넣는다.
  • json은 공식사이트에서 받아온다

hover

html

        <button type="button">
            <lottie-player class="lottie_menu" src="https://lottie.host/37e85c58-88ca-4b7e-a241-3f42fcd7bca4/FmvcD5oN2Q.json"></lottie-player>
        </button>
    
script

        // 로티 호버기능
        function lottie_hover(selector, start_frame, end_frame, speed) {
            const lottie_element = $(selector)[0];
            const lottie_instance = lottie_element.getLottie();

            function play_animation(start, end) {
                lottie_instance.setSpeed(speed);
                lottie_instance.playSegments([start, end], true);
            }

            $(selector).hover(
                () => {
                    const current_frame = lottie_instance.currentFrame;
                    play_animation(current_frame, end_frame);
                },
                () => {
                    const current_frame = lottie_instance.currentFrame;
                    play_animation(current_frame, start_frame);
                }
            );
        }

        lottie_hover('.lottie_menu', 0, 50, 1.5);
    

클릭

html

        <button type="button">
            <lottie-player class="lottie_menu" src="https://lottie.host/37e85c58-88ca-4b7e-a241-3f42fcd7bca4/FmvcD5oN2Q.json"></lottie-player>
        </button>
    
script

        // 로티 클릭기능
        function lottie_click(selector, start_frame, end_frame, speed) {
            const lottie_element = $(selector)[0];
            const lottie_instance = lottie_element.getLottie();
            let is_clicked = false;

            function play_animation(start, end) {
                lottie_instance.setSpeed(speed);
                lottie_instance.playSegments([start, end], true);
            }

            $(selector).click(() => {
                const current_frame = lottie_instance.currentFrame;
                if (is_clicked) {
                    play_animation(current_frame, start_frame);
                } else {
                    play_animation(current_frame, end_frame);
                }
                is_clicked = !is_clicked;
            });
        }

        lottie_click('.lottie_menu', 0, 50, 1.5);
    

체크박스 라이오

html

        <label class="lottie_checkbox">
            <lottie-player class="" src="https://lottie.host/45afa788-745e-4c70-b4e4-3f370bce0a3e/1w61VXC67a.json"></lottie-player>
            <input type="checkbox" checked class="">체크3
        </label>
    
        
        <label class="lottie_radio">
            <lottie-player class="" src="https://lottie.host/b2623135-d4b0-445e-ac7d-fdb0d7efcdf6/p4D1TV7cq5.json"></lottie-player>
            <input type="radio" name="typeA" class="">라디오1
        </label>
        
        <label class="lottie_radio">
            <lottie-player class="" src="https://lottie.host/b2623135-d4b0-445e-ac7d-fdb0d7efcdf6/p4D1TV7cq5.json"></lottie-player>
            <input type="radio" name="typeA" checked class="">라디오2
        </label>
    
script

        // 로티 체크박스 라디오
        function lottie_check_radio(element, checked) {
            const lottie_element = $(element).siblings('lottie-player')[0];
            const lottie_instance = lottie_element.getLottie();

            if (checked) {
                lottie_instance.setSpeed(1);
                lottie_instance.playSegments([10, 30], true);
            } else {
                if (element.type == 'radio') {
                    lottie_instance.playSegments([1, 0], true);
                } else {
                    lottie_instance.playSegments([10, 0], true);
                }
            }
        }

        // 로티 체크박스 라디오 - 초기 상태 확인
        $('.lottie_checkbox input, .lottie_radio input').each(function() {
            const lottie_element = $(this).siblings('lottie-player')[0];
            const lottie_instance = lottie_element.getLottie();

            if ($(this).is(':checked')) {
                lottie_instance.playSegments([10, 30], true); // 예시로 0에서 30 프레임까지 재생
            }
        });

        // 로티 체크박스 라디오 - 상태 변경 시 애니메이션 설정
        $('.lottie_checkbox input, .lottie_radio input').change(function() {
            const name = $(this).attr('name');
            const checked = $(this).is(':checked');

            // 클릭된 요소에 대한 애니메이션 설정
            lottie_check_radio(this, checked);

            if ($(this).attr('type') == 'radio') {
                // 같은 name을 가진 다른 라디오 버튼에 대한 애니메이션 설정
                $('.lottie_radio input[name="' + name + '"]').not(this).each(function() {
                    lottie_check_radio(this, false);
                });
            }
        });
    

특정 게시판에서만 다르게

#특정게시판 #다르게

  • group 페이지에서 특정 게시판 조건에서만 나오게 처리

        <?php if ($list[$i]['bo_table'] == 'growth') { ?>
            growth 게시판에서만
        <?php } else { ?>
            다른 게시판에서
        <?php }?>
    

관리자 일반 화면 다르게

#관리자 #일반 #다르게


        <?php if ($is_admin) { ?>
            관리자
        <?php } else { ?>
            일반
        <?php }?>
    

글쓰기 수정하기 화면 다르게

#글쓰기 #수정 #다르게


        <?php if($w=="") { ?>
            글쓰기 화면
        <?php } else if($w=="u") { ?>
            수정하기 화면
        <?php }?>
    

정사각형 비율 유지

#정사각형 비율 유지

가로 / 세로 비율을 지정할 수 있다


        aspect-ratio: 1 / 1; /* 정사각형 유지 */
    

초기파일

#base #초기파일

초기파일 받기

게시판 작성일 입력하기

#그누보드 #작성일 입력하기

글쓰기 입력폼에 소스 넣기 (관리자만 입력하고 일반인은 보이지 않게)

  • theme\eb4_basic\skin\board\gallery\write.skin.html.php
  • 해당 파일에 아래 소스 추가하기

    <?php if ($is_admin) { // 관리자일 경우 ?>
        <section>
            <div class="bo_w_tit write_div">
                <input type="datetime-local" name="2wr_datetime" value="<?php echo date('Y-m-d\TH:i:s'); ?>" id="2wr_datetime"  class="frm_input harf_input" required placeholder="날짜 입력">    
            </div>
        </section>
        <?php } else { ?>
            <input type="hidden" name="2wr_datetime" value="<?php echo date('Y-m-d\TH:i:s'); ?>">
        <?php } ?>
    
  • Z:\theme\eb4_basic\skin\board\gallery\write_update.skin.php
  • 해당 파일을 만들어서 아래 소스 넣기(기존에는 파일이 없음)

        <?php
        if (!defined("_GNUBOARD_")) exit; // 개별 페이지 접근 불가
        $wr_datetime =  $_POST['2wr_datetime'];
        sql_query(" update ".$write_table." set wr_datetime = '".$wr_datetime."' where wr_id = '".$wr_id."' ");
        ?>
    

그누보드 설치

#그누보드 설치

  • 그두보드 사이트에서 다운로드
  • 설치된 곳에 data파일 생성 후 권한 707 해주기
  • 도메인으로 접속 후 그누보드 설치

카페24로 설치할 경우

그누보드 + 리빌더 설치

#그누보드 #리빌더

  • 그누보드 설치 참고 후 아래 순서 진행
  • 그누보드 설치한 곳에 리빌더 덮어쓰기
  • 도메인/adm 접속(관리자로그인)
  • 빌더설정 - 빌더설정 - 체크항목 체크 - "DB 테이블 설치하기"
  • 빌더설정 - 빌더설정 - "DB 업데이트 실행"
  • 환경설정 - 테마설정 - 리빌더 테마적용
  • 빌더설정 - 빌더설정 - "라이선스키 복사하기" - "라이선스키 등록" - 리빌더 로그인 - 마이페이지 - 라이선스 - 등록
  • [메뉴 설정] / [모듈 추가] /

카페24로 설치할 경우

메인과 서브 따로 보이게 처리

#gnuboard #메인따로 #서브따로


        <?php if (!defined("_INDEX_")) { ?>
            <div id="skip_to_container" class="skip_sub"><a href="#container">본문 바로가기</a></div>
        <?php } else { ?>
            <div id="skip_to_container" class="skip_main"><a href="#main_visual">본문 바로가기</a></div>
        <?php } ?>
    

포커스 시 속성변경

#웹접근성 #focus #포커스


        input:focus-visible {
            outline:-webkit-focus-ring-color auto 1px;outline-offset:-2px;
          }
    

tab으로 포커스시 속성이 변경된다

slick 옵션정리

#slick #슬릭 #슬라이드 #slide

슬릭 옵션


        $('.slider-items').slick({
            rows: 1,                    //이미지를 몇 줄로 표시할지 개수
            dots: false,                //슬라이더 아래에 도트 네비게이션 버튼 표시 여부(true or false) ▶기본값 false
            appendDots: $('selector'),  //네비게이션 버튼 변경
            dotsClass: 'custom-dots',   //네비게이션 버튼 클래스 변경
            infinite: true,             //무한반복(true or false) 기본값 true
            slidesToShow: 4,            //한번에 보여줄 슬라이드 아이템 개수
            slidesToScroll: 4,          //한번에 넘길 슬라이드 아이템 개수
            slidesPerRow: 1,            //보여질 행의 수 (한 줄, 두 줄 ... )
            autoplay: true,             //슬라이드 자동 시작(true or false) ▶기본값 false
            autoplaySpeed: 2000,        //슬라이드 자동 넘기기 시간(1000ms = 1초) 곧, 슬라이드 하나당 머무는 시간
            variableWidth: true,        //사진마다 width의 크기가 다른가?(true or false) ▶기본값 false
            draggable: false,           //슬라이드 드래그 가능여부 (true or false) ▶기본값 true
            arrows: true,               //이전 다음 버튼 표시 여부(true or false) ▶기본값 true
            pauseOnFocus: true,         //마우스 클릭 시 슬라이드 멈춤 ▶기본값 true
            pauseOnHover: true,         //마우스 호버 시 슬라이드 멈춤 ▶기본값 true
            pauseOnDotsHover: true,     //네이게이션버튼 호버 시 슬라이드 멈춤 ▶기본값 false
            vertical: true,             //세로 방향 여부(true or false) ▶기본값 false
            verticalSwiping: true,      //세로 방향 스와이프 여부(true or false) ▶기본값 false
            accessibility: true,        //접근성 여부(true or false) 기본값 false
            appendArrows: $('#arrows'), //좌우 화살표 변경
            prevArrow: $('#prevArrow'), //이전 화살표만 변경
            nextArrow: $('#nextArrow'), //다음 화살표만 변경
            initialSlide: 1,            //처음 보여질 슬라이드 번호 ▶기본값 0
            centerMode: true,           //중앙에 슬라이드가 보여지는 모드 ▶기본값 false
            centerPadding: '70px',      //중앙에 슬라이드가 보여지는 모드에서 패딩 값
            fade: true,                 //크로스페이드 모션 사용 여부 ▶기본값 false
            speed: 2000,                //모션 시간 (얼마나 빠른속도로 넘어가는지)(1000ms = 1초) 곧, 슬라이드 사이에 넘어가는 속도
            waitForAnimate: true,       //애니메이션 중에는 동작을 제한함 ▶기본값 true
            // ▼ 반응형 브레이크포인트 옵션
            // breakpoint: 숫자를 제작자의 환경에 맞게 조정함 ex) breakpoint: 1280
            // 각 브레이크포인트 내에 settings 안에 위의 모든 옵션을 다르게 적용할 수 있음
            responsive: [
              {
                breakpoint: 1024,
                settings: {
                  slidesToShow: 3,
                  slidesToScroll: 3,
                  infinite: true,
                  dots: true
                }
              },
              {
                breakpoint: 600,
                settings: {
                  slidesToShow: 2,
                  slidesToScroll: 2
                }
              },
              {
                breakpoint: 480,
                settings: {
                  slidesToShow: 1,
                  slidesToScroll: 1
                }
              }
            ]
          });
          
    

Let's Encrypt 무료 인증서 안될때

#Let's Encrypt #무료 인증서 #인증서

갱신이나 신규가 안될때 확인사항

  • 방화벽 확인(국내만 오픈해놔서 인증서 갱신시 우리 홈페이지를 확인을 못해서 안되는 문제)
  • 무료인증서 받고 난 후 기본인증서로 변경해주기
  • 무료인증서 받고 난 후 설정에서 해당 도메인이 모두 잘 설정되어있는지 확인

자주쓰는 터미널 명령어

#터미널 명령어

해당 폴더의 파일 확인


        ls
    

상위폴더로 이동


        cd ..
    

특정 폴더로 이동


        cd 폴더명
    

파일 찾기


        find . -name 파일명
    

flutter 기본 lint 무시하기

#flutter 기본 lint 무시하기


        (analysis_options.yaml)

        rules:
            prefer_const_constructors: false
            avoid_print: false
            prefer_typing_uninitialized_variables: false
            prefer_const_constructors_in_immutables: false

    

flutter 스타일

#flutter 스타일

단위

  • Flutter의 모든 단위는 LP (Logical Pixel)
  • px로 넣지 않는 이유는 기기마다 픽셀의 절대적인 크기가 다르기 때문
  • 1cm는 38LP 입니다,

width, height, color

  • width, height를 주고 싶으면 어디서부터 채울 지 좌표를 주어야 함
  • 보통은 Center() 혹은 Align() 로 준다.
  • Center() 위젯은 자식 child 위젯의 position을 정가운데로 잡아주는 유용한 위젯

        MaterialApp(
            home: Center( 
                child: Container(width : 50, height : 50, color: Colors.blue) 
            )
        )
    
  • width 꽉차게 (width : double.infinity)
  • 부모보다 커지지 않음

        Container( width : double.infinity, height : 50, color : Colors.blue )
    

박스정렬

  • Center() 가운데정렬
  • Align() 기타정렬

        Align(
            alignment : Alignment.bottomLeft,
            child : Container( width : 50, height : 50, color : Colors.blue )
        )
    

margin, padding

  • EdgeInsets.all(20) 상하좌우 전체 여백
  • EdgeInsets.fromLTRB(10, 20, 30, 40) 따로
  • (참고) Row(), Column() 이런덴 안되고 Container() 에만 여백을 줄 수 있습니다.

        margin: EdgeInsets.all(30), 
        padding: EdgeInsets.fromLTRB(10, 20, 30, 40),
    

나머지 스타일

  • decoration: BoxDecoration() 안에 넣으면 됨
  • color, shape, boxShadow, gradient, image, borderRadius 등등등

        Container(
            decoration : BoxDecoration(
                border : Border.all(color : Colors.black)
            )
        )
    

flutter 위젯

#flutter 위젯 #태그

글자


        home: Text('안녕')
    

아이콘

아이콘 종류확인

        home: Icon(Icons.star)
    

이미지

  • 루트에 assets폴더 안에 이미지추가
  • pubspec.yaml 파일 수정 앱만드는데 필요한 파일과 라이브러리들을 기록하는 파일
  • flutter: 하위항목에 사용할 폴더 등록

        flutter:
            assets:
                - assets/ 
    
  • 이미지 사용

        home: Image.asset('assets/dog.png')
    

네모박스


        home: Container() 
        home: SizedBox() // width, hdiehgt 정도만 사용할 경우 사용 그이상은 container사용
    

위젯안에 위젯넣기

  • 위젯안에 위젯을 그냥 넣으면 되는데 대신 child: 를 입력해줘야한다.

        MaterialApp(
            home: Container( 
                child: Text('박스안 글자임ㅅㄱ')
            )
        )
    

레이아웃 구글테마 적용

  • MaterialApp()
  • (참고) Material Design 쓰려면 일단 pubspec.yaml 파일에 이런 항목이 켜져있어야합니다.

        flutter:
            uses-material-design: true 
    

레이아웃 상중하로 나누는 위젯

  • Scaffold()
  • body는 필수지만 나머진 필수가 아님

        MaterialApp(
            home: Scaffold(
                appBar: 상단에 넣을 위젯,
                body: 중단에 넣을 위젯,
                bottomNavigationBar: 하단에 넣을 위젯,
            )
        ); 
    

        MaterialApp(
            home: Scaffold(
                appBar: AppBar( title: Text('앱제목') ), 
                body: Text('안녕'), 
                bottomNavigationBar: BottomAppBar( child: Text('하단바임 ㅅㄱ') ),
            )
        ); 
    

가로세로 정렬

  • Row/Column 위젯
  • mainAxisAlignment: 정렬
  • mainAxis의 반대가 crossAxis 입니다.

        MaterialApp(
            home: Scaffold(
                body: Row( 
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: [ Icon(Icons.star), Icon(Icons.star), Icon(Icons.star) ] 
                ), 
            )
        ); 
    

flutter 셋팅

#flutter 셋팅

flutter 설치

https://flutter.dev/docs/development/tools/sdk/releases?tab=windows
  • 원하는 폴더에 flutter 설치(Program Files에는 설치하면 안됨)

Android Studio 셋팅

  • 구글 검색 후 설치
  • 설치는 next 누르다보면 됨
  • Standard로 할건지 Custom 할건지 선택지가 나오면 Standard로
  • 혹여나 AMD Hyper어쩌구, Intel HAXM 어쩌구 실패해도 일단 무시하고 Finish 누르면 끝
  • 설치완료 후 실행 하면 Plugins에서 Flutter 설치
  • projects에서 More Actions 버튼 누르면 나오는 SDK Manager 선택
  • SDK Tools 탭으로 들어가서 Android SDK Command-line tools 부분체크하고 적용

윈도우 환경변수 등록

  • 윈도우 검색메뉴에서 '시스템 환경 변수 편집'을 검색
  • 환경변수 - Path 찾아서 - 편집 - 새로만들기 - Flutter 설치한 경로의 bin 폴더경로 입력(D:\flutter\bin)
  • 잘 되었는지 테스트는 윈도우 검색메뉴 -> Powershell 검색 후 실행한 다음 flutter doctor 입력

        flutter doctor
    

Android Studio 새로운 프로젝트 생성

  • Projects - New Flutter Project
  • Flutter - 경로는 Flutter설치경로 - next
  • Project name (공백안됨, 영어소문자만)입력 - Project location (실제 프로젝트만들 경로 flutter 경로랑 달라도됨) 입력 - Finish
  • 이제 /lib/main.dart에 작업하면 됨
  • 미리보기는 우측 상단에서 Device를 Chrome(Web)으로 설정하고 우측 상단 재생버튼 누르면 앱 실시간 미리보기 가능

vscode에서도 폴더 열어서 가능

  • 익스텐션 Flutter 설치
  • 미리보기도 vscode에서 가능 (start debugging)

VH

#vh #뷰포트

  • vh값을 스크립트로 다시 측정(모바일에서 css vh오류로 이걸 사용하면 유용하다)

css에서 사용


        height:calc(var(--vh) * 100);
    

jquery


        const updateVH = () => {
            const vh = $(window).height() * 0.01;
            $(':root').css('--vh', `${vh}px`);
            console.log(vh);
        };
    
        updateVH();
    
        $(window).resize(updateVH);  
    

script


        const updateVH = () => {
            const vh = window.innerHeight * 0.01;
            document.documentElement.style.setProperty('--vh', `${vh}px`);
            console.log(vh)
        };
        
        updateVH();
        
        window.addEventListener('resize', updateVH);
    

홈페이지 임시페이지

#홈페이지 임시페이지 #공지페이지

나스+도커 상황에 임시페이지

  • 도커 생성 (nginx를 이용한 나스 폴더 매핑)
  • 폴더에 파일 생성
  • 생성한 도커의 포트 방화벽 오픈
  • 역방향프록시 변경(기존 홈페이지에서 생성한 도커로)

날짜형식 포맷

#날짜형식 #date

설치


        npm i moment
    

불러오기


        import moment from 'moment';
    

사용


        <td>{moment(데이터).format('YYYY-MM-DD HH:mm:ss')}</td>
    

Jotai

#jotai #스테이트관리 #state

설치


        npm i jotai
    

생성 (\\bodam-e\bodame\atoms\sessionAtom.js)


        import { atom } from 'jotai';

        //유저정보
        export const sessionAtom = atom(null);
    

추가하기


        'use client'
        import { useAtom } from 'jotai';
        import { sessionAtom } from '/atoms/sessionAtom';

        const [, setSession] = useAtom(sessionAtom);
        
        useEffect(() => {
            if (session) {
                setSession(session);
            }
        }, [session, setSession]);
    

사용하기


        import { useAtom } from 'jotai';
        import { sessionAtom } from '/atoms/sessionAtom';

        const [session, setSession] = useAtom(sessionAtom);
    

ssh 접속

#ssh #터미널

vscode 터미널에서 접속 가능


        ssh -p 2217 ljlj123@bodam-e.com
    

환경변수 개발, 운영따로 나누기

#env #next환경변수

  • .env, .env.development, .env.production 3개의 파일로 기본, 개발, 운영 으로 나뉜다
  • next.config.js 파일은 아래 내용으로 변경

        /** @type {import('next').NextConfig} */
        const nextConfig = {};

        export default nextConfig;
    
  • layout.js에 스크립트추가 import문 아래

콘텐츠타이틀


        require('dotenv').config({
            path: process.env.NODE_ENV === 'production' ? '.env.production' : '.env.development'
        });
    

PWA

#PWA #웹앱 #앱처럼

  • 웹을 앱처럼 PC나 휴대폰에 다운받아서 실행가능
  • manifest.json 파일 생성
  • short_name : 앱의 이름의 짧은 버전
  • name : 앱 이름
  • icons : 앱아이콘
  • start_url : 앱 클릭시 보여지는 처음화면
  • background_color : 앱 처음 로딩시 표시되는 배경색
  • display :
    standalone(네이티브앱처럼 보여짐(권장)),
    fullscreen(앱을 전체화면으로),
    minimal-ui(애플리케이션을 실행할 때 최소한의 브라우저 UI(뒤로 가기, 앞으로 가기 버튼 등)를 표시합니다. 사용자는 앱을 브라우저 내에서 실행하지만, 더욱 몰입감 있는 환경을 경험할 수 있습니다. 모든 브라우저에서 이 옵션을 지원하지는 않습니다.),
    browser(애플리케이션을 표준 브라우저 탭이나 새 창에서 실행합니다. 이 모드는 전통적인 웹 페이지와 같이 브라우저의 표준 UI와 기능을 모두 사용할 수 있게 합니다.)
  • scope : 해당 앱으로 적용할 범위
  • theme_color : 앱 상단 바 색상

        {
            "short_name": "J가이드",
            "name": "J가이드",
            "icons": [
                {
                    "src": "./img/logo.png",
                    "type": "image/png",
                    "sizes": "192x192"
                }
            ],
            "start_url": "./",
            "background_color": "#ffffff",
            "display": "standalone",
            "scope": "./",
            "theme_color": "#000000"
        }
    
  • service-worker.js 파일생성

        self.addEventListener('install', event => {
            event.waitUntil(
                caches.open('v1').then(cache => {
                    return cache.addAll([
                    //캐싱할 파일들
                    './index.html',
                    './css/default.css',
                    ]);
                })
            );
        });
        
        self.addEventListener('fetch', event => {
            event.respondWith(
                // 먼저 네트워크 요청을 시도합니다.
                fetch(event.request).then(response => {
                    // 성공적으로 응답을 받으면, 새로운 데이터로 캐시를 업데이트합니다.
                    return caches.open('v1').then(cache => {
                    cache.put(event.request, response.clone());
                    return response;
                    });
                }).catch(() => {
                    // 네트워크 요청이 실패하면, 캐시에서 리소스를 찾습니다.
                    return caches.match(event.request);
                })
            );
        });
    
  • 스크립트 추가

        //PWA
        if ('serviceWorker' in navigator) {
            $(window).on('load', function() {
                navigator.serviceWorker.register('./service-worker.js').then(function(registration) {
                // 등록 성공
                console.log('ServiceWorker registration successful with scope: ', registration.scope);
                }, function(err) {
                // 등록 실패
                console.log('ServiceWorker registration failed: ', err);
                });
            });
        }
    

회원 라이브러리

#회원 라이브러리 #next-auth

  • NextAuth 라이브러리 셋팅 (secret : JWT생성용 암호 맘대로 길게 입력하면 됩니다.)

        npm install next-auth
    
  • \\bodam-e\bodame\pages\api\auth\[...nextauth].js

        import NextAuth from "next-auth";
        import GithubProvider from "next-auth/providers/github";

        export const authOptions = {
            providers: [
                GithubProvider({
                    clientId: `Github에서 발급받은ID`,
                    clientSecret: `Github에서 발급받은Secret`,
                }),
            ],
            secret : `jwt생성시쓰는암호`
        };
        export default NextAuth(authOptions);
    
  • 버튼

        `use client`;
        import { signIn } from `next-auth/react`

        export default function LoginBtn() {
            return <button onClick={() => { signIn() }}>로그인</button>
        }
    
  • server component에서 유저정보 출력

        import { authOptions } from "@/pages/api/auth/[...nextauth].js"
        import { getServerSession } from "next-auth"

        export default function Page(){
            let session = await getServerSession(authOptions)
            if (session) {
                console.log(session)
            }
        }
    

프로젝트 개발환경 화면보기

#개발 #npm run dev


        npm run dev
    

class 넣기

#class #className

className


        <h4 className="title">내용</h4>
    

인라인 CSS 넣기

#인라인 css넣기

  • background-images 처럼 - 가 있는 경우 backgroundImages 대문자로 표시한다

        style={{ color: `red` }}
    

반복문

#반복문 #map

  • 모든 array 자료 우측엔 map() 함수를 붙일 수 있습니다.
  • array에 들어있는 자료갯수만큼 그 안에 있는 코드를 반복실행해줍니다.
  • 콜백함수(a)에 파라미터 아무렇게나 작명하면 그 파라미터는 반복실행될 때 마다 차례로 array 안의 자료들을 하나씩 넣어줍니다.
  • 반복시킬 태그가 있으면 key={i} 값을 넣어준다.(데이터의 고유값이 있을경우 해당값을 넣어줘도된다)

        let 어레이 = [2,3,4];
        let newArray = 어레이.map((a)=>{
            a * 10
        });
        console.log(newArray)
    

        상품.map((a, i)=>{
            <div className="food" key={i}>
                <h4>{a} $40</h4>
            </div>
        })
    

최적화이미지 넣는 법

#최적화 이미지 #images #lazy loading

  • 성능과 속도가 중요하다면 이미지 넣을 때 <Image /> 태그를 씁시다.
  • 그럼 자동으로 이미지 lazy loading & 사이즈 최적화 & layout shift 방지를 해줍니다.

※ 외부이미지를 가져올 경우 설정할게 많아.... 그냥 img태그 씁시다.


        import Image from `next/image`
        import 이미지 from `./food0.png`

        <Image src={이미지} alt="설명"/>
    

컴포넌트 만들기

#컴포넌트 만들기 #component

  • 컴포넌트 만들고 싶으면 우선 function을 만들고 작명합니다. 관습적으로 영어 대문자로 시작합니다.(파일명도 대문자로시작)
  • return바로 아래는 하나의 태그로 되어있어야 한다.
  • 2개이상의 태그로 써야할 경우 < > 내용 </> 안에 넣으면 된다.

        export default function Item(){
            return(
              <div>
                내용
              </div>
            )
          }
    

        import Item from `../../components/Item`;

        export default function Cart() {
            return (
                <div>
                    <Item />
                </div>
            )
        }
    

SERVER, CLIENT 컴포넌트

#server #client #component #컴포넌트

app라우터 방식 기준(next.js)

server component

  • 컴포넌트는 기본적으로 모두 server component 입니다.
  • 장점 : 페이지로드가 빠릅니다.
  • 단점 : html 안에 자바스크립트를 못 넣습니다. useState, useEffect, onClick 이런거 사용불가능합니다.

client component

  • 컴포넌트 만들 때 페이지 맨 위에 `use client` 라는 코드를 넣으면 client component가 됩니다.
  • 장점 : html 안에 자바스크립트 맘대로 넣어서 기능개발 가능
  • 단점 : 쓸데없는 자바스크립트로 인해 페이지 용량도 커지고 페이지 로딩속도도 약간 느려질 수 있습니다.

        `use client`
    

NEXT 프로젝트 생성하기

#next #시작하기 #프로젝트 생성하기 #next설치


        npx create-next-app@latest
    

props

#props #프롭스 #변수

  • 변수는 다른 컴포넌트에서 사용이 불가하다
  • 부모컴포넌트가 자식컴포넌트로 보내기는 가능
  • 부모나 형제에게 보내기는 불가능
  • 자식컴포넌트 사용하는 곳에 가서 <자식컴포넌트 작명={전해줄데이터} />
  • 자식컴포넌트 정의부분으로 가서 props라는 파라미터 등록 후 props.작명 사용

        export default function Cart() {
            let 장바구니 = [`Tomatoes`, `Pasta`]
            return (
                <div>
                    <h4>Cart</h4>
                    <CartItem 상품={장바구니[0]}/>
                    <CartItem 상품={장바구니[1]}/>
                </div>
            )
        }

        function CartItem(props){
            return(
                <div className="cart-item">
                    <p>{props.상품}</p>
                    <p>$40</p>
                    <p>1개</p>
                </div>
            )   
        }
   

useState

#useState #변수

'set작명을' 이용해서 값을 변경할 수 있으나, 기존 값을 유지하고 변경할 경우 let 작명2 = [...작명]; 이런식으로 새로 복사해서 사용하면 된다 복사시 ...을 사용해줘야 한다.


        import {useState} from `react`
        let [작명, set작명] = useState(변수에넣을값);

        // 예시
        let [count, setCount] = useState(0);
        
        <p className=`num`>{count}</p>
        <h4 onClick={()=>{ setCount(count++); }}>버튼</h4>
   

React Native 프로젝트 생성

#react native 프로젝트 생성

터미널에서 실행


        npx react-native init 프로젝트명(폴더생성됨)
    

vscode에서 앱 에뮬레이터 실행

#app #앱 #안드로이드스튜디오

vscode와 Android Studio 설정 모두 완료 후 vscode 터미널에서 아래 명령어 실행


        npx react-native run-android
    

도커 ssh로 들어가기

#도커 ssh로 들어가기


        sudo docker exec -it 컨테이너명 /bin/sh
    

접근성 관련 포커스 강제 이동

#접근성 관련 포커스 강제 이동

HTML


        <a href="javascript:void(0);" data-focus="guide_focus" data-focus-next="guide_focus" class="btn_close">닫기</a>
    

data-focus="focus01" - 해당 태그 포커스 이름

data-focus-prev="focus06" - 이전으로갈 포커스 이름

data-focus-next="focus09" - 다음으로갈 포커스 이름

JS


        // 접근성 관련 포커스 강제 이동
        function accessibilityFocus() { 
            $(document).on('keydown', '[data-focus-prev], [data-focus-next]', function(e){ 
                var next = $(e.target).attr('data-focus-next'), 
                    prev = $(e.target).attr('data-focus-prev'),
                    target = next || prev || false; 
                if(!target || e.keyCode != 9) { 
                    return; 
                } 
                if( (!e.shiftKey && !!next) || (e.shiftKey && !!prev) ) { 
                    setTimeout(function(){ 
                        $('[data-focus="' + target + '"]').focus();
                    }, 1);
                }
            });
        };
        $(document).ready(function(){
            accessibilityFocus();
        });
    

select 선택시 placeholder 변경

#select 선택시 placeholder 변경

HTML


        <select class="selectWrap">
            <option data-name="일번">가나다1</option>
            <option data-name="이번">가나다2</option>
            <option data-name="삼번">가나다3</option>
            <option data-name="사번">가나다4</option>
        </select>
        
        <textarea class="textareaWrap" placeholder="일번">
    

JS


        $('.selectWrap').on('change', function(){
            let dataName = $(".selectWrap option:selected").attr('data-name');
            $('.textareaWrap').attr('placeholder', dataName);
        })
    

기능 무효화

#기능 무효화

js


        e.preventDefault();
    

css


        pointer-events : none; // 기본 auto
    

AOS

#aos

다운로드
AOS 사이트

CDN


        <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
        <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
    

예시


        <div class="todayBox" data-aos="fade-up" data-aos-delay="600"></div>
    

HTML


        data-aos="fade-up" data-aos-delay="600"
    

기본JS


        AOS.init();
    

기본+옵션JS


        AOS.init({
            offset: 10,
            duration: 600,
            easing: 'ease-in-out', 
            once: true,
            initClassName: 'aos-init',
            animatedClassName: 'aos-animate'
        });
    

offset: 요소가 화면 상단에서 얼마나 떨어져 있을 때 애니메이션을 시작할지 설정합니다. (단위: px)

duration: 애니메이션 지속 시간을 설정합니다. (단위: ms)

easing: 애니메이션 진행 방식을 설정합니다. (옵션: 'ease', 'ease-in', 'ease-out', 'ease-in-out', 'linear')

once: 애니메이션을 한 번만 실행할지 여부를 설정합니다. (기본값: false)

initClassName: 초기화된 요소에 추가될 클래스 이름을 설정합니다. (기본값: 'aos-init')

animatedClassName: 애니메이션이 실행되는 요소에 추가될 클래스 이름을 설정합니다. (기본값: 'aos-animate')

CSS 배경블러처리

#CSS 배경블러처리


        backdrop-filter: blur(10px);
    

가로스크롤

#가로스크롤


        $("#contents").on('mousewheel',function(e){
            var wheelDelta = e.originalEvent.wheelDelta;
            if(wheelDelta > 0){
                console.log("up");
                $(this).scrollLeft(-wheelDelta + $(this).scrollLeft());
            }else{
                console.log("down");
                $(this).scrollLeft(-wheelDelta + $(this).scrollLeft());
            }
        });
    

이미지맵 반응형

#이미지맵 반응형

이미지맵반응형 다운로드

HTML


        <img src="img.png" usemap="#popMap" style="width:100%;">
        <map id="popMap" name="popMap">
            <area shape="rect" coords="0,55,250,244" href="#">
            <area shape="rect" coords="250,55,500,244" href="#">
            <area shape="rect" coords="0,244,250,430" href="#">
            <area shape="rect" coords="250,243,500,430" href="#">
        </map>    
    

JS


        $("img[usemap]").rwdImageMaps();
    

삼항연산자

#삼항연산자


        let cont = cont1
            ? '참' 
            : '거짓'
                ? '충접도'
                : '가능'
    

다크모드

#다크모드

기기에서 설정한 모드에 맞춰 적용(CSS)


        @media (prefers-color-scheme: dark) {
            내용
        }        
    

버튼클릭시 적용(JS)


        $('.btnMode').on('click', function(){
            $('body').toggleClass('darkMode');
                let mode = $('body').hasClass('darkMode') ? 'dark' : 'light';
                localStorage.setItem('mode', mode);
            });
            if (localStorage.getItem('mode') == 'dark') {
                $('body').addClass('darkMode')
        };    
    

자동으로 적당히 적용됨(META태그)


        <meta name="color-scheme" content="dark light" />
    

반응형 쿼리

#미디어 쿼리 #media #반응형 #프린트 #반응형 쿼리 #콘테이너 쿼리 #컨테이너 쿼리

기본


        @media (조건) {
            스타일
        }    
    

@container

컨테이너쿼리 적용할 최상단 부모의 컨테이너 타입을 지정 후 사용 가능

  • inline-size(주로사용) : 인라인 레벨 기준으로 컨테이너를 적용. 요소의 width 값에 따라 반응형이 동작된다.
  • size : 블록 레벨 기준으로 컨테이너를 적용. width 뿐만 아니라 height 값에 따라 반응형이 동작 된다.
  • normal : 해당 값이 부여된 요소를 container에서 제외시킨다. 일종의 none 의미라고 보면 되겠다.

        .paging {container-type: inline-size;}
        .paging ul {display:block;}
        @container (max-width:768px){
            .paging ul {display:flex;}
        }
    

마우스 사용 디바이스, 마우스 사용하지 않은 디바이스 구분 (pointer:coarse = 마우스 사용안하는 디바이스)


        @media (pointer:coarse) {
        
        }
        @media (pointer: fine) {

        }
    

반응형 pc기준(px보다 작을때)


        @media all and (max-width: 1920px) {

        }
        @media all and (max-width: 1400px) {
        
        }
        @media all and (max-width: 1024px) {
        
        }
        @media all and (max-width: 768px) {
        
        }
        @media all and (max-width: 480px) {
        
        }    
    

반응형 모바일기준(px보다 클때)


        @media all and (min-width: 768px) { .. }
    

px ~ px 중간


        @media all and (min-width: 768px) and (max-width) { .. }
    

장치방향


        // 장치가 가로 방향인 경우 적용
        @media (orientation: landscape){ .. }

        // 장치가 세로 방향인 경우 적용
        @media (orientation: portrait){ .. }    
    

프린트


        @media print {

        }    
    

다크모드


        @media (prefers-color-scheme: dark) {

        }    
    

meta태그에서 구분


        <link href="css/common.css" rel="stylesheet" type="text/css" media="screen and (min-width:0px) and (max-width:480px)">
    

전체 확대 축소

#전체 확대 축소

HTML


        <a href="#" class="zoomIn">확대</a>
        <a href="#" class="zoomOut">축소</a>
        <a href="#" class="zoomReset">초기화</a>    
    

JS


        // 전체확대축소
        $(function(){
            let nowZoom = 100;
            let minZoom = 70;
            let maxZoom = 130;
        
            function zooms(){
                $('body').css('zoom', nowZoom + '%');
            };
            $('.zoomIn').on('click',function(){
                if(nowZoom == maxZoom){
                    alert ("더 이상 확대할 수 없습니다.");
                } else {
                    nowZoom = nowZoom + 10;
                    zooms();
                }
            });
            $('.zoomOut').on('click',function(){
                if(nowZoom == minZoom){
                    alert ("더 이상 축소할 수 없습니다.");
                } else {
                    nowZoom = nowZoom - 10;
                    zooms();
                }
            });
            $('.zoomReset').on('click',function(){
                nowZoom = 100;
                zooms();
            });
        });  
    

top 버튼 footer 위로 올리기

#top 버튼 footer 위로 올리기

스크롤길이 < 전체높이값 - 브라우저높이값 - footer높이값


        $(window).on('load scroll', function() {
            if ($(window).scrollTop() < $(document).height() - $(window).height() - $('footer').outerHeight()) {
                $('.btnTop').removeClass('active');
            } else {
                $('.btnTop').addClass('active');
            };
        });        
    

include(CSS)

#include #인클루드


        @import "../style.css";
    

include(PHP)

#include #인클루드


        <? include("경로"); ?>
    

include(JSP)

#include #인클루드


        <%@ include file="경로"%>
    

PHP 시간체크 소스내리기

#PHP 시간체크 소스내리기

해당 날짜가 지나면 안에 내용이 표시되지않음


        <?php if('24-02-01 18:00:00' > date('y-m-d H:i:s')){?> 
            내용
        <? } ?>
    

tab 기능

#tab 기능 #새로고침 안되는 tab #탭

HTML


        <!-- 텝 메뉴 -->
            <div class="tabSt01">
                <ul>
                    <li data-tab="tab01" class="active"><a href="javascript:void(0);">텝메뉴1</a></li>
                    <li data-tab="tab02"><a href="javascript:void(0);">텝메뉴2</a></li>
                    <li data-tab="tab03"><a href="javascript:void(0);">텝메뉴3</a></li>
                    <li data-tab="tab04"><a href="javascript:void(0);">텝메뉴4</a></li>
                    <li data-tab="tab05"><a href="javascript:void(0);">텝메뉴5</a></li>
                    <li data-tab="tab06"><a href="javascript:void(0);">텝메뉴6</a></li>
                    <li data-tab="tab07"><a href="javascript:void(0);">텝메뉴7</a></li>
                    <li data-tab="tab08"><a href="javascript:void(0);">텝메뉴8</a></li>
                </ul>
            </div>
            <!-- //텝 메뉴 -->

            <!-- 텝 내용 -->
            <div class="tabViewWrap">
                <div class="tabView tab01">내용1</div>
                <div class="tabView tab02">내용2</div>
                <div class="tabView tab03">내용3</div>
                <div class="tabView tab04">내용4</div>
                <div class="tabView tab05">내용5</div>
                <div class="tabView tab06">내용6</div>
                <div class="tabView tab07">내용7</div>
                <div class="tabView tab08">내용8</div>
            </div>
            <!-- //텝 내용 -->
    

JS


        // tab메뉴
        var tabMenu = $('.tabMenu01');
        var tabViewWrap = $('.tabViewWrap01');        
        tabMenu.find('li').on('click', function() {
            if($(this).hasClass('active')) return;
            var tabClass = $(this).attr('data-tab');
            tabMenu.find('li').removeClass('active');
            $(this).addClass('active');
            tabViewWrap.children('.tabView').hide();
            tabViewWrap.children('.' + tabClass).fadeIn();
            });
        });    
    

CSS


        .tabView + .tabView {display:none;}
    

CSS animation

#animation #애니메이션

축약


animation: ani01 3s 1s infinite ease alternate;

@keyframes ani01 {
    0% {margin-left: 100%;width: 300%}
    100% {margin-left: 0%;width: 100%;}
}
    
속성 설명 속성값 예시
animation-name 키프레임 애니메이션 이름을 지정.
특수문자를 제외한 문자열, 숫자, -,_ 를 조합해 1글자 이상.
-moz-animation-name:ani01;
-webkit-animation-name:ani01;
animation-name:ani01;
animation-duration 애니메이션 재생 시간, 또는 반복 루프 1회를 도는 시간 0, 3s, 1.5s, 300ms
기본 값 0은 애니메이션 재생되지 않음.
"s"(초), "ms"(밀리초) 단위로 표현 가능.
-moz-animation-duration: 3s;
-webkit-animation-duration: 3s;
animation-duration: 3s;
animation-timing-function 애니메이션 진행 속도, 또는 가속 방식을 지정. 미리 설정된 속도 커브 중 한가지를 선택. linear | ease | ease-in | ease-out | ease-in-out | step-start | step-end | steps(int,start|end) | cubic-bezier(n,n,n,n) 중 한가지 선택 가능. -moz-animation-timing-function: 1s;
-webkit-animation-timing-function: 1s;
animation-timing-function: 1s;
animation-delay 애니메이션 시작 지연 시간.
"s"(초), "ms"(밀리초) 2가지 단위 사용 가능
0s, 0ms, 미지정: 지연 없이 즉시 애니메이션 시작.
3s: 3초 후 애니메이션 시작.
500ms: 0.5초 후 애니메이션 시작.
-moz-animation-delay: 1s;
-webkit-animation-delay: 1s;
animation-delay: 1s;
animation-direction 애니메이션 재생 방향 normal: 정방향 재생
reverse: 역방향 재생
alternate: 정방향과 역방향으로 한 번씩 번갈아 재생(정 방향 시작)
alternate-reverse: 역방향과 정방향으로 한 번씩 번갈아 재생(역방향 시작)
-moz-animation-direction: alternate;
-webkit-animation-direction: alternate;
animation-direction: alternate;
animation-iteration-count 애니메이션 반복 횟수 지정 양수: 정수로 횟수 표기. 횟수만큼 애니메이션 반복 실행 후 정지.
infinite: 무한 반복.
-moz-animation-iteration-count: infinite;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
animation-fill-mode 애니메이션 시작 전, 종료 후 적용할 CSS 스타일을 지정.
"none"은 요소의 CSS 스타일을 유지하며, 그 외에는 키프레임 애니메이션의 CSS 스타일을 유지함.
none: 기본 값. 애니메이션 중이 아닌 경우, 요소의 CSS 스타일을 유지함.
forwards: 애니메이션 중이 아닌 경우, 애니메이션 마지막 키프레임의 CSS 스타일을 유지 함.
backwards: 애니메이션 중이 아닌 경우, 첫 번째 애니메이션 키프레임의 CSS 스타일을 유지 함.(지연 시간 포함)
both: 애니메이션 시작 전에는 첫 번째 애니메이션 키프레임을 유지하며, 종료 후에는 마지막 키프레임 애니메이션의 CSS 스타일을 유지함. "none" 과는 다름.
"none" 과 "backwards" 속성 값은 애니메이션 중이 아닌 경우 다른 화면을 표시할 수 있으므로 주의해야 함.
animation-play-state 애니메이션의 초기 실행 상태를 결정.
웹페이지 로딩 후 애니메이션을 자동 실행할지 여부를 선택할 수 있음.
paused: 애니메이션이 일시 중지된 상태 유지
running: 애니메이션이 재생중인 상태.
-moz-animation-play-state: paused;
-webkit-animation-play-state: paused;
animation-play-state: paused;

emmet

#emmet #에밋 #태그자동완성

vscode에서 사용안될때 : vscode > 설정 > emmet Trigger 검색 > 체크

기본사용법 : ul>li*10 입력 후 "tab"클릭

자녀 > 형제 + 상승 ^
id # 속성넣기 [] 숫자 $
* 그룹 () class .
시작숫자 $@3 숫자거꾸로 $@- 테그 안 텍스트 {}

fullpage

#fullpage #패럴렉스 #풀페이지

참고사이트

2.9.7 버전까지만 무료

콘텐츠 타이틀

HTML


        <div id="fullpage">
            <div class="section" data-anchor="section01"></div>
            <div class="section" data-anchor="section02"></div>
            <div class="section" data-anchor="section03">
                <div class="slide" data-anchor="slide1">slide1</div>
                <div class="slide" data-anchor="slide2">slide2</div>
                <div class="slide" data-anchor="slide3">slide3</div>
                <div class="slide" data-anchor="slide4">slide4</div>
            </div>
            <div class="section" data-anchor="section04"></div>
        </div>    
    

JS


        $(function () {
            $('#fullpage').fullpage({
                responsiveWidth : 1024, //풀페이지 기능 삭제 크기
                responsiveHeight : 800, //풀페이지 기능 삭제 크기
                anchors:['section01', 'section02', 'section03', 'section04', 'section05'], //id값과 겹치지 않게 지정
                navigation : true, //작은원 위치표시
                // navigationPosition : 'left', //위치표시 위치
                navigationTooltips : ['section01','section02','section03','section04','FOOTER'], //툴팁
                // showActiveTooltip : true, //해당 영역일때 툴팁이 상시 표시
                slidesNavigation : true, //좌우슬라이드 작은원 위치표시
                slidesNavPosition : 'top', //좌우슬라이드 작은원 위치표시 위치
                // normalScrollElements : 'section05' //일반스크롤이 필요한경우(전체스크롤 영향X)(스크롤영역의 class나 id 입력)
                afterLoad: function(){ //aos 적용시 문제 해결
                    $('.section [data-aos]').removeClass("aos-animate");
                    setTimeout(function(){
                        $('.section.active [data-aos]').addClass("aos-animate");
                    }, 0);
                }
            })
        });
    

AOS + fullpage

#aos #fullpage


        AOS.init({
            offset: 100,
            duration: 600,
            easing: 'ease-in-out', 
            once: true, //반복삭제
            initClassName: 'aos-init',
            animatedClassName: 'aos-animate'
        });
        $('.section [data-aos]').removeClass("aos-animate"); //처음 로딩시 기능삭제
    
        
        $('#fullpage').fullpage({
            onLeave: function(origin, destination, direction) {// 이동시 aos 기능삭제
                $('.section [data-aos]').removeClass("aos-animate");
            },
            afterLoad: function(){ //이동시 aos 재실행
                $('.fp-table.active [data-aos]').addClass('aos-animate');
            },
            
        });
    

SFTP config설정(vscode)

#vscode #sftp #config #설정

콘텐츠 타이틀


        {
            "name": "pub_guide",
            "host": "192.168.0.236",
            "protocol": "sftp",
            "port": 22,
            "username": "root",
            "password": "Curonsys",
            "remotePath": "/home/curonsys/www/care/pub_guide",
            "concurrency": 5,
            "timeout": 30,
            "uploadOnSave": true,
            "downloadOnOpen": true,
            "confirm": false,
            "ignore" : [
                "**/.vscode",
                "**/.history",
                "**/.sftp.json"
            ]
        }
    

name : 프로젝트 명(파일명과 동일하게 해주면 보기 편합니다.)

host : 접속할 ftp 아이피

protocol : ftp 종류

port : ftp 포트번호 (서버관리자가 변경하지 않은이상 기본 22)

username : ftp ID

password: ftp PW

remotePath: 연결할 경로

concurrency: 한번에 몇개까지 파일전송(기본이 4)

timeout: 몇초간 응답없을시 멈춤

uploadOnSave: 로컬에서 저장시 서버 반영여부

downloadOnOpen: 파일 열때 서버에서 자동 다운로드

ignore : 서버와 동기화에서 제외 폴더

swiper

#swiper

데모사이트

HTML


        <div class="슬라이드이름">
            <div class="swiper-wrapper">
                <div class="swiper-slide"><img src="./images/main_related01.png" alt=""></div>
                <div class="swiper-slide"><img src="./images/main_related02.png" alt=""></div>
            </div>
        </div>
    

JS


        var 슬라이드이름 = new Swiper(".슬라이드이름", {
            effect: "fade", //슬라이드종류
            autoplay: { //자동슬라이드
                delay: 3000,
            },
            pagination: { //페이징
                el: ".swiper-pagination",
                clickable: true, // 페이징을 클릭하면 해당 영역으로 이동, 필요시 지정해 줘야 기능 작동
            },
            navigation : { // 네비게이션 설정
                nextEl : '.swiper-button-next', // 다음 버튼 클래스명
                prevEl : '.swiper-button-prev', // 이번 버튼 클래스명
            },
            
            speed : 2000, //슬라이드넘어가는 속도
            initialSlide: 4, //시작슬라이드순번
            loop : true, //무한
            loopAdditionalSlides: 1, //무한슬라이드시 마지막 다음에 보이지 않을때
            centeredSlides: true, //active 슬라이드 가운데로
            grabCursor: true, //슬라이드 잡기모양(마우스커서)
            pagination : false, // pager 여부
            slidesPerView: 'auto', // 한슬라이드에 보여지는 슬라이드수
            spaceBetween : 6, // 슬라이드 사이 여백
            autoHeight : true, // true로 설정하면 슬라이더 래퍼가 현재 활성 슬라이드의 높이에 맞게 높이를 조정합니다.
            slideToClickedSlide : true, // 해당 슬라이드 클릭시 슬라이드 위치로 이동
            allowTouchMove : true, // false시에 스와이핑이 되지 않으며 버튼으로만 슬라이드 조작이 가능
            watchOverflow : true, // 슬라이드가 1개 일 때 pager, button 숨김 여부 설정
            observer: true, //css속성이 변경될때 업데이트된다(1/2) (display none block 할때 유용)
            observeParents: true, //css속성이 변경될때 업데이트된다(2/2) (display none block 할때 유용)
            slidesOffsetBefore : number, // 슬라이드 시작 부분 여백
            slidesOffsetAfter : number, // 슬라이드 시작 부분 여백
            pagination : {   // 페이저 버튼 사용자 설정
                el : '.pagination',  // 페이저 버튼을 담을 태그 설정
                clickable : true,  // 버튼 클릭 여부
                type : 'bullets', // 버튼 모양 결정 "bullets", "fraction" 
                renderBullet : function (index, className) {  // className이 기본값이 들어가게 필수 설정
                return '<a href="#" class="' + className + '">' + (index + 1) + '</a>'
                },
            
                renderFraction: function (currentClass, totalClass) { // type이 fraction일 때 사용
                return '<span class="' + currentClass + '"></span>' +
                        '<span class="' + totalClass + '"></span>';
                }
            },
            //5.3.0부터 "비율"(너비 / 높이)로 설정이 가능해졌습니다.
            breakpoints: { //반응형
                1024 : {
                    slidesPerView: 2,
                    spaceBetween: 20,
                },
            
                768 : {
                    slidesPerView: 3,
                    spaceBetween: 40,
                },
            
                480 : {
                    slidesPerView: 4,
                    spaceBetween: 50,
                },
            }
            
        });
        
        // slide 포커스시 해당 슬라이드로 이동
        $('.slide .swiper-wrapper a').each(function(i){
            $(this).focus(function(){
                reportSlide.slideTo(i, 1000, false)
            })
        });
    

구글 메터리얼 아이콘

#구글아이콘 #메터리얼 #material icons

구글아이콘 사이트

cdn


        <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded" rel="stylesheet" />
    

        font-family: 'Material Symbols Rounded';
    

라운드된거만 사용해서 다른건 인터넷 검색 하세요

cdn html 사용


        <i class="material-symbols-rounded">close</i>
    

태그로 보여주기


        <a href="javascript:void(0);" class="material-icons">close</a>
    

가상요소로 보여주기


        content:'close';font-family: 'Material Icons';
        content:'close';font-family: 'Material IconsR';
        content:'close';font-family: 'Material IconsO';
    

아이콘 속성 변경


        font-variation-settings:
        'FILL' 0,
        'wght' 400,
        'GRAD' 0,
        'opsz' 24
    

FILL : 0, 1 (비우기, 채우기)

wght : 100~700 (굵기1)

GRAD : -25~200 (굵기2)

opsz : 20~48 (크기)

자주사용하는 아이콘

search

search

home

home

menu

menu

close

close

settings

settings

done

done

add

add

delete

delete

star

star

first_page

first_page

chevron_left

chevron_left

chevron_right

chevron_right

last_page

first_page

login

login

logout

logout

expand_less

expand_less

expand_more

expand_more

arrow_forward

arrow_forward

arrow_back

arrow_back

arrow_upward

arrow_upward

arrow_downward

arrow_downward

more_vert

more_vert

open_in_new

open_in_new

toggle_on

toggle_on

toggle_off

toggle_off

radio_button_unchecked

radio_button_unchecked

radio_button_checked

radio_button_checked

check_box_outline_blank

check_box_outline_blank

check_box

check_box

download

download

Autorenew

Autorenew

Block

Block

restart_alt

restart_alt

shopping_cart

shopping_cart

shopping_cart_checkout

shopping_cart_checkout

undo

undo

backspace

backspace

share

share

edit

edit

photo_camera

photo_camera

filter_alt

filter_alt

image

image

photo_library

photo_library

play_arrow

play_arrow

play_circle

play_circle

pause

pause

skip_previous

skip_previous

skip_next

skip_next

replay

replay

stop

stop

stop_circle

stop_circle

fast_rewind

fast_rewind

fast_forward

fast_forward

notifications

notifications

aaaaa

aaaaa

aaaaa

aaaaa

VSCODE 추천단어 삭제

#vscode #추천단어삭제

컨트롤 + , 눌려 설정페이지 진입 후 "Quick Suggestions" 찾아서 off로 모두 변경

HTML 특수문자

#HTML 특수문자

표현문자 숫자표현 문자표현 설명
&#160;&nbsp;Non-breaking space
space&#09;-수평탭
space&#10;-줄 삽입
space&#32;-여백
!&#33;-느낌표
"&#34;&quot;따옴표
#&#35;-숫자기호
$&#36;-달러
%&#37;-백분율 기호
&&#38;&amp;Ampersand
'&#39;-작은 따옴표
(&#40;-왼쪽 괄호
)&#41;-오른쪽 괄호
*&#42;-아스트릭
+&#43;-더하기 기호
,&#44;-쉼표
-&#45;-Hyphen
.&#46;-마침표
/&#47;-Solidus (slash)
0 - 9&#48;-&#57;-0부터 9까지
:&#58;-콜론
;&#59;-세미콜론
<&#60;&lt;보다 작은
=&#61;-등호
>&#62;&gt;보다 큰
?&#63;-물음표
@&#64;-Commercial at
A - Z&#65;-&#90;-A부터 Z까지
[&#91;-왼쪽 대괄호
\&#92;-역슬래쉬
]&#93;-오른쪽 대괄호
^&#94;-탈자부호
_&#95;-수평선
`&#96;-Acute accent
a - z&#97;-&#122;-a부터 z까지
{&#123;-왼쪽 중괄호
|&#124;-수직선
}&#125;-오른쪽 중괄호
~&#126;-꼬리표
-&#127;-&#159;-사용하지 않음
¡&#161;&iexcl;거꾸로된 느낌표
&#162;&cent;센트 기호
&#163;&pound;파운드
¤&#164;&curren;현재 환율
&#165;&yen;
|&#166;&brvbar;끊어진 수직선
§&#167;&sect;섹션 기호
¨&#168;&uml;움라우트
&#169;&copy;저작권
ª&#170;&ordf;Feminine ordinal
&#171;&laquo;왼쪽 꺾인 괄호
&#172;&not;부정
­&#173;&shy;Soft hyphen
?&#174;&reg;등록상표
&hibar;&#175;&macr;Macron accent
°&#176;&deg;Degree sign
±&#177;&plusmn;Plus or minus
²&#178;&sup2;Superscript two
³&#179;&sup3;Superscript three
´&#180;&acute;Acute accent
μ&#181;&micro;Micro sign (Mu)
&#182;&para;문단기호
·&#183;&middot;Middle dot
¸&#184;&cedil;Cedilla
¹&#185;&sup1;Superscript one
º&#186;&ordm;Masculine ordinal
&#187;&raquo;오른쪽 꺾인 괄호
¼&#188;&frac14;4분의 1
½&#189;&frac12;2분의 1
¾&#190;&frac34;4분의 3
¿&#191;&iquest;거꾸로된 물음표
A&#192;&Agrave;Capital A, grave accent
A&#193;&Aacute;Capital A, acute accent
A&#194;&Acirc; Capital A, circumflex accent
A&#195;&Atilde;Capital A, tilde
A&#196;&Auml;Capital A, dieresis or umlaut mark
A&#197;&Aring;Capital A, ring (Angstrom)
Æ&#198;&AElig;Capital AE diphthong (ligature)
C&#199;&Ccedil;Capital C, cedilla
E&#200;&Egrave;Capital E, grave accent
E&#201;&Eacute;Capital E, acute accent
E&#202;&Ecirc;Capital E, circumflex accent
E&#203;&Euml;Capital E, dieresis or umlaut mark
I&#204;&Igrave;Capital I, grave accent
I&#205;&Iacute;Capital I, acute accent
I&#206;&Icirc;Capital I, circumflex accent
I&#207;&Iuml;Capital I, dieresis or umlaut mark
Ð&#208;&ETH;Capital Eth, Icelandic
N&#209;&Ntilde;Capital N, tilde
O&#210;&Ograve;Capital O, grave accent
O&#211;&Oacute;Capital O, acute accent
O&#212;&Ocirc;Capital O, circumflex accent
O&#213;&Otilde;Capital O, tilde
O&#214;&Ouml;Capital O, dieresis or umlaut mark
×&#215;&times;Multiply sign
Ø&#216;&Oslash;width="130"Capital O, slash
U&#217;&Ugrave;Capital U, grave accent
U&#218;&Uacute;Capital U, acute accent
U&#219;&Ucirc;Capital U, circumflex accent
U&#220;&Uuml;Capital U, dieresis or umlaut mark
Y&#221;&Yacute;Capital Y, acute accent
Þ&#222;&THORN;Capital Thorn, Icelandic
ß&#223;&szlig;Small sharp s, German (sz ligature)
a&#224;&agrave;Small a, grave accent
a&#225;&aacute;Small a, acute accent
a&#226;&acirc;Small a, circumflex accent
a&#227;&atilde;Small a, tilde
a&#228;&auml;Small a, dieresis or umlaut mark
a&#229;&aring;Small a, ring
æ&#230;&aelig;Small ae diphthong (ligature)
c&#231;&ccedil;Small c, cedilla
e&#232;&egrave;Small e, grave accent
e&#233;&eacute;Small e, acute accent
e&#234;&ecirc;Small e, circumflex accent
e&#235;&euml;Small e, dieresis or umlaut mark
i&#236;&igrave;Small i, grave accent
i&#237;&iacute;Small i, acute accent
i&#238;&icirc;Small i, circumflex accent
i&#239;&iuml;Small i, dieresis or umlaut mark
ð&#240;&eth;Small eth, Icelandic
n&#241;&ntilde;Small n, tilde
o&#242;&ograve;Small o, grave accent
o&#243;&oacute;Small o, acute accent
o&#244;&ocirc;Small o, circumflex accent
o&#245;&otilde;Small o, tilde
o&#246;&ouml;Small o, dieresis or umlaut mark
÷&#247;&divide;Division sign
ø&#248;&oslash;Small o, slash
u&#249;&ugrave;Small u, grave accent
u&#250;&uacute;Small u, acute accent
u&#251;&ucirc;Small u, circumflex accent
u&#252;&uuml;Small u, dieresis or umlaut mark
y&#253;&yacute;Small y, acute accent
þ&#254;&thorn;Small thorn, Icelandic
y&#255;&yuml;Small y, dieresis or umlaut mark

CSS 그라디언트

#CSS 그라디언트

▲(0deg) / ▶(90deg) / ▼(180deg) / ◀(270deg)

그라디언트 유형 구문 예시 설명
선형 그라디언트
(Linear Gradient)
background: linear-gradient(45deg, red 10%, blue 50%, green); 왼쪽에서 오른쪽으로 색상이 빨간색에서 노란색으로 변하는 선형 그라디언트를 생성합니다.
방사형 그라디언트
(Radial Gradient)
background: radial-gradient(circle, red, yellow, green); 중심에서부터 원형으로 색상이 빨간색에서 노란색, 그리고 녹색으로 변하는 방사형 그라디언트를 생성합니다.
반복 선형 그라디언트
(Repeating Linear Gradient)
background: repeating-linear-gradient(45deg, blue, yellow 10%, red 20%); 45도 각도로 파란색, 노란색, 빨간색이 10%와 20%의 간격으로 반복되는 선형 그라디언트를 생성합니다.
반복 방사형 그라디언트
(Repeating Radial Gradient)
background: repeating-radial-gradient(circle, blue 0%, red 50%, blue 100%); 중심에서부터 원형으로 파란색과 빨간색이 교차하며 반복되는 방사형 그라디언트를 생성합니다. 색상은 0%, 50%, 100%에서 변화합니다.

select 클릭 후 버튼 클릭시 이동

#select 클릭 후 버튼 클릭시 이동


        <div>
            <select>
                <option value="">관련사이트</option>
                <option value="http://www.naver.com">네이버</option>
                <option value="http://www.daum.net">다음</option>
                <option value="http://www.tistory.com">티스토리</option>
            </select>
            <button class="btn_link">이동</button>
        </div>
        
        <script>
            $(".el0205b .btn_link").on("click", function () {
                var link = $(".el0205b select option:selected").val();
                window.open(link, '_blank');
            })
        </script>
    

select 클릭시 바로이동

#select 클릭시 바로이동


        <div class="select01">
            <select onchange="window.open(value,'_blank');">
                <option value="">관련사이트</option>
                <option value="http://www.naver.com">네이버</option>
                <option value="http://www.daum.net">다음</option>
                <option value="http://www.tistory.com">티스토리</option>
            </select>
        </div>
    

글자자르기

#글자자르기

한줄자르기


        white-space: nowrap;overflow: hidden;text-overflow: ellipsis;
    

여러줄자르기


        line-height: 2em;max-height: 6em;overflow: hidden;display: -webkit-box;-webkit-line-clamp: 3;-webkit-box-orient: vertical;
    

네이밍

#네이밍

네이밍 규칙

camelCase: 소문자로 시작하고 대문자로 시작하는 모든 후속 단어(개인적으로 주로 쓰는 방식)

PascalCase: 모든 단어는 대문자로 시작

snake_case: 밑줄로 구분된 단어

kebab-case: 하이픈으로 구분된 단어

OLD_ARCHIVE: 모든 단어는 대문자로 하이픈으로 구분된 단어

자주 사용할만한 네이밍

네이밍(camelCase) 설명
topUserMenu 홈페이지 상단에 위치한 로그인, 마이페이지 등 사용자 관련 메뉴 영역
quickLinks 바로가기 링크들을 모아 둔 영역, 주로 상단에 위치
breadcrumbNavigation 현재 페이지의 경로를 네비게이션처럼 보여주는 영역, 일반적으로 컨텐츠 위나 옆에 위치
socialShareButtons SNS 공유 기능을 제공하는 버튼들이 모여 있는 영역
footerContactInfo 푸터에 위치한 연락처 정보 영역, 회사 주소나 전화번호 등이 포함
sideAdvertisement 컨텐츠 영역의 우측 또는 좌측에 위치한 광고 영역
newsletterSignupForm 뉴스레터 구독을 위한 가입 양식 영역
searchForm 웹사이트 내 검색 기능을 제공하는 양식 영역
featuredProducts 추천 상품 또는 인기 상품을 보여주는 영역
upcomingEvents 다가오는 이벤트나 행사 정보를 보여주는 영역
userFeedbackSection 사용자 피드백이나 리뷰를 보여주는 섹션
footerLegalLinks 법적 고지, 이용 약관, 개인정보 처리방침 등의 링크를 모아 둔 푸터 영역
modalLoginPopup 로그인을 위한 모달 팝업 창
languageSelector 사용자가 언어를 선택할 수 있는 드롭다운 메뉴 또는 버튼

정규식

#정규식

정규식 테스트
패턴 예시 설명
^ ^abc 문자열이 'abc'로 시작하는지 검사합니다.
$ abc$ 문자열이 'abc'로 끝나는지 검사합니다.
. a.c 임의의 한 문자와 일치합니다('a'와 'c' 사이에 문자가 있음).
* ab*c 0회 이상 반복되는 'b'와 일치합니다('ac', 'abc', 'abbbc').
+ ab+c 1회 이상 반복되는 'b'와 일치합니다('abc', 'abbbc'는 일치하지만, 'ac'는 일치하지 않음).
? ab?c 0회 또는 1회 등장하는 'b'와 일치합니다('ac', 'abc'는 일치하지만, 'abbc'는 일치하지 않음).
{n} ab{2}c 정확히 2회 등장하는 'b'와 일치합니다('abbc').
{n,} ab{2,}c 2회 이상 반복되는 'b'와 일치합니다('abbc', 'abbbc').
{n,m} ab{2,3}c 2회에서 3회 사이에 반복되는 'b'와 일치합니다('abbc', 'abbbc').
[abc] a[abc]c 'a', 'b', 'c' 중 하나와 일치합니다('aac', 'abc', 'acc').
[^abc] a[^abc]c 'a', 'b', 'c'를 제외한 문자와 일치합니다('adc', 'aec').
[a-z] [a-z] 소문자 알파벳과 일치합니다.
[A-Z] [A-Z] 대문자 알파벳과 일치합니다.
[0-9] [0-9] 숫자와 일치합니다.
\d \d 숫자와 일치합니다(동일한 [0-9]와 같음).
\w \w 알파벳, 숫자, 밑줄 문자와 일치합니다.
\s \s 공백 문자(스페이스, 탭 등)와 일치합니다.
| a|b 'a' 또는 'b'와 일치합니다.
( ) (abc) 괄호 안의 패턴을 캡처합니다.

요소탐색-제이쿼리

#요소탐색 #제이쿼리

구분 기능 사용 예시 설명
자식 요소 찾기 .children() $(element).children() 요소의 모든 자식 요소를 jQuery 객체로 반환합니다.
부모 요소 찾기 .parent() $(element).parent() 요소의 부모 요소를 jQuery 객체로 반환합니다.
부모 요소들 찾기 .parents() $(element).parents() 요소의 모든 조상 요소를 jQuery 객체로 반환합니다.
다음 형제 요소 찾기 .next() $(element).next() 요소의 다음 형제 요소를 jQuery 객체로 반환합니다.
이전 형제 요소 찾기 .prev() $(element).prev() 요소의 이전 형제 요소를 jQuery 객체로 반환합니다.
모든 형제 요소 찾기 .siblings() $(element).siblings() 요소의 모든 형제 요소를 jQuery 객체로 반환합니다.
조건에 맞는 부모 찾기 .closest() $(element).closest(selector) 선택자에 해당하는 가장 가까운 조상 요소를 jQuery 객체로 반환합니다.
조건에 맞는 자식 찾기 .find() $(element).find(selector) 선택자에 해당하는 모든 자식 요소를 jQuery 객체로 반환합니다.

요소탐색-자바스크립트

#요소탐색 #자바스크립트

구분 기능 사용 예시 설명
자식 요소 찾기 childNodes element.childNodes 요소의 모든 자식 노드를 NodeList로 반환합니다.
자식 요소 찾기 children element.children 요소의 모든 자식 요소를 HTMLCollection으로 반환합니다.
부모 요소 찾기 parentNode element.parentNode 요소의 부모 노드를 반환합니다.
부모 요소 찾기 parentElement element.parentElement 요소의 부모 요소를 반환합니다.
다음 형제 요소 찾기 nextSibling element.nextSibling 요소의 다음 형제 노드를 반환합니다.
다음 형제 요소 찾기 nextElementSibling element.nextElementSibling 요소의 다음 형제 요소를 반환합니다.
이전 형제 요소 찾기 previousSibling element.previousSibling 요소의 이전 형제 노드를 반환합니다.
이전 형제 요소 찾기 previousElementSibling element.previousElementSibling 요소의 이전 형제 요소를 반환합니다.

이벤트-제이쿼리

#이벤트 #제이쿼리

구분 이벤트 이벤트 예시 설명
사용자 입력click$(element).click(handler)요소 클릭 시 발생
사용자 입력dblclick$(element).dblclick(handler)요소 더블 클릭 시 발생
마우스 이벤트mouseenter$(element).mouseenter(handler)마우스가 요소 위로 진입할 때 발생
마우스 이벤트mouseleave$(element).mouseleave(handler)마우스가 요소를 벗어날 때 발생
마우스 이벤트hover$(element).hover(handlerIn, handlerOut)마우스 진입 및 벗어날 때 이벤트 처리
키보드 이벤트keydown$(element).keydown(handler)키보드 키를 누를 때 발생
키보드 이벤트keyup$(element).keyup(handler)키보드 키에서 손을 떼었을 때 발생
키보드 이벤트keypress$(element).keypress(handler)키가 눌렸다 떼어지는 동작이 완료될 때 발생
폼 이벤트submit$('form').submit(handler)폼 제출 시 발생
폼 이벤트change$(input).change(handler)입력 필드의 값이 변경됐을 때 발생
폼 이벤트focus$(element).focus(handler)요소가 포커스를 받았을 때 발생
폼 이벤트blur$(element).blur(handler)요소가 포커스를 잃었을 때 발생
문서/윈도우 이벤트load$(window).load(handler)페이지나 이미지 로딩 완료 시 발생
문서/윈도우 이벤트resize$(window).resize(handler)브라우저 창 크기가 변경됐을 때 발생
문서/윈도우 이벤트scroll$(window).scroll(handler)스크롤할 때 발생
문서 준비 상태ready$(document).ready(handler)DOM이 준비되었을 때 실행
문서/윈도우 이벤트unload$(window).unload(handler)페이지가 언로드될 때 발생
값 변경input$('input').on('input', handler)입력 필드의 값이 실시간으로 변경될 때
포커스focusin$(element).focusin(handler)요소가 포커스를 받거나 자식 요소가 포커스를 받을 때
포커스focusout$(element).focusout(handler)요소나 요소의 자식이 포커스를 잃었을 때
마우스 이벤트mouseup$(element).mouseup(handler)마우스 버튼이 요소 위에서 떼어졌을 때
마우스 이벤트mousedown$(element).mousedown(handler)마우스 버튼이 요소 위에서 눌렸을 때
스크롤scroll$(window).scroll(handler)스크롤할 때 발생
텍스트 선택select$('input').select(handler)입력 필드의 텍스트를 선택했을 때

이벤트-자바스크립트

#이벤트 #자바스크립트

구분 이벤트 이벤트 예시 설명
사용자 입력clickelement.addEventListener('click', function)요소 클릭 시 발생
사용자 입력dblclickelement.addEventListener('dblclick', function)요소 더블 클릭 시 발생
사용자 입력mouseoverelement.addEventListener('mouseover', function)마우스가 요소 위로 이동할 때 발생
사용자 입력mouseoutelement.addEventListener('mouseout', function)마우스가 요소를 벗어날 때 발생
사용자 입력mousedownelement.addEventListener('mousedown', function)마우스 버튼이 요소 위에서 눌렸을 때 발생
사용자 입력mouseupelement.addEventListener('mouseup', function)마우스 버튼이 요소 위에서 떼어졌을 때 발생
사용자 입력mousemoveelement.addEventListener('mousemove', function)마우스가 요소 위에서 움직일 때 발생
키보드 이벤트keydownelement.addEventListener('keydown', function)키보드 키를 누를 때 발생
키보드 이벤트keyupelement.addEventListener('keyup', function)키보드 키에서 손을 떼었을 때 발생
키보드 이벤트keypresselement.addEventListener('keypress', function)키가 눌렸다 떼어지는 동작이 완료될 때 발생
폼 이벤트submitformElement.addEventListener('submit', function)폼 제출 시 발생
폼 이벤트changeinputElement.addEventListener('change', function)입력 필드의 값이 변경됐을 때 발생
폼 이벤트focuselement.addEventListener('focus', function)요소가 포커스를 받았을 때 발생
폼 이벤트blurelement.addEventListener('blur', function)요소가 포커스를 잃었을 때 발생
뷰 이벤트resizewindow.addEventListener('resize', function)브라우저 창 크기가 변경됐을 때 발생
뷰 이벤트scrollwindow.addEventListener('scroll', function)스크롤할 때 발생
미디어 이벤트playvideoElement.addEventListener('play', function)미디어 재생이 시작됐을 때 발생
미디어 이벤트pausevideoElement.addEventListener('pause', function)미디어 재생이 일시 중지됐을 때 발생
미디어 이벤트endedvideoElement.addEventListener('ended', function)미디어 재생이 끝났을 때 발생
데이터 로딩loadwindow.addEventListener('load', handler)페이지 로딩이 완료됐을 때 발생
에러 처리errorwindow.addEventListener('error', handler)자바스크립트 오류 발생 시
애니메이션animationstartelement.addEventListener('animationstart', handler)CSS 애니메이션이 시작될 때
애니메이션animationendelement.addEventListener('animationend', handler)CSS 애니메이션이 끝났을 때
애니메이션animationiterationelement.addEventListener('animationiteration', handler)CSS 애니메이션이 새로운 사이클을 시작할 때
전환transitionendelement.addEventListener('transitionend', handler)CSS 전환 효과가 끝났을 때
드래그 & 드롭dragstartelement.addEventListener('dragstart', handler)요소를 드래그하기 시작했을 때
드래그 & 드롭dragoverelement.addEventListener('dragover', handler)드래그하는 요소나 선택이 다른 요소 위에 있을 때
드래그 & 드롭dropelement.addEventListener('drop', handler)드래그한 요소를 드롭 영역에 놓았을 때

메소드-제이쿼리

#메소드 #제이쿼리

구분 메소드 메소드 예시 설명
DOM 선택$(selector)$('.class')선택자와 일치하는 요소 선택
DOM 조작.append()$(parent).append(child)요소에 자식 요소 추가
DOM 조작.remove()$(element).remove()선택한 요소 제거
클래스 조작.addClass()$(element).addClass('new-class')요소에 클래스 추가
클래스 조작.removeClass()$(element).removeClass('class-name')요소에서 클래스 제거
이벤트 바인딩.on()$(element).on('click', handler)요소에 이벤트 핸들러 바인딩
이벤트 언바인딩.off()$(element).off('click', handler)요소에서 이벤트 핸들러 언바인딩
애니메이션.fadeIn()$(element).fadeIn(duration)요소를 서서히 나타나게 함
애니메이션.fadeOut()$(element).fadeOut(duration)요소를 서서히 사라지게 함
AJAX 요청$.ajax()$.ajax({ url: 'example.com' })비동기 HTTP(AJAX) 요청
단축 AJAX$.get()$.get('example.com', data => {})HTTP GET 요청을 통한 데이터 로드
단축 AJAX$.post()$.post('example.com', { data: value }, response => {})HTTP POST 요청을 통한 데이터 전송
문서 준비$(document).ready()$(document).ready(function() {})DOM이 준비되었을 때 코드 실행
객체 반복$.each()$.each(array, function(index, value) {})객체나 배열의 각 요소에 대해 함수 실행

메소드-자바스크립트

#메소드 #자바스크립트

구분 메소드 메소드 예시 설명
DOM 선택document.getElementById()document.getElementById('id')ID로 DOM 요소 선택
DOM 선택document.querySelector()document.querySelector('.class')CSS 선택자와 일치하는 첫 번째 요소 반환
DOM 선택(다중)document.querySelectorAll()document.querySelectorAll('div')CSS 선택자와 일치하는 모든 요소 반환
DOM 조작element.appendChild()parent.appendChild(child)요소에 자식 요소 추가
DOM 조작element.removeChild()parent.removeChild(child)요소에서 자식 요소 제거
클래스 조작element.classList.add()element.classList.add('new-class')요소에 클래스 추가
클래스 조작element.classList.remove()element.classList.remove('class-name')요소에서 클래스 제거
스타일 조작element.style.propertyelement.style.color = 'red'요소의 스타일 변경
이벤트 리스너 추가element.addEventListener()element.addEventListener('click', handler)요소에 이벤트 리스너 추가
이벤트 리스너 제거element.removeEventListener()element.removeEventListener('click', handler)요소에서 이벤트 리스너 제거
데이터 매핑Array.prototype.map()array.map(x => x * 2)배열의 각 요소에 함수 적용
데이터 필터링Array.prototype.filter()array.filter(x => x > 10)조건을 만족하는 배열 요소 필터링
데이터 검색Array.prototype.find()array.find(x => x > 10)조건을 만족하는 첫 번째 요소 반환
데이터 축소Array.prototype.reduce()array.reduce((total, x) => total + x, 0)배열 요소를 하나의 값으로 축소
비동기 요청fetch()fetch('url')네트워크 요청을 비동기적으로 수행
프로미스 생성new Promise()new Promise((resolve, reject) => {})비동기 작업을 위한 프로미스 객체 생성
동기 처리async/awaitasync function example() { await fetch('url'); }비동기 코드를 동기적으로 작성

기본필터 선택자(Basic Filter)

#제이쿼리선택자

선택자 예제 설명
:odd $("div:odd") 홀수 번째에 위치한 문서 객체를 선택함
:even $("div:even") 짝수 번째에 위치한 문서 객체를 선택함
:first $("div:first") 첫 번째 위치한 문서 객체를 선택함
:last $("div:last") 마지막에 위치한 문서 객체를 선택함
:root $("div:root") document의 루트 요소 선택
:target $("div:target") document의 URL의 flagment 식별자로 지정된 대상 요소를 선택
:header $("div:header") h1, h2, h3 등과 같이 헤더인 모든 요소를 선택
:empty $("div:empty") 자식이 없는 모든 요소(텍스트 노드 포함)를 선택
:parent $("div:parent") 하나 이상의 하위 노드(요소 또는 텍스트)가 있는 모든 요소를 선택

함수 필터 선택자(function Filter)

#제이쿼리선택자

선택자 예제 설명
:eq(index) $("div:eq(1)") 일치하는 집합 내의 인덱스 n에 있는 요소를 선택
:gt(index) $("div:gt(2)") 일치하는 세트 내의 인덱스보다 큰 인덱스에서 모든 요소를 선택
:lang(language) $("div:lang(en-us)") 지정된 언어의 모든 요소를 선택
:lt(index) $("div:lt(4)") 일치하는 집합 내의 인덱스보다 작은 인덱스에서 모든 요소를 선택
:not(selector) $("div:not(:checked)") 지정된 선택자와 일치하지 않은 모든 요소를 선택
:contains(text) $("div:contains('Hello'") 지정된 텍스트를 포함하는 모든 요소를 선택
:has(selector) $("div:has(p)") 지정한 선택자와 일치하는 요소를 하나 이상 포함하는 요소를 선택
:animated $("div:animated") 선택자를 실행할 때 애니메이션 진행 상태에 있는 모든 요소를 선택
":not(:animated)" => 애니메이션중이지 않은것

입력 양식 폼(Form) 필터 선택자

#속성선택자

선택자 예제 설명
:button $(":button") input 태그중 type 속성이 button인 문서 객체와 button 태그를 선택
:checkbox $(":checkbox") 체크박스 유형의 모든 요소 선택
:checked $(":checked") 체크되거나 선택된 모든 요소와 일치한 요소 선택
:disabled $(":disabled") 비활성화된 모든 요소 선택
:enabled $(":enabled") 활성화된 모든 요소 선택
:file $(":file") 파일 유형의 모든 요소를 선택
:focus $(":focus") 현재 포커스가 있는 요소 선택
:image $(":image") 이미지 유형의 모든 요소 선택
:input $(":input") 모든 input, textarea, select, button 요소 선택
:password $(":password") 패스워드 유형의 모든 요소 선택
:radio $(":radio") 라디오 유형의 모든 요소 선택
:reset $(":reset") reset 유형의 모든 요소 선택
:selected $(":selected") 선택된 모든 요소 선택
:submit $(":submit") submit 유형의 모든 요소 선택
:text $(":text") text 유형의 모든 input 요소 선택

자식 선택자 (chlid)

#nth-child 자식선택

선택자 예제 설명
:first-child div:first-child 부모의 첫 번째 자식인 모든 요소를 선택
:first-of-type div:first-of-type 동일한 요소 이름의 형제 중 첫 번째 요소를 모두 선택
:last-child div:last-child 부모의 마지막 하위 요소인 모든 요소를 선택
:last-of-type div:last-of-type 동일한 name 요소의 형제 중 마지막 요소인 모든 요소를 선택
:nth-child(index/even/odd/equation/n) div:nth-child(2) 부모의 n 번째 자식인 모든 요소를 선택
:nth-last-child(index/even/odd/equation) div:last-child(2) 마지막 요소에서 첫 번째 요소까지 계산하여 부모의 n 번째 자식인 모든 요소를 선택
:nth-of-type(index/even/odd/equation) div:nth-of-type(2) 동일한 name 요소를 갖는 형제와 관련하여 부모의 n번째 자식인 모든 요소 선택
:nth-last-of-type(index/even/odd/equation) div:nth-last-of-type(2) 마지막 요소부터 첫 번째 요소까지 같은 name 요소를 가진 형제와 관련하여 부모의 n 번째 자식인 모든 요소 선택
:only-child div:only-child 부모의 유일한 자식인 모든 요소를 선택
:only-of-type div:only-of-type 동일한 name 요소를 갖는 형제 노드가 없는 모든 요소 선택
:where div:where (.list01, .list02, list03) div .list01, div .list02 처럼 여러개 선택시 사용
:is (where와 다른점:is로 지정후 추후 속성을 다시 지정시 속성변경이 어려움) div:is (.list01, .list02, list03) div .list01, div .list02 처럼 여러개 선택시 사용

CSS 계층 선택자

#Hierarchy #계층선택자

선택자 예제 설명
> :: parent > child ul > li "parent"로 지정된 요소의 "child"로 지정된 모든 직접 자식 요소 선택
(공백) :: ancestor descendant form input 지정된 조상의 자손인 모든 요소 선택
+ :: prev + next label+input 형제 "prev"가 바로 앞에 오는 "next"와 일치하는 다음 요소 모두 선택
~ :: prev~siblings #prev~div "prev"요소 다음에 오는 모든 형제 요소를 선택하고, 상위 요소가 같으며 필터링 "siblings" 선택자와 일치하는 요소

CSS 속성 선택자

#CSS 속성 conTable

선택자 예제 설명
[attribute|='value'] [name|=apple] 속성 name값이
apple이거나,
apple- 으로 시작하는 요소
[attribute*='value'] [name*=apple] 속성 name값이
apple이란 단어를 포함하는 요소 (어느 위치든)
[attribute~='value'] [name~=apple] 속성 name값이
apple이거나
apple 공백 / 공백 apple 으로 구분된 단어를 포함하는 요소
[attribute$='value'] [name$=apple] 속성 name값이
apple이거나
apple로 정확히 끝나는 값인 요소
비교는 대소 문자를 구분함.
[attribute='value'] [name=apple] 속성 name값이
정확히 apple인 요소
[attribute!='value'] [name!=apple] 속성 name값이
apple을 아예 갖지 않거나,
apple 이외의 값을 갖지 않는 요소
[attribute^='value'] [name^=apple] 속성 name값이
apple이거나,
apple로 정확히 시작하는 요소
[attribute] [name] 속성 name을 갖고있는 요소
[attribute='value'][attribute2='value2'] [name=apple][name2=banana] 각 속성 선택자들이 and로 일치하는 요소

실시간 검색 기능

#검색기능

검색 창에 검색시 temp요소에서 찾아 보여주기


        //input에 keyup 이벤트 등록
        $(".searchWrap .tag").keyup(function(){
            var searchText = $(this).val(); //keyup 이벤트 발생 시 해당 input의 value 가져오기.
            $('section').hide(); //실시간 검색이 필요한 영역 숨김 처리
            var temp = $("section .tag li:contains('" + searchText + "')"); //input에 입력한 데이터가 있는 Element 찾기.
            $(temp).parents('section').show(); //입력한 데이터가 있는 Elemnet의 부모만 표시.
        });
    

a태그 클릭시 부드럽게 이동

#a #부드럽게 #스크롤이동

id값으로 이동 할 때 애니메이션 적용


        $('a[href^="#"]').on('click',function (e) {
            e.preventDefault();
            var target = $(this.hash);
            var target_height = $('#list10').height(); //원하는 위치 height값 가져오기
            var offset_top = target.offset().top - target_height; //해당 값만큼 -
            $('#contents').stop().animate({scrollTop: offset_top}, 500); //스크롤 원하는 영역
        });        
    

빌드 후 서버배포 한번에(터미널 명령어)

#도커 #서버배포 #빌드

보담이네 나스 도커용


        sudo docker-compose up --build
    

설명

sudo : 관리자실행

docker-compose : docker-compose.yml파일 참조(라이브러리)

up : 서비스 실행

--build : 이미지빌드

복사되었습니다.