如何根据文本获取列号

时间:2017-05-23 09:35:53

标签: javascript html

我已使用following steps将Html内容(属于电子书)分成多个列。

1)我在容器内的内容中添加了HTML。

<body>
<div id="container">
    <div id="content">

        BOOK HTML CONTENT

        <span id="endMarker"></span>
    </div>
</div>
</body>

2)接下来,我添加了内容和容器的CSS样式,如下所示:

#container {
    width: 240px;
    overflow: hidden;
    background-color: yellow;
}
#content {
     position: relative;
     height: 30em;

    -moz-column-width: 240px;
    -webkit-column-width: 240px;
    column-width: 240px;

    -moz-column-gap: 10px;
    -webkit-column-gap: 10px;
    column-gap: 10px;
}

现在,我想使用javascript找到文本(或一行)的列号?

还有其他问题,显示如何根据ID获取列号。就我而言,没有身份证。唯一可用的是文本(或行),我需要通过搜索Html内容来获取列号。

目前,我有两个“解决方案”来获取列号,但它们不完整。

1)我可以使用window.find(text)找到文本是否存在,之后我不确定我该做什么。

2)另一种选择是临时向每行添加<span>并删除它。添加后,我可以将总列数计算到该行(如下所示)。

columnCount = Math.floor($('#marker').position().left/(columnWidth + columnGap));

如果该行扩展到另一列,这将给出错误的数字。

第二个解决方案很棘手,书籍内容很大。我不认为这是获取列号的最佳方法。我正在寻找一个更简单的解决方案。

2 个答案:

答案 0 :(得分:3)

试试这个,为你的问题制作一个可行的版本。 jsfiddle link

虽然OP没有使用jQuery标记问题,但实际上在问题中使用了jQuery,我也使用它来获得更清晰的代码。 (并且适合问题)

我在这个例子中做了什么:

  1. 跨多个页面制作一个长内容,以显示分页(使用css:column-width)。
  2. 点击上一页/旁边的浏览页面。
  3. 输入并点击“查找”&#39;按钮,突出显示找到的文本。
  4. 列出使用输入文本找到的所有列(页面)。
  5. 点击链接并跳转到包含搜索文字的列。
  6. 详细地说,我创建了临时DOM元素来计算列,并在之后立即删除它们以保持DOM树的清洁。

    2017/6/1已编辑:为搜索文本添加了突出显示颜色。

      $('#find').click( () => {
        var text = $('#findtext').val();
        var columns = [];
    
        var doms = [];
        while (window.find(text, false)) {
          var sel = window.getSelection();
          if (sel) {
            var range = sel.getRangeAt(0);
    
            var el = document.createElement("span");
            var frag = document.createDocumentFragment();
            frag.appendChild(el);
            range.insertNode(frag);
    
            columns.push(Math.floor(el.offsetLeft/(_columnWidth + _columnGap)));
            doms.push(el);
          }
        }
    
        /// distinct
        columns = columns.filter( (value, index, self) => self.indexOf(value) === index );
    
        /// show result    
        $("#foundlist").empty();
        for (var i=0; i<columns.length; i++)
          $("#foundlist").append(`<li><a href="#" onclick="setColumn(${columns[i]})">Found in Column ${columns[i]+1}</a></li>`);
    
        /// remove dom. keep dom tree clean
        while (doms.length > 0) {
          var dom = doms.pop();
          dom.parentNode.removeChild(dom);
        }
      });
    

答案 1 :(得分:0)

您可以暂时将其插入找到文字的位置,然后在确定位置后立即将其删除,而不是事先添加<span>

关键是如何在长文档中查找文本。此任务的接口是TreeWalker,它可以遍历DOM子树中的每个文本节点。

如何在here

中复制在文本节点中间插入元素

您的问题没有说明,但使用jQuery作为依赖项。此解决方案仅使用vanilla DOM接口。

var columnWidth = 240,
    columnGap   = 10;

function getColumn(text) {
  // the subtree to search in
  var root = document.getElementById('content');
  // define an iterator that only searches in text nodes
  var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
    // filter the text nodes to those containing the search text
    acceptNode: function(node) {
      if ( node.data.includes(text) ) {
        return NodeFilter.FILTER_ACCEPT;
      }
    }
  });

  // look if there is a result
  if (treeWalker.nextNode()) {
    var node = treeWalker.currentNode;

    // get start index of found text
    var index = node.data.indexOf(text);
    // and split into two nodes, referencing the second part
    var foundTextNode = node.splitText(index);

    // define an empty inline element
    var span = document.createElement('span');
    // insert it between the two text nodes
    var elem = node.parentElement;
    elem.insertBefore(span, foundTextNode);

    // compute the column from the position of the element
    // you might have to account for margins here
    var x = span.getBoundingClientRect().left - root.getBoundingClientRect().left;
    var column = Math.floor(x / (columnWidth + columnGap));

    // restore previous state
    elem.removeChild(span);
    elem.normalize();

    return column;
  } else {
    // no result
    return false;
  }
}

此解决方案的明显限制是它不会找到跨越多个节点的文本。所以,如果你有一个文本片段

<p>The quick brown fox <em>jumps</em> over the lazy dog.</p>

搜索“狐狸跳过”&#39;不会找到这句话。