使用其编辑器进行并排降价预览滚动

时间:2015-03-25 12:31:07

标签: javascript jquery html markdown

我的左侧是Markdown编辑器,右侧是HTML预览。

如何使预览滚动到与编辑器相同的位置。

4 个答案:

答案 0 :(得分:5)

答案 1 :(得分:1)

您链接的示例只是将滚动条对齐到相同的高度,它似乎没有对元素进行任何智能匹配。

所以一个好的开始只是对齐滚动条。

答案 2 :(得分:1)

试试这个:

var $elements = $('textarea');

var sync = function(e){
    var $other = $elements.not(this).off('scroll'), other = $other.get(0);
    var percentage = this.scrollTop / (this.scrollHeight - this.offsetHeight);
    other.scrollTop = percentage * (other.scrollHeight - other.offsetHeight);
    setTimeout( function(){ $other.on('scroll', sync ); },10);
}

$elements.on( 'scroll', sync);

小提琴:http://jsfiddle.net/b75KZ/5/

虽然,我不确定它是否是您想要的textarea,也许是div来显示呈现的HTML?

如果是这样,只需将html中的元素和jQuery中的选择器更改为var $elements = $('textarea, div#html');,并确保为id设置div属性。

此外,如果您在页面上有多个textarea并希望更具体,只需将选择器更改为var $elements = $('textarea#markdown, div#html');并相应地更新标记,例如

<textarea id="markdown">...</textarea>
<div id="html">...</div>

答案 3 :(得分:0)

我已经为PanWriter实现了此功能。

this commit的要点:

var editor = ... // a CodeMirror editor instance
var frameWindow = document.querySelector('iframe').contentWindow; // my preview frame
var scrollMap;

editor.on("scroll", function() {
  if (!scrollMap) {
    buildScrollMap(editor, 10);
  }
  frameWindow.scrollTo(0, scrollMap[scrollTop]);
});

function buildScrollMap(editor, editorOffset) {
  // scrollMap maps source-editor-line-offsets to preview-element-offsets
  // (offset is the number of vertical pixels from the top)
  scrollMap = [];
  scrollMap[0] = 0;

  // lineOffsets[i] holds top-offset of line i in the source editor
  var lineOffsets = [undefined, 0]
    , knownLineOffsets = []
    , offsetSum = 0
    ;
  editor.eachLine( function(line) {
    offsetSum += line.height;
    lineOffsets.push(offsetSum);
  });

  var lastEl;
  frameWindow.document.querySelectorAll('body > [data-source-line]').forEach( function(el){
    // for each element in the preview with source annotation
    var line = parseInt(el.getAttribute('data-source-line'), 10)
      , lineOffset = lineOffsets[line]
      ;
    // fill in the target offset for the corresponding editor line
    scrollMap[lineOffset] = el.offsetTop - editorOffset;
    knownLineOffsets.push(lineOffset)

    lastEl = el;
  });
  if (lastEl) {
    scrollMap[offsetSum] = lastEl.offsetTop + lastEl.offsetHeight;
    knownLineOffsets.push(offsetSum);
  }

  // fill in the blanks by interpolating between the two closest known line offsets
  var j = 0;
  for (var i=1; i < offsetSum; i++) {
    if (scrollMap[i] === undefined) {
      var a = knownLineOffsets[j]
        , b = knownLineOffsets[j + 1]
        ;
      scrollMap[i] = Math.round(( scrollMap[b]*(i - a) + scrollMap[a]*(b - i) ) / (b - a));
    } else {
      j++;
    }
  }
}

要使其正常工作,您需要在HTML输出上使用源代码行注释(例如,使用markdown-it-source-map)。

当然,您还必须按照相反的方式进行操作(滚动预览时,使编辑器滚动),并根据布局确定边缘情况/偏移量。但这是基本算法。

您可能希望将其包装在_.throttle之类的东西中。