表情输入组件

本文介绍了一种基于input/textarea标签开发的轻量级表情插件,解决冗余与样式问题,重点讲解了获取光标位置、插入内容方法,并提到了隐藏滚动条的技巧。提供示例代码和表情大全网址,适用于简化输入体验。
摘要由CSDN通过智能技术生成

富文本插件因为要满足很多功能,所以比较冗余,大部分功能是没有必要的,样式也难以改成达到设计原型的样式。基于input/textarea标签开发简易版表情插件效果如图所示

示例效果

在这里插入图片描述

原理

需要解决的问题:

  1. 如何获取输入标签光标的位置
  2. 如何输入内容在光标位置的后面
  3. 如果是textarea输入内容过多会出现默认滚动条,如果设置overflow-y: hidden会导致无法滚动

方法:

  1. 通过节点的selectionStart属性获取光标的位置
  2. 通过节点的setRangeText方法输入内容在光标位置的后面
  3. 预先获取浏览器滚动条样式的宽度,利用外层盒子的overflow:hidden隐藏掉textarea的滚动条

表情大全网址

示例代码

<!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>简单表情组件开发测试</title>
</head>
<style>
.test{
  width: 400px;
  height: 500px;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
  background-color: #d6d3d5;
  box-shadow: 0 0 10px 1px #d6d3d5;
}
.chat{
  width: 100%;
  height: 250px;
}
.text-area-function{
  width: 100%;
  height: 50px;
  background-color: #fff;
  position: relative;
}
.emoji-component{
  position: absolute;
  width: 320px;
  height: 160px;
  line-height: 0;
  top: -160px;
  left: 0;
  background-color: #fff;
  display: none;
}
.emoji-item-outter{
  display: inline-block;
  width: 40px;
  height: 40px;
}
.emoji-item{
  width: 36;
  height: 36px;
  line-height: 36px;
  text-align: center;
  border: 1px solid #ffffff;
  font-size: 20px;
  cursor: pointer;
}
.emoji-item:hover{
  background-color: #f2f2f2;
  border: 1px solid #f2f2f2;
  border-radius: 4px;
}
.emoji{
  width: 40px;
  height: 40px;
  display: inline-block;
  margin-top: 5px;
  margin-left: 10px;
  line-height: 40px;
  text-align: center;
  border: 1px solid #dfdddd;
  border-radius: 4px;
  font-size: 25px;
  cursor: pointer;
}
.emoji:hover{
  background-color: #f2f2f2;
}
.text-area-input{
  width: 100%;
  height: 200px;
  overflow: hidden;
}
#send-text-content{
  overflow-y: scroll;
  width: 400px;
  height: 200px;
  resize: none;
  border: none;
  outline: none;
  font-size: 16px;
  color: var(--text-color);
  /* overflow-y: hidden; */
}
textarea::-webkit-input-placeholder {
  color: #dfdddd !important;
}

textarea:-moz-placeholder {
    color: #dfdddd !important;
}

textarea::-moz-placeholder {
    color: #dfdddd !important;

}

textarea:-ms-input-placeholder {
    color: #dfdddd !important;
}
</style>
<body>
  <div class="test">
    <!-- 聊天框 -->
    <div class="chat"></div>
    <!-- 输入框功能,当前示列仅实现表情功能
      其中cancelEmojiComponent()用于隐藏表情组件
    -->
    <div class="text-area-function" onclick="cancelEmojiComponent()" >
      <!-- 显示表情组件按钮 -->
      <div class="emoji">
        😃
      </div>
      <!-- 表情组件 由于数目很多,原生用js添加,vue可以通过v-for即可 -->
      <div class="emoji-component"></div>
    </div>
    <!-- 输入框 -->
    <div class="text-area-input">
      <textarea 
        id="send-text-content"
        placeholder="请输入内容..."
      ></textarea>
    </div>
  </div>
