我正试图在一个使用textarea和编号div的编辑器上添加go to line和find text功能。
我已经尝试了下面的代码,但它并没有滚动编辑器来关注用户在提示符中输入的行或文本;
请帮助我在编辑器上实现go to line和find text函数。
const ta = document.querySelector('textarea')
function updateRowNumbering() {
const num = ta.value.split("\n").length;
const numbers = ta.parentNode.querySelector(".numbers");
numbers.innerHTML = Array(num).fill("<span></span>").join("");
}
ta.value = `One
Two
Three
Four
Five
Six
Seven
Eight
Nine
Ten
Eleven
Kumi na Mbili
`
updateRowNumbering()
//Trying to implement go to line and find text;
const numbers = ta.parentNode.querySelector('.numbers');
const gotoLinePrompt = document.querySelector('.goto-line-prompt');
const findPrompt = document.querySelector('.find-prompt');
// Hide the prompts by default.
gotoLinePrompt.style.display = 'none';
findPrompt.style.display = 'none';
// Add event listeners to the "Go to Line" and "Find" buttons.
document.querySelector('.goto-line-button').addEventListener('click', function() {
gotoLinePrompt.style.display = 'block';
});
document.querySelector('.find-button').addEventListener('click', function() {
findPrompt.style.display = 'block';
});
// Add event listeners to the "OK" buttons in the prompts.
gotoLinePrompt.querySelector('.ok-button').addEventListener('click', function() {
const lineNumber = gotoLinePrompt.querySelector('input').value;
if (lineNumber !== null) {
const lineHeight = ta.scrollHeight / ta.clientHeight;
ta.scrollTop = (lineNumber - 1) * lineHeight;
numbers.scrollTop = ta.scrollTop;
}
gotoLinePrompt.style.display = 'none';
});
findPrompt.querySelector('.ok-button').addEventListener('click', function() {
const searchTerm = findPrompt.querySelector('input').value;
if (searchTerm !== null) {
const text = ta.textContent;
const index = text.indexOf(searchTerm);
if (index !== -1) {
const lineNumber = Math.floor(index / ta.value.split('\n')[0].length) + 1;
ta.scrollTop = (lineNumber - 1) * lineHeight;
numbers.scrollTop = ta.scrollTop;
}
}
findPrompt.style.display = 'none';
});
body, textarea {
font-family: Consolas, "Courier New", Courier, monospace;
}
.editor {
display: inline-grid;
grid-template-columns: 3em auto;
gap: 10px;
line-height: 21px;
background: rgb(40 42 58);
border-radius: 2px;
overflow-y: auto;
max-height: 250px;
}
.editor>* {
padding-top: 10px;
padding-bottom: 10px;
}
.numbers {
text-align: right;
background: #333;
padding-right: 5px;
}
.numbers span {
counter-increment: linenumber;
}
.numbers span::before {
content: counter(linenumber);
display: block;
color: #888;
}
textarea {
line-height: 21px;
border: 0;
background: transparent;
color: #fff;
min-width: 500px;
outline: none;
resize: none;
padding-right: 10px;
}
<div class="actions">
<div class="goto-line-prompt" style="display: none;">
<h1>Go to Line</h1>
<input type="number" placeholder="Enter the line number to go to:" />
<button type="button" class="ok-button">OK</button>
</div>
<div class="find-prompt" style="display: none;">
<h1>Find</h1>
<input type="text" placeholder="Enter the text to find:" />
<button type="button" class="ok-button">OK</button>
</div>
<button class="goto-line-button">Go to Line</button>
<button class="find-button">Find</button>
</div>
<div class="editor">
<div class="numbers">
<span></span>
</div>
<textarea wrap="off" onkeyup="updateRowNumbering()"></textarea>
</div>
2条答案
按热度按时间iklwldmw1#
.value
永远不会为空,所以检查是无用的。文本区域没有textContent
。有内置的api可以滚动到视图中的元素,所以没有理由重新发明轮子。
beq87vna2#
我在这里看到了一些问题,但我认为问题的核心是,当您应该针对编辑器组件时,您却针对要滚动的文本区域。你会注意到,如果你在
.editor
(不是.editor>*
)上设置height/min-height,比如40 px,你会得到一个双滚动条的场景,文本区域滚动,编辑器也滚动-如果你试图滚动数字,整个编辑器滚动,而当关注文本区域时,只有文本滚动。在方向上,这样的东西可能会有所帮助:
+1也对@epascarello的回答与点不重新发明滚动API,这将有助于确保事情正确滚动无论你最终滚动的元素。