javascript - 棱镜JS : Centering Highlighted Lines Vertically

标签 javascript html css

PrismJS是网页源代码的语法高亮器。它有一个 line-highlight突出显示源代码中某些行的插件。特别是,该插件支持确定要从散列中突出显示的行(例如,#play.5-6 表示要突出显示 <pre> 元素的第 5 行到第 6 行,其中 idplay)。

对于那个散列,the plugin uses scrollIntoView() 确保突出显示的行可见:

document.querySelector('.temporary.line-highlight').scrollIntoView();

(此处 line-highlight 作为一个类添加到行中)

然而,scrollIntoView()将突出显示的行放在顶部。在我的用例中,最好让突出显示的行垂直居中,假设突出显示的范围比可用空间短。

为了使那些突出显示的行垂直居中,我应该用什么替换上面的行?

FWW:

  • 虽然我可以使用 CSS/JS,但我不是专家

  • 如果重要的话,我的用例是在 WebView 中显示这段代码Android 应用中的小部件

最佳答案

这是一个在滚动时将突出显示的行居中的函数(假设滚动条位于 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);
  }
}

关于javascript - 棱镜JS : Centering Highlighted Lines Vertically,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35182928/

相关文章:

php - 鼠标悬停透明div类显示图片

html - 用特定格式的数据库条目替换一行 HTML

jquery - Javascript,为所有相同类型的元素添加动态类

html - 如何删除 IE 边缘中特殊字符周围的边框?

css - 将背景图像添加到 Font Awesome 图标

javascript - html表格单元格以更好的方式显示在输入框中输入的文本

javascript - Angular : Using a sprite sheet with ng-repeat

javascript - 将 webpack 升级到版本 5 后出现运行时错误 : Buffer is not defined

javascript - 如何使用 CSS 使 Angular Material slider 垂直?

javascript - 根据第一个下拉菜单禁用第二个下拉选项