기본 콘텐츠로 건너뛰기

브라우저에 보여지는 상태 감지(IntersectionObserver) - javascript

특정 요소가 브라우저에 보여질 때 감지하기 html(sample) ... <div class="box"></div> <div class="box"></div> <div class="box_change bg1"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box_change bg2"></div> <div class="box"></div> <div class="box"></div> <div class="box_change bg3"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box_change bg4"></div> <div class="box"></div> <div class="box"></div>

dayjs를 이용한 주간 날짜 구하기 - javascript

주간 날짜 구하기 html(template) ... <div class="week_txt_line"> <button class="btn_cal left" @click="currentWeek('prev')"> <img src="@/assets/images/icon_arrow_cal.svg" alt=""> </button> <p class="week_txt">{{ showeek }}</p> <button class="btn_cal right" @click="currentWeek('next')"> <img src="@/assets/images/icon_arrow_cal.svg" alt=""> </button> </div> ... javascript <script setup> import { ref, computed } from 'vue' import dayjs from 'dayjs' import isSameOrBefore from 'dayjs/plugin/isSameOrBefore' import isSameOrAfter from 'dayjs/plugin/isSameOrAfter' dayjs.extend(isSameOrBefore) dayjs.extend(isSameOrAfter) // const info = ref({ weeks: [],// 현재 '주'의 날짜들 moveweekno: 0,// ± 이동한 주 }) // 현재 '주'의 날짜구하기(일0 ~ 토6) const selectWeek = (date) =

router/index.js 관련 내용. createRouter, beforeEach, afterEach - vuejs 관련

router 관련 세팅 /router/index.js or router.js import { createRouter, createWebHistory } from "vue-router" // const alwaysTitle = "브라우저 틀에 항상 보여지는 타이틀" const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), // 라우터 이동 시 이전 화면으로 돌아갈 때 이전 스크롤 위치로 이동할 경우 확인(savedPosition) scrollBehavior(to, from, savedPosition) { console.log('SavedPosition', savedPosition) if (savedPosition) { return savedPosition } return { top: 0, left: 0 } }, routes: [ // { path: "/", redirect: "/directurl" }, { path: "/404", name: "notFound", component: () => import("@/views/NotFound.vue"), meta: { title: "페이지를 찾을 수 없습니다" } }, { path: "/:pathMatch(.*)*", redirect: "/404" }, // 로그인 레이아웃 { path: "/login", name: "loginLayout", component: () =

웹페이지에서 화면을 pdf로 다운로드 하기, 바로 출력 시 - javascript

웹페이지에서 화면을 pdf로 다운로드 하거나 바로 출력하기 html 부분 <section ref="pdfRef"> <div class="winpop"> <section id="first-section"> ... </section> ... </div> </section> 스크립트 부분 import { ref } from "vue"; import html2canvas from "html2canvas"; import { jsPDF } from "jspdf"; const pdfRef = ref(null); // pdf 다운로드 const generatePDF = () => { const winpop = document.querySelector(".winpop"); winpop.style.height = "auto"; //loading.value = true; html2canvas(pdfRef.value, { scrollX: 0, scrollY: 0, scale: 3, logging: false, // useCORS:true }).then(canvas => { let image = canvas.toDataURL("image/jpg"); const doc = new jsPDF("p", "mm", "a4", true); winpop.style.scroll = "auto"; const section = document.querySelector("#first-section"); let resolution =

현재 보고 있는 컨텐츠의 위치를 화면 맨 위에 progress 스타일로 알려주기 - javascript, html

스크롤바가 아닌 progress bar 스타일로 현재 컨텐츠의 위치 표시하기 Progress bar로 컨텐츠의 위치 표시 <template> <div class="progress_line"> <input type="range" min="0" step="0.1" max="100" :value="info.val"> </div> </template> <script setup> import { ref } from "vue" // const info = ref({ val: 0,// }) // @input="checkValue" @mousedown="mDown" @mouseup="mUp" // progress bar 에서 클릭드래그 시 컨텐츠 영역이 현재 progress 위치에 맞게 같이 이동되게 할 때 추가 // const mDown = () => { // document.documentElement.classList.add("scrollbehavior_no"); // } // const mUp = () => { // document.documentElement.classList.remove("scrollbehavior_no"); // } // const checkValue = (e) => { // info.value.val = e.target.value; // let scrolheight = document.documentElement.scrollHeight; // let scrolly = Math.floor((scrolheight - window.innerHeight) * info.value.val / 100) // win

drag해서 가로로 스크롤 이동하기 - javascript

