【问题标题】:Replicate input scroll on div在 div 上复制输入滚动
【发布时间】:2019-10-23 21:59:12
【问题描述】:

我正在尝试在 div 元素上复制输入水平滚动,因此每当用户沿输入移动时,div 元素的滚动与输入完全相同。

我的问题在于 Chrome,因为似乎输入具有不同的滚动行为,导致两个元素中的 scrollLeft 值不同。在 Firefox 中,它按预期工作。

有没有办法在 Chrome 中实现这一点不使用 jQuery 或其他库?还是我在问不可能?

var theTextDiv = document.getElementById("the-text");
var theText = document.getElementById("the-text-input");

function keepScroll(txt) {
		theTextDiv.scrollLeft = theText.scrollLeft;
}

theText.addEventListener("blur", function() { keepScroll("blur"); });
theText.addEventListener("change", function() { keepScroll("change"); });
theText.addEventListener("focus", function() { keepScroll("focus"); });
theText.addEventListener("input", function() { keepScroll("input"); });
theText.addEventListener("keydown", function() { keepScroll("keydown"); });
theText.addEventListener("keyup", function() { keepScroll("keyup"); });
theText.addEventListener("scroll", function() { keepScroll("scroll"); });
theText.addEventListener("select", function() { keepScroll("select"); });
#the-text {
    border: 1px solid red;
    max-width: 98px;
    font-size: 14px;
    overflow-x: scroll;
    word-wrap: break-word;
    white-space: nowrap;
    font-family: "Times New Roman", Times, serif;
    padding: 1px;
    margin-right: 10px;
}

#the-text-input {
    border: 1px solid red;
    width: 100px;
    font-size: 14px;
    font-family: "Times New Roman", Times, serif;
}
<div id="the-text">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</div>

<input type="text" id="the-text-input" value="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." />

编辑:

我在 Mac 上的 Chrome 77 上尝试了上述代码,它按预期工作,两个元素之间没有差距,我开始认为这是 Windows 问题而不是 Chrome 问题

编辑(2):

重新启动我的电脑后,所有工作都按预期(严重)可能是某些 chrome 缓存导致出现奇怪的行为

【问题讨论】:

  • 那是实际的代码吗?它似乎在 Chrome 77 上运行良好。
  • 我已经用 Chrome 试过了,它可以工作。
  • 适用于 Windows 10 上的 Chrome 77。

标签: javascript html css google-chrome firefox


【解决方案1】:

这可能与 input 和/或 div 上的填充和边框有关,并且看起来它在 Chrome 77 中运行良好,您要么忘记在发布的示例中添加一些代码,要么这些元素的默认样式也在这里发挥作用。

无论如何,我的建议是从两个元素中删除边距、填充和边框,并添加一个包装 div 来代替(红色示例)。

您也可以使用box-sizing: border-box,保留这些样式并避免使用包装器,但paddinginput 中的行为不同,因为填充区域中的内容不可见(蓝色示例)。

最后,您更新滚动的代码在模糊时无法正常工作,因为当事件触发时,输入上的滚动尚未重置为 0。用setTimeoutwindow.requestAnimationFrame 包裹它可以解决问题。此外,后者还将使更新更加流畅和同步。

const text = document.getElementById('text');
const input = document.getElementById('input');

function updateScroll() {
  // Scroll not updated on blur without requestAnimationFrame
  // or setTimeout:
  requestAnimationFrame(() => text.scrollLeft = input.scrollLeft);
}

input.addEventListener('blur', updateScroll);
input.addEventListener('change', updateScroll);
input.addEventListener('focus', updateScroll);
input.addEventListener('input', updateScroll);
input.addEventListener('keydown', updateScroll);
input.addEventListener('keyup', updateScroll);
input.addEventListener('scroll', updateScroll);
input.addEventListener('select', updateScroll);

const textAlternative = document.getElementById('text-alternative');
const inputAlternative = document.getElementById('input-alternative');

function updateScrollAlternative() {
  // Scroll not updated on blur without requestAnimationFrame
  // or setTimeout:
  requestAnimationFrame(() => textAlternative.scrollLeft = inputAlternative.scrollLeft);
}

inputAlternative.addEventListener('blur', updateScrollAlternative);
inputAlternative.addEventListener('change', updateScrollAlternative);
inputAlternative.addEventListener('focus', updateScrollAlternative);
inputAlternative.addEventListener('input', updateScrollAlternative);
inputAlternative.addEventListener('keydown', updateScrollAlternative);
inputAlternative.addEventListener('keyup', updateScrollAlternative);
inputAlternative.addEventListener('scroll', updateScrollAlternative);
inputAlternative.addEventListener('select', updateScrollAlternative);
body {
  margin: 0;
}

.box {
  position: relative;
  display: block;
  width: 50%;
  box-sizing: border-box;
  
  /* Moved styles here: */
  border: 3px solid red;
  padding: 8px;
  margin: 8px auto 0;
}

#text,
#input,
#text-alternative,
#input-alternative {
  display: block;
  width: 100%; 
  font-size: 14px;
  font-family: monospace;
  outline: none;
}

#text,
#input {  
  /* Removed margin, padding and borders: */
  border: 0;
  padding: 0;
  margin: 0;
}

#text-alternative,
#input-alternative {
  width: 50%;
  box-sizing: border-box;
  
  /* Keep styles here thanks to box-sizing, but behaves differently: */
  border: 3px solid blue;
  padding: 8px;
  margin: 8px auto 0;
}


#text,
#text-alternative {
  word-wrap: break-word;
  white-space: nowrap;
  
  /* No need to keep it visible unless you want to scroll manually too: */
  overflow-x: hidden;
}
<div class="box">
  <div id="text">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
  </div>
</div>

<label class="box">
  <input id="input" value="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." />
</label>

<div id="text-alternative">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</div>

<input id="input-alternative" value="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." />

【讨论】:

  • @rulogaf 不客气 :) 不要忘记接受答案,如果它回答了您的问题,请点赞;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-26
相关资源
最近更新 更多