1.获取光标位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | <html> <head> <title>光标测试</title> <style> p { display: flex; flex-direction: row; } .btn { height: 24px; margin: 0 10px; } .edit-div { display: inline-block; width: 225px; border: 1px solid #decdcd; } </style> <script> function getCursortPosition(e) { var eleP = e.target.parentNode; //获取父级元素 var pos = 0; if (e.target.nodeName == "DIV" ) { pos = getDivPosition(e.target); } else { pos = getPosition(e.target); } var spanEle = (eleP.childNodes)[7]; spanEle.innerText = pos; } //可编辑div获取坐标 const getDivPosition = function (element) { var caretOffset = 0; var doc = element.ownerDocument || element.document; var win = doc.defaultView || doc.parentWindow; var sel; if ( typeof win.getSelection != "undefined" ) { //谷歌、火狐 sel = win.getSelection(); if (sel.rangeCount > 0) { //选中的区域 var range = win.getSelection().getRangeAt(0); var preCaretRange = range.cloneRange(); //克隆一个选中区域 preCaretRange.selectNodeContents(element); //设置选中区域的节点内容为当前节点 preCaretRange.setEnd(range.endContainer, range.endOffset); //重置选中区域的结束位置 caretOffset = preCaretRange.toString().length; } } else if ((sel = doc.selection) && sel.type != "Control" ) { //IE var textRange = sel.createRange(); var preCaretTextRange = doc.body.createTextRange(); preCaretTextRange.moveToElementText(element); preCaretTextRange.setEndPoint( "EndToEnd" , textRange); caretOffset = preCaretTextRange.text.length; } return caretOffset; } //输入框获取光标 const getPosition = function (element) { let cursorPos = 0; if (document.selection) { //IE var selectRange = document.selection.createRange(); selectRange.moveStart( 'character' , -element.value.length); cursorPos = selectRange.text.length; } else if (element.selectionStart || element.selectionStart == '0' ) { cursorPos = element.selectionStart; } return cursorPos; } </script> </head> <body> <p> <label>输入框测试:</label> <input type= "text" style= "width:220px" onclick= "getCursortPosition(event);" /> <span>光标位置:</span> <span></span> </p> <p> <label>文本框测试:</label> <textarea rows= "5" style= "width:220px" onclick= "getCursortPosition(event);" ></textarea> <span>光标位置:</span> <span></span> </p> <div> <label>可编辑div:</label> <div contenteditable= "true" class = "edit-div" onclick= "getCursortPosition(event);" ></div> <span>光标位置:</span> <span></span> </div> </body> </html> |
2.设置光标位置
2.1 设置光标位置input、textarea
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <!DOCTYPE html> <html> <head> <meta charset= "UTF-8" > <title></title> </head> <body> <input type= "text" id= "test-input" value= "Example" /> <input type= "text" id= "test-input2" value= "Example" /> </body> <script> function setCaretPosition(ctrl, pos) { // Modern browsers if (ctrl.setSelectionRange) { ctrl.focus(); ctrl.setSelectionRange(pos, pos); // IE8 and below } else if (ctrl.createTextRange) { var range = ctrl.createTextRange(); range.collapse( true ); range.moveEnd( 'character' , pos); range.moveStart( 'character' , pos); range. select (); } } var input = document.getElementById( 'test-input' ); setCaretPosition(input, input.value.length); </script> </html> |
2.2 设置光标位置可编辑div
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "UTF-8" > <title>在可编辑div中定位和设置光标</title> <style> #edit { height: 500px; width: 500px; border: 1px solid red; } </style> </head> <body> <div id= "edit" contenteditable></div> <input type= "text" id= "emojiInput" > <button id= "sendEmoji" >发送表情</button> <script> // 发送表情的按钮 var sendEmoji = document.getElementById( 'sendEmoji' ); // 定义最后光标对象 var lastEditRange; // 编辑框点击事件 document.getElementById( 'edit' ).onclick = function () { // 获取选定对象 var selection = getSelection(); // 设置最后光标对象 lastEditRange = selection.getRangeAt(0); } // 编辑框按键弹起事件 document.getElementById( 'edit' ).onkeyup = function () { // 获取选定对象 var selection = getSelection(); // 设置最后光标对象 lastEditRange = selection.getRangeAt(0); } // 发送表情 document.getElementById( 'sendEmoji' ).onclick = function () { // 获取可编辑框 var edit = document.getElementById( 'edit' ); // 获取输入框 var emojiInput = document.getElementById( 'emojiInput' ); // 编辑框获得焦点 edit.focus(); // 获取选定对象 var selection = getSelection(); // 如果保存的有上次的光标对象 if (lastEditRange) { // 清除所有选区 selection.removeAllRanges(); // 添加最后光标还原之前的状态 selection.addRange(lastEditRange); } // 判断选定对象范围是编辑框还是文本节点,如果是编辑框范围 if (selection.anchorNode.nodeName != '#text' ) { // 创建表情文本节点进行插入 var emojiText = document.createTextNode(emojiInput.value); // 如果文本框的子元素大于0,则表示有其他元素,则按照位置插入表情节点 if (edit.childNodes.length > 0) { for ( var i = 0; i < edit.childNodes.length; i++) { if (i == selection.anchorOffset) { edit.insertBefore(emojiText, edit.childNodes[i]); } } } else { // 否则直接插入一个表情元素 edit.appendChild(emojiText); } // 创建新的光标对象 var range = document.createRange(); // 将光标对象的范围界定为新建的表情节点 range.selectNodeContents(emojiText); // 定位光标位置在表情节点的最大长度位置 range.setStart(emojiText, emojiText.length); // 将选区折叠为一个光标 range.collapse( true ); // 清除所有光标对象 selection.removeAllRanges(); // 添加新的光标对象 selection.addRange(range); // 如果是文本节点 } else { // 获取光标对象 var range = selection.getRangeAt(0); // 获取光标对象的范围界定对象,一般就是textNode对象 var textNode = range.startContainer; // 获取光标位置 var rangeStartOffset = range.startOffset; // 在光标位置处插入新的表情内容 textNode.insertData(rangeStartOffset, emojiInput.value); // 添加了新内容,将光标移动到新的位置 range.setStart(textNode, rangeStartOffset + emojiInput.value.length); // 将选区折叠为一个光标 range.collapse( true ); // 清除所有光标对象 selection.removeAllRanges(); // 添加新的光标对象 selection.addRange(range); } // 记录最后光标对象 lastEditRange = selection.getRangeAt(0) } </script> </body> </html> |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