</body>
</html>
<script>
// 由于显示表情组件按钮的外层还有一个click事件,所以要取消冒泡事件
// html通过e.stopPropagation();vue通过修饰符stop即可
document.getElementsByClassName('emoji')[0].onclick = (e)=>{
  e.preventDefault();
  e.stopPropagation()
  // 显隐控制
  let emojiComponent = document.getElementsByClassName('emoji-component')[0];
  emojiComponent.style.display = 'block';
}
// 获取浏览器滚动条宽度
function getBarWidth() {
  var noScroll, scroll, oDiv = document.createElement("DIV");  
  oDiv.style.cssText = "position:absolute; top:-1000px; width:100px; height:100px; overflow:hidden;";  
  noScroll = document.body.appendChild(oDiv).clientWidth;  
  oDiv.style.overflowY = "scroll";  
  scroll = oDiv.clientWidth;  
  document.body.removeChild(oDiv);  
  return noScroll - scroll; 
}
// 取消表情组件显示
function cancelEmojiComponent(e) {
  let emojiComponent = document.getElementsByClassName('emoji-component')[0];
  emojiComponent.style.display = 'none';
}
// 由于textarea要内容够多才有显示条
// 在css中通过overflow-y: scroll;迫使他出现滚动条
// 通过计算textarea的父节点的宽度和浏览器滚动条宽度得到textarea的宽度
function initTextArea(){
  let ele = document.getElementById('send-text-content');
  let parent = ele.parentNode;
  let clientWidth = parent.getBoundingClientRect().width;
  let barWidth = getBarWidth();
  let width = clientWidth + barWidth +'px';
  ele.style.width = width;
}
// 初始化组件,通过js往组件标签加内容
// 采用了文档流碎片一次性将需要操作DOM的操作给完成避免过多的重绘回流
function initEmojiComponent() {
  let g = document.createDocumentFragment();
  emojiList = [
    '😃 ','😄','😉','😆','😅','🤣','😂','🙂',
    '🙃','😘','😚','😜','🤑','🤪','🤫','😒',
    '😬','😈','😪','😷','😟','😨','😰','😡',
    '💀','🙏','💪','👐','👍','✊','✌️','👌'
  ]
  for (let i = 0; i < emojiList.length; i++) {
    let outerdiv = document.createElement('div');
    let innerdiv = document.createElement('div');
    outerdiv.className = 'emoji-item-outter';
    innerdiv.className = 'emoji-item';
    innerdiv.innerHTML = emojiList[i];
    innerdiv.onclick = (e) =>{
      cancelEmojiComponent();
        console.log(e)
        let ele = document.getElementById('send-text-content');
        let cursor = ele.selectionStart;
        // // 获取文本输入框元素节点
        ele.setRangeText(e.srcElement.innerHTML);
        // 表情占据2个字符否则乱码
        ele.selectionStart = cursor + 2;
        console.log(ele.selectionStart);
        ele.focus();
        ele = null;
    }
    outerdiv.append(innerdiv);
    g.append(outerdiv);
  }
  document.getElementsByClassName('emoji-component')[0].append(g);
}
initTextArea();
initEmojiComponent()
</script>
UniApp是一款跨平台的开发框架,可以同时在iOS和Android系统中构建原生应用程序。在UniApp中,我们可以使用表情输入来增加用户之间的交流和表达。具体来说,UniApp可以通过以下几种方式实现表情输入。 首先,UniApp可以利用内置的Emoji表情库来实现表情输入Emoji是一种图形化符号,可以在文本中表示各种表情和情绪。在UniApp中,我们可以使用内置的Emoji表情库,在输入框或对话框中插入表情符号,用户可以通过点击或选择来添加表情到他们的输入中。 其次,UniApp还可以集成第三方表情键盘插件,以提供更丰富的表情输入功能。通过与第三方表情键盘插件的集成,用户可以使用更多种类和风格的表情符号。这些插件通常提供了自定义的表情包,用户可以根据自己的喜好选择和使用。 此外,UniApp还可以通过开发者自定义组件来实现表情输入。开发者可以根据自己的需求和设计,创建表情选择器组件,并将其嵌入到UniApp应用程序中的输入框或对话框中。通过这种方式,UniApp的用户可以根据自己的喜好和需要,自定义表情输入的方式和样式。 总的来说,UniApp可以通过内置的Emoji表情库、第三方表情键盘插件以及开发者自定义组件来实现表情输入。这些方式可以增加应用程序的趣味性和互动性,提升用户之间的沟通和交流体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值