如何在web端使用emoji进行输入

5 篇文章 0 订阅
2 篇文章 0 订阅

思路

  • 渲染好emoji列表,为每个emoji图标绑定点击事件。
  • emoji是通过unicode16进行展示的,需要将其插入textarea或者inputinnerhtml中才能展示出来。再将其赋值给value,这样value就包含了所有的输入内容。
  • 在点击插入emoji时,需要先获取textareainputinnerhtml光标位置。如果光标位置innerhtml长度是相等的,说明是从后面插入,直接拼接字符串即可。如果不相等说明是从中间插入,需要先分割html再拼接字符串。
  • 注意重新设置光标位置,每一个emoji占用2个字符,光标位置是加2的。设置光标位置的方法是element.setSelectionRange(start,end)。这也是从MDN找到的。

鸣谢

思路来源

效果

在这里插入图片描述
在这里插入图片描述

源码

gitee仓库地址 emoji资源也在里面。
index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>使用emoji</title>
    <style>
      html,
      body,
      div,
      span,
      applet,
      object,
      iframe,
      h1,
      h2,
      h3,
      h4,
      h5,
      h6,
      p,
      blockquote,
      pre,
      a,
      abbr,
      acronym,
      address,
      big,
      cite,
      code,
      del,
      dfn,
      em,
      img,
      ins,
      kbd,
      q,
      s,
      samp,
      small,
      strike,
      strong,
      sub,
      sup,
      tt,
      var,
      b,
      u,
      i,
      center,
      dl,
      dt,
      dd,
      ol,
      ul,
      li,
      fieldset,
      form,
      label,
      legend,
      table,
      caption,
      tbody,
      tfoot,
      thead,
      tr,
      th,
      td,
      article,
      aside,
      canvas,
      details,
      embed,
      figure,
      figcaption,
      footer,
      header,
      hgroup,
      menu,
      nav,
      output,
      ruby,
      section,
      summary,
      time,
      mark,
      audio,
      video {
        margin: 0;
        padding: 0;
        border: 0;
        font-size: 100%;
        font: inherit;
        vertical-align: baseline;
      }

      .app {
        width: 100%;
        height: 100vh;
        background-color: #f5f5f5;
      }

      .main {
        width: 1080px;
        min-width: 1080px;
        height: 100%;
        margin: 0 auto;
        padding: 16px 24px;
        box-sizing: border-box;
        background-color: #fff;
      }

      .toolbar {
        display: flex;
        justify-content: space-between;
        align-items: center;
        width: 100%;
        box-sizing: border-box;
      }

      .emoji-btn {
        cursor: pointer;
        font-size: 18px;
        color: #909090;
      }

      .primary-btn {
        display: inline-block;
        line-height: 1;
        white-space: nowrap;
        cursor: pointer;
        background-color: #409eff;
        border: 1px solid #409eff;
        color: #fff;
        -webkit-appearance: none;
        text-align: center;
        box-sizing: border-box;
        outline: none;
        margin: 0;
        transition: 0.1s;
        font-weight: 500;
        padding: 12px 20px;
        font-size: 14px;
        border-radius: 4px;
      }

      .primary-btn:active,
      .primary-btn:hover {
        background: #66b1ff;
        border-color: #66b1ff;
        color: #fff;
      }

      .textarea {
        width: 100%;
        height: 80px;
        margin-top: 16px;
      }

      .clearfix {
        width: 100%;
        display: flex;
        flex-wrap: wrap;
      }

      li {
        list-style: none;
        margin: 6px;
      }

      .content {
        margin-top: 24px;
        width: 100%;
        color: #323233;
        font-size: 16px;
        font-weight: bold;
      }
    </style>
    <script src="/lib/jquery-3.6.0.min.js"></script>
    <script src="/lib/emoji-lib/emoji-list-with-image.js"></script>
    <script src="/lib/emoji-lib/punycode.js"></script>
    <script src="/lib/emoji-lib/punycode.min.js"></script>
    <script src="/lib/emoji-lib/emoji.js"></script>
  </head>
  <body>
    <div class="app">
      <div class="main">
        <p>发布动态</p>
        <textarea
          class="textarea"
          maxlength="280"
          value=""
          oninput="handleInput(this)"
        ></textarea>
        <div class="toolbar">
          <span class="emoji-btn">表情</span>
          <button class="primary-btn">发布动态</button>
        </div>
        <div class="emoji">
          <div class="emoji-cont"></div>
        </div>
        <div class="content"></div>
      </div>
    </div>

    <script type="text/javascript" src="./index.js"></script>
  </body>
