[jQuery] 17.Wheelmouse


실습: Wheelmouse(세로 스크롤)




마우스 휠 이벤트가 발생했을 때의 처리를 하는 실습을 진행하겠습니다!

먼저, 다음과 같이 jquery.mousewheel.js 파일을 작업 파일에 저장해둡니다!


/*----------- jquery.mousewheel.js-----------------*/



/*!
 * jQuery Mousewheel 3.1.13
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license
 * http://jquery.org/license
 */

(function (factory) {
    if ( typeof define === 'function' && define.amd ) {
        // AMD. Register as an anonymous module.
        define(['jquery'], factory);
    } else if (typeof exports === 'object') {
        // Node/CommonJS style for Browserify
        module.exports = factory;
    } else {
        // Browser globals
        factory(jQuery);
    }
}(function ($) {

    var toFix  = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
        toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
                    ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
        slice  = Array.prototype.slice,
        nullLowestDeltaTimeout, lowestDelta;

    if ( $.event.fixHooks ) {
        for ( var i = toFix.length; i; ) {
            $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
        }
    }

    var special = $.event.special.mousewheel = {
        version: '3.1.12',

        setup: function() {
            if ( this.addEventListener ) {
                for ( var i = toBind.length; i; ) {
                    this.addEventListener( toBind[--i], handler, false );
                }
            } else {
                this.onmousewheel = handler;
            }
            // Store the line height and page height for this particular element
            $.data(this, 'mousewheel-line-height', special.getLineHeight(this));
            $.data(this, 'mousewheel-page-height', special.getPageHeight(this));
        },

        teardown: function() {
            if ( this.removeEventListener ) {
                for ( var i = toBind.length; i; ) {
                    this.removeEventListener( toBind[--i], handler, false );
                }
            } else {
                this.onmousewheel = null;
            }
            // Clean up the data we added to the element
            $.removeData(this, 'mousewheel-line-height');
            $.removeData(this, 'mousewheel-page-height');
        },

        getLineHeight: function(elem) {
            var $elem = $(elem),
                $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
            if (!$parent.length) {
                $parent = $('body');
            }
            return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
        },

        getPageHeight: function(elem) {
            return $(elem).height();
        },

        settings: {
            adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
            normalizeOffset: true  // calls getBoundingClientRect for each event
        }
    };

    $.fn.extend({
        mousewheel: function(fn) {
            return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
        },

        unmousewheel: function(fn) {
            return this.unbind('mousewheel', fn);
        }
    });


    function handler(event) {
        var orgEvent   = event || window.event,
            args       = slice.call(arguments, 1),
            delta      = 0,
            deltaX     = 0,
            deltaY     = 0,
            absDelta   = 0,
            offsetX    = 0,
            offsetY    = 0;
        event = $.event.fix(orgEvent);
        event.type = 'mousewheel';

        // Old school scrollwheel delta
        if ( 'detail'      in orgEvent ) { deltaY = orgEvent.detail * -1;      }
        if ( 'wheelDelta'  in orgEvent ) { deltaY = orgEvent.wheelDelta;       }
        if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY;      }
        if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }

        // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
        if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
            deltaX = deltaY * -1;
            deltaY = 0;
        }

        // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
        delta = deltaY === 0 ? deltaX : deltaY;

        // New school wheel delta (wheel event)
        if ( 'deltaY' in orgEvent ) {
            deltaY = orgEvent.deltaY * -1;
            delta  = deltaY;
        }
        if ( 'deltaX' in orgEvent ) {
            deltaX = orgEvent.deltaX;
            if ( deltaY === 0 ) { delta  = deltaX * -1; }
        }

        // No change actually happened, no reason to go any further
        if ( deltaY === 0 && deltaX === 0 ) { return; }

        // Need to convert lines and pages to pixels if we aren't already in pixels
        // There are three delta modes:
        //   * deltaMode 0 is by pixels, nothing to do
        //   * deltaMode 1 is by lines
        //   * deltaMode 2 is by pages
        if ( orgEvent.deltaMode === 1 ) {
            var lineHeight = $.data(this, 'mousewheel-line-height');
            delta  *= lineHeight;
            deltaY *= lineHeight;
            deltaX *= lineHeight;
        } else if ( orgEvent.deltaMode === 2 ) {
            var pageHeight = $.data(this, 'mousewheel-page-height');
            delta  *= pageHeight;
            deltaY *= pageHeight;
            deltaX *= pageHeight;
        }

        // Store lowest absolute delta to normalize the delta values
        absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );

        if ( !lowestDelta || absDelta < lowestDelta ) {
            lowestDelta = absDelta;

            // Adjust older deltas if necessary
            if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
                lowestDelta /= 40;
            }
        }

        // Adjust older deltas if necessary
        if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
            // Divide all the things by 40!
            delta  /= 40;
            deltaX /= 40;
            deltaY /= 40;
        }

        // Get a whole, normalized value for the deltas
        delta  = Math[ delta  >= 1 ? 'floor' : 'ceil' ](delta  / lowestDelta);
        deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
        deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);

        // Normalise offsetX and offsetY properties
        if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
            var boundingRect = this.getBoundingClientRect();
            offsetX = event.clientX - boundingRect.left;
            offsetY = event.clientY - boundingRect.top;
        }

        // Add information to the event object
        event.deltaX = deltaX;
        event.deltaY = deltaY;
        event.deltaFactor = lowestDelta;
        event.offsetX = offsetX;
        event.offsetY = offsetY;
        // Go ahead and set deltaMode to 0 since we converted to pixels
        // Although this is a little odd since we overwrite the deltaX/Y
        // properties with normalized deltas.
        event.deltaMode = 0;

        // Add event and delta to the front of the arguments
        args.unshift(event, delta, deltaX, deltaY);

        // Clearout lowestDelta after sometime to better
        // handle multiple device types that give different
        // a different lowestDelta
        // Ex: trackpad = 3 and mouse wheel = 120
        if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
        nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);

        return ($.event.dispatch || $.event.handle).apply(this, args);
    }

    function nullLowestDelta() {
        lowestDelta = null;
    }

    function shouldAdjustOldDeltas(orgEvent, absDelta) {
        // If this is an older event and the delta is divisable by 120,
        // then we are assuming that the browser is treating this as an
        // older mouse wheel event and that we should divide the deltas
        // by 40 to try and get a more usable deltaFactor.
        // Side note, this actually impacts the reported scroll distance
        // in older browsers and can cause scrolling to be slower than native.
        // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
        return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
    }

}));




