PrismJS:垂直居中突出显示的线条

时间:2016-02-03 16:48:09

标签: javascript html css

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小部件中显示此代码

2 个答案:

答案 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放在不同的位置。