2016-09-05 2 views
0

У меня есть текст с каждым словом, обернутым элементом span, чтобы сделать их доступными для кликов. Я хочу, чтобы вы могли выделить раздел текста, щелкнув первое и последнее слова для выделения, а затем нажмите отдельную кнопку, чтобы выполнить выделение (т. Е. Обернуть каждое слово между первым и последним выбранными словами и включить их). Комментарий будет добавлен после выделенного раздела. Я добилась прогресса и получили до этой части:jQuery: wrapAll() элементы span при сохранении пробелов

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"> 

JavaScript:

$('#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() не кажется, чтобы сохранить пространство между обернутых span элементами

Как на самом деле это не нужно, потому что они не в JQuery набор вы сказали, что вы хотели, чтобы обернуть. 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. Вы должны получить textNode также с помощью contents() метод в 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">