2015-05-04 68 views
7

可以說我有一個句子:「這是一個測試句子。」我希望用戶能夠選擇文本的小節,但沒有標點符號或不完整的單詞。如何擴展選定的文本以包含整個單詞

所以「測試句子」。應該成爲 「試驗一句」 和 「EST sentenc」 應該也成爲 「試驗一句」

這裏是我當前的代碼:

var getSelectedText = function() { 
    var text = ""; 
    if (window.getSelection) { 
     text = window.getSelection().toString().trim(); 
    } else if (document.selection && document.selection.type != "Control") { 
     text = document.selection.createRange().text; 
    } 
    return text; 
} 

FYI:jQuery代碼就可以了。

編輯爲Bender:

好吧,這幾乎是存在的。我有超過5萬句和用戶的選擇是可變的,所以我必須做這樣的事情:

var selection = getSelectedText(); 
var exp = new RegExp("\\w*" + selection + "\\w+"); 
text.match(exp); 

然而,這將不匹配如果用戶沒有選擇「測試一句」這是更容易比不。

+4

我會用一個正則表達式來匹配整個單詞。這是一個基礎示例:https://regex101.com/r/xW0mR8/1您必須對其進行增強才能使其適用於任何選擇案例 – BeNdErR

+0

@BeNdErR聰明! :) – Nico

+0

@BeNdErR請參閱我的編輯。 –

回答

2

有趣的挑戰。

下面的代碼將類別爲selected的範圍內的選擇進行包裝。

它抓住previousSiblingnodeValue並獲得由非單詞字符分割相應的文本的新元件–的nextSibling,和彈出(previousSibling)或移位(nextSibling)。

然後刪除selected範圍(同時保留其內容)。這必須在超時內完成,以便元素有時間添加到DOM。

此時,我們剩下三個相鄰的文本節點。代碼通過在文檔主體上調用normalize()來加入它們。

$(document).mouseup(function() { 
 
    alert(getSelectedText()); 
 
}); 
 

 
var getSelectedText = function() { 
 
    var el= document.createElement('span'), 
 
     sel= window.getSelection().getRangeAt(0), 
 
     prev= '', 
 
     next= ''; 
 
    
 
    el.className= 'selected'; 
 
    sel.surroundContents(el); 
 
    if(!sel.toString().match(/^\W/)) { 
 
    prev= el.previousSibling.nodeValue; 
 
    if(prev.match(/\W$/)) { 
 
     prev= ''; 
 
    } 
 
    else { 
 
     prev= prev.split(/\W/).pop(); 
 
    } 
 
    } 
 
    if(!sel.toString().match(/\W$/)) { 
 
    next= el.nextSibling.nodeValue; 
 
    if(next.match(/^\W/)) { 
 
     next= ''; 
 
    } 
 
    else { 
 
     next= next.split(/\W/).shift(); 
 
    } 
 
    } 
 
    setTimeout(function() { 
 
    $('.selected').contents().unwrap() 
 
    $('.selected').remove(); 
 
    document.body.normalize(); 
 
    }); 
 
    return prev+sel.toString()+next; 
 
}
.selected { 
 
    color: red; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
This is a test sentence. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

0

我設法得到它的工作通過增加跨到每個字。這個想法是,你將無法選擇少於一個跨度/單詞,這樣整個跨度將被選中。 這個答案不依賴於jQuery

function customSelect(target, onSelect) { 
 
    var oldHTML = target.innerHTML; 
 
    
 
    // this is the regex that wraps the words with spans: 
 
    target.innerHTML = oldHTML.replace(/[\d\w']+[\s,.]*/g, '<span>$&</span>'); 
 
    var spans = target.querySelectorAll('span'); 
 
    
 
    // I used a basic blue/white style, but you can change it in the CSS 
 
    // using the ".text-selected" selector 
 
    var alreadySelected = []; 
 
    var setSpanOn = function(span) { 
 
    alreadySelected.push(span); 
 
    span.className = 'text-selected'; 
 
    }; 
 
    var setSpanOff = function(span) { 
 
    span.className = ''; 
 
    }; 
 
    
 
    // here starts the logic 
 
    var isSelecting = false; 
 
    for (var i=0, l=spans.length; i<l; i++) { 
 
    (function span_handlers(span, pos) { 
 
    
 
     // when the user starts holding the mouse button 
 
     span.onmousedown = function() { 
 
     // deselect previous selection, if any: 
 
     alreadySelected.splice(0).forEach(setSpanOff); 
 
     
 
     // and enable selection: 
 
     isSelecting = true; 
 
     span.onmouseenter(); 
 
     }; 
 
     
 
     // the main logic, we check if we need to set or not this span as selected: 
 
     span.onmouseenter = function() { 
 
     if (!isSelecting) 
 
      return; 
 
     
 
     // if already selected 
 
     var j = alreadySelected.indexOf(span); 
 
     if (j >= 0) { 
 
      // then deselect the spans that were selected after this span 
 
      alreadySelected.splice(j+1).forEach(setSpanOff); 
 
     } 
 
     else { 
 
      // else if is not the first, check if the user selected another word 
 
      // one line down or up. This is done by checking the indexes: 
 
      if (alreadySelected.length) { 
 
      var last = alreadySelected[alreadySelected.length-1]; 
 
      var posLast = [].indexOf.call(spans, last); 
 
      var typeSibling = pos > posLast ? 'nextSibling' : 'previousSibling'; 
 
      while (1) { 
 
       last = last[typeSibling]; 
 
       if (last !== span) 
 
       setSpanOn(last); 
 
       else break; 
 
      } 
 
      } 
 
      setSpanOn(span); 
 
     } 
 
     }; 
 
     
 
     // when the user hold up the mouse button: 
 
     span.onmouseup = function() { 
 
     isSelecting = false; 
 
     
 
     // call the onSelect function passing the selected spans content: 
 
     if (typeof onSelect === 'function') { 
 
      var spansSelected = target.querySelectorAll('.text-selected'); 
 
      var text = [].map.call(spansSelected, function(span) { 
 
      return span.textContent || ''; 
 
      }).join('').trim(); 
 
      onSelect(text); 
 
     } 
 
     }; 
 
    })(spans[i], i); 
 
    } 
 
}; 
 

 
// Usage: 
 
var element = document.getElementById('target'); 
 
var onSelect = function(text) { 
 
    console.log(text); 
 
}; 
 
customSelect(element, onSelect);
#target { 
 
    user-select: none; 
 
} 
 

 
.text-selected { 
 
    background-color: blue; 
 
    color: white; 
 
}
<div id="target"> 
 
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. 
 
</div>

我記錄了一些意見的代碼,但是如果你有任何疑問,隨時問。

希望它有幫助:)

相關問題