【留言板】可编辑输入框操作总结

闲暇之余,用于加深自己对基础的了解,徒手撸了一个留言板:输入框。废话少说,进入正题。简陋的效果如下(下载代码):

一、定义需求

  1. 可输入文本,以及插入表情。
  2. 兼容性:IE与标准浏览器

二、详细设计

根据需求,我们大致可以想到如下问题:

  1. 兼容性的处理
    1. 事件绑定的兼容性
    2. 可编辑输入框的表情插入兼容性
    3. 获取数据的兼容性
  2. 三个模块
    1. 留言板与ui交互的模块
    2. 表情展示模块
    3. 可编辑输入框的操作模块 因此我规划了如下的类结构:

  • LeaveMsg:实现UI与留言板的交互
  • FaceWrap:实现表情殂的管理,以及相应事件的响应,如显示/隐藏,获取表情,初始化表情列表等。
  • SelectionUitls:实现可编辑输入框的操作,如:插入一个表情、获取数据等。 各模块的兼容性在以下细节中进行介绍。

三、代码实现

1. FaceWrap类(表情列表管理类)

var FaceWrap = function(head, cont, opts){
this.$head = head;
this.$cont = cont;
this.data = ['one', 'two', 'thr'];
var self = this;
var toggle = false;
this.onClickHandHandle = function(evt){
if(!toggle){
self.$cont.style.display = 'block';
toggle = true;
}else{
self.$cont.style.display = 'none';
toggle = false;
}
if(opts.onClickHandHandle){
opts.onClickHandHandle(toggle);
}
}
this.onChooseImg = opts. onChooseImg || function(){}
this.generalFaceImg();
this.bind();
}
var facePt = FaceWrap.prototype;
facePt.generalFaceImg = function(){
var fragment = document.createDocumentFragment();
for( var index =0; index < this.data.length;   index){
var data = this.data[index];
var img = document.createElement('img');
img.setAttribute('src', '../img/face/'   data   '.jpg');
img.setAttribute('data-id', data);
img.setAttribute('class','face-img');
fragment.appendChild(img);
}
this.$cont.appendChild(fragment);
}
facePt.bind = function(){  
if(document.attachEvent){
this.$head.attachEvent('onclick',this.onClickHandHandle);
this.$cont.attachEvent('onclick',this.onChooseImg);
}else{       
this.$head.addEventListener('click',this.onClickHandHandle);
this.$cont.addEventListener('click',this.onChooseImg);
}
}
facePt.hide = function(){
this.onClickHandHandle();
}

需要注意的点:

     1. 在初始化表情列表(generalFaceImg)的时候,用到了Fragment(文档碎片)来提高性能;

     2. 在class中设元素的display为none后,用js是获取不到此元素的display值的。

兼容性有以下几个点:

  1. 事件的绑定:attacheEvent和addEventListener。
  2. classList在ie8-不支持的问题,暂时选择的用setAttribute代替
  3. appendChild全都支持,append在chrome中支持,但ie不支持

2. SelectionUitls类(可编辑输入框管理类)

var SelectionUitls = function(dom){
this.dom = dom;
this.cursorIndex;
}
var pt = SelectionUitls.prototype;
pt.insertDomForStandard = function(dom){
var sel = window.getSelection(); //获取选区集合
var range = sel.getRangeAt(0); //获取第一个选择
range.deleteContents(); //删除选区选重的元素
range.insertNode(dom); //插入元素在选区的首位置
range = range.cloneRange(); //克隆一个选区
range.setStartAfter(dom); //设置选区起点光标位置在指定元素的后面
range.collapse(true);//合并起点、终点光标
sel.removeAllRanges();//移除所有选区
sel.addRange(range); //添加一个选区
}
pt.insertDomForIe = function(dom){
this.dom.focus();
var wrap = document.createElement('div');
wrap.appendChild(dom);
document.selection.createRange().pasteHTML(wrap.innerHTML);
}
pt.insertDom = function(dom){
//光标处插入非元素
if(window.getSelection){
this.insertDomForStandard(dom);
}else{
this.insertDomForIe(dom);
}
}
pt.getContent = function(){
//获取数据
var nodes = this.dom.childNodes;
var datas = [];
for(var index = 0; index < nodes.length; index   ){
var node = nodes[index];
if(node.nodeType == 3){
datas.push(node.textContent || node.nodeValue || node.data);
}else{
datas.push(node.getAttribute('data-id'));
}
}
return datas.join('##');
}

主要内容:

  1. range(选区):IE与标准浏览器的兼容性,值得注意的IE操控选区时,需要让被操控元素(也就是选区所在的元素)获取焦点,否则会失败。
  2. 标准浏览器range的APi可参考此地址:http://www.w3school.com.cn/xmldom/dom_range.asp
  3. 获取数(getContent):将html结构的数据转换为标准的数据,防止脚本攻击。

3. LeaveMsg类(留言板管理类)

