2017-04-05 59 views
3

最後一個字符我有一個​​可以包含純文本或其他HTML元素的HTML元素:查找使用jQuery

<!-- plain text --> 
<div class="content"> 
    SIMPLE TEXT. 
</div> 

<!-- or other html elements --> 
<div class="content"> 
    SIMPLE <span>TEXT.</span> 
    <table> 
    <tr> 
     <td>1</td> 
     <td>2</td> 
    </tr> 
    <tr> 
     <td>a</td> 
     <td>b</td> 
    </tr> 
    </table> 
</div> 

<!-- more html elements --> 
<div class="content"> 
    SIMPLE <span>TEXT.</span> 
    <div> 
    OTHER TEXT WITH MORE <span>HTML!</span> 
    </div> 
</div> 

<!-- one more example --> 
<div class="content"> 
    SIMPLE <span>TEXT.</span> 
    <div> 
    OTHER TEXT WITH MORE <span>HTML</span>! 
    </div> 
</div> 

我怎麼能在我的.content DIV多了一個HTML元素追加到最後一個可打印的字符,不管在哪個HTML元素中該字符是?

預期的結果:

<!-- plain text --> 
<div class="content"> 
    SIMPLE TEXT.<span class="end"></span> 
</div> 

<!-- or other html elements --> 
<div class="content"> 
    SIMPLE <span>TEXT.</span> 
    <table> 
    <tr> 
     <td>1</td> 
     <td>2</td> 
    </tr> 
    <tr> 
     <td>a</td> 
     <td>b<span class="end"></span></td> 
    </tr> 
    </table> 
</div> 

<!-- more html elements --> 
<div class="content"> 
    SIMPLE <span>TEXT.</span> 
    <div> 
    OTHER TEXT WITH MORE <span>HTML!<span class="end"></span></span> 
    </div> 
</div> 

<!-- one more example --> 
<div class="content"> 
    SIMPLE <span>TEXT.</span> 
    <div> 
    OTHER TEXT WITH MORE <span>HTML</span>!<span class="end"></span> 
    </div> 
</div> 
+0

威爾l除了將元素添加到最後可讀字符之外,文檔保持靜態?如果它是靜態的,那麼可以給最後一個帶有可編輯字符的元素一個類並使用grimdog_john的解決方案。 –

回答

1