drag해서 가로로 스크롤 이동 .vue <template> ... <div class="pd_img" @pointerenter="pEnter" @pointerdown="pDown" @pointerleave="pLeave" @pointerup="pUp" @pointermove="pMove" @click="pClick" @scroll="pScroll"><!-- @wheel="pWheel" --> <img src="가로로 긴~ 이미지.jpg" alt=""> </div> ... </template> <script setup> import { ref } from "vue" // const info = ref({ is_down: false,// 스크롤/드래그 시작 여부 start_x: null, scroll_left: null, imgdiv: null,// 이미지 imgtxtno: 0,// 이미지의 특정 위치를 지날 때 보여지는 텍스트 번호 }) // const pEnter = () => { if(info.value.imgdiv === null) { info.value.imgdiv = document.querySelector(".pd_img"); } } const pDown = (e) => { // console.log("mDown", e); info.value.is_down = true; info.value.start_x = e.pageX - info.value.imgdiv.offsetLeft; info.va

ios라서 잘 안되는거 수정하는 방법

AOS는 잘 되지만 IOS에서 안되는 현상 수정 Video 자동재생 시 인라인으로 보여지기 <video muted autoplay loop playsinline oncontextmenu="return false" controlsList="nodownload" controls preload="metadata" poster=""> <source src="@/assets/video/video2.mp4" type="video/mp4" /> </video> iphone, ipad에서는 비디오 자동재생 시 비디오가 전체화면으로 보여지는데, playsinline 을 추가하면 안드로이드 폰처럼 인라인으로 보여져서 관리하기가 쉬워진다. 폰에서 숫자 키패드만 나오기 <input type="text" inputmode="numeric" pattern="[0-9]*"> iphone, ipad에서는 <input type="number">일 때 숫자만 나오지 않는데, 그 때 위와 같이 inputmode를 지정하고 pattern으로 숫자만 포함시키면 된다. 비슷한 다른 방법으로는 <input type="tel"> 이 있다. button에 focus 하기 <a role="button" tabindex="1"> iphone, ipad에서 button에 focus가 안될 때는 role="button" tabindex="1" 같은 속성을 추가하면 가능해진다. 끝.

vuejs에서 달력 플러그인(flatpickr)을 component 로 사용 시. 시작일, 종료일 지정하기 - vuejs

