2016-09-05 7 views
0

각 단어를 span 요소로 감싸서 클릭 할 수있게하는 텍스트가 있습니다. 강조 표시 할 첫 단어와 마지막 단어를 클릭하여 텍스트의 한 섹션을 강조 표시 한 다음 강조 표시를 실행하는 별도의 버튼을 클릭 할 수 있기를 원합니다 (예 : 선택한 단어와 첫 단어 사이에서 모든 단어 줄 바꿈). 강조 표시된 섹션 다음에 주석이 추가됩니다. 나는 진전을했는데이 부분까지 입수했습니다 :jQuery : wrapAll()은 공백을 유지하면서 요소를 확장합니다.

html로 :

<div id="textbox"> 
<span>Foo</span> <span>foo</span> <span>foo</span> <span>foo</span> 
<span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span> 
<span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span>. 
</div> 
<input id="commentbox" placeholder="Type your comment here"> 
<button id="exechighlight" value="Highlight"> 

자바 스크립트 : 나는 잘 일을 마무리 할 수 ​​

$('#textbox > span').click(function() { 
    $(this).addClass('selected'); 
}); 

$('#exechighlight').click(function(){ 
if($('#commentbox').val() !== '') { 
    $('.selected').filter(":last").after(' <span class="comment">' + $('#commentbox').val() + '</span>'); 
} else { 
    $('.selected').filter(':last').after(' <span class="comment">Default comment</span>'); 
} 
$('.selected').filter(":first").nextUntil('.comment').andSelf().wrapAll('<span class="highlight">'); 
$('.selected').removeClass('selected'); 
$('#commentbox').val(''); 
}); 

하지만 wrapAll()하지 않는 것 포장 된 span 요소 사이의 공백을 유지합니다. CSS로 시도했지만 아무런 소용이 없습니다.

.highlight { 
    background-color: #f00; 
    white-space: pre-wrap; 
    white-space: -moz-pre-wrap; 
} 

진행 방법? 강조 표시를 취소 할 수 있어야합니다. 즉, <span class='highlight'>의 포장을 풀고 원래 간격을 유지해야합니다.

+0

당신은 당신이 ** [mcve]를 사용하여 스택 조각 (은'<>은 ** 실행 가능한로 그 코드 블록을 설정하는 경우가 ** 매우 ** 쉽게 도움을 만들 것 툴바 버튼). –

+0

지적 해 주셔서 감사합니다. 나는 질문을 게시 할 필요가있을 때를 기억할 것입니다! – TwoRE

답변

0

하지만 wrapAll()들은 jQuery를 당신이 포장 원한다고 설정하지이기 때문에, 랩 span 요소로서 참으로

말아야 사이의 공간을 유지하지 않는 것 같습니다. nextUntil은 텍스트 노드가 아닌 요소 만 찾습니다.

스팬 사이의 텍스트 노드를 포함하여 jQuery 세트를 직접 작성해야합니다. 주석을 참조하십시오 :

$("#btn").on("click", function() { 
 
    // Find the selected span 
 
    var sel = $(".selected"); 
 
    
 
    // Find the comment span (raw, no jQuery wrapper) 
 
    var comment = sel.siblings(".comment")[0]; 
 
    
 
    // Gather up all nodes (including text nodes) following it, up until the comment element 
 
    var node = sel[0]; 
 
    var nodes = []; 
 
    while (node && node !== comment) { 
 
    nodes.push(node); 
 
    node = node.nextSibling; 
 
    } 
 
    
 
    // Disregard final text node if any 
 
    if (nodes.length && nodes[nodes.length - 1].nodeType === 3) { 
 
    --nodes.length; 
 
    } 
 
    
 
    // Get a jQuery set for them, and wrap it 
 
    $(nodes).wrapAll("<span class='wrapper'></span>"); 
 
});
.wrapper { 
 
    border: 1px solid red; 
 
}
<div> 
 
    <span class="selected">one</span> 
 
    <span>two</span> 
 
    <span>three</span> 
 
    <span class="comment">The comment</span> 
 
</div> 
 
<input type="button" id="btn" value="Click Me"> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

0

nextUntil() 방법은 textnode 포함되지 않습니다. textNodecontents() 메소드를 jQuery에서 얻어야합니다.

$('#textbox > span').click(function() { 
 
    $(this).addClass('selected'); 
 
}); 
 

 
$('#exechighlight').click(function() { 
 
    if ($('#commentbox').val() !== '') { 
 
    $('.selected').filter(":last").after(' <span class="comment">' + $('#commentbox').val() + '</span>'); 
 
    } else { 
 
    $('.selected').filter(':last').after(' <span class="comment">Default comment</span>'); 
 
    } 
 
    getAllNode($('.selected').filter(":first").nextUntil('.comment').andSelf()).wrapAll('<span class="highlight">'); 
 
    $('.selected').removeClass('selected'); 
 
    $('#commentbox').val(''); 
 
}); 
 

 
// method for getting the element which also includes textnode 
 
function getAllNode($sel) { 
 
    // get the first element from selector 
 
    var $first = $sel.first(), 
 
    // get the last element from selector 
 
    $last = $sel.last(), 
 
    // flag variable for filter method 
 
    match = false; 
 
    // get all nodes includes text node of it's parent 
 
    return $sel.parent().contents().filter(function() { 
 
    // filter out element eleemnt in between the first and last including the first and last 
 
    if ($(this).is($first) || $(this).is($last)) { 
 
     match = !match; 
 
     return true; 
 
    } 
 
    return match; 
 
    }); 
 
}
.highlight { 
 
    background-color: #f00; 
 
    white-space: pre-wrap; 
 
    white-space: -moz-pre-wrap; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="textbox"> 
 
    <span>Foo</span> <span>foo</span> <span>foo</span> <span>foo</span> 
 
    <span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span> 
 
    <span>foo</span> <span>foo</span> <span>foo</span> <span>foo</span>. 
 
</div> 
 
<input id="commentbox" placeholder="Type your comment here"> 
 
<button id="exechighlight" value="Highlight">