[英]How to make this div scrollTop value match that of the textarea?
我正在使用 div 來格式化和顯示來自等尺寸文本區域的文本,我需要它們永久同步。 但是,在輸入文本超過文本區域底部后,我無法同步它們各自的 scrollTops。
我的過程與此處描述的過程類似,但我無法讓他的解決方案在我的項目中發揮作用。
這是最少相關代碼的演示和片段:
<section>
<div class="input-text__container">
<div id="input-text--mirror" class="input-text"></div>
<textarea
id="input-text--original"
cols="30"
rows="6"
autofocus
class="input-text"
placeholder="Enter your text here"
autocomplete="off"
autocorrect="off"
spellcheck="false"
></textarea>
</div>
<section>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500&display=swap');
html {
font-size: 62.5%;
box-sizing: border-box;
scroll-behavior: smooth;
}
*,
*::after,
*::before {
margin: 0;
padding: 0;
border: 0;
box-sizing: inherit;
vertical-align: baseline;
}
body {
height: 100vh;
}
section {
display: flex;
flex-direction: column;
min-height: 100%;
padding: 1rem;
}
.input-text__container {
width: 100%;
position: relative;
flex: 1;
}
.input-text {
width: 100%;
height: 100%;
position: absolute;
font-size: 3.2rem;
overflow-wrap: break-word;
font-family: "Inter";
}
#input-text--mirror {
background-color: #e9ecf8;
color: #0a3871;
overflow: hidden;
}
#input-text--original {
background-color: transparent;
-webkit-text-fill-color: transparent;
resize: none;
outline: none;
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
#input-text--original::placeholder {
color: #e9ecf8;
-webkit-text-fill-color: #052051;
}
#input-text--original::selection {
-webkit-text-fill-color: #ffffff;
}
.invalid {
font-weight: 400;
color: #ff0000;
}
#input-text--original::-webkit-scrollbar {
display: none;
}
let invalidInput = false;
const patterns = {
valid: "a-z ",
invalid: "[^a-z ]",
linebreaks: "\r|\r\n|\n",
};
const textIn = document.querySelector("#input-text--original");
const mirror = document.querySelector("#input-text--mirror");
function validateInput(string, className) {
let anyInvalidChar = false;
// Generate regular expressions for validation
const regExpInvalids = new RegExp(patterns.invalid, "g");
const regExpLinebreaks = new RegExp(patterns.linebreaks);
// Generate innerHTML for mirror
const mirrorContent = string.replace(regExpInvalids, (match) => {
if (regExpLinebreaks.test(match)) {
return "<br/>";
} else {
anyInvalidChar = true;
return `<span class=${className}>${match}</span>`;
}
});
// Update mirror
mirror.innerHTML = mirrorContent;
return anyInvalidChar;
}
textIn.addEventListener("input", (e) => {
const plain = textIn.value;
const newInputValidity = validateInput(plain, "invalid");
mirror.scrollTop = textIn.scrollTop;
});
textIn.addEventListener(
"scroll",
() => {
mirror.scrollTop = textIn.scrollTop;
},
{ passive: true }
);
在桌面屏幕上鍵入列中的前 8 個自然數應該足以重現該問題。
我檢查的最后一件事,但也許到目前為止最相關的是這個。 它似乎在 React 上處理完全相同的問題,但恐怕我不知道如何使該解決方案適應 Vanilla JavaScript,因為我才剛剛開始學習 React。 請注意,我正在嘗試尋找一種不依賴於 jQuery 或 React 等庫的解決方案。
除此之外,我通過替換return "<br/>";
嘗試了上述博客中描述的解決方案; return "<br/> ";
在我的validateInput
function 中,但這沒有用。 我還在 append 中添加了一個條件,一個空格到plain
in const plain = textIn.value;
如果最后一個字符是換行符,但我沒有運氣。
我還在mirror.scrollTop = textIn.scrollTop;
在 textIn 滾動處理程序中跟蹤每個 scrollTop 的值,即使它們不同,鏡像 scrollTop 也沒有更新。 我讀到這可能是因為默認情況下 div 不可滾動,但是將“溢出:滾動”添加到其 styles 也沒有解決問題。
我閱讀了與 scrollTop 相關的其他屬性,如offsetTop 和 pageYOffset ,但它們要么是只讀的,要么沒有為 div 定義。
我也查看了以下帖子/站點,但仍然無法解決此問題。
我不再記得我還審查了什么,但沒有任何效果,我不再知道還能做什么。 感謝您的關注和幫助。
在嘗試復制我在帖子中提到的 React 應用程序的解決方案后,使用 vanilla JavaScript (此處演示) ,我嘗試將其應用於我自己的項目,我所要做的就是向mirror
添加一個<br>
標簽在我的validateInput
function 的末尾。即: mirror.innerHTML = mirrorContent + "<br>";
.
除此之外,不需要在每次觸發 textarea 上的輸入事件時更新鏡像的 scrollTop。 也不是將{ passive: true }
參數傳遞給滾動事件。
修改后的代碼在這里:
function validateInput(string, className) {
let anyInvalidChar = false;
// Generate regular expressions for validation
const regExpInvalids = new RegExp(patterns.invalid, "g");
const regExpLinebreaks = new RegExp(patterns.linebreaks);
// Generate innerHTML for mirror
const mirrorContent = string.replace(regExpInvalids, (match) => {
if (regExpLinebreaks.test(match)) {
return "<br/>";
} else {
anyInvalidChar = true;
return `<span class=${className}>${match}</span>`;
}
});
// Update mirror
mirror.innerHTML = mirrorContent + "<br>";
return anyInvalidChar;
}
textIn.addEventListener("input", (e) => {
const plain = textIn.value;
const newInputValidity = validateInput(plain, "invalid");
});
textIn.addEventListener("scroll", () => mirror.scrollTop = textIn.scrollTop);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.