본문 바로가기

WEB/내맘대로 코딩

튤팁 tooltip

See the Pen jgaNwE by rainydaymusickr (@rainydaymusickr) on CodePen.

회사에서는 전용코어를 개발해서 사용하는데, 외부 프로젝트에서는 차용해서 사용할 여건이 안되다보니 직접 만들어서 사용하게 된다.

요즘 함수기반클래스와 프로토타입클래스 두 방식으로 만드는 연습을 하는 중인데 개인적으로는 함수기반클래스가 스코프안에 자리잡아 코드관리가 용이한거 같다.

함수기반클래스는 객체생성마다 동일한 내부함수를 만들어주기에 안좋다고는 하지만, 엄청난 데이타를 처리할 정도가 아니라면 굳이 고집한다해도 상관없을듯 하다. 그리고 함수선언 기본형인 function 함수명(){ 으로 시작하는 형태가 내겐 부담이 덜한거 같다.

실전에서는 리터럴기반클래스 방식이 주로 사용되긴 하지만, 어떤 방식을 취하든 개개인의 취향 나름이고 각자 코딩 스타일이 있기 마련 아니겠는가.

<div id="container">
	<div id="header"></div>
	<div id="content">
		<div style="width:100px;height:300px;background-color:#000;color:#fff;">빈박스^^<br>스크롤생길만큼 길어도 무관</div>

		<a href="#" id="pop1" data-item="1" class="ly_link">버튼1</a>
		<a href="#" id="pop2" data-item="2" class="ly_link">버튼2</a>
	</div>
	<div id="footer"></div>
</div>

<div data-item="1" class="ly_container" style="display:none">
	<div class="ly_inner">
		<div class="ly_header">레이어제목</div>
		<div class="ly_content">
			<p class="txt"><a href="" target="_blank">레이어컨텐츠 영역</a></p>
			<p id="a" class="txt" tabindex="0">레이어컨텐츠 영역</p>
			<p class="txt">레이어컨텐츠 영역</p>
			<p class="txt">레이어컨텐츠 영역</p>
			<p class="txt"><a href="" target="_blank">레이어컨텐츠 영역</a></p>
		</div>
		<div class="ly_footer">레이어푸터</div>
		<button type="button" class="ly_close" aria-label="레이어닫기">X</button>
	</div>
</div>

<div data-item="2" class="ly_container" style="display:none">
	<div class="ly_inner">
		<div class="ly_header">레이어제목2</div>
		<div class="ly_content">
			레이어컨텐츠2 영역<br>
			레이어컨텐츠2 영역<br>
			레이어컨텐츠2 영역<br>
			레이어컨텐츠2 영역<br>
			레이어컨텐츠2 영역<br>
		</div>
		<div class="ly_footer">레이어푸터2</div>
		<button type="button" class="ly_close" aria-label="레이어닫기">X</button>
	</div>
</div>
.dimmed{display:none;position:fixed;left:0;top:0;z-index:5;width:100%;height:100%;background-color:#000;opacity:.7;filter:alpha(opacity=70);}
.ly_container{position:absolute;left:50%;z-index:10;width:500px;background-color:#fff;border-radius:10px;}
.ly_header{padding:10px 0;background-color:green;color:#fff;text-align:center;border-radius:10px 10px 0 0;}
.ly_content{padding:10px;background-color:#eee;}
.ly_content .txt{line-height:1.5;}
.ly_footer{padding:10px 0;background-color:pink;color:#000;text-align:center;border-radius:0 0 10px 10px;}
.ly_close{position:absolute;right:10px;top:10px;background-color:#fff;color:purple;border:0;font-size:20px;}
/* ================================================ */
/*    함수기반클래스(단점: 객체생성시 메서드누적   */
/* ================================================ */
$(document).ready(function(){
	var lypop1 = new lyPopup("#pop1");
	var lypop2 = new lyPopup("#pop2");
});

function lyPopup(selector,options){
	//디폴트
	this.default = {

	};
	//옵션확장
	options = $.extend({}, this.default, options);
	//변수설정
	var that = this;
	this.$ly_link = null;
	this.ly_num = 0;
	this.$ly_body = null;
	this.$ly_close = null;
	this.$ly_dimm = null;

	//초기화
	this.init = function(selector){
		this.$ly_link = $(selector);
		this.ly_num = this.$ly_link.attr("data-item");
		this.$ly_body = $(".ly_container[data-item="+ this.ly_num +"]");
		this.$ly_dimm = $(".ly_container[data-item="+ this.ly_num +"]").prev();
		this.$ly_close = $(".ly_container[data-item="+ this.ly_num +"]").find(".ly_close");
	},
	//이벤트 핸들러
	this.evtListener = function(){
		this.$ly_link.on('click', function(){

			that.$ly_body.show().css({
				'margin-left': '-' + (that.$ly_body.innerWidth()/2) +'px',
				'top': ($(window).height() - that.$ly_body.outerHeight())/2 + $(window).scrollTop()
			}).attr('tabIndex','0').focus().before("<div class='dimmed'></div>").prev().fadeIn()
			.on('click', function(){
				that.$ly_body.fadeOut().prev().fadeOut().remove();
				that.$ly_link.attr('tabindex','0').focus();
				return false;
			});

			var ly_arr = [];
			that.$ly_body.find("*").each(function(i, v) {
	         if (v.tagName.match(/^A$|AREA|INPUT|TEXTAREA|SELECT|BUTTON/gim) && parseInt(v.getAttribute("tabIndex")) !== -1) {
	             ly_arr.push(v)
	         }
	         if ((v.getAttribute("tabIndex") !== null) && (parseInt(v.getAttribute("tabIndex")) >= 0) && (v.getAttribute("tabIndex", 2) !== 32768)) {
	             ly_arr.push(v)
	         }
	      });

			var firstItem = ly_arr[0],
			   lastItem = ly_arr[ly_arr.length - 1];

			$(firstItem).on({
			   keydown: function(e) {
			       if (e.target == this) {
			           var key = e.keyCode || e.which;
			           if (key == 9) {
			               if (e.shiftKey) {
			                   $(lastItem).focus();
			                   e.preventDefault();
			               }
			           }
			       }
			   }
			});
			$(lastItem).on({
			   keydown: function(e) {
			       var key = e.keyCode || e.which;
			       if (key == 9) {
			           if (!e.shiftKey) {
			               $(firstItem).focus();
			               e.preventDefault();
			           }
			       }
			   }
			});

			return false;
		});

		this.$ly_close.on('click', function(){
			that.$ly_body.fadeOut().prev().fadeOut().remove();
			that.$ly_link.attr('tabindex','0').focus();
			return false;
		});

	}

	this.init(selector);
	this.evtListener();
}
/* ================================================ */
/*                  일반형(복수제어)                */
/* ================================================ */
$(".ly_link").each(function(){

	$(this).on('click', function(){
		var ly_link = $(this);
		var ly_num = ly_link.attr("data-item");
		var ly_body = $(".ly_container[data-item="+ ly_num +"]");

		ly_body.show().css({
			'margin-left': '-' + (ly_body.innerWidth()/2) +'px',
			'top': ($(window).height() - ly_body.outerHeight())/2 + $(window).scrollTop()
		}).attr('tabIndex','0').focus().before("<div class='dimmed'></div>").prev().fadeIn();

		ly_body.prev().on('click', function(){
			$(this).fadeOut().next().fadeOut();
			ly_link.attr('tabindex','0').focus();
			return false;
		});

		
		var ly_arr = [];
		ly_body.find("*").each(function(i, v) {
         if (v.tagName.match(/^A$|AREA|INPUT|TEXTAREA|SELECT|BUTTON/gim) && parseInt(v.getAttribute("tabIndex")) !== -1) {
             ly_arr.push(v)
         }
         if ((v.getAttribute("tabIndex") !== null) && (parseInt(v.getAttribute("tabIndex")) >= 0) && (v.getAttribute("tabIndex", 2) !== 32768)) {
             ly_arr.push(v)
         }
     });

     var firstItem = ly_arr[0],
         lastItem = ly_arr[ly_arr.length - 1];
     $(firstItem).on({
         keydown: function(e) {
             if (e.target == this) {
                 var key = e.keyCode || e.which;
                 if (key == 9) {
                     if (e.shiftKey) {
                         $(lastItem).focus();
                         e.preventDefault()
                     }
                 }
             }
         }
     });
     $(lastItem).on({
         keydown: function(e) {
             var key = e.keyCode || e.which;
             if (key == 9) {
                 if (!e.shiftKey) {
                     $(firstItem).focus();
                     e.preventDefault()
                 }
             }
         },
         click: function(e) {
         	ly_body.fadeOut().prev().fadeOut();
         	ly_link.attr('tabindex','0').focus();
         	e.preventDefault();
         }
     });
		return false;
	});
});

'WEB > 내맘대로 코딩' 카테고리의 다른 글

틀린그림찾기  (0) 2020.04.15
swiperjs - 앙케이트 설문지  (0) 2020.04.14
전체 체크박스  (0) 2019.08.21
튤팁 tooltip  (0) 2019.08.05
풍선말 (함수형 vs 프로토타입형 코드 비교)  (0) 2019.08.04
스와이퍼+스크롤탭  (0) 2018.08.11