PrismJS是网页中源代码的语法高亮显示。它有一个line-highlight插件,突出显示了源代码中的某些行。特别是,该插件支持确定要从哈希中突出显示哪些行(例如,#play.5-6
表示要突出显示<pre>
元素的第5行到第6行id
play
)。
对于该哈希,the plugin uses scrollIntoView()
以确保突出显示的行可见:
document.querySelector('.temporary.line-highlight').scrollIntoView();
(此处line-highlight
作为类添加到行中)
但是,scrollIntoView()
会将突出显示的行放在顶部。在我的用例中,最好将突出显示的行垂直居中,假设突出显示的范围比可用空间短。
为了让那些突出显示的行垂直居中,我会用上面的行代替什么?
FWIW:
虽然我可以使用CSS / JS,但我不是专家
如果重要,我的用例是在Android应用中的WebView
小部件中显示此代码
答案 0 :(得分:3)
这是一个在滚动时将高亮线条居中的功能(假设滚动条位于pre
元素上):
function scrollToLines (pre) {
var lines = document.querySelector('.temporary.line-highlight'),
linesHeight = lines.offsetHeight,
preHeight = pre.offsetHeight;
lines.scrollIntoView();
if (preHeight > linesHeight && pre.scrollTop < (pre.scrollHeight - preHeight)) {
pre.scrollTop = pre.scrollTop - (preHeight / 2) + (linesHeight / 2);
}
}
在调用appyHash
函数后,只需在highlightLines
函数中调用此函数:
function applyHash() {
// ...
highlightLines(pre, range, 'temporary ');
scrollToLines(pre);
}
<强>解释强>
就像之前一样,调用scrollIntoView()
method并将pre
元素滚动到第一个突出显示的行的顶部。
如果这两个条件都属实......
preHeight > linesHeight
- 突出显示范围的高度小于pre
元素 和 的高度:pre.scrollTop < (pre.scrollHeight - preHeight)
- pre
元素未滚动到底部(即,当前滚动位置小于可用滚动高度减去pre
元素的高度)。 ...然后从当前滚动位置减去pre
元素高度的一半,并添加一半突出显示的行的高度。这样,如果范围的高度不超过pre
元素的高度,则突出显示的线将垂直居中。
基于我在编写代码时使用的实时片段的基本测试用例:
正如您在评论中指出的那样,这并不适合您,因为滚动条实际上位于body
元素上(而不是上面的pre
元素)。
要解决此问题,请更改逻辑,以使计算相对于body
元素和窗口:
function scrollToLines () {
var lines = document.querySelector('.temporary.line-highlight'),
linesHeight = lines.offsetHeight,
body = document.body,
windowHeight = window.innerHeight;
lines.scrollIntoView();
if (windowHeight > linesHeight && body.scrollTop < (body.scrollHeight - windowHeight)) {
body.scrollTop = body.scrollTop - (windowHeight / 2) + (linesHeight / 2);
}
}
以下是一些基本测试用例,证明当突出显示的范围位于顶部/底部或突出显示范围的高度超出窗口高度时,它可以正常工作:
由于您可能不知道滚动条是在pre
元素还是body
上,您可以检查pre
元素是否可以先滚动然后再回到制作相对于body
元素的计算,如果它不是
function scrollToLines (pre) {
var lines = document.querySelector('.temporary.line-highlight'),
linesHeight = lines.offsetHeight,
pre = pre.scrollHeight > pre.clientHeight ? pre : document.body,
preHeight = pre === document.body ? window.innerHeight : pre.offsetHeight;
lines.scrollIntoView();
if (preHeight > linesHeight && pre.scrollTop < (pre.scrollHeight - preHeight)) {
pre.scrollTop = pre.scrollTop - (preHeight / 2) + (linesHeight / 2);
}
}
答案 1 :(得分:0)
如果使用jQuery可以,你可以使用这样的东西:
function goToHighLight(selector, container){
document.querySelector(selector).scrollIntoView();
var scroll = document.querySelector(container).clientHeight ;
var half_scroll = scroll/2;
var selector_h = document.querySelector(selector).clientHeight/2;
var next = 0;
$(selector).nextAll().each(function( index ) {
next += this.clientHeight;
});
var prev = 0;
$(selector).prevAll().each(function( index ) {
prev += this.clientHeight;
});
if(next < half_scroll){
var diff = half_scroll-next-selector_h;
$(container).children().last().css("margin-bottom",diff);
var where_am_i = $(container).scrollTop();
$(container).scrollTop(where_am_i+diff);
}
else if(prev < half_scroll){
var diff = half_scroll-prev-selector_h;
$(container).children().first().css("margin-top",diff);
var where_am_i = $(container).scrollTop();
$(container).scrollTop(where_am_i-diff);
}
else{
var where_am_i = $(container).scrollTop();
$(container).scrollTop(where_am_i-half_scroll+selector_h);
}
}
goToHighLight("#highlight4", "#container");
$(".goH").click(function(){
goToHighLight("#"+this.id,"#container");
});
#container{
width:250px;
height: 300px;
overflow-y: auto;
overflow-x: hidden;
float:left;
}
.foo{
width:250px;
height: 600px;
display:block;
background:grey;
}
.bar{
width:250px;
height: 100px;
display:block;
background:yellow;
overflow:hidden;
}
.highlight{
width:250px;
background:green;
}
#buttons{
float:left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div class="highlight" id="highlight1">
highlight, highlight, highlight<br>
highlight, highlight, highlight<br>
highlight, highlight, highlight<br>
highlight, highlight, highlight<br>
highlight, highlight, highlight
</div>
<div class="bar">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. <br> Fusce dolor ante, luctus ut nibh in, ultrices eleifend elit.
</div>
<div class="highlight" id="highlight2">
highlight2, highlight2, highlight2<br>
highlight2, highlight2, highlight2
</div>
<div class="bar">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. <br> Fusce dolor ante, luctus ut nibh in, ultrices eleifend elit.
</div>
<div class="highlight" id="highlight3">
highlight3, highlight3, highlight3<br>
highlight3, highlight3, highlight3<br>
highlight3, highlight3, highlight3
</div>
<div class="foo">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. <br> Fusce dolor ante, luctus ut nibh in, ultrices eleifend elit.
</div>
<div class="foo">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. <br> Fusce dolor ante, luctus ut nibh in, ultrices eleifend elit.
</div>
<div class="foo">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. <br> Fusce dolor ante, luctus ut nibh in, ultrices eleifend elit.
</div>
<div class="foo">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. <br> Fusce dolor ante, luctus ut nibh in, ultrices eleifend elit.
</div>
<div class="foo">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. <br> Fusce dolor ante, luctus ut nibh in, ultrices eleifend elit.
</div>
<div class="highlight" id="highlight4">
highlight4, highlight4, highlight4<br>
highlight4, highlight4, highlight4<br>
highlight4, highlight4, highlight4<br>
highlight4, highlight4, highlight4<br>
highlight4, highlight4, highlight4<br>
highlight4, highlight4, highlight4<br>
highlight4, highlight4, highlight4
</div>
<div class="bar">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. <br> Fusce dolor ante, luctus ut nibh in, ultrices eleifend elit.
</div>
<div class="highlight" id="highlight5">
highlight5, highlight5, highlight5<br>
highlight5, highlight5, highlight5<br>
highlight5, highlight5, highlight5<br>
highlight5, highlight5, highlight5<br>
highlight5, highlight5, highlight5<br>
</div>
</div>
<div id="buttons">
<button class="goH" id="highlight1">
highlight1
</button>
<button class="goH" id="highlight2">
highlight2
</button>
<button class="goH" id="highlight3">
highlight3
</button>
<button class="goH" id="highlight4">
highlight4
</button>
<button class="goH" id="highlight5">
highlight5
</button>
</div>
尝试将highlight
div放在不同的位置。