본문 바로가기

WEB/내맘대로 코딩

풍선말 (함수형 vs 프로토타입형 코드 비교)

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

<div class="container">
	<div>
		<!-- 1set -->
		풍선말 <b>사용자정의 클래스명 지정</b>
		<a href="/" data-pos="bottom" title="도움말 설명이 들어가는 영역입니다." id="tooltip_9" class="tooltip">tooltip</a>
		<!-- //1set -->
	</div>
	<div>
		<!-- 2set -->
		풍선말 <b>타이틀이 없는 경우</b>
		<a href="/" data-pos="left" title="" id="tooltip_10" class="tooltip">tooltip</a>
		<!-- //2set -->
	</div>
</div>
/* =여백 맞춤용 */
*{margin:0;padding:0}
.container{padding:150px}
.container >div{margin:20px 0}

/* =Tooltip Area */
.tooltip_wrap{display:inline-block;position:relative}
.tooltip{display:inline-block;padding:2px 5px;border-radius:5px;background-color:#6c5b7b;color:#fff;text-decoration:none}
.tooltip_wrap .txt_inner{display:none;position:absolute;z-index:10;padding:10px;border-radius:10px;background-color:purple;line-height:1.4}
.tooltip_wrap .txt_inner .piece{display:inline-block;position:absolute;width:15px;height:15px;background-color:purple;transform:rotate(-45deg)}
.tooltip_wrap .txt_inner.top .piece{bottom:-7px}
.tooltip_wrap .txt_inner.bottom .piece{top:-7px}
.tooltip_wrap .txt_inner.left .piece{right:-7px}
.tooltip_wrap .txt_inner.right .piece{left:-7px}
.tooltip_wrap .txt_inner strong{display:block;overflow:hidden;width:200px;color:#fff;text-overflow:ellipsis}

/* =사용자지정 스타일 정의*/
.jw_class .tooltip{border-radius:100%;background-color:crimson;color:yellow}
.jw_class .txt_inner{background-color:blue}
.jw_class .txt_inner .piece{background-color:blue}
.jw_class .txt_inner strong{color:skyblue}

/* ============================================================================== */
/*                                    함수형 코드                                 */
/* ============================================================================== */
$(document).ready(function(){

  var tooltip1 = new Tooltip("#tooltip_9",{
    width : 100,
    easing : 'linear'
  });

  var tooltip2 = new Tooltip("#tooltip_10",{
    effect : 'fade',
    speed : 350,
    userClass : 'jw_class'
  });

});

function Tooltip(selector,options){
  this.$link = null;
  this.$tooltipBody = null;
  this.index = 0;
  this.userClass = '';

  this.default = {
    width : 200,
    speed : 500,
    effect : 'normal',
    easing : 'swing',   
    userClass : ''
  };
  options = $.extend({},this.default,options);

  //초기화
  this.init = function(selector){
    this.$link = $(selector);
    this.index  = selector.split("_")[1];
    this.$link.wrap('<div id="tooltip_wrap' + this.index + '" class="tooltip_wrap ' + options.userClass + '"> </div>').parent();
    
    $('<p id="tooltip_body' + this.index + '" class="txt_inner" role="tooltip"> </p>')
      .appendTo( $("#tooltip_wrap" + this.index) ).prev().attr("aria-describedby","tooltip_body" + this.index);

    this.setPosition(this.index);
  }
  //이벤트 핸들러
  this.evtListener = function(){
    var _that = this;
    this.$link.on({
      'mouseenter focusin': function() {
        _that.aniShow(this);
      },
      'mouseleave focusout': function() {
        _that.aniHide(this);
      }
    });
  }
  //위치 세팅
  this.setPosition = function(idx){
    var tooltip_link = $('[aria-describedby=tooltip_body' + this.index + ']'),
      tooltip_body = $('#tooltip_body' + this.index),
      tooltip_title = tooltip_link.attr('title'),
      _direction = (tooltip_link.attr('data-pos')) ? tooltip_link.data('pos') : 'bottom',
      _pos_x = 0,
      _pos_y = 0;

    tooltip_title ? tooltip_body.find('.txt').text(tooltip_title) : tooltip_body.find('.txt').text('적절한 타이틀을 넣어주세요!!');
    switch (_direction) {
      case 'top':
        tooltip_body.addClass('top');
        _pos_x = tooltip_link.position().left;
        _pos_y = tooltip_link.position().top - tooltip_body.innerHeight() - tooltip_body.find('.piece').innerHeight();
      break;
      case 'bottom':
        tooltip_body.addClass('bottom');
        _pos_x = tooltip_link.position().left;
        _pos_y = tooltip_link.position().top + tooltip_link.innerHeight() + tooltip_body.find('.piece').innerHeight();
      break;
      case 'left':
        tooltip_body.addClass('left');
        _pos_x = tooltip_link.position().left - tooltip_body.innerWidth() - tooltip_body.find('.piece').innerWidth();
        _pos_y = tooltip_link.position().top - tooltip_link.innerHeight()/3;
      break;
      case 'right':
        tooltip_body.addClass('right');
        _pos_x = tooltip_link.position().left + tooltip_link.innerWidth() + tooltip_body.find('.piece').innerWidth();
        _pos_y = tooltip_link.position().top - tooltip_link.innerHeight()/3;
      break;
      default:
        _body.addClass('bottom');
        _pos_x = tooltip_link.position().left;
        _pos_y = tooltip_link.position().top + tooltip_link.innerHeight();
      break;
    }
    tooltip_body.css({ 'left': _pos_x, 'top': _pos_y });
  }
  //이펙트 모션(show)
  this.aniShow = function(elem){
    //console.log(elem);
    if (!$(elem).next().is(':animated')) {
      $('.tooltip_wrap .txt_inner').hide();
      //console.log(options.effect);
      switch(options.effect){
        case 'normal':
          $(elem).next().show();
        break;
        case 'fade':
          $(elem).next().fadeIn(options.speed, options.easing);
        break;
        default:
          $(elem).next().show();
        break;
      }
    }
  }
  //이펙트 모션(hide)
  this.aniHide = function(elem){
    //console.log(elem);
    $('.tooltip_wrap .txt_inner').hide();
    $(elem).next().hide();
  }
  //실행
  this.init(selector);
  this.evtListener();
}

/* ============================================================================== */
/*                             프로토타입형 코드                                 */
/* ============================================================================== */
$(document).ready(function(){

  var tooltip1 = new Tooltip("#tooltip_9",{
    width : 100,
    easing : 'linear'
  });

  var tooltip2 = new Tooltip("#tooltip_10",{
    effect : 'fade',
    speed : 1000,
    userClass : 'jw_class'
  });

});

function Tooltip(selector,options){
  this.$link = null;
  this.$tooltipBody = null;
  this.index = 0;
  this.userClass = '';

  this.default = {
    width : 200,
    speed : 500,
    effect : 'normal',
    easing : 'swing',   
    userClass : ''
  };
  this.options = $.extend({},this.default, options);

  //실행
  this.init(selector,options);
  this.evtListener();
}

//초기화
Tooltip.prototype.init = function(selector,options){
  this.$link = $(selector);
  this.index  = selector.split("_")[1];
  this.$link.wrap('<div id="tooltip_wrap' + this.index + '" class="tooltip_wrap ' + this.options.userClass + '"> </div>').parent();
  //console.log(this.options.width);
  $('<p id="tooltip_body' + this.index + '" class="txt_inner" role="tooltip"> </p>')
    .appendTo( $("#tooltip_wrap" + this.index) ).prev().attr("aria-describedby","tooltip_body" + this.index);

  this.setPosition(this.index);
}
//이벤트 핸들러
Tooltip.prototype.evtListener = function(){
  var _that = this;
  this.$link.on({
    'mouseenter focusin': function() {
      //console.log(_that.options.effect);
      _that.aniShow(this,_that.options.effect,_that.options.speed,_that.options.easing);
    },
    'mouseleave focusout': function() {
      _that.aniHide(this);
    }
  });
}
//위치 세팅
Tooltip.prototype.setPosition = function(idx){
  var tooltip_link = $('[aria-describedby=tooltip_body' + this.index + ']'),
    tooltip_body = $('#tooltip_body' + this.index),
    tooltip_title = tooltip_link.attr('title'),
    _direction = (tooltip_link.attr('data-pos')) ? tooltip_link.data('pos') : 'bottom',
    _pos_x = 0,
    _pos_y = 0;

  tooltip_title ? tooltip_body.find('.txt').text(tooltip_title) : tooltip_body.find('.txt').text('적절한 타이틀을 넣어주세요!!');
  switch (_direction) {
    case 'top':
      tooltip_body.addClass('top');
      _pos_x = tooltip_link.position().left;
      _pos_y = tooltip_link.position().top - tooltip_body.innerHeight() - tooltip_body.find('.piece').innerHeight();
    break;
    case 'bottom':
      tooltip_body.addClass('bottom');
      _pos_x = tooltip_link.position().left;
      _pos_y = tooltip_link.position().top + tooltip_link.innerHeight() + tooltip_body.find('.piece').innerHeight();
    break;
    case 'left':
      tooltip_body.addClass('left');
      _pos_x = tooltip_link.position().left - tooltip_body.innerWidth() - tooltip_body.find('.piece').innerWidth();
      _pos_y = tooltip_link.position().top - tooltip_link.innerHeight()/3;
    break;
    case 'right':
      tooltip_body.addClass('right');
      _pos_x = tooltip_link.position().left + tooltip_link.innerWidth() + tooltip_body.find('.piece').innerWidth();
      _pos_y = tooltip_link.position().top - tooltip_link.innerHeight()/3;
    break;
    default:
      _body.addClass('bottom');
      _pos_x = tooltip_link.position().left;
      _pos_y = tooltip_link.position().top + tooltip_link.innerHeight();
    break;
  }
  tooltip_body.css({ 'left': _pos_x, 'top': _pos_y });
}
//이펙트 모션(show)
Tooltip.prototype.aniShow = function(elem,effect,speed,easing){
  //console.log(elem);
  if (!$(elem).next().is(':animated')) {
    $('.tooltip_wrap .txt_inner').hide();
    //console.log(effect);
    switch(effect){
      case 'normal':
        $(elem).next().show();
      break;
      case 'fade':
        $(elem).next().fadeIn(speed, easing);
      break;
      default:
        $(elem).next().show();
      break;
    }
  }
}
//이펙트 모션(hide)
Tooltip.prototype.aniHide = function(elem){
  //console.log(elem);
  $('.tooltip_wrap .txt_inner').hide();
  $(elem).next().hide();
}

'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