Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
115 views
in Technique[技术] by (71.8m points)

javascript - Some parts of the html page are automatically highlighted after changing html

I am using jQuery to highlight some similar parts of the words in HTML page. To highlight the similar words, I tried to change html content. So at first, I get html content of the element. And change that html by adding span tag to highlight similar words in specific color. I could make the html content successfully and I replace the html content by using jQuery. But the problem is here. Some parts of the text are automatically highlighted when changing html content. When I comment that part, it does not happen. So I think the problem is here.

Here is the screenshot of the problem

For example, when I select 42, from first part of html to the 42 are automatically highlighted.

Here is my html file. https://drive.google.com/file/d/1lWlZW1psmYLIr7g-nQahWzyPVoN1q-hT/view?usp=sharing

Appreciate any help. Thanks

var selection = '';
var selectedObj = null;
var originHTML = $('#mainContent').html();
$('#mainContent').mousemove(function(event) {
    getSelectedText();
    if (selectedObj.focusNode) {
        var wholeText = selectedObj.focusNode.nodeValue;
        if (wholeText != null ) {
            var startOffset = (selectedObj.baseOffset > selectedObj.focusOffset ? selectedObj.focusOffset : selectedObj.baseOffset);
            var endOffset = (selectedObj.baseOffset > selectedObj.focusOffset ? selectedObj.baseOffset : selectedObj.focusOffset);
            var selectedText = wholeText.slice(startOffset, endOffset);
            if (selectedText != '' && selectedText != ' ' && selectedText != '.' && selectedText != ',' && selectedText != '(' && selectedText != ')' && selectedText != '+' && selectedText != '=' && selectedText != '/' ) {
                if (selection != selectedText) {
                    selection = selectedText;
                    if (wholeText != null ) {                   
                        if (
                            (wholeText[startOffset - 1] >= '0' && wholeText[startOffset - 1] <= '9') || 
                            (wholeText[startOffset - 1] >= 'a' && wholeText[startOffset - 1] <= 'z') || 
                            (wholeText[startOffset - 1] >= 'A' && wholeText[startOffset - 1] <= 'Z') ||
                            (wholeText[endOffset] >= '0' && wholeText[endOffset] <= '9') || 
                            (wholeText[endOffset] >= 'a' && wholeText[endOffset] <= 'z') || 
                            (wholeText[endOffset] >= 'A' && wholeText[endOffset] <= 'Z')
                        ) {
                        } else {
                            var wholeHtml = originHTML;
                            var newTag = '<span class="selectedCom">' + selectedText + '</span>';
                            var inCompleteNewTag = '<span class="selectedIncom">' + selectedText + '</span>';
                            var indicies = [];
                            var indic = -1;
                            while (1) {
                                indic = wholeHtml.indexOf(selectedText, indic + 1);
                                if (indic == -1) {
                                    break;
                                }
                                indicies.push(indic);
                            }
                            var searchIndex = 0;
                            for (searchIndex = indicies.length - 1; searchIndex >= 0; searchIndex --) {
                                var strIndex = indicies[searchIndex];
                                if (
                                    (wholeHtml[strIndex - 1] >= '0' && wholeHtml[strIndex - 1] <= '9') || 
                                    (wholeHtml[strIndex - 1] >= 'a' && wholeHtml[strIndex - 1] <= 'z') || 
                                    (wholeHtml[strIndex - 1] >= 'A' && wholeHtml[strIndex - 1] <= 'Z') ||
                                    (wholeHtml[strIndex + selectedText.length] >= '0' && wholeHtml[strIndex + selectedText.length] <= '9') || 
                                    (wholeHtml[strIndex + selectedText.length] >= 'a' && wholeHtml[strIndex + selectedText.length] <= 'z') || 
                                    (wholeHtml[strIndex + selectedText.length] >= 'A' && wholeHtml[strIndex + selectedText.length] <= 'Z')
                                ) {
                                } else {
                                    while (1) {
                                        if (wholeHtml[strIndex] == '<' || wholeHtml[strIndex] == '>') {
                                            break;
                                        }
                                        strIndex --;
                                    }
                                    if (wholeHtml[strIndex] == '>') {
                                        var prevString = wholeHtml.slice(0, indicies[searchIndex] );
                                        var lastString = wholeHtml.slice(indicies[searchIndex] + selectedText.length, wholeHtml.length);
                                        wholeHtml = prevString + (indicies.length == 1 ? inCompleteNewTag : newTag) + lastString;
                                    }
                                }
                            }
                            $('#mainContent').html(wholeHtml);
                        }
                    }
                }
            }
        }
    }
});

$('#mainContent').mousedown(function() {
    if (selection == undefined || selection == null || selection != '') {
        selection = '';
        $('#mainContent').html(originHTML);         
    }
});

function getSelectedText() {
    if (window.getSelection) {
        selectedObj = window.getSelection();
        return window.getSelection().toString();
    } 
    else if (document.selection) {
        return document.selection.createRange().text;
    }
    return '';
}
question from:https://stackoverflow.com/questions/65643741/some-parts-of-the-html-page-are-automatically-highlighted-after-changing-html

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The example below works as you have requested,

  • Highlight by selection - adding a mouseup event trigger which then checks for the selected text and passes it to the highlight function
  • Highlight by input - add text to the input and then launch the search by clicking on the button. The term in the input is passed to the highlight function.

The highlight function is fully commented but it basically searches for any span.highlight and removes them (to get rid of old searches), before then wrapping the search term in new span.highlight.

Let me know if you were hoping for something else.

The code is fully commented


// Add event listener for mouseup
$(document).on("mouseup", function() {

  // Check for selected text
  var text = "";
  if (window.getSelection) {
    text = window.getSelection().toString();
  } else if (document.selection && document.selection.type != "Control") {
    text = document.selection.createRange().text;
  }

  // Check if selection exists
  if (text != "") {

    // Highlight text
    highlight(text);

  }

});


// Add event trigger to button
$("#highlightButton").click(function() {

  // Load term to search for
  term = $("#highlightTerm").val();

  // Highlight text
  highlight(term);

});



// Create highlight function
function highlight(term) {

  // Cycle through all highlightable content
  $(".highlightable").each(function() {

    // Cycle through each highlighted span
    $("span.highlight").each(function() {

      // Replace it without the highlight span
      $(this).replaceWith($(this).html());

    });

    // Get inner HTML
    iHTML = $(this).html();

    // Create regex
    // g - global
    // m - multiline
    regex = new RegExp(term, "gm")

    // Create replacement span
    rep = "<span class='highlight'>" + term + "</span>"

    // Replace search term with highlight span
    iHTML = iHTML.replace(regex, rep);

    // Update original element
    $(this).html(iHTML);

  });

}
span.highlight {
  background: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="highlightable">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ut felis consectetur, sagittis mi eu, aliquet leo. Quisque vitae lobortis mauris. Nam consectetur, nibh vel porttitor auctor, urna ex semper erat, non ullamcorper neque lacus vel diam. In
  aliquet ipsum rutrum est rutrum pulvinar. Morbi sem ante, ornare non leo ut, dapibus lacinia lectus. Praesent euismod sagittis orci, ac scelerisque turpis vehicula et. Aenean eget sodales enim. In vitae eleifend leo. Duis tempor ultrices odio. Nullam
  condimentum ullamcorper risus eu ornare. Sed efficitur ipsum nec vulputate eleifend. Morbi vitae cursus mi. Pellentesque et molestie erat. Nullam vitae nisl quis nibh congue ullamcorper. Nullam tincidunt congue ligula non tempor.
</div>
<input id="highlightTerm">
<button id="highlightButton">Search</button>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...