/*----------- Wheelmouse.css -----------------*/

html,body{
	height:100%;
}
*{
	margin:0;
	padding:0;
	box-sizing:border-box;
}
.nav{
	width:200px;
	position:fixed;
	margin-top: -120px;
	top: 50%;
    left: 0;
	z-index:999;
	font-size: 18px;
	font-family: 'Righteous', cursive;
}
.nav li a{
	display:block;
	height:70px;
	padding-top:10px;
	text-align: right;
	text-decoration:none;
	color:#fff;
	border-top:1px solid #fff;
	transition: .5s;
}

.nav li:nth-child(1):hover a{
	color:#3c99e6;
	border-top:1px solid #3c99e6;
}
.nav li:nth-child(2):hover a{
	color:#c9193e;
	border-top:1px solid #c9193e;
}
.nav li:nth-child(3):hover a{
	color:#fed325;
	border-top:1px solid #fed325;
}
.nav li:nth-child(4):hover a{
	color:#58e9f0;
	border-top:1px solid #58e9f0;
}
.nav li:nth-child(1).on a{
	font-size:24px;
	color:#3c99e6;
	border-top:1px solid #3c99e6;
}
.nav li:nth-child(2).on a{
	font-size:24px;
	color:#c9193e;
	border-top:1px solid #c9193e;
}
.nav li:nth-child(3).on a{
	font-size:24px;
	color:#fed325;
	border-top:1px solid #fed325;
}
.nav li:nth-child(4).on a{
	font-size:24px;
	color:#58e9f0;
	border-top:1px solid #58e9f0;
}
section{
	position:relative;
	height:100%;
	background-position:center;
	background-size:cover;
	background-repeat:no-repeat;
}
#sec1{
	background-image: url(bg1.jpg);
}
#sec2{
	background-image: url(bg2.jpg);
}
#sec3{
	background-image: url(bg3.jpg);
}
#sec4{
	background-image: url(bg4.jpg);
}
article{
	width:400px;
	position:absolute;
	left:20%;
	top:30%;
}
article h3{
	font-size: 30px;
	padding-bottom:5px;
	margin-bottom: 20px;
	font-family: 'Righteous', cursive;
}
#sec1 h3{
	color:#3c99e6;
	border-bottom:1px solid #3c99e6;
}
#sec2 h3{
	color:#c9193e;
	border-bottom:1px solid #c9193e;
}
#sec3 h3{
	color:#fed325;
	border-bottom:1px solid #fed325;
}
#sec4 h3{
	color:#58e9f0;
	border-bottom:1px solid #58e9f0;
}
article p{
	color:#fff;
}




