Collage

n. A piece of art made by sticking various different materials, aka PHENOMENA Magazine
Department
front-end

front-end

Q The :) event at 11pm is correctly appearing on the correct date (8/1), but the :( event that starts 1 minute later appears to span across two days (8/1 - 8/2). See screenshot below.   A If you don't specify the end time, the default duration is 1 hour which makes it run into the next day: defaultTimedEventDuration - Docs | FullCalendar FullCalendar Demos Docs Support Getting Help Reporting Bugs Requesting Features Contributing Pricing Jul 12 — v6.1.15 Event Model Event Parsing Event Object Recurring Events RRule Plugin Event Data Parsing eventDataTransform defaultAllDay defaultAllDayEve https://fullcalendar.io/docs/defaultTimedEventDuration   ***** If the start time and the end time are the same, then the issue will also arise. Solutions: let calendar = new FullCalendar.Calendar(calendarEl, { initialView: 'dayGridMonth', //timeZone: 'Asia/Seoul', eventTimeFormat: { hour: '2-digit', minute: '2-digit', hourCycle: 'h24' }, defaultTimedEventDuration: '00:00', events: [ { id: 'a', title: 'my event', "start": "2024-07-09T23:02:21", "end": "2024-07-09T23:02:21", //"start": "2024-07-09T23:02:20+0900", //"end": "2024-07-09T23:02:21+0900", } ] });   OR   let calendar = new FullCalendar.Calendar(calendarEl, { initialView: 'dayGridMonth', //timeZone: 'Asia/Seoul', eventTimeFormat: { hour: '2-digit', minute: '2-digit', hourCycle: 'h24' }, //defaultTimedEventDuration: '00:00', events: [ { id: 'a', title: 'my event', //"start": "2024-07-09T23:02:21", //"end": "2024-07-09T23:02:21", "start": "2024-07-09T23:02:20+0900", "end": "2024-07-09T23:02:21+0900", } ] });   Ref. Events after 11pm appear to span two days · Issue #5008 · fullcalendar/fullcalendar See: https://jsfiddle.net/412qh7zx/5/ The :) event at 11pm is correctly appearing on the correct date (8/1), but the :( event that starts 1 minute later appears to span across two days (8/1 - 8/2).... https://github.com/fullcalendar/fullcalendar/issues/5008
John Doe · July 30, 2024, 8:36 p.m.
fullcalendar
Check this out!   <!DOCTYPE html> <html> <head> <title>Move (drag/pan) and zoom object (image or div) in pure js</title> <style> html, body { margin: 0; padding: 0; } #zoomContainer { width: 100vw; height: 100vh; overflow: hidden; position: relative; } #zoomImage { position: absolute; cursor: move; transition: transform 0.3s; max-width: 100%; max-height: 100%; top: 0; left: 0; width: 100%; height: 100%; } .zoomButton { position: fixed; top: 20px; padding: 10px; font-size: 16px; background-color: #ffffff; border: none; cursor: pointer; } #zoomInButton { left: 20px; } #zoomOutButton { left: 60px; } </style> </head> <body> <div id="zoomContainer"> <img id="zoomImage" src="bg.jpg" alt="zoom image" /> </div> <button id="zoomInButton" class="zoomButton">zoom in</button> <button id="zoomOutButton" class="zoomButton">zoom out</button> <script> document.addEventListener('DOMContentLoaded', function() { var zoomContainer = document.getElementById('zoomContainer'); var zoomImage = document.getElementById('zoomImage'); var zoomLevel = 1; var minZoomLevel = 1; var maxZoomLevel = 2; var zoomIncrement = 0.2; var isDragging = false; let newPosX = 0, newPosY = 0, startPosX = 0, startPosY = 0; function updateZoomedImage() { var imageWidth = zoomImage.offsetWidth; var imageHeight = zoomImage.offsetHeight; var newImageWidth = imageWidth * zoomLevel; var newImageHeight = imageHeight * zoomLevel; var left = zoomImage.offsetLeft; var top = zoomImage.offsetTop; zoomImage.style.transform = 'scale(' + zoomLevel + ')'; zoomImage.style.width = newImageWidth + 'px'; zoomImage.style.height = newImageHeight + 'px'; // Restrict images from leaving containers if (Math.abs(zoomImage.offsetLeft - newPosX) >= Math.abs((parseInt(zoomImage.style.width, 10) - window.innerWidth) / 2)) { left = 0; } if (Math.abs(zoomImage.offsetTop - newPosY) >= Math.abs((parseInt(zoomImage.style.height, 10) - window.innerHeight) / 2)) { top = 0; } zoomImage.style.left = left + 'px'; zoomImage.style.top = top + 'px'; // when the user clicks down on the element zoomImage.addEventListener('mousedown', function(e) { e.preventDefault(); // get the starting position of the cursor startPosX = e.clientX; startPosY = e.clientY; document.addEventListener('mousemove', mouseMove); document.addEventListener('mouseup', function() { document.removeEventListener('mousemove', mouseMove); }); }); } function zoomIn() { if (zoomLevel < maxZoomLevel) { zoomLevel += zoomIncrement; zoomLevel = Math.min(zoomLevel, maxZoomLevel); updateZoomedImage(); } if (zoomLevel === maxZoomLevel) { document.getElementById('zoomInButton').disabled = true; } document.getElementById('zoomOutButton').disabled = false; } function zoomOut() { if (zoomLevel > minZoomLevel) { zoomLevel -= zoomIncrement; zoomLevel = Math.max(zoomLevel, minZoomLevel); updateZoomedImage(); } if (zoomLevel === minZoomLevel) { document.getElementById('zoomOutButton').disabled = true; } document.getElementById('zoomInButton').disabled = false; if (zoomLevel === 1) { zoomImage.style.cursor = 'move'; } } function mouseMove(e) { // calculate the new position newPosX = startPosX - e.clientX; newPosY = startPosY - e.clientY; // with each move we also want to update the start X and Y startPosX = e.clientX; startPosY = e.clientY; // Restrict images from leaving containers if (Math.abs(zoomImage.offsetLeft - newPosX) >= Math.abs((parseInt(zoomImage.style.width, 10) - window.innerWidth) / 2) || Math.abs(zoomImage.offsetTop - newPosY) >= Math.abs((parseInt(zoomImage.style.height, 10) - window.innerHeight) / 2) ) { return; } // set the element's new position: zoomImage.style.left = (zoomImage.offsetLeft - newPosX) + "px"; zoomImage.style.top = (zoomImage.offsetTop - newPosY) + "px"; } function initialize() { var windowWidth = window.innerWidth; var windowHeight = window.innerHeight; zoomContainer.style.width = windowWidth + 'px'; zoomContainer.style.height = windowHeight + 'px'; updateZoomedImage(); document.getElementById('zoomInButton').addEventListener('click', zoomIn); document.getElementById('zoomOutButton').addEventListener('click', zoomOut); } initialize(); window.addEventListener('resize', function() { initialize(); }); }); </script> </body> </html>   Result: Edit fiddle - JSFiddle - Code Playground Close Start with a boilerplate: jQuery Vue React React + JSX Preact TypeScript CoffeeScript SCSS CSS Grid Bootstrap PostCSS Show boilerplate bar less often? Links: ?? Roadmap (vote for features) ? Bug tracker ? Docs ? Service status Support JSFiddle and g https://jsfiddle.net/xxxvvvxxx/ygwqxcpm/   Ref. How to drag an element using javascript While building out a new image generator, I needed a way to drag and move HTML elements inside of another element. Take a look at what I was building below: This is actually the new Post Image Genera... https://devdojo.com/tnylea/how-to-drag-an-element-using-javascript
John Doe · June 2, 2023, 1:22 a.m.
Sample code: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <script src='https://code.jquery.com/jquery-1.9.1.js'></script> <style> * { box-sizing: border-box; margin: 0px; } .scene { width: 100%; height: 100vh; perspective: 1000px; } .cube { width: 100%; height: 100vh; position: relative; transform-style: preserve-3d; transform: translateZ(-50vh); transition: transform 1s; } .cube.show-front { transform: translateZ(-50vh) rotateY( 0deg); } .cube.show-bottom { transform: translateZ(-50vh) rotateX( 90deg); } .cube__face { position: absolute; width: 100%; height: 100vh; font-size: 40px; font-weight: bold; color: white; text-align: center; } .cube__face--front { background: hsla( 0, 100%, 50%, 0.7); transform: rotateY( 0deg) translateZ(50vh); } .cube__face--bottom { background: hsla(300, 100%, 50%, 0.7); transform: rotateX(-90deg) translateZ(50vh); } #ajax-loading-screen { background-color: transparent; width: 100%; height: 100%; position: fixed; top: 0; left: 0; display: block; z-index: 1000000000; } #ajax-loading-screen .mask-top { top: 0; left: 0; height: 50%; width: 100%; } #ajax-loading-screen .mask-right { top: 0; right: 0; height: 100%; width: 50%; } #ajax-loading-screen .mask-bottom { bottom: 0; right: 0; height: 50%; width: 100%; } #ajax-loading-screen .mask-left { top: 0; left: 0; height: 100%; width: 50%; } #ajax-loading-screen[data-effect="center_mask_reveal"] span { position: absolute; background: #fff; z-index: 100; -webkit-transition: 0.8s cubic-bezier(0.12,0.75,0.4,1); transition: 0.8s cubic-bezier(0.12,0.75,0.4,1); } #ajax-loading-screen.loaded .mask-top { -webkit-transform: translateY(-100%) translateZ(0); -ms-transform: translateY(-100%) translateZ(0); transform: translateY(-100%) translateZ(0); } #ajax-loading-screen.loaded .mask-right { -webkit-transform: translateX(100%) translateZ(0); -ms-transform: translateX(100%) translateZ(0); transform: translateX(100%) translateZ(0); } #ajax-loading-screen.loaded .mask-bottom { -webkit-transform: translateY(100%) translateZ(0); -ms-transform: translateY(100%) translateZ(0); transform: translateY(100%) translateZ(0); } #ajax-loading-screen.loaded .mask-left { -webkit-transform: translateX(-100%) translateZ(0); -ms-transform: translateX(-100%) translateZ(0); transform: translateX(-100%) translateZ(0); } </style> </head> <body> <div id="ajax-loading-screen" data-effect="center_mask_reveal"> <span class="mask-top"></span> <span class="mask-right"></span> <span class="mask-bottom"></span> <span class="mask-left"></span> </div> <div class="scene"> <div class="cube"> <div class="cube__face cube__face--front">ORIEL</div> <div class="cube__face cube__face--bottom">INDIFFERENCE</div> </div> </div> <script> var currentClass = ''; var cube = document.querySelector('.cube'); var showClass = ''; window.addEventListener('wheel', function(event) { if ( currentClass ) { cube.classList.remove( currentClass ); } if (event.deltaY < 0) { showClass = 'show-front'; } else if (event.deltaY > 0) { showClass = 'show-bottom'; } cube.classList.add( showClass ); currentClass = showClass; }); $(function() { $("#ajax-loading-screen").addClass("loaded"); setTimeout(function() { $("#ajax-loading-screen").hide(); }, 800); }); </script> </body> </html>   Result: Edit fiddle - JSFiddle - Code Playground Close Start with a boilerplate: jQuery Vue React React + JSX Preact TypeScript CoffeeScript SCSS CSS Grid Bootstrap PostCSS Show boilerplate bar less often? Links: ?? Roadmap (vote for features) ? Bug tracker ? Docs ? Service status Support JSFiddle and g https://jsfiddle.net/xxxvvvxxx/j4619srL/   Ref. https://codepen.io/desandro/pen/KRWjzm
John Doe · May 21, 2023, 10:37 p.m.
ECMAScript 사양에 따르면 Boolean 형식으로 출력했을 때 true 또는 false를 반환하는 기준을 다음과 같이 정의한다.     특정객체가 undefined / null 이면 false를 반환 object면 true를 반환 이런식이다. document.all 의 경우 console.log(typeof document.all); 이렇게 type을 확인해보면 undefined가 찍힌다. 따라서 document.all 은 false 다. ​ 그런데 단순히 아래코드의 결과를 보면 console.log(document.all); HTMLAllCollection 즉 object가 나오는데 왜 false가 될까? ​ 답은 아래에 있다. Document: all property - Web APIs | MDN The Document interface's read-only all property returns an HTMLAllCollection rooted at the document node. In other words, it returns all of the document's elements, accessible by order (like an array) and by ID (like a regular object). https://developer.mozilla.org/en-US/docs/Web/API/Document/all   이곳에 보면 document.all is the only falsy object accessible to JavaScript, because it has the [[IsHTMLDDA]] internal slot. 이런 문구가 있는데, document.all 은 JavaScript에서 액세스할 수 있는 유일한 false 객체라고 한다.   일단 document.all 은 과거 브라우저(ie 등)에서 쓰였던 웹표준에 어긋나는 코딩방식이다. ECMAScript edition 5 를 제창할 당시 요구사항들을 보면 * all 특성은 모든 html 요소와 일치하는 문서 노드에 뿌리를 둔 HTMLAllCollection을 반환해야 한다. - "all" 에 대해 반환된 개체에는 몇 가지 비정상적인 동작이 있다. * 사용자 에이전트(브라우저)는 all 객체를 JavaScript의 boolean 연산을 했을 때 false 값으로 변환하는 것처럼 작동해야 한다. * 사용자 에이전트는 JavaScript에서 == 및 != 연산자를 사용했을 때 all 객체가 마치 정의되지 않은 값과 동일한 것처럼 작동해야 한다. * 사용자 에이전트는 JavaScript의 typeof 연산자가 all 객체에 적용될 때에 문자열 'undefined'를 반환하도록 작동해야 한다. ​ 이러한 요구 사항들은 작성 당시(ECMAScript 버전 5) 현재 JavaScript 사양을 고의적으로 위반한 것이다. JavaScript 사양에는 ToBoolean() 연산자가 모든 객체를 참 값으로 변환해야 하며 특정 연산자의 목적을 위해 정의되지 않은 것처럼 작동하는 객체에 대한 조항은 없다. 이러한 위반은 레거시 콘텐츠의 두 클래스와의 호환성에 대한 요구에 의해 발생했다. 1. 레거시 사용자 에이전트를 감지하는 방법으로 document.all을 사용하고 2. 다른 하나는 특정 요소의 존재 여부를 먼저 테스트하지 않고. 해당 레거시 사용자 에이전트만 지원하고 document.all 객체를 사용하는 경우이다. ​ 예제코드를 보면 if (document.all) { // 과거 ie같은 브라우저에서 사용 } else if (document.getElementById) { // 최신 브라우저에서 사용 } 기본적으로 오랫동안 document.all은 이러한 방식으로 오래된 브라우저를 감지하는 데 사용되었다. 하지만 document.all 을 먼저 검사하기 때문에 두 속성을 모두 제공하는 최신 브라우저는 여전히 document.all 경로안에 있게 된다. 최신 브라우저에서는 물론 document.getElementById를 사용하는 것을 선호하지만 대부분의 브라우저에는 여전히 이전 버전과의 호환성을 위해 document.all이 있기 때문에 document.all이 true이면 else 문은 실행되지 않게 된다. 그래서 코드를 아래처럼 바꾸어야 한다. if (document.getElementById) { // "최신" 브라우저용 `document.getElementById`를 사용하는 코드 } else if (document.all) { // 과거 ie같은 브라우저용 `document.all`을 사용하는 코드 } 하지만 많은 기존 코드는 아직 그 반대다. ​ 이 문제에 대한 가장 간단한 수정방법은 document.all을 여전히 쓸 수 있는 최신 브라우저에서 단순히 document.all을 "false" 로 만드는 것이다. ​ 요약하면 1. 최신 브라우저에서도 document.all 을 이용하여 html 요소객체에 접근이 가능하다. 2. 하지만 위와 같은 코드로 기존버전/최신버전 브라우저를 구분하는 데에는 한계가 있을수 있고 일일이 수정을 해주어야 한다. 3. 따라서 if (document.all) 으로 검사했을 때에는 단순히 document.all 을 false로 반환함과 동시에, document.all 자체를 요소객체에 접근하는 목적으로도 사용할 수 있도록 object (객체) 로 만들었다.   Ref.​ Why is document.all falsy? document.all is a non-primitive object in the DOM that is falsy. For example, this code doesn't do anything: if (document.all) { alert("hello"); } Can someone explain why this is? https://stackoverflow.com/questions/10350142/why-is-document-all-falsy
John Doe · May 4, 2023, 9:32 p.m.
html javascript
  • 1 (current)