- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
最近我的 chrome 版本越来越频繁地做一些奇怪的事情(ubuntu 18.04 上的 74.0.3729.131)。我有一个小的编辑器脚本,它有一个显示代码的 textarea。 textarea 具有固定大小和垂直滚动条。除此之外没有什么花哨的。
通常,当我插入换行符(textarea 的正常行为)时,滚动条不会移动。现在出于某种原因,大约 80% 的时间它会向下滚动 textarea 直到插入符号的位置位于 textarea 的顶部。奇怪的是,如果我删除并在同一位置输入换行符,它通常不会滚动。
我不确定这是否是 Chrome 中的一些新问题。我以前使用相同编辑器的版本没有这个问题。
这是一个演示问题的代码笔,滚动到某行,按回车键,textarea 应该向下滚动。尝试几次以查看不可预测的行为(添加代码只是为了能够添加链接,因为您可以看到它只是一个文本区域)。
https://codepen.io/anon/pen/rgKqMb
<textarea style="width:90%;height:300px"></textarea>
最佳答案
快到2020年底了,Chrome 86版本还存在这个问题?更重要的是,我很惊讶我没有找到关于这个问题的更多信息(投诉)(这篇文章是我发现的唯一一篇专门谈到这个问题的文章。)我观察到这种行为不仅发生在打字中,而且粘贴任何包含换行符的文本。我还观察到,如果我在发生这种情况后执行撤消操作,则会发生另一个随机滚动,使我在页面上更远,并且离插入符号的位置不远。
我对这种行为进行了长时间的试验和检查,但找不到任何可重复的情况,这可能会提供有关如何预测何时会发生的线索。它真的只是看起来“随机”。尽管如此,我不得不为我正在创建的 NWJS 编辑器应用程序解决这个问题(NWJS 使用 Chrome 作为 UI。)
这似乎对我有用:
首先,让我从简单开始介绍原理。我们将“输入”监听器和“滚动”监听器附加到文本区域。这是有效的,因为根据我的观察,“输入”[1] 监听器在随机滚动 Action 发生之前被触发。
滚动监听器记录每个滚动操作并将其保存在全局 prevScrollPos
中。 .它还检查全局标志 scrollCorrection
.
“输入”监听器设置 scrollCorrection
每次将文本输入到 textarea 时标记。请记住,这发生在随机滚动发生之前。
所以下一次滚动发生,这可能是令人讨厌的随机 Action ,滚动监听器将清除 scrollCorrection
,然后将 textarea 滚动到上一个滚动位置,即,将其滚动回“随机”滚动之前的位置。但问题是不可预测的,如果没有随机滚动并且下一次滚动是有意的怎么办?这没什么大不了的。这只是意味着如果用户手动滚动,第一个滚动事件基本上无效,但之后(清除 scrollCorrection
)一切都会正常滚动。由于在正常滚动期间,事件会如此迅速地吐出,因此不太可能有任何明显的影响。
这是代码:
let textarea;
let prevScrollPos = 0;
let scrollCorrection = false;
function onScroll(evt) {
if (scrollCorrection) {
// Reset this right off so it doesn't get retriggered by the corrction.
scrollCorrection = false;
textarea.scrollTop = prevScrollPos;
}
prevScrollPos = textarea.scrollTop;
}
function onInput(evt) {
scrollCorrection = true;
}
window.addEventListener("load", () => {
textarea = document.getElementById("example_textarea");
textarea.addEventListener("scroll", onScroll);
textarea.addEventListener("input", onInput);
})
现在让我们扩展它:
getBoundingClientRect
在生成的包含块等上。在我的情况下,我已经为我的编辑做了大部分工作,所以这不是什么额外的费用。但是我已经包含了一些伪代码来展示如何在滚动校正机制中实现这一点。
setCaretCorrection
基本上执行上面的步骤 1 - 7。
let textarea;
let prevScrollPos = 0;
let scrollCorrection = false;
let caretCorrection = 0;
function onScroll(evt) {
if (scrollCorrection) {
// Reset this right off so it doesn't get retriggered by the correction.
scrollCorrection = false;
textarea.scrollTop = prevScrollPos + caretCorrection;
caretCorrection = 0;
}
prevScrollPos = textarea.scrollTop;
}
function onTextareaInput() {
scrollCorrection = true;
setCaretCorrection();
}
function setCaretCorrection(evt) {
let caretPos = textarea.selectionStart;
let scrollingNeeded;
let amountToScroll;
/* ... Some code to determine xy position of caret relative to
textarea viewport, if it is scrolled out of view, and if
so, how much to scroll to bring it in view. ... */
if (scrollingNeeded) {
if (scrollCorrection) {
// scrollCorrection is true meaning random scroll has not occurred yet,
// so flag the scroll listener to add additional correction. This method
// won't cause a flicker which could happen if we scrollBy() explicitly.
caretCorrection = amountToScroll;
} else {
// Random scroll has already occurred and been corrected, so we are
// forced to do the additional "out of viewport" correction explicitly.
// Note, in my situation I never saw this condition happen.
textarea.scrollBy(0, amountToScroll);
}
}
}
可以更进一步,使用实验事件“beforeinput”[3] 来优化这一点,从而减少对
setCaretCorrection
的不必要调用。制作。如果检查
event.data
来自“beforeinput”事件,在某些情况下它会报告要输入的数据。如果没有,则输出
null
.不幸的是,当输入换行符时,
event.data
是
null
.但是,如果它们被粘贴,它会报告换行符。所以至少可以看到 event.data 是否包含字符串,如果字符串不包含换行符,则跳过整个更正操作。 (另外,请参见下面的 [1]。)
scrollCorrection
在随机滚动发生之前。尽管请注意“beforeinput”是实验性的。
关于javascript - 添加换行符后防止 chrome 中的 textarea 滚动行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56329625/
我想创建一个基于 jQuery 的非常简单的 html 编辑器(不是所见即所得)。 我的问题是如何制作 textarea或 div可能 在上面写一些文字 然后样式即标签(例如 some stuff 将
根据文档 isset 条款“测试此项目中是否已设置给定属性”。我不明白设置属性时 isset 返回 true 还是 false 在下面的代码片段中,当 env.JAVA_HOME 未设置时,java.
我正在尝试取消映射 o这是执行 :only 的默认命令( :help :only ),所以我尝试的第一件事是: nmap o 这种作品,除非我按 ,等待超过timeoutlen ms 然后按 o
我有以下型号: class MetaData(models.Model): created_at = models.DateTimeField(auto_now_add=True, auto_
下面列出了两行代码。两者对日期和时间的期望相同,但只有一个有效。我正在使用 R 3.1。 以下不起作用: DateTime2=strftime("08/13/2010 05:26:24.350", f
我有一个关于 C 代码的问题。 #include void foo(void){ int a; printf("%d\n",a); } void bar(void){
如果文件大小 > 8k,为什么读取的最后一个字节 = 0? private static final int GAP_SIZE = 8 * 1024; public static void main(
我有一个命令 Get-Testdata从不同来源检索测试数据并将这些数据存储到 PSObject以不同的值作为属性。然后将对象总数存储为数组,以便于操作、排序、计算等。 我的问题是我希望能够将这些数据
我正在使用 epoll 将大消息写入使用 HTTP 协议(protocol)的服务器。 fds 都设置为非阻塞,我正在使用边缘触发事件。我知道对于 EPOLLIN,我需要循环读取 fd,直到返回 EA
这对我来说听起来很奇怪: $test_1 = 'string'; $test_2 = '0'; var_dump(intval($test_1)); // Output: int 0 var_dump
这个问题在这里已经有了答案: Java: Integer equals vs. == (7 个回答) 7年前关闭。 请您解释以下行为。 public class EqAndRef { publ
Drupal 的行为到底是什么? 它为模块开发人员提供什么类型的服务层? 它映射到 jQuery.ready 的关系类型是什么? 最佳答案 长版:Drupal.behaviors 不仅仅是 jQuer
以下代码: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ for (int i=0
人们可以将项目添加到数据库中。我让他们选择在此时添加它,或手动选择日期。 因此我得到了这个 HTML 结构。 (请注意,我将日期和时间选择器妥协为只有一行文本) Selec
创建了一个数据框: simpleDF is.na(simpleDF$vals) [1] TRUE TRUE FALSE > is.nan(simpleDF$vals) [1] FALSE TRU
我有一个大的 docker 镜像 A,我创建了一个新的 Dockerfile FROM A RUN rm /big-folder 我尝试使用以下方法构建图像: docker build --squas
我想知道以下情况下 JVM 的行为是什么: JVM 最小堆大小 = 500MB JVM 最大堆大小 = 2GB 操作系统有 1GB 内存 JVM启动后,程序运行一段时间后,使用内存超过1GB。我想知道
我们正在使用 spikeearrest 策略,但我们不了解其工作原理。峰值逮捕配置如下: 5pm 阅读文档,我们了解到,如果我们在一分钟内调用此流超过 5 次,则该策略将在第 5 次之后
我正在使用 cURL 发送 POST 请求: curl http://tarvos.local:8080/partial_Users/2 -d '{currentPage : 1, firstID :
我的表中有 6442670 条记录,我正在使用以下命令获取它们jdbctemplate 使用行号一次 1000000 个。以下是查询 select * from (select rowNum rn
我是一名优秀的程序员,十分优秀!