How to wrap selected text with span and place div located relative to it in javascript?

My ultimate goal is for the user to:

  • select text from paragraph
  • wrap text in between
  • place the action button / div at the end of the selection, which they can click to take further action.

Here is my code:

function Discussion(){ var $this = this; $(document).bind("mouseup",function(){ $this.selectText($this); }); } Discussion.prototype.selectText = function($this){ var selection = $this.getSelectedText(); if(selection.length > 3){ console.log(selection); var spn = '<span class="selected">' + selection + '</span>'; $(this).html($(this).html().replace(selection, spn)); //ERROR here; it says that it can't replace() on undefined $(this).html() } } Discussion.prototype.getSelectedText = function(){ if(window.getSelection){ return window.getSelection().toString(); } else if(document.getSelection){ return document.getSelection(); } else if(document.selection){ return document.selection.createRange().text; } } 

As expected, so far I can get the selection text using window.getSelection().toString() . If I remove .toString() , I get a Selection object. With this, I can use window.getSelection().anchorNode.parentNode to get most of the information I need.

I also see that Selection.anchorOffset and Selection.extentOffset will provide me with the range of characters that I selected. Is there any way to use this information to place a range?

I think my questions will be as follows:

  • Why does this code not complete the selection in divs?
  • Would it be with multiple instances of the same text?
  • After you separate the selection using a div or an inline div block or something else, can I get (and use) its position to place an extra / div button?

Phew, thanks for your time!

Edit: I added a JS script here: http://jsfiddle.net/nn62G/

+4
source share
3 answers

The value returned by getSelectedText is a selection, not an element in the DOM. This is why your cal for the html function does not work, the choice does not have this property.

You can do what you want as follows: set the part of the document you want to process as contentEditable , for example, <p> or <div> . When you select inside this area, you can get the HTML element using document.activeElement . If you select outside the contentEdiatble , then activeElement returns a body element. activeElement YOU CAN process:

 document.activeElement.innerHTML = document.activeElement.innerHTML.replace (selection, spn); 

However, if you make parts of your document editable, other things happen that you might not want. Seriously, if the selected text appears several times, you cannot determine which one was selected, so this cannot be the solution to your problem.

Updated fiddle here

+1
source

I am going to post my js fiddle here with a solution for posterity. Thanks for all the help, everyone!

http://jsfiddle.net/prodikl/mP8KT/

 function Discussion(){ var $this = this; $(document).bind("mouseup",function(){ $this.selectText($this); }); } Discussion.prototype.selectText = function($this){ $("mark").contents().unwrap(); $("mark").remove(); var selection = $this.getSelection(); var range = selection.getRangeAt(0); var cssclass = $(selection.anchorNode.parentNode).attr("class"); if(selection.toString().length > 2){ $this.startPoint = selection.anchorOffset; $this.endPoint = selection.extentOffset; var newNode = document.createElement("mark"); range.surroundContents(newNode); $("mark").attr('title', ' '); $("mark").tooltip({ content : "<a class='content' href='http://www.google.com' target='_blank'>Here a link.</a>" }); $("mark").on('mouseleave',function(event){ event.stopImmediatePropagation(); }).tooltip("open"); } } Discussion.prototype.getSelection = function(){ if(window.getSelection){ return window.getSelection(); } else if(document.getSelection){ return document.getSelection(); } else if(document.selection){ return document.selection.createRange().text; } } var discussion = new Discussion(); 
+2
source

Well, perhaps the solution might be to find the element containing the current selection and replace it with html like this:

 // this get you all the elements (including the top parent) that contain the selection var existsInElements = $('*:contains("' + selection + '")'); // the exact element match is in the last one var exactElement = existsInElements[existsInElements.length - 1]; 

Here is the fiddle that works.

+1
source

Source: https://habr.com/ru/post/1480257/


All Articles