簡體   English   中英

一次單擊僅一次

[英]Single-click only works once

我想允許用戶通過一個單一的鼠標點擊刪除一個div話。 工作正常,請參閱jsFiddle

唯一的問題是單擊功能僅在第一次單擊時起作用。 之后,您需要雙擊。

我無法理解為什么它會像這樣。 也許你可以? 可能是jQuery(document).ready() ...

jQuery的:

// 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);

    });
});

這可能無法解決您的問題,但這是另一種方法。
此代碼將每個單詞包裝在一個范圍內,並為每個單詞創建一個事件偵聽器。


的HTML

<p>This is an example text</p>


Java腳本

jQuery(document).ready(function($) {
    var text = $('p').text();
    var arr = text.split(' ');

    $('p').html('');

    for (var i = 0; i < arr.length; i++) {
        $('<span />').html(arr[i] + ' ').appendTo('p');

        $('p').on('click', 'span:nth-of-type(' + (i + 1) + ')', function() {
            $(this).remove();
        });
    }
});

我發現主要問題是因為如果anchorOffset等於focusOffset ,則它不起作用,因此,可能的解決方案是在相等時添加+1,然后代碼將按預期工作,因為它找到了子串時至少一個字母。 更改代碼:

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;

var selected = window.getSelection();
                    var offset = selected.focusOffset;
                    if(selected.anchorOffset == selected.focusOffset)
                          offset++;
                    // 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 = offset,
                        range = d.createRange(),
                        rangeLength = 0;

我已經在JFiddle上進行了多次測試,並且工作正常,但是我仍然擔心這會導致其他一些問題。

如果您遇到任何問題,請通知我,我會幫助您。

編輯:

jsFiddle

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM