マウスクリックで、div内の単語を削除できるようにします。正常に動作します。jsFiddleを参照してください。シングルクリックは一度だけ動作します
唯一の問題は、シングルクリック機能がの最初のクリックでのみ機能することです。その後、ダブルクリックする必要があります。
なぜ私はこのような振る舞いをしているのか、頭を悩ますことはできません。たぶんあなたはできる?
// highlight a word/term quicker and smarter: so.com/a/35103840/1185126
jQuery(document).ready(function(e){
(function(els){
// variable declaration for previous range info
// and function for finding the sibling
var prevRangeInfo = {},
findSibling = function(thisNode, direction){
// get the child node list of the parent node
var childNodeList = thisNode.parentNode.childNodes,
children = [];
// convert the child node list to an array
for(var i=0, l=childNodeList.length; i<l; i++) children.push(childNodeList[i]);
return children[children.indexOf(thisNode) + direction];
};
for(var i=0;i<els.length;i++){
var el = els[i];
el.addEventListener('mouseup',function(evt){
if (document.createRange) { // Works on all browsers, including IE 9+
var selected = window.getSelection();
// Removing the following line from comments will make the function drag-only
/* if(selected.toString().length){ */
var d = document,
nA = selected.anchorNode,
oA = selected.anchorOffset,
nF = selected.focusNode,
oF = selected.focusOffset,
range = d.createRange(),
rangeLength = 0;
range.setStart(nA,oA);
range.setEnd(nF,oF);
// Check if direction of selection is right to left
if(range.startContainer !== nA || (nA === nF && oF < oA)){
range.setStart(nF,oF);
range.setEnd(nA,oA);
}
// Extend range to the next space or end of node
while(range.endOffset < range.endContainer.textContent.length && !/\s$/.test(range.toString())){
range.setEnd(range.endContainer, range.endOffset + 1);
}
// Extend range to the previous space or start of node
while(range.startOffset > 0 && !/^\s/.test(range.toString())){
range.setStart(range.startContainer, range.startOffset - 1);
}
// Remove spaces
if(/\s$/.test(range.toString()) && range.endOffset > 0)
range.setEnd(range.endContainer, range.endOffset - 1);
if(/^\s/.test(range.toString()))
range.setStart(range.startContainer, range.startOffset + 1);
// Store the length of the range
rangeLength = range.toString().length;
// Check if another range was previously selected
if(prevRangeInfo.startContainer && nA === nF && oA === oF){
var rangeTryContain = d.createRange(),
rangeTryLeft = d.createRange(),
rangeTryRight = d.createRange(),
nAp = prevRangeInfo.startContainer;
oAp = prevRangeInfo.startOffset;
nFp = prevRangeInfo.endContainer;
oFp = prevRangeInfo.endOffset;
rangeTryContain.setStart(nAp, oAp);
rangeTryContain.setEnd(nFp, oFp);
rangeTryLeft.setStart(nFp, oFp-1);
rangeTryLeft.setEnd(range.endContainer, range.endOffset);
rangeTryRight.setStart(range.startContainer, range.startOffset);
rangeTryRight.setEnd(nAp, oAp+1);
// Store range boundary comparisons
// & inner nodes close to the range boundary --> stores null if none
var compareStartPoints = range.compareBoundaryPoints(0, rangeTryContain) === 0,
compareEndPoints = range.compareBoundaryPoints(2, rangeTryContain) === 0,
leftInnerNode = range.endContainer.previousSibling,
rightInnerNode = range.startContainer.nextSibling;
// Do nothing if clicked on the right end of a word
if(range.toString().length < 1){
range.setStart(nAp,oAp);
range.setEnd(nFp,oFp);
}
// Collapse the range if clicked on last highlighted word
else if(compareStartPoints && compareEndPoints)
range.collapse();
// Remove a highlighted word from left side if clicked on
// This part is quite tricky!
else if(compareStartPoints){
range.setEnd(nFp,oFp);
if(range.startOffset + rangeLength + 1 >= range.startContainer.length){
if(rightInnerNode)
// there is a right inner node, set its start point as range start
range.setStart(rightInnerNode.firstChild, 0);
else {
// there is no right inner node
// there must be a text node on the right side of the clicked word
// set start of the next text node as start point of the range
var rightTextNode = findSibling(range.startContainer.parentNode, 1),
rightTextContent = rightTextNode.textContent,
level=1;
// if beginning of paragraph, find the first child of the paragraph
if(/^(?:\r\n|[\r\n])|\s{2,}$/.test(rightTextContent)){
rightTextNode = findSibling(rightTextNode, 1).firstChild;
level--;
}
range.setStart(rightTextNode, level);
}
}
else
range.setStart(range.startContainer, range.startOffset + rangeLength + 1);
}
// Remove a hightlighted word from right side if clicked on
// This part is also tricky!
else if (compareEndPoints){
range.setStart(nAp,oAp);
if(range.endOffset - rangeLength - 1 <= 0){
if(leftInnerNode)
// there is a right inner node, set its start point as range start
range.setEnd(leftInnerNode.lastChild, leftInnerNode.lastChild.textContent.length);
else {
// there is no left inner node
// there must be a text node on the left side of the clicked word
// set start of the previous text node as start point of the range
var leftTextNode = findSibling(range.endContainer.parentNode, -1),
leftTextContent = leftTextNode.textContent,
level = 1;
// if end of paragraph, find the last child of the paragraph
if(/^(?:\r\n|[\r\n])|\s{2,}$/.test(leftTextContent)){
leftTextNode = findSibling(leftTextNode, -1).lastChild;
level--;
}
range.setEnd(leftTextNode, leftTextNode.length - level);
}
}
else
range.setEnd(range.endContainer, range.endOffset - rangeLength - 1);
}
// Add previously selected range if adjacent
// Upgraded to include previous/next word even in a different paragraph
else if(/^[^\s]*((?:\r\n|[\r\n])|\s{1,})[^\s]*$/.test(rangeTryLeft.toString()))
range.setStart(nAp,oAp);
else if(/^[^\s]*((?:\r\n|[\r\n])|\s{1,})[^\s]*$/.test(rangeTryRight.toString()))
range.setEnd(nFp,oFp);
// Detach the range objects we are done with, clear memory
rangeTryContain.detach();
rangeTryRight.detach();
rangeTryLeft.detach();
}
// Save the current range --> not the whole Range object but what is neccessary
prevRangeInfo = {
startContainer: range.startContainer,
startOffset: range.startOffset,
endContainer: range.endContainer,
endOffset: range.endOffset
};
// Clear the saved range info if clicked on last highlighted word
if(compareStartPoints && compareEndPoints)
prevRangeInfo = {};
// Remove all ranges from selection --> necessary due to potential removals
selected.removeAllRanges();
// Assign the current range as selection
selected.addRange(range);
// Detach the range object we are done with, clear memory
range.detach();
el.style.MozUserSelect = '-moz-none';
// Removing the following line from comments will make the function drag-only
/* } */
} else {
// Fallback for Internet Explorer 8 and earlier
// (if you think it still is worth the effort of course)
}
});
/* This part is necessary to eliminate a FF specific dragging behavior */
el.addEventListener('mousedown',function(e){
if (window.getSelection) { // Works on all browsers, including IE 9+
var selection = window.getSelection();
selection.collapse (selection.anchorNode, selection.anchorOffset);
} else {
// Fallback for Internet Explorer 8 and earlier
// (if you think it still is worth the effort of course)
}
el.style.MozUserSelect = 'text';
});
}
})(document.getElementsByClassName('taggable'));
});
// remove selected text
jQuery(document).ready(function() {
jQuery('.taggable').bind("mouseup", function() {
var text1;
if (window.getSelection().toString() != "") {
selectedText = window.getSelection().toString()
text1 = jQuery(".taggable").text().split("")
pointStart = window.getSelection().anchorOffset
pointEnd = window.getSelection().focusOffset
if (pointEnd < pointStart) {
pointStart = pointEnd
}
text1.splice(pointStart, selectedText.length);
text1 = text1.join("")
} else {
selectedText = jQuery(".taggable").text()
text1 = selectedText;
}
jQuery(".taggable").text(text1);
});
});
この質問の相対的な複雑さを考えると、私は一度資格を50ポイントでそれを報奨金なります。 –
コンソールのエラーはどうですか?あなたはそれを調査しましたか? 'Uncaught WrongDocumentError: 'Range'で 'compareBoundaryPoints'を実行できませんでした。ソース範囲はこの範囲とは異なるドキュメントにあります。 ' –
'引数 'は最初のクリック後にオブジェクトになっていません。あなたはこれを解決する方法を知っていますか? –