div 模拟输入框,支持输入表情

1.html结构

    <div id="app" v-clock @click="emojiClose">
        <div class="editBox" >
            <div class="edit" contenteditable="true" placeholder="发现一个好玩的歌房,快来一起玩吧~"  v-on:input="inputChange($event)" v-on:keydown="inputkeydown($event)" v-on:paste="inputPaste($event)" ></div>
            <div class="editBottom">
                <img class="emojiImg" src="../images/emoji-icon.png" @click.stop="emojiBtn"/>
                <div class="textLen"><span class="curLen">{{curTextLen}}</span>/140</div>
            </div>
            <!--表情框  -->
            <div class="emojiBox" v-show="isEmojiShow">
                <div class="emojiList">
                    <span class="emojiImg" v-for="(value,key) in arrEmojiList" :title="key" @click.stop="selectEmoji($event,value,key)">
                        <img :src="emoji_path+value">
                    </span>
                </div>
            </div> 
        </div>
        <div class="shareBtn" :class="flag?'shareBtnRed':'shareBtnGray'" @click="shareFn">分享</div> 
        <!--分享提示 弹层  -->
        <div class="tipBox" v-show="shareTip.isShow">
            <div class="tipImg" :class="shareTip.type==0?'success':'warn'"></div>
            <span>{{shareTip.text}}</span>
        </div>
    </div>

2.默认分享文案:发现一个好玩的歌房,快来一起玩吧~ , 获取鼠标时,默认文案消失

  

.edit:empty:before{
    content: attr(placeholder);
    color:#999;
}
.edit:focus:before{
    content:none;
}

2.最多输入140个汉字,支持输入表情

  屏蔽回车,粘贴处理,表情处理

        // 屏蔽回车
        inputkeydown(event){
            if (window.event && window.event.keyCode == 13) {
                event.cancelBubble=true;
                event.preventDefault();
                event.stopPropagation();
                // this.shareFn();
            }
        },
        // 获取输入框内容
        inputChange(e) {
            let curTarget=document.getElementsByClassName('edit')[0];
            this.getCursorPosition();
            if(curTarget.innerText.length + curTarget.childElementCount > 140){
                this.shareTipFn(1,"内容不能超过140字");
                // 图片:移除最后一个元素   文字
                if((/<[a-z|/]+>$/).test(curTarget.innerHTML)){
                    curTarget.removeChild(curTarget.lastElementChild);
                }else{
                    let imgArr=curTarget.innerHTML.match(/<img.*?data-id="(.*?)"/?>/ig)||[];
                    let imgLen = imgArr.join('').length-imgArr.length;
                    // curTarget.innerHTML=curTarget.innerHTML.substr(0,140+imgLen);
                    curTarget.innerHTML=curTarget.innerHTML.substr(0,curTarget.innerHTML.length-(curTarget.innerText.length + curTarget.childElementCount-140));
                    
                }
                this.setCursorPosition(curTarget);
                
            }
            
            this.curTextLen=curTarget.innerText.length + curTarget.childElementCount;
            this.content=curTarget.innerHTML;
        },
        // 输入框处理
        inputPaste(e) {
            e.preventDefault();
            var clipboar = e.clipboardData || e.originalEvent.clipboardData;
            if (clipboar) {
                var text = clipboar.getData('Text');
                String.insertAtCaret(e.currentTarget, text.replace(/s/g,''));
                this.inputChange(e);
            }
        },
        //获取当前光标位置
        getCursorPosition () {
            var section = window.getSelection();
            this.sectionObj.anchorNode = section.anchorNode;
            this.sectionObj.anchorOffset =section.anchorOffset;
            
        },
        // 设置光标位置
        setCursorPosition(element){
            var range = document.createRange();
            if(this.sectionObj.anchorNode.nodeType == 1){
                //焦点在图片
                range.setStart(element,Math.min(this.sectionObj.anchorOffset,element.childNodes.length));
            }else{
                //焦点在文本
                let node=this.sectionObj.anchorNode;
                // for(let i=0;i<element.childNodes.length;i++){
                //     if((element.childNodes[i].data&&node.data==element.childNodes[i].data)||i==element.childNodes.length-1){
                //          range.setStart(element.childNodes[i],Math.min(this.sectionObj.anchorOffset,element.childNodes[i].length));
                //          break;
                //     }
                // }
                range.setStart(node,Math.min(this.sectionObj.anchorOffset,node.length));
            }
            range.collapse(true); //设置选中区域为一个点
            var selection = window.getSelection();//获取当前选中区域
            selection.removeAllRanges();//移出所有的选中范围
            selection.addRange(range);//添加新建的范围
         
           
        },
       // 选择表情
        selectEmoji(e,value,key) {
            let curElement=document.getElementsByClassName('edit')[0];
            curElement.focus();
            let str = '<img class="emojiImg" src="' +this.emoji_path+value + '" data-id="' + key + '"/>';
            if(e.target.nodeName == 'IMG') {
                String.insertAtCaret(curElement,str);
                this.inputChange(e);
            }
            this.isEmojiShow=false;
        },
        // 表情按钮 显示 隐藏
        emojiBtn(){
          this.isEmojiShow=!this.isEmojiShow;  
        },

4.分享操作

分享内容:对表情,特殊字符处理

点击分享:防止频繁点击操作,判断有无网

// 分享
shareFn(){
    if(!this.flag) return;
    this.flag=false;
    // 处理表情图片
    this.content=this.content.replace(/<img.*?data-id="(.*?)"/?>/ig, '$1');
    this.content=this.convertHtml(this.content,false);
    var params={
        userID: this.userID,
        toUserID:this.toUserID,
        objectID:this.objectID,
        content:this.content||this.shareDefaultText,
        type: this.type
    }
    params=encodeURIComponent(JSON.stringify(params));
    axios.get('https://music.51vv.com/sod?parameter='+params)
    .then(res=>{
        if(res.data.retCode==1000){
            this.shareTipFn(0,'分享成功!');
        }else{
            this.flag=true;
            this.shareTipFn(1,'分享失败!请稍后重试');
        }
    })
    .catch(error=>{
        console.log(error);
        this.flag=true;
        this.shareTipFn(1,'分享失败!请稍后重试');
    });
},
// 特殊字符转换
convertHtml:function(msg,flag) {
    msg = msg+""; //如果是数字,转为字符串
    if (flag) {
        msg = msg.replace(/&/g,'&amp;').replace(/s/g,'&nbsp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
    } else {
        msg = msg.replace(/&gt;/g,'>').replace(/&lt;/g,'<').replace(/&nbsp;/g,' ').replace(/&amp;/g,'&');
    }
    return msg;
},
原文地址:https://www.cnblogs.com/yuesu/p/9796724.html