Dev Blog

스크립트 & 소스코드 공유

실무에서 유용하게 쓰는 스크립트와 코드 조각을 블로그 게시판으로 저장하고 공유합니다.

14건의 글

jQuery로 스크롤에 따라 이미지 지연 로딩(레이지로드) 구현하기

이미지가 많아 페이지 로딩이 느려질 때, 스크롤을 내리면 화면에 들어오는 이미지만 순서대로 표시되도록 하는 jQuery 레이지로드 예제다. 이미지의 original 속성에 실제 경로를 저장해 두고 scroll 이벤트에서 화면 진입 여부를 판단해 src를 교체한 뒤 fadeIn으로 표시한다. CSS와 HTML 예제도 함께 제공한다.

根据滚动条下拉而延迟加载显示图片特效,通过jquery来实现这个图片延迟加载显示特效,当用户下拉滚动条时才加载图片。

<script src="http://jqueryjs.googlecode.com/files/jquery-1.3.2-vsdoc2.js" type="text/javascript" language="javascript"></script>
<script type="text/javascript">
$(function(){
var $winH = $(window).height();
var $img = $("#show img");
var $imgH = parseInt($img.height()/2);
var $srcDef = "/data/editor/2103/5637885820110126103051018_CYJbtpaHLA.gif";
runing();
$(window).scroll(function(){
runing();
})
function runing(){
$img.each(function(i){
var $src = $img.eq(i).attr("original");
var $scroTop = $img.eq(i).offset();
if($scroTop.top + $imgH >= $(window).scrollTop() && $(window).scrollTop() + $winH >= $scroTop.top + $imgH)
{
if($img.eq(i).attr("src") == $srcDef){
$img.eq(i).hide();
}
$img.eq(i).attr("src",function(){return $src}).fadeIn(300);
}
})
}
})
</script>
*{ border:0;}
a{ display:inline; float:left; margin:55px; background:#ccc; overflow:hidden; font-size:0;}
<div id="show">
<a href="#"><img src="/data/editor/2103/5637885820110126103051018_CYJbtpaHLA.gif" width="160" height="160" original="http://img181.poco.cn/mypoco/myphoto/20110126/10/5637885820110126103208087.jpg" /></a>

<a href="#"><img src="/data/editor/2103/5637885820110126103051018_CYJbtpaHLA.gif" width="160" height="160" original="http://img181.poco.cn/mypoco/myphoto/20110126/10/5637885820110126103303012.jpg" /></a>
</div>

tsparticles로 연결되는 입자(파티클) 배경 만들기

tsparticles 라이브러리를 이용해 입자들이 서로 선으로 연결되며 움직이는 애니메이션 배경을 만드는 방법이다. CDN 스크립트 로드와 배경 컨테이너 HTML, 입자 개수·색상·크기·투명도·연결선, 마우스 호버 repulse와 클릭 push 반응, 배경 색상 등을 설정하는 CSS와 JavaScript 코드를 제공한다.

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/tsparticles.min.js"></script>
<div id="tsparticles"></div>
/* ---- reset ---- */
body {
margin: 0;
font: normal 75% Arial, Helvetica, sans-serif;
}
canvas {
display: block;
vertical-align: bottom;
}
/* ---- tsparticles container ---- */
#tsparticles {
position: absolute;
width: 100%;
height: 100%;
background-color: #0d47a1;
background-image: url("");
background-repeat: no-repeat;
background-size: cover;
background-position: 50% 50%;
}
tsParticles.load("tsparticles", {
fpsLimit: 60,
particles: {
number: {
value: 80,
density: {
enable: true,
value_area: 800
}
},
color: {
value: "#ff0000",
animation: {
enable: true,
speed: 20,
sync: true
}
},
shape: {
type: "circle",
stroke: {
width: 0,
color: "#000000"
},
polygon: {
nb_sides: 5
}
},
opacity: {
value: 0.5,
random: false,
anim: {
enable: false,
speed: 3,
opacity_min: 0.1,
sync: false
}
},
size: {
value: 3,
random: true,
anim: {
enable: false,
speed: 20,
size_min: 0.1,
sync: false
}
},
line_linked: {
enable: true,
distance: 100,
color: "random",
opacity: 0.4,
width: 1,
triangles: {
enable: true,
color: "#ffffff",
opacity: 0.1
}
},
move: {
enable: true,
speed: 6,
direction: "none",
random: false,
straight: false,
out_mode: "out",
attract: {
enable: false,
rotateX: 600,
rotateY: 1200
}
}
},
interactivity: {
detect_on: "canvas",
events: {
onhover: {
enable: true,
mode: "repulse"
},
onclick: {
enable: true,
mode: "push"
},
resize: true
},
modes: {
grab: {
distance: 400,
line_linked: {
opacity: 1
}
},
bubble: {
distance: 400,
size: 40,
duration: 2,
opacity: 0.8,
speed: 3
},
repulse: {
distance: 200
},
push: {
particles_nb: 4
},
remove: {
particles_nb: 2
}
}
},
retina_detect: true,
background: {
color: "#000000",
image: "",
position: "50% 50%",
repeat: "no-repeat",
size: "cover"
}
});