這裏是我的方法來解決這個問題,JQuery的一行一行,然後是片段示例。

  • 首先環槽每.content元件:

    $('.content').each(function(){ 
    
  • 然後,在VAR這是最後一個字符存儲:

    var ch = $(this).text().trim().slice(-1); 
    
  • 現在,因爲有時最後一個字符可以只是在textNode中,而不是在.content的孩子裏面,我們需要區分這個條件,我們可以識別最後的nodeText子女和實際最後元素。

    var lastnode = $(this).contents().last(); 
    var textnode = $(this).contents().filter(function(){ 
        return this.nodeType === 3 && $.trim(this.nodeValue) !== '';; 
    }).last(); 
    
  • 最後,如果最後一個孩子是一個textNode我們只需要append()元素添加到。內容父,otherway找到最後元素:contains我們存儲的字符,做append()

$('.content').each(function(){ 
 
    var ch = $(this).text().trim().slice(-1); 
 
    var lastnode = $(this).contents().last(); 
 
    var textnode = $(this).contents().filter(function(){ 
 
    return this.nodeType === 3 && $.trim(this.nodeValue) !== '';; 
 
    }).last(); 
 
    
 
    if (lastnode[0] == textnode[0]) { 
 
    $(this).append('<span class="end"></span>') 
 
    } else { 
 
    $(this).find(":contains('"+ch+"')").last().append('<span class="end"></span>') 
 
    } 
 
})
.end { 
 
    width: 10px; 
 
    height: 10px; 
 
    margin:0 5px; 
 
    background: purple; 
 
    display: inline-block; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<!-- plain text --> 
 
<div class="content"> 
 
    SIMPLE TEXT. 
 
</div> 
 

 
<!-- or other html elements --> 
 
<div class="content"> 
 
    SIMPLE<span>TEXT.</span> 
 
    <table> 
 
    <tr> 
 
     <td>1</td> 
 
     <td>2</td> 
 
    </tr> 
 
    <tr> 
 
     <td>b</td> 
 
     <td>b</td> 
 
    </tr> 
 
    </table> 
 
</div>

+1

太棒了!接受這個是因爲所有的解釋和嵌入式代碼片段! ;) – errata

-1
$('.content :last').append("<span class='end'></span>"); 
+3

它基於最後一個字符,而不是最後一個TD – ControlAltDel

+0

究竟是什麼@ControlAltDel說:) – errata

+0

這也假設我有'tr'元素...我更新了我的問題,使其更清楚... – errata

-2

老回答

另一種方法是使用appendTo()

$("<span class="end"></span>").appendTo(".content"); 

這將只是之前的元素追加c丟失任何具有.content標記的標記。

新建答案

不是最完美的解決方案 - 但它做什麼,你把它想

<script> 
    //Loop each DOM element with a content class 
    $(".content").each(function() { 
    //Find out what the last Text Character is in the DOM Element 
    //and use regex to determine the last position in the inner HTML 
    //(Regex excludes tags) 
    var positionToInsert = $(this).html().search("(?![^<]*>)" + 
     $(this).text().trim().charAt($(this).text().trim().length-1))+1; 

    //Insert the <span> tag at the correct position and save to string 
    var newHtml = [$(this).html().slice(0, positionToInsert), 
        "<span class='end'></span>",                 
        $(this).html().slice(positionToInsert)].join(''); 

    //Reset the HTML for the DOM element to the new string 
    $(this).html(newHtml); 
    }); 
</script> 
+1

但我想將它追加到最後一個字符,而不是最後一個元素。 – errata

+0

用自定義解決方案更新了答案。謝謝 –

0

找到最後文本,你需要這樣

遞歸函數
function getLastText(element) { 
    if (!element) return null; 
    if (element.childNodes && element.childNodes.length > 0) { 
    //alert('loop'); 
    for (var i = element.childNodes.length - 1; i >= 0; i++) { 
     var glt = getLastText(element.childNodes[i]); 
     if (glt != null) { 
     return glt; 
     } 
    } 
    } 
    if (element.textContent && element.textContent.length > 0) { 
    return element; 
    } 
    return null; 
} 

這將返回文本包含在元素中的最後一個元素NT在初始getLastText調用

1

遞歸通過你的元素,以獲得最後的文本節點

https://jsfiddle.net/30ezoyau/

<div id="content"> 
    SIMPLE <span>TEXT.</span> 
    <table> 
    <tr> 
     <td>1</td> 
     <td>2</td> 
    </tr> 
    <tr> 
     <td>a</td> 
     <td id="last">b</td> 
    </tr> 
    </table> 
</div> 

JS

// get your root element 
const tree = document.querySelector('#content') 

// flatten your tree into a list, then pop it to get last text node 
const walk = (node = {}, list = []) => { 
    // assuming you want the text node's parent node, not the text node itself 
    if (/\w{1,}/i.test(node.textContent || '') && node.nodeName !== '#text') 
    list.push(node) 
    if (node.childNodes) { 
    return [...node.childNodes].reduce((acc, child, i) => { 
     const branch = walk(child, acc) 
     return [...acc, ...branch] 
    }, []) 
    } else { 
    return list 
    } 
} 

// walk through tree to get last non-empty text node 
const lastString = walk(tree).pop() 

// append it 
lastString.innerHTML = lastString.innerHTML + `<b> is last</b>` 

// test 
console.assert(
    document.getElementById('last').innerHTML === 'b<b> is last</b>', 
    'should append span to last text' 
) 
+0

這隻適用於你在小提琴上實際擁有的html ...... #include中的額外內容,因爲textnode失敗https://jsfiddle.net/30ezoyau/1/ – DaniP