2017-05-23 77 views
4

我使用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?

還有其他一些關於SO的問題,顯示如何根據id獲取列號。在我的情況下,沒有身份證。唯一可用的是文本(或行),我需要通過搜索Html內容來獲得列號。

目前,我有兩個「解決方案」來獲得列號,但它們不完整。

1)我可以通過使用window.find(text)找到文本是否存在,之後我不知道該怎麼做。

2)另一種選擇是將<span>與一個id臨時添加到每一行並將其刪除。一旦添加,我可以得到總列數達到該行(如下所示)。

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

如果行被擴展到另一列,這將給出錯誤的數字。

第二種解決方案非常棘手,書籍內容非常龐大。我不認爲這是獲得列號的最佳方式。我正在尋找更簡單的解決方案。

+0

我正在爲Android電子書應用程序開發此應用程序,任何在電子書應用程序上工作的android開發人員也可能知道JavaScript開發人員的答案。另外,你的javascript解決方案最終會從android'webView.loadUrl()'中調用。 –

+0

請不要鏈接到您自己的問題中的其他問題。應該發佈問題以便自己依賴,而不需要其他問題等外部資源。如果該問題被刪除,該怎麼辦?你的問題被打破了。將相關代碼粘貼到自己的問題中,以便人們瞭解您正在處理的內容。 – Glubus

+0

@Glubus這個鏈接應該給我一個關於我在做什麼和我已經達到多遠的背景。用戶可以提供解決方案,而無需通過鏈接。我不認爲這個問題太多依賴於共享的問題。另外,我不確定分享哪些代碼。它只是一個常規的HTML文件,包含頭部,body標籤和幾行javascript,可將單個頁面拆分爲多個列。沒有什麼比這更多的了。如果你想要一個特定的代碼部分,你覺得是相關的,需要添加讓我知道。 –

回答

3

試試這個,爲你的問題做了一個可行的版本。 jsfiddle link

儘管OP沒有用jQuery標記問題,但實際上在問題中使用了jQuery,我也使用它來獲得更簡潔的代碼。(和適應問題)

我在這個例子中做什麼:

  1. 使一個長期的內容跨越多個頁面可視化頁面(用CSS:列寬度)。
  2. 點擊上一頁/下一頁瀏覽頁面。
  3. 輸入並單擊'查找'按鈕,使找到的文本突出顯示。
  4. 列出所有找到輸入文本的列(頁)。
  5. 點擊鏈接並跳轉到搜索文本欄。

詳細地說,我製作了臨時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); 
    } 
    }); 
+0

如果我註釋掉這行'if(first){first = false;繼續; }' –

+0

你能告訴我布爾型「第一個」的目的是什麼? –

+0

@SrikarReddy,因爲我放在頂部的輸入框將匹配第一個'window.find'。我會給jsfiddle添加評論。你可以自由刪除它=) – Val

0

您可以在預先添加<span>之前暫時將其插入到找到文本的位置,並在您確定位置後立即將其刪除。

關鍵是如何在長文檔中查找文本。該任務的接口是TreeWalker,它可以迭代DOM子樹中的每個文本節點。

如何在文本節點中插入元素是從here複製的。

你的問題沒有說明,但使用jQuery作爲依賴。該解決方案僅使用香草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> 

搜索'狐狸跳過'不會找到這句話。

+0

儘管OP沒有要求jQuery。無論如何,移除了 –

+0

,計算相對偏移量時出現錯誤。 – ccprog