var LeaveMsg = function(opts){
this.opts = opts;
this.createFaceWrap();
this.createUitls();
this.curLocation;
}
var leaveMsgPt = LeaveMsg.prototype;
leaveMsgPt._insertFace = function(id){
var img = document.createElement('img');
img.setAttribute('class','face-img');
img.setAttribute('data-id', id);
img.src= '../img/face/'   id   '.jpg';
this.selectionUitls.insertDom(img);
this.faceWrap.hide();
}
leaveMsgPt.createFaceWrap = function(){
var self = this;
var faceOpt = {
onChooseImg:function(evt){
//插入表情,获取位置,获取表情,插入表情
var id = (evt.target||evt.srcElement).getAttribute('data-id');
self._insertFace(id);
}
}
this.faceWrap = new FaceWrap(this.opts.faceHead, this.opts.faceCont, faceOpt);
}
leaveMsgPt.createUitls = function(){
this.selectionUitls = new SelectionUitls(this.opts.area);
}
leaveMsgPt.getContent = function(evt){
this.selectionUitls.getContent();
}

实现FaceWrap、SelectionUitls类与LeaveMsg类的组合,并对UI提供相就的API。

四、使用他们

js部分代码

var leaveMsgArea = document.getElementById('leaveMsgArea');
var faceHead = document.getElementById('head');
var faceCont = document.getElementById('cont');
var leaveMsg = new LeaveMsg({
area: leaveMsgArea,
faceHead: faceHead,
faceCont: faceCont
});

HTML部分代码

<div class="leaveMsgArea" contenteditable="true" id="leaveMsgArea">
</div>
<div class="face-wrap">
<a class="face-head" id="head" href="javascript:void(0)">表情</a>
<div class="face-cont" id="cont">
</div>
</div>
<div class="button-group">
<button type="button" onclick="leaveMsg.getContent(event)" >获取内容</button>
</div>

更多专业前端知识,请上 【猿2048】www.mk2048.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363653.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2021年兰州师大附中高考成绩查询,2021年兰州重点高中名单及排名,兰州高中高考成绩排名榜...

”一千个人眼中&#xff0c;就有一千个哈姆雷特“。关于兰州高职学校排名&#xff0c;每个人的观点也是各不相同&#xff0c;今天就给大家分享一下我心中的兰州高中排名及格局分布&#xff0c;主要参考依据是近年中考录取分数线及高考成绩。数据仅供参考&#xff01;希望对你有…

use vue vuex vue-router, not use webpack

vue,vuex,vue-router放在一起能做什么&#xff1f;不用webpack之类的打包工具使用他们是否可行&#xff1f;各位道友在初学vue时是否有这样的困惑。因为现代构建前端项目的一般模式是&#xff1a; 安装webapck&#xff0c;某种是glup,grunt&#xff0c;或者是fis等构建工具然后…

SQL重复记录查询(转载)

1、查找表中多余的重复记录&#xff0c;重复记录是根据单个字段&#xff08;peopleId&#xff09;来判断select * from peoplewhere peopleId in (select peopleId from people group by peopleId having count(peopleId) > 1) 例二&#xff1a;select * from testt…

ubuntu16 升级pip3后报错File /usr/bin/pip3, line 9, in module from pip import main ImportError: cannot...

问题&#xff1a;ubuntu16 执行pip3 install --upgrade pip之后&#xff0c;pip3执行出错。 Traceback (most recent call last): File "/usr/bin/pip3", line 9, in <module> from pip import mainImportError: cannot import name main 截图如下&#xff1a;…

HTTP 简介

1、HTTP 简介 HTTP协议&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;&#xff0c;是用于从WWW万维网服务器传输超文本到本地浏览器的传送协议。 HTTP基于TCP/IP通信协议来传递数据&#xff08;HTML 文件, 图片文件, 查询结果等&#xff09…

计算机博士英语复试题目,博士复试自我介绍中英文双语解读

博士复试自我介绍中英文双语解读关于博士复试自我介绍中英文篇一(中文篇)尊敬的老师,晚上好!我很高兴能来这里参加面试。现在让我给一个简短的自我介绍。我是* * *,出生在* *。我是一个老师的信息科学与工程学院,山东科技大学。我在1997年进入这所大学,主修计算机科学与技术。2…

如何在J2ME中创建MIDlet

总览 Java移动应用程序称为J2ME。 通常&#xff0c;当我们在移动技术领域工作时&#xff0c;我们必须考虑J2ME应用程序。 通过这种方式&#xff0c;我们可以开发我们的移动应用程序&#xff0c;也可以通过jad或jar文件将其安装在我们的设备中。 近年来&#xff0c;手机开发中最…

感悟测试驱动开发

软件开发方法学的泰斗Kent Beck先生最为推崇"模式、极限编程和测试驱动开发"。在他所创造的极限编程&#xff08;XP&#xff09;方法论中&#xff0c;就向大家推荐"测试先行"这一最佳实践&#xff0c;并且还专门撰写了《测试驱动开发》一书&#xff0c;详细…

