inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

172만명의 커뮤니티!! 함께 토론해봐요.

페이지가 처음 로딩 되었을 때 애니메이션 처리가 되지 않는 느낌입니다

미해결

애플 웹사이트 인터랙션 클론!

페이지가 맨 처음 로딩 되었을 때에는 애니메이션이 작동하지 않다가... 페이지 섹션을 일정 부분 진행하고 다시 윗방향 스크롤을 걸었을때 애니메이션이 정상작동을 합니다. 그 후부터는 페이지의 시작 위치로 이동해서 시작부터 차근차근 내렸을때 정상작동을 합니다. 원인이 잘 생각이 나지 않네요 Main.js (() => { let yOffset = 0; // window.pageYOffset 대신에 쓸 변수 let prevScrollHeight = 0; // 현재 스크롤 위치(yOffset) 보다 이전에 위치한 스크롤 섹션들의 스크롤 높이값의 합 let currentScene = 0; // 현재 활성화된 (눈 앞에 보고있는) 씬 (Scrollsection) let enterNewScene = false; // 새로운 Scene이 시작된 순간 true // sceneInfo는 각 scene에 대한 정보를 담고 있다. const sceneInfo = [ { // 0 type: 'sticky', heightNum: 5, // 브라우저 높이의 5배로 scrollHeight 세팅 scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-0'), messageA: document.querySelector('#scroll-section-0 .main-message.a'), messageB: document.querySelector('#scroll-section-0 .main-message.b'), messageC: document.querySelector('#scroll-section-0 .main-message.c'), messageD: document.querySelector('#scroll-section-0 .main-message.d') }, values: { messageA_opacity_in: [0, 1, { start: 0.1, end: 0.2 }], messageB_opacity_in: [0, 1, { start: 0.3, end: 0.4 }], messageC_opacity_in: [0, 1, { start: 0.5, end: 0.6 }], messageD_opacity_in: [0, 1, { start: 0.7, end: 0.8 }], messageA_translateY_in: [20, 0, { start: 0.1, end: 0.2 }], messageB_translateY_in: [20, 0, { start: 0.3, end: 0.4 }], messageC_translateY_in: [20, 0, { start: 0.5, end: 0.6 }], messageD_translateY_in: [20, 0, { start: 0.7, end: 0.8 }], messageA_opacity_out: [1, 0, { start: 0.25, end: 0.3 }], messageB_opacity_out: [1, 0, { start: 0.45, end: 0.5 }], messageC_opacity_out: [1, 0, { start: 0.65, end: 0.7 }], messageD_opacity_out: [1, 0, { start: 0.85, end: 0.9 }], messageA_translateY_out: [0, -20, { start: 0.25, end: 0.3 }], messageB_translateY_out: [0, -20, { start: 0.45, end: 0.5 }], messageC_translateY_out: [0, -20, { start: 0.65, end: 0.7 }], messageD_translateY_out: [0, -20, { start: 0.85, end: 0.9 }] } }, { // 1 type: 'normal', // heightNum: 5, // type normal에서는 필요 없음 scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-1'), content: document.querySelector('#scroll-section-1 .description') } }, { // 2 type: 'sticky', heightNum: 5, scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-2'), messageA: document.querySelector('#scroll-section-2 .a'), messageB: document.querySelector('#scroll-section-2 .b'), messageC: document.querySelector('#scroll-section-2 .c'), pinB: document.querySelector('#scroll-section-2 .b .pin'), pinC: document.querySelector('#scroll-section-2 .c .pin') }, values: { messageA_translateY_in: [20, 0, { start: 0.15, end: 0.2 }], messageB_translateY_in: [30, 0, { start: 0.5, end: 0.55 }], messageC_translateY_in: [30, 0, { start: 0.72, end: 0.77 }], messageA_opacity_in: [0, 1, { start: 0.15, end: 0.2 }], messageB_opacity_in: [0, 1, { start: 0.5, end: 0.55 }], messageC_opacity_in: [0, 1, { start: 0.72, end: 0.77 }], messageA_translateY_out: [0, -20, { start: 0.3, end: 0.35 }], messageB_translateY_out: [0, -20, { start: 0.58, end: 0.63 }], messageC_translateY_out: [0, -20, { start: 0.85, end: 0.9 }], messageA_opacity_out: [1, 0, { start: 0.3, end: 0.35 }], messageB_opacity_out: [1, 0, { start: 0.58, end: 0.63 }], messageC_opacity_out: [1, 0, { start: 0.85, end: 0.9 }], pinB_scaleY: [0.5, 1, { start: 0.5, end: 0.55 }], pinC_scaleY: [0.5, 1, { start: 0.72, end: 0.77 }], pinB_opacity_in: [0, 1, { start: 0.5, end: 0.55 }], pinC_opacity_in: [0, 1, { start: 0.72, end: 0.77 }], pinB_opacity_out: [1, 0, { start: 0.58, end: 0.63 }], pinC_opacity_out: [1, 0, { start: 0.85, end: 0.9 }] } }, { // 3 type: 'sticky', heightNum: 5, scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-3'), canvasCaption: document.querySelector('.canvas-caption') }, values: { } } ]; function setLayout() { // 각 스크롤 섹션의 높이 세팅 for (let i = 0; i < sceneInfo.length; i++) { if(sceneInfo[i].type === 'sticky') { sceneInfo[i].scrollHeight = sceneInfo[i].heightNum * window.innerHeight; // window.innerHeight는 브라우저 창의 높이 } else if(sceneInfo[i].type === 'normal') { sceneInfo[i].scrollHeight = sceneInfo[i].objs.container.offsetHeight } sceneInfo[i].objs.container.style.height = `${sceneInfo[i].scrollHeight}px` } yOffset = window.scrollY; let totalScrollHeight = 0; for (let i = 0; i < sceneInfo.length; i++) { totalScrollHeight += sceneInfo[i].scrollHeight; if(totalScrollHeight >= yOffset) { // 이미지로 그려보면 이해가 쉬움 currentScene = i; break; } } document.body.setAttribute('id', `show-scene=${currentScene}`) } function calcValues (values, currentYOffset) { // currentYOffset은 현재 씬에서 얼마나 스크롤 됐는지를 의미 let rv; // 현재 씬(스크롤섹션)에서 스크롤된 범위를 비율로 구하기 const scrollHeight = sceneInfo[currentScene].scrollHeight const scrollRatio = currentYOffset / sceneInfo[currentScene].scrollHeight; if (values.length === 3) { // start ~ end 사이의 애니메이션을 실행 const partScrollStart = values[2].start * scrollHeight; const partScrollEnd = values[2].end * scrollHeight; const partScrollHeight = partScrollEnd - partScrollStart if (currentYOffset >= partScrollStart && currentYOffset <= partScrollEnd) { rv = (currentYOffset - partScrollStart) / partScrollStart * (values[1] - values[0]) + values[0]; } else if (currentYOffset < partScrollStart) { rv = values[0]; } else if (currentYOffset > partScrollEnd) { rv = values[1]; } } else { rv = scrollRatio * (values[1] - values[0]) + values[0]; } return rv; } function playAnimation() { const objs = sceneInfo[currentScene].objs; const values = sceneInfo[currentScene].values; const currentYOffset = yOffset - prevScrollHeight; const scrollHeight = sceneInfo[currentScene].scrollHeight; const scrollRatio = currentYOffset / scrollHeight; switch (currentScene) { case 0: // console.log('0 play'); if (scrollRatio <= 0.22) { // in objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.42) { // in objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.62) { // in objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.82) { // in objs.messageD.style.opacity = calcValues(values.messageD_opacity_in, currentYOffset); objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageD.style.opacity = calcValues(values.messageD_opacity_out, currentYOffset); objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_out, currentYOffset)}%, 0)`; } break; case 2: // console.log('2 play'); if (scrollRatio <= 0.32) { // in objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.67) { // in objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`; objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset); objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`; } else { // out objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`; objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset); objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`; } if (scrollRatio <= 0.93) { // in objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`; objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset); objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`; } else { // out objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`; objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset); objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`; } break; case 3: // console.log('3 play'); break; } } function scrollLoop() { enterNewScene = false; prevScrollHeight = 0; // PrevScrollHeight의 초기화가 함수 내에 있어야 맥북 기준 4 scene의 총합 11540이 찍히고 다음 scrollLoop() 이 실행될 때 다시 초기화 된다. (값이 누적되지 않는다.) for (let i = 0; i < currentScene; i++) { prevScrollHeight += sceneInfo[i].scrollHeight; } if(yOffset > prevScrollHeight + sceneInfo[currentScene].scrollHeight) { enterNewScene = true; currentScene++; document.body.setAttribute('id', `show-scene-${currentScene}`); } if(yOffset < prevScrollHeight) { enterNewScene = true; if (currentScene === 0) return; // scene 0에서 바운싱 스크롤이 일어났을 때 콘솔에 -값을 찍히지 않게 방지 currentScene--; document.body.setAttribute('id', `show-scene-${currentScene}`); } if (enterNewScene) return; playAnimation(); } window.addEventListener('scroll', () => { yOffset = window.scrollY; // window.pageYOffset은 deprecated 되었다. scrollLoop() }); // window.addEventListener('DOMContentLoaded', setLayout) window.addEventListener('load', setLayout) window.addEventListener('resize', setLayout) // 화면 크기가 바뀌었을때를 기준으로 setLayout을 정의하기 })(); main.css @charset "utf-8"; html { font-family: 'Noto Sans KR' , sans-serif; font-size: 14px; } body { overflow-x: hidden; color: rgb(29, 29, 31); letter-spacing: -0.05em; background: white; } p { line-height: 1.6; } a { color: rgb(29, 29, 31); text-decoration: none; } .global-nav { position: absolute; top: 0; left: 0; width: 100%; height: 44px; padding: 0 1rem; } .local-nav { position: absolute; top: 45px; left: 0; width: 100%; height: 52px; padding: 0 1rem; border-bottom: 1px solid #ddd; } .global-nav-links, .local-nav-links { display: flex; align-items: center; max-width: 1000px; height: 100%; margin: 0 auto; /* background-color: gold; */ } .global-nav-links { justify-content: space-between; } .local-nav-links .product-name { margin-right: auto; font-size: 1.4rem; font-weight: bold; } .local-nav-links a { font-size: 0.8rem; } .local-nav-links a:not(.product-name) { margin-left: 2em; } .scroll-section { border: 3px solid red; padding-top: 50vh; } #scroll-section-0 h1 { font-size: 4rem; text-align: center; } .main-message { display: flex; align-items: center; justify-content: center; top: 35vh; margin: 5px 0; height: 3em; font-size: 2.5rem; opacity: 0; } .main-message p { font-weight: bold; text-align: center; line-height: 1.2; } .main-message small { display: block; margin-bottom: 0.5em; font-size: 1.2rem; } #scroll-section-2 .main-message { font-size: 3.5rem; } .description { max-width: 1000px; margin: 0 auto; padding: 0 1rem; font-size: 1.2rem; color: #888 } .description strong { float: left; margin-right: 0.2em; /* font-size: 3rem; */ color: rgb(29, 29, 31); } .desc-message { width: 50%; font-weight: bold; } .pin { width: 1px; height: 100px; background: rgb(29,29,31); } #scroll-section-2 .b { top: 10%; left: 40%; } #scroll-section-2 .c { top: 15%; left: 45%; } .mid-message { max-width: 1000px; margin: 0 auto; padding: 0 1rem; font-size: 2rem; color: #888; } .mid-message strong { color: rgb(29,29,31); } .canvas-caption { max-width: 1000px; margin: 0 auto; padding: 0 1rem; font-size: 1.2rem; color: #888; } .footer { display: flex; align-items: center; justify-content: center; height: 7rem; color: white; background: darkorange; } .sticky-elem { display: none; position: fixed; left: 0; width: 100%; } body#show-scene-0 #scroll-section-0 .sticky-elem, body#show-scene-1 #scroll-section-1 .sticky-elem, body#show-scene-2 #scroll-section-2 .sticky-elem, body#show-scene-3 #scroll-section-3 .sticky-elem { display: block; } @media(min-width: 1024px) { #scroll-section-0 h1 { font-size: 9vw; } .main-message { font-size: 4vw; } .description { font-size: 2rem; } .description strong { font-size: 6rem; } #scroll-section-2 .main-message { font-size: 6vw; } .main-message small { font-size: 1.5vw; } .desc-message { width: 20%; } #scroll-section-2 .b { top: 20%; left: 53%; } #scroll-section-2 .c { left: 55%; } .mid-message { font-size: 4vw; } .canvas-caption { font-size: 2rem; } } blank.html <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>AirMug Pro</title> <link href=" https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;900&display=swap " rel="stylesheet"> <link rel="stylesheet" href="css/default.css"> <link rel="stylesheet" href="css/main.css"> </head> <body> <div class="container"> <nav class="global-nav"> <div class="global-nav-links"> <a href="" class="global-nav-item">Rooms</a> <a href="" class="global-nav-item">Ideas</a> <a href="" class="global-nav-item">Stores</a> <a href="" class="global-nav-item">Contact</a> </div> </nav> <nav class="local-nav"> <div class="local-nav-links"> <a href="#" class="product-name">AirMug Pro</a> <a href="#">개요</a> <a href="#">제품사양</a> <a href="#">구입하기</a> </div> </nav> <section class="scroll-section" id="scroll-section-0"> <h1>AirMug Pro</h1> <div class="sticky-elem main-message a"> <p>온전히 빠져들게 하는<br>최고급 세라믹</p> </div> <div class="sticky-elem main-message b"> <p>주변 맛을 느끼게 해주는<br>주변 맛 허용 모드</p> </div> <div class="sticky-elem main-message c"> <p>온전히 편안한<br>맞춤형 손잡이</p> </div> <div class="sticky-elem main-message d"> <p>새롭게 입가를<br>찾아온 매혹</p> </div> </section> <section class="scroll-section" id="scroll-section-1"> <p class="description"> <strong>보통 스크롤 영역</strong> Lorem, ipsum dolor sit amet consectetur adipisicing elit. Dolore explicabo commodi facere nisi expedita eaque quasi doloremque eligendi natus architecto, facilis velit nobis voluptatum suscipit autem soluta debitis neque illum quibusdam similique odio maiores. Ab optio laborum eum sit praesentium, aperiam voluptatem nihil modi tempore a magni necessitatibus hic exercitationem temporibus doloremque error omnis. Sequi, repudiandae dolor eaque non soluta praesentium doloremque, doloribus, ea consequuntur sit perferendis ex! Repellendus natus harum soluta dolorem voluptas alias qui, ipsa vero! Alias voluptate libero, facilis molestias nam aspernatur, amet accusantium consequatur a nostrum temporibus. Qui obcaecati optio quod iusto totam, aut iste dolor ea. Explicabo dolorem ducimus natus, officiis aut minima, ad sapiente voluptatem repellat aliquid suscipit at. Architecto nostrum perferendis, fugiat velit perspiciatis illum dignissimos, vitae delectus magnam blanditiis omnis ratione nihil minus deserunt repudiandae necessitatibus et, tempore cupiditate sapiente? Debitis obcaecati repellendus corrupti odit incidunt deleniti exercitationem dolorum ipsum consequatur rerum maxime, corporis placeat deserunt veniam cum qui dolorem nulla fugit eius ipsam quibusdam saepe! Aut culpa excepturi perferendis, sint animi tempora. Officia necessitatibus libero impedit alias commodi excepturi accusamus molestiae modi laudantium voluptates totam earum autem eos numquam at consequuntur ipsam repellat, perspiciatis veniam? Expedita nobis ducimus quisquam accusantium! Velit! </p> </section> <section class="scroll-section" id="scroll-section-2"> <div class="sticky-elem main-message a"> <p> <small>편안한 촉감</small> 입과 하나 되다 </p> </div> <div class="sticky-elem desc-message b"> <p> 편안한 목넘김을 완성하는 디테일한 여러 구성 요소들, 우리는 이를 하나하나 새롭게 살피고 재구성하는 과정을 거쳐 새로운 수준의 머그, AirMug Pro를 만들었습니다. 입에 뭔가 댔다는 감각은 어느새 사라지고 오롯이 당신과 음료만 남게 되죠. </p> <div class="pin"></div> </div> <div class="sticky-elem desc-message c"> <p> 디자인 앤 퀄리티 오브 스웨덴,<br>메이드 인 차이나 </p> <div class="pin"></div> </div> </section> <section class="scroll-section" id="scroll-section-3"> <p class="mid-message"> <strong>Retina 머그</strong> 아이디어를 광할하게 펼칠<br> 아름답고 부드러운 음료 공간. </p> <p class="canvas-caption"> Lorem ipsum dolor sit amet consectetur adipisicing elit. Expedita nulla nesciunt tempora asperiores culpa, illo et assumenda vel odio voluptatem? Saepe rerum qui accusamus maiores ex libero natus obcaecati accusantium aperiam eligendi ut et facere quis molestias quos repudiandae, omnis facilis deserunt cum! Expedita ipsam aliquid beatae doloremque, officia explicabo non neque reprehenderit qui quo, recusandae incidunt saepe totam! Adipisci dolorem inventore soluta. Natus pariatur sit quisquam dicta placeat! Molestias voluptas eos asperiores maxime, dolorem corporis eum quos iste dolores eveniet, cumque officiis beatae adipisci! Corporis quibusdam voluptates explicabo officiis quis cupiditate qui officia expedita. Praesentium placeat debitis recusandae ipsa similique optio accusamus, omnis vero a ducimus blanditiis fugit asperiores maiores mollitia? Pariatur exercitationem culpa, fugiat accusantium soluta incidunt beatae debitis laborum, harum neque aliquam, asperiores quod! Error numquam voluptate aut corrupti nam! Iusto illum accusamus sapiente asperiores quo eum perspiciatis aliquam blanditiis dolorem natus, modi magnam molestiae accusantium porro quisquam iure tempora laborum deserunt recusandae omnis dolore eos pariatur eveniet. Exercitationem mollitia inventore at quasi aperiam blanditiis minima accusantium, delectus, possimus quidem labore sapiente eius sint molestias doloribus est autem cupiditate iure veniam optio! Placeat dolor et, eos, saepe nemo tempore aliquid alias, facere pariatur optio sint nam ea. </p> </section> <footer class="footer"> 2023-08-01 Jun </footer> </div> <script src="js/main.js"></script> </body> </html>

  • HTML/CSS
  • javascript
  • 웹-디자인
  • svg
  • 인터랙티브-웹
  • 클론코딩
Jun 댓글 1 좋아요 0 조회수 467

클론코딩 시

미해결

[하루 10분|Web Project] HTML/JS/CSS로 나만의 심리테스트 사이트 만들기

- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 어떤 웹페이지를 클론 코딩할때 검사에 들어가서 요소만 보고도 똑같이 만드는게 가능한가요? 비슷하게는 되는데 한계가 있는 거 같아서요

  • HTML/CSS
  • javascript
  • bootstrap
영은 댓글 1 좋아요 0 조회수 389

TypeNotPresentException

미해결

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 MemberServiceIntegrationTest 에서 회원가입을 run하는 과정중에, 처음에는 NullPointerException 이 뜨다가, 코드수정만 했는데 이제는 아얘 실행조차 안되고 다음과 같이 오류가 뜹니다 __________________ 위의 오류를 해결하려고 아래와 같이 src/java/main을 소스루트로 지정했습니다 캐쉬삭제도 해보고 이것저것 해봤는데 실행조차 안됩니다 어떻게 고쳐야하나요 ... ㅠㅠ 도와주세요 ..

  • java
  • spring
  • mvc
  • spring-boot
study 댓글 2 좋아요 0 조회수 417

(실습) JSX 코드 작성해보기

미해결

처음 만난 리액트(React)

이 화면이 나오게 하고 싶습니다. npm start 엔터 이후로 어떻게 해야 하는지 모르겠습니다

  • HTML/CSS
  • javascript
  • react
이민준 댓글 3 좋아요 0 조회수 829

섹션 2 create-react-app

미해결

처음 만난 리액트(React)

npx create-react-app my-app이라고 작성했는데 오류가 나타납니다. node.js와 npm버전은 모두 14.0과 6.14 이상입니다 PS C:\Users\이민준> npx create-react-app my-app npm ERR! code ENOENT npm ERR! syscall lstat npm ERR! path C:\Users\이민준\AppData\Roaming\npm npm ERR! errno -4058 npm ERR! enoent ENOENT: no such file or directory, lstat 'C:\Users\이민준\AppData\Roaming\npm' npm ERR! enoent This is related to npm not being able to find a file. npm ERR! enoent npm ERR! A complete log of this run can be found in: npm ERR! C:\Users\이민준\AppData\Local\npm-cache\_logs\2023-08-02T12_46_01_759Z-debug-0.log PS C:\Users\이민준>

  • HTML/CSS
  • javascript
  • react
이민준 댓글 1 좋아요 0 조회수 1920

섹션 2 리액트 시작하기 (실습) 직접 리액트 연동하기

미해결

처음 만난 리액트(React)

click 버튼이 나타나지 않습니다. 코드는 정상적으로 오타가 없는지 여러 번 확인했습니다. function MyButton(props){ const [isClicked, setIsClicked] = React.useState(false); return React.createElement( 'button', {onClick: () => setIsClicked(true)}, isClicked ? 'Clicked!' : 'Click here!' ) } <html> <head> <title>민준의 블로그</title> <link rel="stylesheet" href="sylesj.css"> </head> <body> <h1>민준의 블로그에 오신 여러분들 환영합니다</h1> <div id="root"></div> <!--리액트 가져오기--> <script src="https://unpkg.com/react@17/umd/react.decelopment.js" crossorigin></script> <script src="https://unpkg.com/react-dom@17/umd/react.decelopment.js" crossorigin></script> <!--리액트 컴포넌트 가져오기--> <script src="MyButtonj.js"></script> </body> </html>

  • HTML/CSS
  • javascript
  • react
이민준 댓글 2 좋아요 1 조회수 834

npm start해도 안됩니다.

미해결

처음 만난 리액트(React)

index.js Library.jsx Book.jsx

  • HTML/CSS
  • javascript
  • react
son5646 댓글 2 좋아요 0 조회수 859

kotlin closure 는 별도의 메모리 공간에 데이터를 복사해서 가지고 있는게 맞을까요?

미해결

자바 개발자를 위한 코틀린 입문(Java to Kotlin Starter Guide)

Java 에서 Final 만 사용할 수 있는게 외부 변수가 메모리에서 해제 되었을 경우, 가비지를 참조할 수 있는 것을 방지하기 위해서로 알고 있는데 코틀린은 이게 가능한게 아예 메모리를 통째로 떠와서 그런걸까요? ㅎㅎ 강의 영상에서 포획한다 라고 표현하신게 그런 의미 같아요!

  • java
  • kotlin
  • 객체지향
목동 개발자 댓글 1 좋아요 2 조회수 409

Async Await 오류가 나서 문의드립니다.

미해결

자바스크립트 제대로 배워볼래?

안녕하세요. 스크립트는 아래와 같이 작성하였으며, 콘솔에는 3-12.AsyncAwait.html:20 Uncaught (in promise) TypeError: data is not iterable at calculateSum 이라는 오류가 나왔습니다. <!DOCTYPE html> <html> <head> <title>Document</title> </head> <body> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <script> var url ="https://74f8c451-bcda-46f0-820b-f63caee12b28.mock.pstmn.io/productList"; async function getData2(){ return (await axios.get(url)).data; } async function calculateSum(){ var data = await getData2(); var total = 0; for(var item of data){ total += item.price; } console.log(total); } calculateSum(); </script> </body> </html> 어디가 잘못된걸까요... 강의랑 똑같이 작성을 한거같은데..

  • HTML/CSS
  • javascript
  • es6
cis3093 댓글 2 좋아요 0 조회수 589

npm start

미해결

처음 만난 리액트(React)

npm start를 하면 여기서 멈추고 원하는 화면이 안나오는데 어떻게 해야하나요?

  • HTML/CSS
  • javascript
  • react
댓글 1 좋아요 1 조회수 489

(실습_리액트18)시계만들기_코드_index.js

미해결

처음 만난 리액트(React)

import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; import Library from './chapter_03/Library'; import Clock from './chapter_04/Clock'; const root = ReactDOM.createRoot(document.getElementById('root')); setInterval(() => { root.render( <React.StrictMode> <Clock /> </React.StrictMode> ); },1000);

  • HTML/CSS
  • javascript
  • react
박규원 댓글 2 좋아요 1 조회수 1281

A1타입 최종본 만들기

미해결

[2026년 출제기준] 웹디자인개발기능사 실기시험 완벽 가이드

최종본 만들때 슬라이드 안에 있는 사진 사이즈와 텍스트는 포토샵으로 만든건가요?

  • HTML/CSS
  • jquery
  • 웹-디자인
댓글 1 좋아요 1 조회수 264

프로젝트를 마치며 배포 페이지에서 업로드 작동이 안됨

미해결

비전공자를 위한 진짜 입문 올인원 개발 부트캠프

상품 업로드에 관한 이슈 과정을 다 마치고, fly.io와 vercel.com 을 통하여 배포한 페이지 중에서 상품 업로드가 제대로 이뤄지지 않습니다. github 주소 : https://github.com/arominddo/Inflearn_full_stack_boot_camp vercel을 통해 배포된 web 어플리케이션 url : https://grab-market-client-ashen.vercel.app/ grab_market_web > src > upload > index.js에 코드 내용이 작성되어 있습니다. 배포된 페이지의 DB 초기화 문제 프로젝트를 전부 마치면서, 다시 한번 fly.io에 최신 코드로 재배포를 해보고 실험을 해보았는데도, web에서 특정 상품을 업로드하거나(오류가 나지 않았을 당시), 상품 구매하기 기능을 통하여 soldout 값을 1로 바꿔줬음에도, 약 5분이 지나면 DB가 배포 됐을 당시의 내용으로 계속 초기화가 됩니다. 해결 방안이 궁금합니다. ex) A라는 물건 업로드 -> 5분 지남 -> 새로고침 해보면 A라는 물건이 리스트에서 삭제 ex) B라는 물건 구매 하기 버튼 클릭 -> soldout 값 1로 변경 -> 약 5분 지남 -> 다시 soldout 값 0으로 복귀

  • HTML/CSS
  • javascript
  • react
  • node.js
  • react-native
  • 머신러닝
  • express
  • tensorflow
밍또 댓글 2 좋아요 0 조회수 462

미니블러그 질문

미해결

처음 만난 리액트(React)

Button(props) 에서 props로 받은 title이 버튼 목록에 표시하고 props로 받은 onClick은 <StyleButton>에 onClick에 넣어 주므로써 <질문> onClick이벤트를 상위 컴포넌트에서 받을수 있도록 해 주었다고 설명하셨는데~ 질문입니다? onClick={onClick} 이벤트를 상위 컴포넌트에서 받을수 있도록 해 주었다라고 위에서 설명 하셨는데, 이해가 잘 안되어서 질문합니다 onClickItem(post)도 같은 맥락인것 같은데 이해가 안됩니다

  • HTML/CSS
  • javascript
  • react
정하 댓글 2 좋아요 1 조회수 414

AOP가 적용되지않습니다.

미해결

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] "package hello.hellospring.aop; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Component @Aspect public class TimeTraceAop { @Around("execution(* hello.helloSpring..*(..))") public Object execute(ProceedingJoinPoint joinPoint) throws Throwable { long start = System. currentTimeMillis (); System. out .println("START : " + joinPoint.toString()); try { return joinPoint.proceed(); } finally { long finish = System. currentTimeMillis (); long timeMs = finish - start; System. out .println("END : " + joinPoint.toString()+ " " + timeMs + "ms"); } } }" TimeTraceAop 클래스를 작성한 이후에 실행을 시켜보아도 수업처럼 START END 부분이실행되지 않습니다. 단순 스프링 실행화면만 보이는데 어디가 문제일까요?

  • java
  • spring
  • mvc
  • spring-boot
digeuthi 댓글 3 좋아요 0 조회수 2227

화면 오른쪽 스크롤이 넘어가질 않아요!

미해결

프로그래밍 시작하기 : 웹 입문 (Inflearn Original)

<html> <head> <meta charset="utf-8"> <title>인스타그램</title> <link rel = "stylesheet" href = "styles/card.css"> </head> <body> <section class = "container"> <article class = "card"> <header> <div class = "circle-image"> <img src = "images/profile.png"/> </div> <div class = "card-username"> <span>taeyun_kwon1118</span> </div> <div class = "option-more"> <button class = "transparent-button"><img src = "images/icons/mark.png"/></button> </div> </header> <main> <div class = "carousel" data = "0"> <div> <ul> <li><img src = "images/mountain1.jpg"/> </li><li><img src = "images/mountain2.jpg"/> </li><li><img src = "images/mountain3.jpg"/> </li><li><img src = "images/mountain4.jpg"/></li> </ul> <div class = "slide slide-left"> <button class = "transparent-button"><img src = "images/icons/arrow-left.png"/></button> </div> <div class = "slide slide-right"> <button class = "transparent-button"><img src = "images/icons/arrow-right.png"/></button> </div> </div> <footer> <div class = "active"></div> <div></div> <div></div> <div></div> </footer> </div> <div class = "card-container"> <div class = "card-buttons"> <div> <button class = "transparent-button"> <img src = "images/icons/heart.png"/> </button> </div> <div> <button class = "transparent-button"> <img src = "images/icons/chat.png"/> </button> </div> <div> <button class = "transparent-button"> <img src = "images/icons/paper-plane.png"/> </button> </div> <div class = "last-card-button"> <button class = "transparent-button"> <img src = "images/icons/bookmark.png"/> </button> </div> </div> <div class = "card-likes"> taeyun_kwon1118님 외 여러 명이 좋아합니다 </div> <div class = "card-contents"> <ul> <li> <div> <span>taeyun_kwon1118</span> 여행 사진 올립니다. 좋아요 부탁 드려요 !!! </div> </li> <li class = "comment"> <div> <span>taeyun_kwon1118</span> 댓글 1 <button class = "transparent-button"> <img src = "images/icons/heart.png"/> </button> </div> </li> <li class = "comment"> <div> <span>taeyun_kwon1118</span> 댓글 2 <button class = "transparent-button"> <img src = "images/icons/heart.png"/> </button> </div> </li> </ul> </div> <div class = "card-time"> 7일 전 </div> </div> </main> <footer class = "card-comment"> <input type = "text" placeholder = "댓글 달기..." name = "comment"> <div> <button class = "transparent-button"> 게시</button> </div> </footer> </article> </section> <script type = "text/javascript" src = "scripts/carousel.js"></script> <script type = "text/javascript" src = "scripts/smoothscroll.min.js"></script> </body> </html> !function(){"use strict";function o(){var o=window,t=document;if(!("scrollBehavior"in t.documentElement.style&&!0!==o.__forceSmoothScrollPolyfill__)){var l,e=o.HTMLElement||o.Element,r=468,i={scroll:o.scroll||o.scrollTo,scrollBy:o.scrollBy,elementScroll:e.prototype.scroll||n,scrollIntoView:e.prototype.scrollIntoView},s=o.performance&&o.performance.now?o.performance.now.bind(o.performance):Date.now,c=(l=o.navigator.userAgent,new RegExp(["MSIE ","Trident/","Edge/"].join("|")).test(l)?1:0);o.scroll=o.scrollTo=function(){void 0!==arguments[0]&&(!0!==f(arguments[0])?h.call(o,t.body,void 0!==arguments[0].left?~~arguments[0].left:o.scrollX||o.pageXOffset,void 0!==arguments[0].top?~~arguments[0].top:o.scrollY||o.pageYOffset):i.scroll.call(o,void 0!==arguments[0].left?arguments[0].left:"object"!=typeof arguments[0]?arguments[0]:o.scrollX||o.pageXOffset,void 0!==arguments[0].top?arguments[0].top:void 0!==arguments[1]?arguments[1]:o.scrollY||o.pageYOffset))},o.scrollBy=function(){void 0!==arguments[0]&&(f(arguments[0])?i.scrollBy.call(o,void 0!==arguments[0].left?arguments[0].left:"object"!=typeof arguments[0]?arguments[0]:0,void 0!==arguments[0].top?arguments[0].top:void 0!==arguments[1]?arguments[1]:0):h.call(o,t.body,~~arguments[0].left+(o.scrollX||o.pageXOffset),~~arguments[0].top+(o.scrollY||o.pageYOffset)))},e.prototype.scroll=e.prototype.scrollTo=function(){if(void 0!==arguments[0])if(!0!==f(arguments[0])){var o=arguments[0].left,t=arguments[0].top;h.call(this,this,void 0===o?this.scrollLeft:~~o,void 0===t?this.scrollTop:~~t)}else{if("number"==typeof arguments[0]&&void 0===arguments[1])throw new SyntaxError("Value could not be converted");i.elementScroll.call(this,void 0!==arguments[0].left?~~arguments[0].left:"object"!=typeof arguments[0]?~~arguments[0]:this.scrollLeft,void 0!==arguments[0].top?~~arguments[0].top:void 0!==arguments[1]?~~arguments[1]:this.scrollTop)}},e.prototype.scrollBy=function(){void 0!==arguments[0]&&(!0!==f(arguments[0])?this.scroll({left:~~arguments[0].left+this.scrollLeft,top:~~arguments[0].top+this.scrollTop,behavior:arguments[0].behavior}):i.elementScroll.call(this,void 0!==arguments[0].left?~~arguments[0].left+this.scrollLeft:~~arguments[0]+this.scrollLeft,void 0!==arguments[0].top?~~arguments[0].top+this.scrollTop:~~arguments[1]+this.scrollTop))},e.prototype.scrollIntoView=function(){if(!0!==f(arguments[0])){var l=function(o){for(;o!==t.body&&!1===(e=p(l=o,"Y")&&a(l,"Y"),r=p(l,"X")&&a(l,"X"),e||r);)o=o.parentNode||o.host;var l,e,r;return o}(this),e=l.getBoundingClientRect(),r=this.getBoundingClientRect();l!==t.body?(h.call(this,l,l.scrollLeft+r.left-e.left,l.scrollTop+r.top-e.top),"fixed"!==o.getComputedStyle(l).position&&o.scrollBy({left:e.left,top:e.top,behavior:"smooth"})):o.scrollBy({left:r.left,top:r.top,behavior:"smooth"})}else i.scrollIntoView.call(this,void 0===arguments[0]||arguments[0])}}function n(o,t){this.scrollLeft=o,this.scrollTop=t}function f(o){if(null===o||"object"!=typeof o||void 0===o.behavior||"auto"===o.behavior||"instant"===o.behavior)return!0;if("object"==typeof o&&"smooth"===o.behavior)return!1;throw new TypeError("behavior member of ScrollOptions "+o.behavior+" is not a valid value for enumeration ScrollBehavior.")}function p(o,t){return"Y"===t?o.clientHeight+c<o.scrollHeight:"X"===t?o.clientWidth+c<o.scrollWidth:void 0}function a(t,l){var e=o.getComputedStyle(t,null)["overflow"+l];return"auto"===e||"scroll"===e}function d(t){var l,e,i,c,n=(s()-t.startTime)/r;c=n=n>1?1:n,l=.5*(1-Math.cos(Math.PI*c)),e=t.startX+(t.x-t.startX)*l,i=t.startY+(t.y-t.startY)*l,t.method.call(t.scrollable,e,i),e===t.x&&i===t.y||o.requestAnimationFrame(d.bind(o,t))}function h(l,e,r){var c,f,p,a,h=s();l===t.body?(c=o,f=o.scrollX||o.pageXOffset,p=o.scrollY||o.pageYOffset,a=i.scroll):(c=l,f=l.scrollLeft,p=l.scrollTop,a=n),d({scrollable:c,method:a,startTime:h,startX:f,startY:p,x:e,y:r})}}"object"==typeof exports&&"undefined"!=typeof module?module.exports={polyfill:o}:o()}(); window.addEventlistener('load', function(){ var carousels = document.getElementsByClassName('carousel'); for(var i = 0; i < carousels.length; i++) { addEventToCarousel(carousels[i]); } }); function addEventToCarousel(carouselElem){ var ulElem = carouselElem.querySelector('ul'); var liElems = ulElem.querySelectorAll('li'); //너비 값 조정 var liWidth = liElems[0].clientWidth;//600px var adjustedWidth = liElems.length * liWidth; ulElem.style.width = adjustedWidth + 'px'; //슬라이드 버튼 이벤트 등록 var slideButtons = carouselElem.querySelectorAll('.slide'); for(var i = 0; i < slideButtons.length; i++) { slideButtons[i].addEventlistener('click', createListenerSlide(carouselElem)); } } function createListenerSlide(carouselElem){ return function(event){ var clickedButton = event.currentTarget; var liElems = carouselElem.querySelectorAll('li'); var liCount = liElems.length; var currentIndex = carouselElem.attributes.data.value; if(clickedButton.className.includes('right') && currentIndex < licount - 1){ currentIndex ++; scrollDiv(carouselElem, currentIndex); } else if(clickedButton.className.includes('left') && currentIndex > 0){ currentIndex --; scrollDiv(carouselElem, currentIndex); } // indicator update // slide button 보여줌 여부 update // 새롭게 보여지는 이미지 인덱스 값을 현재 data값으로 업데이트 carouselElem.attributes.data.value = currentIndex; } } function scrollDiv(carouselElem, nextIndex){ var scrollable = carouselElem.querySelector('div'); var liWidth = scrollable.clientWidth; var newLeft = liWidth * nextIndex; scrollable.scrollTo({left: newleft, behavior: 'smooth'}); }

  • HTML/CSS
  • javascript
taeyun1118 댓글 1 좋아요 0 조회수 545

@Deprecated

해결됨

실전! Querydsl

안녕하세요 queryDsl의 기본 문법에 대해서 듣고 있는데요. 현재 기준, fetchResults(), fetchCount() 가 deprecated 되었네요.(자바11, springboot 2.7 버전에 맞는 queryDsl) 강의 끝부분에서 말씀하신, 복잡한 페이징 & 쿼리 부분에서는 coun와 select 쿼리가 다르니까 따로 작성해서 해야된다는 말씀 것과 연관되어서 그런 것 맞을까요? 그러면 @Deprecated 된 현재는 fetchResults(), fetchCount() 는 사용을 지양하고 별개의 쿼리로 각각의 값들을 얻어 조합해서 response 해주는 것이 맞죠?

  • java
  • jpa
highjune 댓글 1 좋아요 3 조회수 1568

:hover 와 ::after (콜론 하나와 두개 차이?)

미해결

풀스택을 위한 탄탄한 프런트엔드 부트캠프 (HTML, CSS, 바닐라 자바스크립트 + ES6) [풀스택 Part2]

:hover 처럼 콜론 하나를 쓰는 것도 있고 ::after 로 콜론 두개를 쓰는 것도 있던데 어떤 차이가 있는건가요 ?? 의미가 있는지 궁금합니다.

  • HTML/CSS
  • javascript
  • es6
hanyn 댓글 1 좋아요 0 조회수 972

certbot과 git충돌 질문자 입니다.

미해결

비전공자를 위한 풀스택 맛집지도 만들기 프로젝트!: Front, Back-end 그리고 배포까지

안녕하세요. certbot 실행 이후 git clone이 되지 않아 질문을 남겼었던 질문자입니다! 당시 얼추 인도해주신 솔루션이 인스턴스 설정 초기화 후 새로 설치 였던터라 시간이 걸릴것으로 예상이 되어서 우선순위를 좀 뒤로 미루고, 다른 일들을 하다가 오느라 이제야 다시 질문의 일로 돌아왔습니다. 그런데 이제와 생각해보니 certbot 과 git의 충돌이 유력한 원인이라면... certbot을 재설치? 재실행? 하면 되지 않을까 싶어서 인터넷에 검색을 해봤는데 자동갱신에 관한 글뿐이 없더군요.. 해서 혹시 certbot을 날렸다가 다시 설치하거나 certbot의 설정파일들이 임시로 작동하지 않도록 하는 방법이 있을까요? 만약 임시 비활성화가 가능하다면 그 사이에 git clone을 진행하고, 다시 활성화 하면 될것 같아서.. 혹시 아시는 방법이 있으실지 여쭤봅니다

  • HTML/CSS
  • javascript
  • aws
  • git
  • mysql
  • rest-api
  • github
전예준 댓글 1 좋아요 0 조회수 306

인기 태그

인프런 TOP Writers

주간 인기글