前端最基础的就是HTML+CSS+Javascript。掌握这三项技术算是入门,但也只是入门而已。现在前端开发的定义远不止于此。前端小课堂(HTML/CSS/JS),本着提高技术水平,夯实基础知识的中心思想,开课(每周四)。初级阶段结束,针对前面提到的内容进行实景分享。就在前段时间,我一直在加班加点做聊天功能。今天我们就来说说我们遇到的事情。我们要谈什么?聊天功能中发送框的实现以及一些常规操作的实现。contentEditableNode和Element插入功能(表情、截图等)粘贴功能拖入功能测试地址-测试以下功能关键字text换行图片input√××textarea√√×contentEditable√√√contentEditable你会说这个东西我知道,您可以通过添加到元素来编辑内容。老铁,当然不会这么简单。当你按回车/回车在可编辑区域创建一个新的文本行时,不同的主流浏览器对此有不同的处理(Firefox插入,IE/Opera将使用
,Chrome/Safari将使用
)css也可以支持同样的功能——webkit-user-modify,值有inherit(继承);初始(默认);只读(read-only);读写(读写);read-write-plaintext-only(读写,非富文本);未设置(未设置);当一个属性定义了一个未设置的值时,如果该属性是默认继承属性,则该值相当于inherit,如果该属性是非继承属性,则该值相当于initial以上contentEditable属性不支持逻辑值。plaintext-only是其中最聪明的。最早是张新旭大哥-小提示:如何让contenteditable元素只能在能看到的地方输入纯文本。当然,我们还是使用富文本样式。因为我们需要表达式Node,而ElementNodeNode是一个接口,很多类型的DOMAPI对象都会继承自这个接口。它允许我们以相似的方式处理这些不同类型的对象;例如,继承相同的方法集,或以相同的方式进行测试。ThefollowinginterfacesallinherittheirmethodsandpropertiesfromNode:Document,Element,Attr,CharacterData(whichText,Comment,andCDATASectioninherit),ProcessingInstruction,DocumentFragment,DocumentType,Notation,Entity,EntityReference-----------------https://developer.mozilla.org...Node.nodeNamereturnsaDOMStringcontainingthenameofthenode.Nodenamesarestructureddifferentlythannodetypes.ThenameofHTMLElementcorrespondstothelabelitisassociatedwith,forexample,HTMLAudioElementcorrespondsto'audio'Textnodecorrespondsto'#text'.TheDocumentnodecorrespondsto'#document'.Node.nodeTypeNameValuestatusELEMENT_NODE1ATTRIBUTE_NODE2warnTEXT_NODE3CDATA_SECTION_NODE4ENTITY_REFERENCE_NODE5warnENTITY_NODE6warnPROCESSING_INSTRUCTION_NODE7COMMENT_NODE8DOCUMENT_NODE9DOCUMENT_TYPE_NODE10DOCUMENT_FRAGMENT_NODE11NOTATION_NODE12warn上面两个属于比较重要的ElementElement是非常通用的基类,所有Document对象下的对象都继承它.这个接口描述了所有相同种类的元素所普遍具有的方法andproperties.TheseinterfacesinheritfromElementandaddsomeadditionalfunctionstodescribespecificbehaviors.Forexample,theHTMLElementinterfaceisthebaseinterfaceofallHTMLelements,andtheSVGElementinterfaceisthebaseinterfaceofallSVGelements.MostofthefunctionsarefurtherintheclasshierarchyFormulate.Inlanguages??otherthantheweb,XULcanpasstheXULElementinterface,andalsoimplementtheElementinterface.ThedifferencebetweenNodeandElementisthatNodewillcontaintextnodes.SuchasText.并且Element包含所有标签节点。如果把插入功能换成DOM操作,貌似appendChild、insertBefore、replaceChild这些比较简单的功能基本都可以搞定。但是切换到富文本呢?我们需要解决几个问题,获取当前焦点位置,在文本内容中插入内容,在节点内容中插入内容。其实还有一点。插入的时候会点击其他位置,导致失去焦点,所以我们需要记住,然后设置到指定的Location。获取当前焦点位置window.getSelection();这可用于获取焦点位置。anchorNode指向用户开始选择(按下鼠标按钮)的位置,而focusNode指向用户结束选择(释放鼠标按钮)的位置。注意不要与选区的起始位置和结束位置混淆,因为选区的起始位置可能在结束选区的前面,也可能在结束选区的后面,这取决于选择文本时鼠标移动的方向(即按下鼠标键和释放鼠标键的位置)。isCollapsed布尔值,用于判断选区的起点和终点是否在同一位置。//可以用这段代码观察setInterval(()=>{varselection=window.getSelection();console.log(selection)},1000)在文本内容中插入内容从上面的内容我们可以看出,文中是一个Node节点,我应该如何插入节点呢?这实际上只是调用insertDataapi。但是怎么会这么简单呢?我们插入的是DOM而不是纯文本,所以这行不通。我们这里要用到的其实是splitText,它是用来分割焦点处的内容的。然后在后面添加内容。在节点中插入内容相对简单。如果是节点,直接添加即可。因为节点不存在说中间插入。但是,当你在节点后面时,你需要获取所有节点并根据偏移量找到点。childNodes和children应该使用哪一个?这就涉及到上面提到的Node和Element的区别。留个小作业,自己试试吧。友情提示,报错时记得检查anchorNode是否为Text节点。记录焦点位置&整合应用由于点击会失去焦点,那么我们在模糊的时候记录下来。然后再秀回去就OK了。在测试地址中,其实还有一个效果没有处理,那就是选区的处理。它可以用作课后作业。粘贴功能这个功能很靠谱,因为还是富文本。所以粘贴的内容是有样式的。但是我们不需要样式,所以我们过滤掉所有标签。但同样是因为我们可以复制和粘贴图片。所以我们需要过滤掉我们的图像。有两种方法可以获取文本。图片会变成alt属性的值(我用的就是这个)得到html,需要自己过滤。要粘贴传入的内容,我们需要处理粘贴事件。e.clipboardData是获取剪贴板对象。提供getData以获取剪贴板内容。例如getData('text');获取文本内容。getData('文本/html');获取html格式的内容。tips:可以复制单张图片。将在剪贴板中的文件内。无法执行setData方法。看来浏览器厂商正在考虑安全方向。因此,不能直接通过替换剪贴板的内容来达到目的。然后我们要注意e.preventDefault();,它是用来防止default事件的。拖放功能未实现。感觉很难。达不到原来的感觉。也可能是我没找到API。希望知道的人告诉我。说说我能给出的方案,因为setData不能设置,所以方案还是考虑防止默认的单独处理,内部拖拽使用系统操作。禁止外拖。都是用自己的processing却拿不到焦点。要解决这个问题,你可以添加一个提示,然后添加它。如果你拖放,你可以有一个文件级别。判断如果是文本文件之类的,可以读取文件内容。后记主讲人文章-浏览器科普感谢评论区的回复,document.execCommand的支持--MDN确实会少控制一些逻辑。