Swiper5/Swiper4 자주 쓰이는 옵션 정리 (roundLengths, parallax, center…

Swiper 슬라이더에서 자주 쓰이지 않지만 필요할 때 유용한 옵션들을 정리한 글이다. roundLengths(너비 반올림), grabCursor(손 모양 커서), parallax(시차), autoHeight(자동 높이), nested(중첩 슬라이더), watchOverflow, preloadImages, centeredSlides, slidesPerGroup, slidesPerColumn, simulateTouch 등 옵션별 설명과 사용 예제 코드를 담고 있다.

不常用但偶尔必要的选项

roundLengths

如果设置为true,则将slide的宽和高取整(四舍五入),以防止某些分辨率的屏幕上文字或边界(border)模糊。

例如当你设定slidesPerView : 3时,则可能出现slide的宽度为341.33px,开启roundLengths后宽度取整数341px。

var mySwiper = new Swiper('.swiper-container',{
roundLengths : true,
})

grabCursor

该选项给Swiper用户提供小小的贴心应用,设置为true时,鼠标覆盖Swiper时指针会变成手掌形状,拖动时指针会变成抓手形状。(根据浏览器形状有所不同)

var mySwiper = new Swiper('.swiper-container',{
grabCursor : true,
})

parallax

设置为true开启Swiper的视差效果,内容在切换时更有层次感。

效果可以应用于container或slide的子元素。当应用于container的子元素(常用于视差背景图),每次切换时视差效果仅有设定值的slide个数-1分之1

<div class="swiper-container">
<div style="background-image:url(/img/Parallax.jpg)" data-swiper-parallax="-23%" data-swiper-parallax-duration="3000"></div>
<div class="swiper-wrapper">
<div class="swiper-slide">
<div class="title" data-swiper-parallax="-100">从右边100px开始进入</div>
<div class="subtitle" data-swiper-parallax="-200">从右边200px开始进入</div>
<div class="text" data-swiper-parallax="-300" data-swiper-parallax-duration="600">
<p>从右边300px开始进入,时间600ms</p>
</div>
<div data-swiper-parallax="0" data-swiper-parallax-opacity="0.5" >透明度变化</div>
<div data-swiper-parallax-scale="0.15" >缩放变化</div>
</div>
</div>
</div>
<script language="javascript">
var mySwiper = new Swiper('.swiper-container',{
parallax : true,
})
</script>

autoHeight

自动高度。设置为true时,wrapper和container会随着当前slide的高度而发生变化。

var swiper = new Swiper('.swiper-container', {
autoHeight: true, //高度随内容变化
});

nested

用于嵌套相同方向的swiper时,当切换到子swiper时停止父swiper的切换。

请将子swiper的nested设置为true。

由于需要在slideChangeEnd时判断作用块,因此快速滑动时这个选项无效。

var mySwiper = new Swiper('#swiper-container1')//父swiper
var mySwiper2 = new Swiper('#swiper-container2',{//子swiper
nested:true,
resistanceRatio: 0,
})

watchOverflow

当没有足够的slide切换时,例如只有1个slide,swiper会失效且隐藏导航等。默认不开启这个功能。

loop模式无效,因为会复制slide。

<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide blue-slide">
slider1</div>
</div>
<div class="swiper-pagination"></div>
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<div class="swiper-scrollbar"></div>
</div>
<script>
var mySwiper = new Swiper('.swiper-container',{
watchOverflow: true,//因为仅有1个slide,swiper无效
navigation: {
nextEl: '.swiper-button-next',//自动隐藏
prevEl: '.swiper-button-prev',//自动隐藏
},
pagination: {
el: '.swiper-pagination',//自动隐藏
},
scrollbar: {
el: '.swiper-scrollbar',//自动隐藏
},
})
</scrip>

preloadImages

默认为true,Swiper会强制加载所有图片后才初始化。

var mySwiper = new Swiper('.swiper-container',{
preloadImages:false,
})

updateOnImagesReady

当所有的内嵌图像(img标签)加载完成后Swiper会重新初始化。使用此选项需要先开启preloadImages: true

var mySwiper = new Swiper('.swiper-container',{
updateOnImagesReady : true,
})

centeredSlides

设定为true时,active slide会居中,而不是默认状态下的居左。

<script language="javascript">
var mySwiper = new Swiper('.swiper-container',{
slidesPerView : 3,
centeredSlides : true,
})
</script>
<style type="text/css">
.swiper-slide-active{
background:#ff6600;
color:#fff;
}
</style>

centeredSlidesBounds

当设置了Active Slide居中后,还可以配合设置此参数,使得第一个和最后一个Slide 始终贴合边缘。

<script language="javascript">
var mySwiper = new Swiper('.swiper-container',{
slidesPerView : 3,
centeredSlides : true,
centeredSlidesBounds: true,
})
</script>
<style type="text/css">
.swiper-slide-active{
background:#ff6600;
color:#fff;
}
</style>

slidesPerGroup

在carousel mode下定义slides的数量多少为一组。

var mySwiper = new Swiper('.swiper-container',{
slidesPerView : 3,
slidesPerGroup : 3,
})

slidesPerColumn

设置多行布局里面每列的slide数量。

当slidesPerColumnFill:column,需要同时设定swiper-container的高度。

slidesPerColumn目前还不兼容loop模式(loop: true)。

在slide数量不足以填满的情况下可能会出现布局不理想(例如4行3列,但是只有10个slide),建议使用空的slide将数量补足。

var mySwiper = new Swiper('.swiper-container',{
slidesPerView: 3,//一行显示3个
slidesPerColumn: 2,//显示2行
})

slidesPerColumnFill

多行布局中以什么形式填充

var mySwiper = new Swiper('.swiper-container',{
slidesPerView: 3,
slidesPerColumn : 2,
slidesPerColumnFill : 'row',
})

slidesOffsetBefore

设定slide与左边框的预设偏移量(单位px)。

var mySwiper = new Swiper('.swiper-container',{
slidesOffsetBefore : 100,
})

slidesOffsetAfter

设定slide与右边框的预设偏移量(单位px)。

var mySwiper = new Swiper('.swiper-container',{
slidesOffsetAfter : 100,
})

simulateTouch

鼠标模拟手机触摸。默认为true,Swiper接受鼠标点击、拖动。

var mySwiper = new Swiper('.swiper-container',{
simulateTouch : false,//禁止鼠标模拟
})

JavaScript로 동영상을 연속 재생하는 배너 (onended 이벤트)

여러 개의 동영상을 순서대로 연속 재생하는 메인 배너 구현 예제다. video 태그의 onended 이벤트로 현재 영상이 끝나면 다음 영상이 자동 재생되도록 하고, 하단 닷(dot) 버튼을 클릭하면 해당 영상으로 이동해 재생한다. 배너 레이아웃 CSS와 jQuery 제어 코드를 포함한 전체 예제를 제공한다.

<style>
#video-box {min-width:1200px; position:relative;}
#video-box .main-banner {display:none; width:100%; height:750px;  overflow:hidden;position:relative; background-color:#000;}
#video-box .main-banner.open{display:block;}
#video-box .main-banner video {position:absolute;width:100%;top:50%; left:50%;transform:translate(-50%,-50%);border:0;}
#video-box .dot-box {position:absolute; width:100%; bottom:0; text-align:center;}
#video-box .dot-box a{display:inline-block; margin:0.5em; width:20px;height:20px; border-radius:50%; background-color:#06F;text-indent:-9999px;}
#video-box .dot-box a.open{background-color:yellowgreen;}
@media screen and (max-width:1400px) { #video-box .main-banner {height:550px;} }
</style>
<div id="video-box">
<div class="main-banner open">
<video autoplay muted>
<source src="https://www.bodyfriend.co.kr/video/1.mp4" type="video/mp4">
</video>
</div>
<div class="main-banner">
<video muted>
<source src="https://www.bodyfriend.co.kr/video/main02.mp4" type="video/mp4">
</video>
</div>
<div class="main-banner">
<video muted>
<source src="https://www.bodyfriend.co.kr/video/main03.mp4" type="video/mp4">
</video>
</div>
<div class="dot-box"></div>
</div>
<script>
$(function() {
var len = $('.main-banner').length
$('.main-banner').each(function(index, element) {
$(this).addClass('v' + index);
var video = $(this).find('video')[0];
video.onended = function(e) {
$('.main-banner').removeClass('open');
$('.main-banner.v'+((index+1) % len)).addClass('open');
$('.main-banner.v'+((index+1) % len)).find('video')[0].play();
$('#video-box a.dot').removeClass('open');
$('#video-box a.dot.v'+((index+1) % len)).addClass('open');
};
$('#video-box .dot-box').append('<a href="#" class="dot v'+index+'" data-idx="'+index+'">'+(index+1)+'번째 비디오</a>');
});
$('#video-box a.dot').click(function(e) {
var idx = $(this).data('idx');
$('.main-banner.open').find('video')[0].pause();
$('.main-banner').removeClass('open');
$('.main-banner.v'+(idx % len)).addClass('open');
$('.main-banner.v'+(idx % len)).find('video')[0].play();
$('#video-box a.dot').removeClass('open');
$('#video-box a.dot.v'+(idx % len)).addClass('open');
});
$('#video-box a.dot.v0').addClass('open');
});
</script>

jQuery로 Ajax 폼 전송하기 (submit 이벤트 가로채기)

jQuery의 submit 이벤트를 가로채 페이지 새로고침 없이 Ajax로 폼을 전송하는 방법이다. event.preventDefault()로 기본 전송을 막고, 서버에 Ajax 사용을 알리는 hidden 필드를 설정한 뒤 폼의 action URL과 serialize() 데이터를 준비한다. 이후 $.get으로 데이터를 보내고 응답받은 HTML 조각을 body에 추가하는 전체 코드를 담고 있다.

//form요소를 찾아서 그의  submit 이벤트를 가로챈다.
  $('form').submit(function (event) {
    //ajax를 사용하여 폼을 전송시키고자 한다(페이지의 새로고침을 막는다)
    event.preventDefault();
    //필요하다면, 유효성 검사 코드를 이부분에 추가하도록 한다.
    // .....
    //이는 ajax 가 사용되었음을 서버측에 알리는 용도이다.
    $('input[name='usingAJAX']', this).val('true');
    //폼에대한 참조를 저장한다.
    var $this = $(this);
    //폼요소의 url을 가로챈다.
    var url = $this.attr('action');
    //전송시킬 폼 데이터를 준비한다.
    var dataToSend = $this.serialize();
    // 서버측처리이후에 실행되어야 할 콜백함수
    var collback = function (dataReseived) {
      //폼을 숨긴다(폼에대한 참조를 $this에 저장해 놓았기에 가능)
      $this.hide();
      //서버로부터 다음과 같은  HTML 조각을 반환 맏을 것이기에 DOM에 이 HTML 조각이 추가된다.
      //&lt;div id='result'&gt;Your favorite food is pizza!
      // Thanks for telling us!&lt;/div&gt;
      $('body').append(dataReseived);
    };
    //수신되는 데이터의 형식(이번예제에서는 html 코드가 수신될 것이라 기대한다)
    var tyhpeOfDataToReceive = 'html';
    //폼을 전송한 후 데이터의 수신을 기다린다.
    $.get(url, dataToSend, collback, tyhpeOfDataToReceive);
  });//.submit() 을 닫는다.


Let's create something great together.

프로젝트 문의 및 견적 요청은 언제든 환영합니다.