创建一个学生信息表,与页面分离

一、需求分析 做一个jsp页面&#xff0c;动态显示信息表的内容。 1、 做一个实体类&#xff1a;StudentInfo &#xff08;包含4个字段&#xff09; 2、 如图模拟生成3条数据&#xff0c;本质上就是new StudentInfo 3个实例&#xff0c;每个实例代表一行记录&#xff08;后面…

【Unity】材质基础

【Unity】材质基础 a.基本概念 b.Albedo Maps反射率贴图 c.Alpha Maps着色器shader下四大渲染模式 d.Metallic and Smoothness Maps e.Normal Maps法线贴图 f.Height Maps g.Occlusion Maps h.Emission Maps i.Detail Mask & Secondary Maps j.Standard 金属/Standard&…

科学计算机二进制算法,计算机是怎么理解二进制的?

计算机是怎么理解二进制的?计算机的发明最初纯粹是为了计算数字, 让一个机器能够通过输入不同的数字, 进行加减乘除等. 首先要约定好机器能处理的数是什么样的, 即输入是什么样的, 才能去制造计算机. 二进制只是一种尝试, 十进制也有科学家尝试过, 但由于复杂程度较二进制要高…

WPF 实现ScrollViewer的垂直偏移滚动跳转

问题&#xff1a;考虑屏幕大小&#xff0c;一般都是会在表单问卷的页面使用ScrollViewer。问卷中问题漏填漏选时&#xff0c;在提交时校验不过&#xff0c;需要滚动跳转至漏填漏选项。 页面如下&#xff1a; 每个选项使用StackPanel&#xff0c;并对复选框和单选的勾选事件进行…

限制 计算机中 某用户上网 win7,Win7旗舰版怎么限制孩子的上网时间?电脑限制孩子上网时间的方法...

Win7旗舰版怎么限制孩子的上网时间&#xff1f;我们在家里有孩子的时候非常害怕孩子沉迷与网络&#xff0c;不把心思放在学习上。所以会想方设法的限制孩子上网。那么我们怎么使用电脑的自带的功能限制孩子上网呢&#xff1f;下面小编就带着大家一起看一下吧&#xff01;设置管…

论图计算

自从机械计算开始以来&#xff0c;图形概念就已经存在&#xff0c;并且在纯数学领域已经存在了数十年。 由于数据库的黄金时代&#xff0c;图形在软件工程中变得越来越流行。 图形数据库提供了一种持久化和处理图形数据的方法。 但是&#xff0c;图形数据库并不是存储和分析图形…

html 拼接onmouseout,HTML onmouseout事件用法及代码示例

将鼠标指针移出元素或其子元素时&#xff0c;将发生HTML DOM onmouseout事件。用法:在HTML中&#xff1a;在JavaScript中&#xff1a;object.onmouseout function(){myScript};在JavaScript中&#xff0c;使用addEventListener()方法&#xff1a;object.addEventListener(&quo…

7 selenium 模块

selenium 模块 一.简介 1.Python的一个第三方库&#xff0c;对外提供的接口可以操作浏览器&#xff0c;然后让浏览器完成自动化的操作。 2.自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题 selenium本质是通过驱动浏览器&#xff0c;完全…

针对新手的Java EE7和Maven项目-第3部分-定义ejb服务和jpa实体模块

从前面的部分恢复 第1部分 第2部分 我们在第三部分继续介绍&#xff0c;我们已经有一个父pom&#xff0c;并且已经为我们的war模块定义了pom。 在我们的原始设置中&#xff0c;我们定义了我们的应用程序将包含一个ejb jar形式的服务jar。 这是我们的Enterprise Java Bean&…

计算机本地网络如何共享,本地网络共享怎么实现

本地网络共享可以满足多台电脑同时联网&#xff0c;台式电脑实现网络共享可以使用路由器&#xff0c;笔记本电脑事项网络共享需要使用无线路由器或者无线网卡。那么本地网络共享又是如何实现的呢&#xff0c;下面为大家详细介绍一下。通过路由器实现本地网络共享&#xff1a;第…

Git初始化配置以及配置github

1&#xff0c;配置用户名和邮箱&#xff08;这里是我github中配置的用户名和邮箱&#xff09;&#xff0c;执行下面命令后&#xff0c;在C:\Users\yaosq盘下会出现一个全局文件.gitconfig. git config --global user.name "这里换上你的用户名" git config --global…

数据知识栈

并发不适合胆小者 我们都知道并发编程很难正确实现。 这就是为什么在执行线程任务之后要进行大量的设计和代码审查会议。 您永远不会将并发问题分配给经验不足的开发人员。 仔细分析问题空间&#xff0c;提出设计&#xff0c;并记录和审查解决方案。 这就是通常处理线程相关任…