vuejs (3.0)에서 달력 플러그인(flatpickr)을 component로 사용 할 때 시작일, 종료일 지정하기 .vue <flat-pickr class="input_cal trans calStr" placeholder="시작일" readonly v-model="info.sdate" @on-change="stChange" :config="config('st')" /> <flat-pickr class="input_cal trans calEnd" placeholder="종료일" readonly v-model="info.edate" @on-change="edChange" :config="config('ed')" /> <flat-pickr class="input_cal trans calToay" placeholder="오늘" readonly v-model="info.today" :config="configtoday" /> javascript <script setup> import { ref, computed, nextTick } from "vue"; import flatPickr from "vue-flatpickr-component"; import "flatpickr/dist/flatpickr.min.css"; import dayjs from "dayjs"; const info = ref({ sdate:"",// 시작일 edate:"",// 종료일

cookie를 이용한 하루 그만 보기 설정 - javascript

오늘 그만 보기 설정하기. setCookie, getCookie javascript // 쿠키 확인 if(!getCookie("onday")) { // oneday 쿠키가 없으면 info.value.show = true; // (레이어)팝업 보이기 } ... // 닫기 const closePop = (n) => { info.value.show = false; // 오늘 그만 보기로 닫을 때 if(n !== undefined) { setCookie("onday", 1, 1); // oneday 쿠키 설정 } } ... // 조건에 맞는 쿠키가 없다면 undefined를 반환 const getCookie = (name) => { const encodeName = encodeURIComponent(name); const matches = document.cookie.match(new RegExp( "(?:^|; )" + encodeName.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)" )); return matches ? decodeURIComponent(matches[1]) : undefined; } // const setCookie = (name, value, days) => { let expires = ''; // e.g. 'hello world' -> 'hello%20world', 'test?' -> 'test%3F' const updatedCookie = encodeURIComponent(name) + '=' + encodeURIComponent(value); if(days) { const date = new D

[javascript] 지연 실행(debounce) 함수 만들기

지연 실행 함수(debounce) 만들기 .vue 파일 <template> ... <input type="text" class="keyword_input" placeholder="키워드를 입력하세요" :value="info.keyword" @input="info.keyword = $event.target.value" @keyup="searchUp"> ... </template> <script setup> import { ref } from "vue" const info = ref({ keyword: "", // 검색어 }) // 입력할 때마다 이벤트 보내지 않게 const debounce = (fn, delay) => { let timer; return (...args) => { if(timer) { clearTimeout(timer); } const context = this; timer = setTimeout(() => { fn.apply(context, args); }, delay); } } const searchUp = debounce(() => { console.log(info.value.keyword);// 타이핑이 0.4초 멈추면 실행 }, 400); </script> debounce 함수 사용하기 끝.

[vuejs 관련] Radio component

Radio component component .vue파일 <template> <div class="m_radio"> <input type="radio" :name="name" :id="idfor" :value="value" :checked="value === selected"> <label :for="idfor">{{ txt }}</label> </div> </template> <script setup> const props = defineProps({ name: { type: String, defatult: undefined }, idfor: { type: String, defatult: undefined }, value: { type: String, defatult: undefined }, txt: { type: String, default: '' }, selected: { type: String, defatult: undefined } }) </script> <style scoped src="./Radio.scss"></style> <!-- // 부모 컴포넌트에서 사용 시 # name : radio name # idfor : radio id = label for # value : radio value # selected : 현재 선택된 radio # txt : label <Radio name="name" idfor="idfor" value="value"

[javascript] 두 개의 배열 비교하기, 추가, 삭제

배열 두개 비교해서 배열값 추가, 삭제 script 부분 const inf = ref({ arr1: [1, 2, 3, 4, 5], arr2: [1, 2, 3, 4, 5], val: ["ㄱ", "ㄴ", "ㄷ", "ㄹ", "ㅁ"] }) // arr2에서 특정 값 제거. [1, 2, 4, 5] inf.value.arr2.splice(2, 1); // arr2에서 배열 값이 제거되어서 arr1이 더 많을 때 if(inf.value.arr1.length > inf.value.arr2.length) { // arr1과 비교해서 없는 값의 index를 찾고, 대응하는 val에서 값 제거하기 inf.value.arr1.some((ele, idx) => { // arr1에서 arr2에 없는 값 찾기 = false 인거 if(!inf.value.arr2.includes(ele)) { // arr2에 없는 arr1의 값의 index를 이용해 val의 값 제거하기 inf.value.val.splice(idx, 1); console.log(inf.value.val);// val에서 대응하는 값 제거됨. ["ㄱ", "ㄴ", "ㄹ", "ㅁ"] } }) } // const imf = ref({ ar1: [1, 2, 3, 9], ar2: [1, 2, 3, 9], va: ["ㄱ", "ㄴ", "ㄷ", "ㅈ"] }) // ar2에 특정 값 추가. [1, 2, 3, 7, 9] imf.value.ar2.splice(3, 0, 7); // ar2에 배열 값이 추가되어서 ar2가 더 많을 때 if(imf.value.ar2.length > imf.value.

[vuejs 관련] Selectbox component

Selectbox component component .vue파일 <template> <div class="m_selectbox_cm"> <button class="multi_del" v-if="info.multiple && info.multitxt.length > 1" @mouseenter="info.multidel = true" @mouseleave="info.multidel = false" @click="multiDel"> <img src="@/assets/images/icon_close.svg" alt=""> </button> <a role="button" tabindex="1" :id="id" class="select" @click="showList" @blur="optionHide" @mouseenter="info.blurbo = false" @mouseleave="info.blurbo = true"> {{ info.multiple ? info.selecmulti : info.selecone }} </a> <div class="optionwrap" v-if="info.showopt"> <div class="optionslist"> <button class="opt" :class

[vuejs 관련] Checkbox component

Checkbox component component .vue파일 <template> <div class="m_checkbox" :class="{ nolabel: txt === '' }"> <input type="checkbox" :name="name" :id="idfor" :value="value" /><label :for="idfor">{{ txt }}</label> </div> </template> <script setup> const props = defineProps({ name: { type: String, defatult: undefined }, idfor: { type: String, defatult: undefined }, value: { type: String, defatult: undefined }, txt: { type: String, default: '' } }) </script> <!-- // 부모 컴포넌트에서 사용 시 # name : checkbox name # idfor : checkbox id = label for # value : checkbox value # txt : label <Checkbox name="name" idfor="idfor" value="value" txt="text" /> ex : <Checkbox name="agreeall" idfor="agreeall" v-model="agree.chec

[vuejs 관련] Input component

Input component component .vue파일 <template> <div class="input_wrap"> <p class="top_title" v-if="inputtxt">{{ txt }}</p> <input :id="id" :type="type" class="box_input" :class="{ on: inputtxt }" :placeholder="txt" :readonly="read" v-model="inputtxt" @input="upInfo(inputtxt = $event.target.value)"> </div> </template> <script setup> import { ref, watch } from "vue"; const props = defineProps({ id: undefined, type: { type: String, defatult: "text" }, txt: { type: String, defatult: undefined }, val: undefined, read: { type: Boolean, default: false }, }) watch(props, (e) => { if(e.val) { inputtxt.value = e.val } }) const inputtxt = ref(); inputtxt.value = props.val; const emit = defineEmits(["model"]); cons