/*----------- Wheelmouse.js -----------------*/

$(function(){
	$('.nav li').click(function(e){
    	e.preventDafault;
		$('.nav li').removeClass('on');
		$(this).addClass('on');
		
		var href=$(this).attr('id'); //id 값 가져옴
		
		//가져온 id의 위치를 스크롤 탑으로 변경(stop은 똑같은 것 클릭 계속해도 한번만 실행되게함)
		$('html,body').stop().animate({scrollTop:$(href).offset().top},500,'easeOutBounce')
	})
	$(window).scroll(function(){
		var winh=$(window).height();//window 높이
		var scrT=$(window).scrollTop(); //스크롤 높이
		//console.log(winh) 
		//console.log(scrT)
		for(var i=0;i<5;i++){
			if(scrT>=winh*i && scrT<winh*(i+1)){
				$('.nav li').removeClass('on');
				$('.nav li').eq(i).addClass('on');
			}
		}
		
	})
	$('section').mousewheel(function(event,delta){
		if(delta>0){ //delta가 0보다 크면 마우스 휠을 위로 올리고 있는것임
			var prev=$(this).prev('section').offset().top //이전 섹션의 top
			//easeOutBounce는 easing 효과
			$('html,body').stop().animate({scrollTop:prev},500,'easeOutBounce')
		}else if(delta<0){ //delta가 0보다 작으면 마우스 휠을 아래로 내리고 있는것임
			var next=$(this).next('section').offset().top //다음 섹션의 top
			$('html,body').stop().animate({scrollTop:next},500,'easeOutBounce')
		}
	})
})




<!-------------------Wheelmouse.html------------------->

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Wheelmouse</title>
	<link href="https://fonts.googleapis.com/css?family=Righteous" rel="stylesheet">
	<link rel="stylesheet" href="Wheelmouse.css">
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
	<script src="Wheelmouse.js"></script>
	
	<!-- jquery.mousewheel.js 추가-->
	<script src="jquery.mousewheel.js"></script> 
	
	<!-- easing 효과를 위한 script -->
	<script src="http://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
	<div class="nav">
		<ul>
			<li class="on" id="#sec1"><a href="#">Mini Copper</a></li>
			<li id="#sec2"><a href="#">Tesla</a></li>
			<li id="#sec3"><a href="#">Lamborghini</a></li>
			<li id="#sec4"><a href="#">Porsche</a></li>
		</ul>
	</div>
	<section id="sec1">
		<article>
			<h3>Mini Copper</h3>
			<p>미니는 독일의 자동차 제조사인 BMW의 전륜구동, 상시 4륜구동 해치백형 쿠페를 말한다. 영국의 자동차 제조사 브리티쉬 모터의 자동차 브랜드인 미니를 BMW가 인수한 후 새롭게 설계하여 출시했다. 2001년 4월부터 영국 옥스퍼드셔 주 옥스퍼드 공장에서 생산하고 있으며, 2세대부터 모델 라인업이 증가했다.</p>
		</article>
	</section>
	<section id="sec2">
		<article>
			<h3>Tesla</h3>
			<p>테슬라 주식회사는 미국의 전기자동차 회사이다. 2003년, 마틴 에버하드와 마크 타페닝가 창업했다. 2004년 페이팔의 최고경영자이던 일론 머스크가 투자자로 참여했다. 회사 이름은 물리학자이자 전기공학자인 니콜라 테슬라의 이름을 따서 지었다. 2010년 6월 나스닥에 상장되었다</p>
		</article>
	</section>
	<section id="sec3">
		<article>
			<h3>Lamborghini</h3>
			<p>회사의 철칙은 페라리보다 빠른 차를 만들자이다. 페라리가 GT 계열 스포츠카[2]를 추구한다면 람보르기니는 말그대로 타협이라곤 일절없는 퓨어 스포츠카를 지향한다. 아이러니한건 창업주 페루초 람보르기니는 튼튼하고 편안한 GT카를 좋아했다는 것. 페라리의 잦은 고장에 질려서 직접 차를 만들 정도였으니까..</p>
		</article>
	</section>
	<section id="sec4">
		<article>
			<h3>Porsche</h3>
			<p>주식회사 포르쉐는 독일의 고급 스포츠카 전문 제조 기업이다. 포르쉐 자동차 제조사인 포르쉐 AG와 폭스바겐 AG가 대주주이다. 독일 바덴뷔르템베르크 주 슈투트가르트에 본사가 있다. 1931년 오스트리아-헝가리 제국의 기술자였던 공학박사 페르디난트 포르셰에 의해 설립되었다. 주로 고급 스포츠카를 만들며, SUV와 고급 세단 시장에도 진출했다</p>
		</article>
	</section>
