繁体   English   中英

如何使用插入符号 position 在文本区域中垂直导航

[英]How to vertically navigate through a textarea using caret position

我正在研究一组 vanilla js 函数,以在单击相应的箭头按钮时导航 html 文本区域。

例如,

 var text = document.getElementById('text'); function larr(){ text.focus(); var pos = text.selectionStart; pos-- text.setSelectionRange(pos, pos); }
 <textarea id='text'></textarea> <button onclick="larr()">&larr;</button>

左右功能很简单,但我还想包括向上和向下箭头。 由于每个换行符可以有不同数量的字符,我认为这不像将 position 向前或向后设置一个最大行长度那么简单。

我会满足于将您带到下一个或上一个换行符的箭头。 我正在考虑在插入符号 position 处拆分 textarea 值,并在该方向上循环字符直到达到 \n,但我无法绕开它。

有没有人有什么建议? 谢谢!

*重要提示-这将适用于隐藏本机键盘的移动设备,因此没有操作系统的帮助? (除非可能是 jquery trigger() 或 execCommand?)

警告:如果您使用此方法禁用调整文本区域大小的功能,建议您使用。 通过这种方式,您可以控制所需的调整器,以考虑不同大小的字符宽度的差异以及使用 textarea 自动换行根据实际宽度选择字符的方式。

注意:没有在移动版上进行测试。

我可以使用我在这里在线找到的几个函数来实现它:如何使用 JavaScript 获取textarea中的行数? . 基本上,海报使用高度、行高、溢出和滚动高度来确定 textarea 的高度,简而言之,获取 textareas 内容中的行数。 我包括了海报的原始评论,以帮助您理解逻辑。 我调整了他们的第二个 function 以将行数除以文本区域内的字符数,这使我们对每行的宽度有一个基本的了解,尽管它并不精确! 请参阅警告...根据每行中的字符(可能会根据 textarea 的宽度而变化),行中字符的四舍五入量会有所不同。 因此,当我们 go 向上或向下一行时,它会根据该变化向右或向左跳跃。

我们如何上/下线...

    let style = (window.getComputedStyle) ?
    window.getComputedStyle(text) : text.currentStyle,

    // This will get the line-height if it is set in the css
    textLineHeight = parseInt(style.lineHeight, 10),
    // Get the scroll height of the textarea
    textHeight = calculateContentHeight(text, textLineHeight),
    // calculate the number of lines by dividing
    // the scroll height by the line-height
    numberOfLines = Math.ceil(textHeight / textLineHeight),
    // get the amount of characters in the textarea
    numOfChars = text.value.length,
    // this following number will vary depending on how the width of your 
    // lines character count is calculated and rounded in terms 
    // of what the actual width in character count actually is
    // you will have to adjust this number accordingly
    adjustor = 14,
    // divide the number of characters by the amount of lines
    percentage = numOfChars / numberOfLines + adjustor;

    return percentage;

同样,这在向上和向下时并不精确,但它可以工作,在按下按钮时向上或向下移动 cursor,它会根据字符的四舍五入数量与该特定行上的数量进行轻微的左右移动。

编辑:我已将您的移动功能组合到一个 function 中,该功能通过forEach循环运行按钮class 并使用事件目标检查每个元素的ID并相应地移动 Z1791A97A8403730EE0760489A2AEB9Z。

 let text = document.getElementById('text'); text.value = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Mauris in aliquam sem fringilla ut morbi tincidunt augue. Scelerisque in dictum non consectetur a erat nam. Consectetur adipiscing elit ut aliquam purus sit amet luctus venenatis. "; // lets just set a cursor middle of the road for testing... text.focus(); text.setSelectionRange(181, 181); let calculateContentHeight = (text, scanAmount) => { let origHeight = text.style.height, height = text.offsetHeight, scrollHeight = text.scrollHeight, overflow = text.style.overflow; /// only bother if the ta is bigger than content if (height >= scrollHeight) { /// check that our browser supports changing dimension /// calculations mid-way through a function call... text.style.height = `${(height + scanAmount)}px`; /// because the scrollbar can cause calculation problems text.style.overflow = 'hidden'; /// by checking that scrollHeight has updated if (scrollHeight < text.scrollHeight) { /// now try and scan the ta's height downwards /// until scrollHeight becomes larger than height while (text.offsetHeight >= text.scrollHeight) { text.style.height = `${(height -= scanAmount)}px`; } /// be more specific to get the exact height while (text.offsetHeight < text.scrollHeight) { text.style.height = `${(height++)}px`; } /// reset the ta back to it's original height text.style.height = origHeight; /// put the overflow back text.style.overflow = overflow; return height; } } else { return scrollHeight; } } let calculateLineWidth = (text) => { let style = (window.getComputedStyle)? window.getComputedStyle(text): text.currentStyle, // This will get the line-height only if it is set in the css, // otherwise it's "normal" textLineHeight = parseInt(style.lineHeight, 10), // Get the scroll height of the textarea textHeight = calculateContentHeight(text, textLineHeight), // calculate the number of lines numberOfLines = Math.ceil(textHeight / textLineHeight), // get the amount of characters in the textarea numOfChars = text.value.length, // this number will vary depending on how the width of your // lines character count is calculated and rounded in terms // of what the actual width in character count actually is // you will have to adjust this number accordingly adjustor = 14, // divide the number of characters by the amount of lines percentage = numOfChars / numberOfLines + adjustor; return percentage; } const moveCursor = (text) => { const btns = document.querySelectorAll('.btns'); btns.forEach((btn) => { btn.addEventListener('click', (e) => { text.focus(); let pos = text.selectionStart; if (e.target.id === 'left') { pos--; text.setSelectionRange(pos, pos); } else if (e.target.id === 'right') { pos++; text.setSelectionRange(pos, pos); } else if (e.target.id === 'up') { if (pos - Number(calculateLineWidth(text)) > 0) { pos = pos - Number(calculateLineWidth(text)); text.setSelectionRange(pos, pos); } else { text.setSelectionRange(0, 0); } } else { pos = pos + Number(calculateLineWidth(text)); text.setSelectionRange(pos, pos) } }) }) } moveCursor(text);
 #text { line-height: 1.5; text-align: justify; resize: none; } #btns { display: flex; align-items: center; } #mid { display: flex; flex-direction: column; }.btns { height: 20px; }
 <textarea id='text' cols="50" rows="6"></textarea> <div id="btns"> <button id="left" class="btns">&larr;</button> <div id="mid"> <button id="up" class="btns">&#129045;</button> <button id="down" class="btns">&#129043;</button> </div> <button id="right" class="btns">&rarr;</button> </div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM