我想搜索文本到一个可滚动div和滚动到创建的元素,就像浏览器的搜索功能(CTRL + F)。这段代码只适用于前3/4次点击,之后滚动位置是完全错误的。我做错了什么?
function windowFind() {
const input = document.getElementById('input');
if ( window.find(input.value, false) ) {
const s = window.getSelection();
const oRange = s.getRangeAt(0);
const oRect = oRange.getBoundingClientRect();
const wrapper = document.getElementById('wrapper');
const scrollTo = oRect.top - wrapper.offsetTop;
wrapper.scrollTo({ top: scrollTo });
}
}
<input type="text" id="input" value="stackoverflow"><button type="button" onclick="windowFind()">Search</button>
<div id="wrapper" style="height: 200px; width: 100%; display: block; overflow: auto">
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 1</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 2</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 3</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 4</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 5</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 6</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 7</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 8</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 9</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 10</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 11</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 12</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 13</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 14</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 15</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 16</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 17</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 18</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 19</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 20</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 21</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 22</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow</div>
</div>
在您的代码中,您忘记计算包装器的实际scrollTop。
那么在第一次点击scrollTo后将其附加到默认滚动条上,因此为0之后就会得到负值和错误值
将wrapper.scrollTop
添加到您的const scrollTo
是您搜索的:)
function windowFind() {
const input = document.getElementById('input');
const wrapper = document.getElementById('wrapper');
if ( window.find(input.value, false) ) {
const s = window.getSelection();
const oRange = s.getRangeAt(0);
const oRect = oRange.getBoundingClientRect();
const scrollTo =( oRect.top - wrapper.offsetTop)+wrapper.scrollTop;
wrapper.scrollTo({ top: scrollTo });
}
}
//Can be shorten to
windowFindShort = () => {
const e = document.getElementById("input"),
t = document.getElementById("wrapper");
if (window.find(e.value, !1)) {
const e = window.getSelection().getRangeAt(0).getBoundingClientRect();
t.scrollTo({
top: e.top - t.offsetTop + t.scrollTop
})
}
};
<input type="text" id="input" value="stackoverflow"><button type="button" onclick="windowFind()">Search</button>
<button type="button" onclick="windowFindShort()">Search (short verison)</button>
<div id="wrapper" style="height: 200px; width: 100%; display: block; overflow: auto">
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 1</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 2</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 3</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 4</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 5</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 6</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 7</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 8</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 9</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 10</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 11</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 12</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 13</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 14</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 15</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 16</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 17</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 18</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 19</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 20</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow 21</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow 22</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block; background-color: lightgray;">stackoverflow</div>
<div style="height: 100px; width: 100%; display: block">stackoverflow</div>
</div>