</body>
</html>




실행결과





실습: Wheelmouse(가로 스크롤)




/*----------- Wheelmouse2.css -----------------*/

html,body{
	height:100%;
}
*{
	margin:0;
	padding:0;
	box-sizing:border-box;
}
.nav{
	width:200px;
	position:fixed;
	margin-top: -120px;
	top: 50%;
    left: 0;
	z-index:999;
	font-size: 18px;
	font-family: 'Righteous', cursive;
}
.nav li a{
	display:block;
	height:70px;
	padding-top:10px;
	text-align: right;
	text-decoration:none;
	color:#fff;
	border-top:1px solid #fff;
	transition: .5s;
}

.nav li:nth-child(1):hover a{
	color:#3c99e6;
	border-top:1px solid #3c99e6;
}
.nav li:nth-child(2):hover a{
	color:#c9193e;
	border-top:1px solid #c9193e;
}
.nav li:nth-child(3):hover a{
	color:#fed325;
	border-top:1px solid #fed325;
}
.nav li:nth-child(4):hover a{
	color:#58e9f0;
	border-top:1px solid #58e9f0;
}
.nav li:nth-child(1).on a{
	font-size:24px;
	color:#3c99e6;
	border-top:1px solid #3c99e6;
}
.nav li:nth-child(2).on a{
	font-size:24px;
	color:#c9193e;
	border-top:1px solid #c9193e;
}
.nav li:nth-child(3).on a{
	font-size:24px;
	color:#fed325;
	border-top:1px solid #fed325;
}
.nav li:nth-child(4).on a{
	font-size:24px;
	color:#58e9f0;
	border-top:1px solid #58e9f0;
}
.wrap{
	width:400%;
	height:100%;
}
section{
	position:relative;
	width:25%;
	height:100%;
	background-position:center;
	background-size:cover;
	background-repeat:no-repeat;
	float:left;
}
#sec1{
	background-image: url(bg1.jpg);
}
#sec2{
	background-image: url(bg2.jpg);
}
#sec3{
	background-image: url(bg3.jpg);
}
#sec4{
	background-image: url(bg4.jpg);
}
article{
	width:400px;
	position:absolute;
	left:20%;
	top:30%;
}
article h3{
	font-size: 30px;
	padding-bottom:5px;
	margin-bottom: 20px;
	font-family: 'Righteous', cursive;
}
#sec1 h3{
	color:#3c99e6;
	border-bottom:1px solid #3c99e6;
}
#sec2 h3{
	color:#c9193e;
	border-bottom:1px solid #c9193e;
}
#sec3 h3{
	color:#fed325;
	border-bottom:1px solid #fed325;
}
#sec4 h3{
	color:#58e9f0;
	border-bottom:1px solid #58e9f0;
}
article p{
	color:#fff;
}




/*----------- Wheelmouse2.js -----------------*/

