絵文字をjqueryでmixiぽいポップアップで使う。

携帯っぽい絵文字をjqueryからポップアップで使う。


MIXIなどで絵文字を表示する時に、ポップアップするあれです。
jquery使います。
一枚の全体画像を背景に設定し、マウスクリック部分では、透過gifを上に重ねる感じ。
マウスオーバー時には、cssにてバックグラウンドの変更するようにすれば、選択感がでてなおいい。


TypePadで利用している、絵文字画像ファイルは、前回紹介したものを利用。
http://start.typepad.jp/typecast/#emoji-about

●ポップアップ時に絵文字を一つ一つ出していては、読み込みに時間がかかるので、同じページにある一枚の全体画像もダウンロード。emoji_all.gifとして保存。
http://www.typepad.jp/.shared/images/emoticons.gif

●あとは、絵文字の挟む方法がIE,FFで違うのでその差を吸収する部分の作成
http://archiva.jp/web/javascript/getRange_in_textarea.html


●てことで完成したやつ

//絵文字のタグを[e:###]として設定しています
//クリックボタンは、<input type="button" id="emoji_popup_button">
//表示エリアは、<textarea id="body"></textarea>

  $(document).ready(function(){
    emojiMenuClick();
  });

  //絵文字作成
  var emojiIcon = new Object();
  //emoji###.gif => alt_name
  emojiIcon['000'] = '';
  emojiIcon['001'] = '';
  emojiIcon['002'] = '';
  emojiIcon['003'] = '';
  emojiIcon['004'] = '';
  emojiIcon['005'] = '';
  emojiIcon['006'] = '';
  emojiIcon['007'] = '';
  emojiIcon['008'] = '';
  emojiIcon['009'] = '';
  emojiIcon['010'] = '';
  emojiIcon['011'] = '';
  emojiIcon['012'] = '';
  emojiIcon['013'] = '';
  emojiIcon['014'] = '';
  emojiIcon['015'] = '';
  emojiIcon['016'] = '';
  emojiIcon['017'] = '';

var emojiMenuClick = function(){
  $('#emoji_popup_button').click(function(){
  if($('div[id="emoji_popup"]').is(":visible")){
    //すでに表示されていると削除
    $('div[id="emoji_popup"]').css('display', 'none');
    $('div[id="emoji_popup"]').remove();
    return false;
  }

  //selectionStartを使う為に初期設定
  var bodyElm = document.getElementById('body');
  var pos = getAreaRange(bodyElm);
  //selectionStartを使う初期設定
  var bodyElm = document.getElementById('body');
  var pos = getAreaRange(bodyElm);

  //popup作成
  var popupContainer = $('<div id="popup" />')
    .css('display', 'none')
    .css('width', '400px')
    .css('height', '300px')
    .css('z-index', '99')
    .css('position', 'absolute')
    .css('background','url(/images/emoji/emoji_all.gif) no-repeat #FFFFFF');
  //絵文字を追加
  $.each(emojiIcon, function(i, obj){
    if (i != null){
       $('<a id="emoji_'+i+'"><img src="/images/emoji/blank.gif" alt="'+obj+'" onmouseover="mover(this)" onmouseout="mout(this)"></a>').appendTo(popupContainer);
    }
  });
  popupContainer.appendTo($(this));
  $('div[id="popup"]').show();

  //絵文字マウスオーバー時の設定
  function mout(obj) { $(obj).removeAttr('class'); }
  function mover(obj) { $(obj).attr('class','waku'); }

  //メニューのクリック
  $('div[id="popup"] a[id^="emoji_"]').click(function(){
      emojiCode = $(this).attr('id').replace('emoji_','');
      emojiTag = '[:e'+emojiCode+']';
      
      if(emojiCode != null){
        if(pos.start){
          //文字列の途中に挟む場合
          bodyElm.value = bodyElm.value.substring(0, pos.start) + emojiTag + bodyElm.value.substring(pos.start, bodyElm.value.length);
        }else if(pos.start == 0){
          //文字列の先頭に挟む場合
          $('textarea[id="body"]').val(emojiTag + $('textarea[id="body"]').val());
        }else{
          //文字列の最後に挟む場合
          $('textarea[id="body"]').val($('textarea[id="body"]').val() + emojiTag);
        }
      }
    $('textarea[id="body"]').focus();
    });
    return false;
  });
}

//文字位置取得。ieとffなどの取得差を吸収
var getAreaRange = function(obj) {
  var pos = new Object();
  if (isIE) {
    obj.focus();
    var range = document.selection.createRange();
    var clone = range.duplicate();
    clone.moveToElementText(obj);
    clone.setEndPoint( 'EndToEnd', range);
    pos.start = clone.text.length - range.text.length;
    pos.end = clone.text.length - range.text.length + range.text.length;
  }else if(window.getSelection()) {
    pos.start = obj.selectionStart;
    pos.end = obj.selectionEnd;
  }
  return pos;
}
var isIE = (navigator.appName.toLowerCase().indexOf('internet explorer')+1?1:0);