</html>

index.js

$(function () {
  function initEmoji () {
    $(".emoji-cont").html("");
    renderEmoji();
    // 点击表情
    $(".emoji-icon").each(function (k, v) {
      $(v).click(function () {
        var textarea_cursorPosition = $(".textarea").getCursorPosition()
        var textarea_innerhtmlLength = $(".textarea").html().length
        var code = $(this).attr("unicode16");
        // 光标在最后的情况
        if (textarea_innerhtmlLength === textarea_cursorPosition) {
          // emoji表情的字符串放进innerHtml才展示的了,直接放在value是字符形式
          $(".textarea").html($(".textarea").html() + (parse("&#" + parseInt(code, 16) + ";")))
          // 把innerHtml的内容放进textarea的value
          $(".textarea").val($(".textarea").html())
        } else { // 光标在中间
          var originHtml = $(".textarea").html()
          var newHtml = originHtml.slice(0, textarea_cursorPosition) + parse("&#" + parseInt(code, 16) + ";") + originHtml.slice(textarea_cursorPosition)
          $(".textarea").html(newHtml)
          $(".textarea").val($(".textarea").html())
        }
        $(".textarea").focus()
        // 一个emoji占2个字符所以+2
        $(".textarea")[0].setSelectionRange(textarea_cursorPosition + 2, textarea_cursorPosition + 2)
      });
    });
    $(".emoji-cont").hide();
  }

  initEmoji();

  // 点击展示表情
  function showEmoji () {
    $(".emoji-cont").toggle();
  }

  // 表情列表
  function renderEmoji () {
    var emos = getEmojiList()[0];
    var html = '<ul class="clearfix">';
    for (var j = 0; j < emos.length; j++) {
      var emo = emos[j];
      var data = "data:image/png;base64," + emo[2];
      if (j % 20 == 0) {
        html += '<li class="">';
      } else {
        html += "<li>";
      }
      html +=
        '<img style="display: inline;vertical-align: middle;" src="' +
        data +
        '"  unicode16="' +
        emo[1] +
        '"  class="emoji-icon"  /></li>';
    }
    $(".emoji-cont").append(html);
  }

  // 表情 通过该方法 可以直接把表情在输入框中显示出来。
  function parse (arg) {
    if (typeof ioNull != "undefined") {
      return ioNull.emoji.parse(arg);
    }
    return "";
  }

  // 点击展示表情列表
  $(".emoji-btn").click(() => {
    showEmoji();
  });

  // 获取光标位置方法
  (function ($, undefined) {
    $.fn.getCursorPosition = function () {
      var el = $(this).get(0);
      var pos = 0;
      if ('selectionStart' in el) {
        pos = el.selectionStart;
      } else if ('selection' in document) {
        el.focus();
        var Sel = document.selection.createRange();
        var SelLength = document.selection.createRange().text.length;
        Sel.moveStart('character', -el.value.length);
        pos = Sel.text.length - SelLength;
      }
      return pos;
    }
  })(jQuery);

  // 发布动态
  $(".primary-btn").click(() => {
    $(".emoji-cont").hide();
    $(".content").html($(".textarea").val())
  })
});

// 处理输入框输入
function handleInput (e) {
  $(".textarea").val(e.value)
  $(".textarea").html(e.value)
}

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值