Skip to content

Commit

Permalink
feat: add highlight cross line
Browse files Browse the repository at this point in the history
  • Loading branch information
zou8944 committed Jul 8, 2024
1 parent d218d38 commit 249cc6a
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 15 deletions.
32 changes: 32 additions & 0 deletions content/content.css
Original file line number Diff line number Diff line change
Expand Up @@ -267,4 +267,36 @@
::highlight(search-results-focus) {
background-color: var(--highlight-search-result-focus-bg-color);
color: var(--highlight-search-result-focus-color);
}

#find-lite-highlight-line-x {
display: none;
position: fixed;
top: 200px;
left: 0;
padding: 0;
margin: 0;
height: 0;
width: 100vw;
z-index: 999998;
border-top: 2px orange dotted;
border-left: 0;
border-right: 0;
border-bottom: 0;
}

#find-lite-highlight-line-y {
display: none;
position: fixed;
top: 0;
left: 200px;
padding: 0;
margin: 0;
height: 100vw;
width: 0;
z-index: 999998;
border-top: 0;
border-left: 2px orange dotted;
border-right: 0;
border-bottom: 0;
}
29 changes: 29 additions & 0 deletions content/listener.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ FindLite.listener = (function () {
let ranges = [];
let currentIndex = 0;
let selectRange = null;
let highlightScrollEventElements = []

self.registerAllListeners = function () {
FindLite.panel.element.searchField.oninput = self.findInputChangeListener;
Expand Down Expand Up @@ -125,6 +126,7 @@ FindLite.listener = (function () {
if (ranges.length > 0) {
FindLite.page.highlight(ranges);
FindLite.page.highlightFocused(ranges[currentIndex]);
bindHighlightLineScrollEvent();
}
}

Expand All @@ -136,6 +138,33 @@ FindLite.listener = (function () {
FindLite.panel.clearSearchField();
FindLite.panel.disableNaviButton();
FindLite.panel.hideSidebar();
unbindHighlightLineScrollEvent();
}

function bindHighlightLineScrollEvent() {
window.addEventListener("scroll", updateHighlightLinePosition);
let ele = ranges[currentIndex].commonAncestorContainer;
while (ele) {
if (ele.nodeType === Node.ELEMENT_NODE) {
if (ele.scrollHeight > ele.clientHeight || ele.scrollWidth > ele.clientWidth) {
ele.addEventListener("scroll", updateHighlightLinePosition)
highlightScrollEventElements.push(ele);
}
}
ele = ele.parentElement;
}
}

function unbindHighlightLineScrollEvent() {
window.removeEventListener("scroll", updateHighlightLinePosition)
highlightScrollEventElements.forEach(function (element) {
element.removeEventListener("scroll", updateHighlightLinePosition)
})
highlightScrollEventElements = [];
}

function updateHighlightLinePosition() {
FindLite.page.updateHighlightLine(ranges[currentIndex]);
}

return self;
Expand Down
62 changes: 47 additions & 15 deletions content/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ FindLite.page = (function () {
};

self.expandRange = function (range) {
if (!range) {
return
}
// 递归遍历 range 的父节点,如果存在 details 节点,则让其展开
let parentNode = range.commonAncestorContainer
while (parentNode) {
Expand All @@ -76,55 +79,84 @@ FindLite.page = (function () {
return;
}

const rect = range.getBoundingClientRect();
// 如果 rect 已经在视窗内,则不需要滚动
if (rect.top >= 0 && rect.bottom <= window.innerHeight) {
return;
}

// 如果 rect 的父元素中存在 aside,则先将 aside 移动到视窗内,再将 rect 移动到视窗中间
let asideNode = range.commonAncestorContainer;
while (asideNode && asideNode.tagName !== "ASIDE") {
asideNode = asideNode.parentNode;
}
if (asideNode) {
console.log(asideNode)
asideNode.scrollIntoView({ behavior: 'smooth', block: 'center' })

const rect = range.getBoundingClientRect();
asideNode.scrollIntoView({behavior: 'instant', block: 'center'})
const asideRect = asideNode.getBoundingClientRect();
console.log(rect.top)
console.log(asideRect.top)
asideNode.scrollBy(0, rect.top - window.innerHeight / 2)
asideNode.scrollBy({
left: 0,
top: rect.top - window.innerHeight / 2,
behavior: "instant" // 为了让滚动后马上能够获取到 range 的位置,这里禁用掉动画
})
return;
}

// 不在 aside 中的,在整个 window 中移动
const rect = range.getBoundingClientRect();
if (rect.top >= 0 && rect.bottom <= window.innerHeight) {
return;
}
// 如果range的下半部分在视窗内,则整个range滚动到视窗
if (rect.top < 0 && rect.bottom > 0) {
const yOffset = rect.top;
window.scrollBy(0, yOffset - 2);
window.scrollBy({
left: 0,
top: yOffset - 2,
behavior: "instant"
})
return;
}
// 如果range的上半部分在视窗内,则整个range滚动到视窗
if (rect.top < window.innerHeight && rect.bottom > window.innerHeight) {
const yOffset = rect.bottom - window.innerHeight;
window.scrollBy(0, yOffset + 2);
window.scrollBy({
left: 0,
top: yOffset + 2,
behavior: "instant"
})
return;
}
// 否则,滚动到视窗的中心
const yOffset = -window.innerHeight / 2 + rect.top + rect.height / 2;
window.scrollBy(0, yOffset);
window.scrollBy({
left: 0,
top: yOffset,
behavior: "instant"
})
};

self.highlight = function (ranges) {
CSS.highlights.set("search-results", new Highlight(...ranges));
};

self.highlightFocused = function (range) {
// 高亮
CSS.highlights.set(FindLite.panel.element.currentFocusHighlightName, new Highlight(range));
// 更新定位线位置
self.updateHighlightLine(range);
// 显示定位线
FindLite.panel.element.highlightLineX.style.display = 'block';
FindLite.panel.element.highlightLineY.style.display = 'block';
};

self.updateHighlightLine = function (range) {
// 不在屏幕内就不需要更新
let rect = range.getBoundingClientRect();
FindLite.panel.element.highlightLineX.style.top = rect.top + 'px';
FindLite.panel.element.highlightLineY.style.left = rect.left + 'px';
};

self.clearAllHighlights = function () {
// 清理高亮
CSS.highlights.clear();
// 隐藏定位线
FindLite.panel.element.highlightLineX.style.display = 'none';
FindLite.panel.element.highlightLineY.style.display = 'none';
};

return self;
Expand Down
4 changes: 4 additions & 0 deletions content/panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ FindLite.panel = {
FindLite.panel.element.nextButton = document.getElementById('find-lite-next');
FindLite.panel.element.exitButton = document.getElementById('find-lite-exit');
FindLite.panel.element.sidebar = document.getElementById('find-lite-sidebar');
FindLite.panel.element.highlightLineX = document.getElementById("find-lite-highlight-line-x");
FindLite.panel.element.highlightLineY = document.getElementById("find-lite-highlight-line-y");
},
appendCSS: async function () {
function replaceURL(rawCSS, relativeURL) {
Expand Down Expand Up @@ -53,6 +55,8 @@ FindLite.panel = {
</div>
<div id="find-lite-sidebar">
</div>
<div id="find-lite-highlight-line-x"></div>
<div id="find-lite-highlight-line-y"></div>
</div>`;
const html = document.createElement("div");
html.innerHTML = rawHTML;
Expand Down

0 comments on commit 249cc6a

Please sign in to comment.