$(function(){
	$('.nav li').click(function(e){
    	e.preventDafault;
		$('.nav li').removeClass('on');
		$(this).addClass('on');
		
		var href=$(this).attr('id'); //id 값 가져옴
		
		//가져온 id의 위치를 스크롤 left 값으로 변경(stop은 똑같은 것 클릭 계속해도 한번만 실행되게함)
		$('html,body').stop().animate({scrollLeft:$(href).offset().left},500,'easeOutBounce')
	})
	
	$(window).scroll(function(){
		
		var winw=$(window).width();//window 가로
		var scrL=$(window).scrollLeft(); //스크롤 가로
		for(var i=0;i<5;i++){
			if(scrL>=winw*i && scrL<winw*(i+1)){
				$('.nav li').removeClass('on');
				$('.nav li').eq(i).addClass('on');
			}
		}
		
	})
	$('section').mousewheel(function(event,delta){
		if(delta>0){ //delta가 0보다 크면 마우스 휠을 위로 올리고 있는것임
			var next=$(this).next('section').offset().left //다음 섹션의 left
			//easeOutBounce는 easing 효과
			$('html,body').stop().animate({scrollLeft:next},500,'easeOutBounce')
			
			
		}else if(delta<0){ //delta가 0보다 작으면 마우스 휠을 위로 올리고 있는것임
			var prev=$(this).prev('section').offset().left //이전 섹션의 left
			$('html,body').stop().animate({scrollLeft:prev},500,'easeOutBounce')
		}
	})
})




<!-------------------Wheelmouse2.html------------------->

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Wheelmouse</title>
	<link href="https://fonts.googleapis.com/css?family=Righteous" rel="stylesheet">
	<link rel="stylesheet" href="Wheelmouse2.css">
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
	<script src="Wheelmouse2.js"></script>
	<!-- jquery.mousewheel.js 추가-->
	<script src="jquery.mousewheel.js"></script> 
	
	<!-- easing 효과를 위한 script -->
	<script src="http://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
	<div class="nav">
		<ul>
			<li class="on" id="#sec1"><a href="#">Mini Copper</a></li>
			<li id="#sec2"><a href="#">Tesla</a></li>
			<li id="#sec3"><a href="#">Lamborghini</a></li>
			<li id="#sec4"><a href="#">Porsche</a></li>
		</ul>
	</div>
	<div class="wrap">
		<section id="sec1">
			<article>
				<h3>Mini Copper</h3>
				<p>미니는 독일의 자동차 제조사인 BMW의 전륜구동, 상시 4륜구동 해치백형 쿠페를 말한다. 영국의 자동차 제조사 브리티쉬 모터의 자동차 브랜드인 미니를 BMW가 인수한 후 새롭게 설계하여 출시했다. 2001년 4월부터 영국 옥스퍼드셔 주 옥스퍼드 공장에서 생산하고 있으며, 2세대부터 모델 라인업이 증가했다.</p>
			</article>
		</section>
		<section id="sec2">
			<article>
				<h3>Tesla</h3>
				<p>테슬라 주식회사는 미국의 전기자동차 회사이다. 2003년, 마틴 에버하드와 마크 타페닝가 창업했다. 2004년 페이팔의 최고경영자이던 일론 머스크가 투자자로 참여했다. 회사 이름은 물리학자이자 전기공학자인 니콜라 테슬라의 이름을 따서 지었다. 2010년 6월 나스닥에 상장되었다</p>
			</article>
		</section>
		<section id="sec3">
			<article>
				<h3>Lamborghini</h3>
				<p>회사의 철칙은 페라리보다 빠른 차를 만들자이다. 페라리가 GT 계열 스포츠카[2]를 추구한다면 람보르기니는 말그대로 타협이라곤 일절없는 퓨어 스포츠카를 지향한다. 아이러니한건 창업주 페루초 람보르기니는 튼튼하고 편안한 GT카를 좋아했다는 것. 페라리의 잦은 고장에 질려서 직접 차를 만들 정도였으니까..</p>
			</article>
		</section>
		<section id="sec4">
			<article>
				<h3>Porsche</h3>
				<p>주식회사 포르쉐는 독일의 고급 스포츠카 전문 제조 기업이다. 포르쉐 자동차 제조사인 포르쉐 AG와 폭스바겐 AG가 대주주이다. 독일 바덴뷔르템베르크 주 슈투트가르트에 본사가 있다. 1931년 오스트리아-헝가리 제국의 기술자였던 공학박사 페르디난트 포르셰에 의해 설립되었다. 주로 고급 스포츠카를 만들며, SUV와 고급 세단 시장에도 진출했다</p>
			</article>
		</section>
	</div>
</body>
</html>




실행결과