-7

suppose to be we have a paragraph with this content " Hi , It's a new question in stackoverflow!"
and when we are selecting something in this paragraph , it's turn to be Red .for example we selected stackoverflow & then it turn to <span class="red">stackoverflow</span>.how can we do this with Javascript?
here is my codes :

var x = {};
x.getSelected = function() {
    var t = '';
    if (window.getSelection) {
        t = window.getSelection();

    } else if (document.getSelection) {
        t = document.getSelection();

    } else if (document.selection) {
        t = document.selection.createRange().text;

    }
    return t;
}

$(document).ready(function() {
  var selectedText;
    $(document).bind("mouseup", function() {
      selectedText = x.getSelected()
      if (selectedText !=''){
      alert(selectedText);
//Now I wanna set new content for selected item but not working
        a=selectedText;
        selectedText.html("<span class='red'>"+a+"</span>");
        
      }
    });
});
.red {
  color : red;
}
<p>suppose to be we have a paragraph with this content " Hi , It's a new question in stackoverflow!" and when we are selecting something in this paragraph , it's turn to be Red .for example we selected stackoverflow & then it turn to .how can we do this with Javascript? </p>
2 ChangeZ
  • 31
  • 5
  • It's much more involved than it seems like it might be, mostly because of cross-browser differences. You need to get a Range object for the selected text, split the text node into three parts, insert a `span` element, take the second part and put it in the span, insert the span where the second part of the text used to be... The range part is the part I don't personally know. Tim Down's done a handy lib for it called rangy, though, which could probably help. – T.J. Crowder Dec 07 '15 at 15:12
  • Not the right question for Stackoverflow. You should at least show the code you have created thus far. – Luis Miguel Dec 07 '15 at 15:12

3 Answers3

1

...when we are selecting something in this paragraph , it's turn to be Red...

You could have a stab at the styleWithCSS command of the editing API, execCommand that is.

However, before proceeding please note that:

This spec is incomplete and it is not expected that it will advance beyond draft status. Authors should not use most of these features directly, but instead use JavaScript editing libraries. The features described in this document are not implemented consistently or fully by user agents, and it is not expected that this will change in the foreseeable future.... This spec is to meant to help implementations in standardizing these existing features. It is predicted that in the future both specs will be replaced by Content Editable Events and Input Events....

Having clarified that, the following will work in most modern browsers viz. Edge, FireFox and Chrome that I could test in.

By default the foreColor command of execCommand wraps the selected text with a font tag, which is deprecated. So, you need to use the styleWithCSS command. Now this works with the editing API, which means that the element you are trying to work with, should have its contentEditable attribute set.

To work around this, you can temporarily set this attribute just before changing the color in the selected text fragment and then resetting the attribute once done.

Given your paragraph like this:

<p id="p">
  Hi , It's a new question in StackOverflow!
</p>

When you select the word StackOverflow, the following code will result in this...

<p id="p">
  Hi , It's a new question in <span style="color: rgb(255, 0, 0);">StackOverflow</span>!
</p>

... wrapping your selected text in a span with the style applied.

Fiddle: http://jsfiddle.net/abhitalks/j9w6dj7m/

Snippet:

p = document.getElementById('p');
p.addEventListener('mouseup', setColor);
function setColor() {
    p.setAttribute('contentEditable', true);
    document.execCommand('styleWithCSS', false, true);
    document.execCommand('foreColor', false, "#f00");
    p.setAttribute('contentEditable', false);
}
<p id="p" contentEditable="false">
    Hi , It's a new question in stackoverflow!
</p>

Edit:

Now that you have added code (and what you have already tried) in your question, you could use the range selection to do what you are after.

Specifically, you will need to learn:

  1. selection: https://developer.mozilla.org/en-US/docs/Web/API/Selection, this you have already done. Cheers!
  2. range: https://developer.mozilla.org/en-US/docs/Web/API/Range/Range, because you will be dealing with ranges here
  3. selection.getRangeAt(): https://developer.mozilla.org/en-US/docs/Web/API/Selection/getRangeAt, because you will need to extract the selected text as a range object
  4. range.surroundContents(): https://developer.mozilla.org/en-US/docs/Web/API/range/surroundContents, because you will need to surround the selected text range with a span.

Putting it all together all you have to do is (explanation in code comments):

function setClass() {
    var selection = x.getSelected(), range, // you have already done this
        span = document.createElement("span"); // create a span element
    span.classList.add('red'); // add the class to the span
    if (selection != '') {
      range = selection.getRangeAt(0); // get the range from selected text
      range.surroundContents(span); // surround the range with span
    }  
}

Fiddle 2: http://jsfiddle.net/abhitalks/kn0u5frj/

Snippet 2:

var x = {}, 
    p = document.getElementById('p');

p.addEventListener('mouseup', setClass);

function setClass() {
    var selection = x.getSelected(), range, 
        span = document.createElement("span");
    span.classList.add('red');
    if (selection != '') {
        range = selection.getRangeAt(0);
        range.surroundContents(span);
    }  
}

x.getSelected = function() {
    var t = '';
    if (window.getSelection) {
        t = window.getSelection();
    } else if (document.getSelection) {
        t = document.getSelection();
    } else if (document.selection) {
        t = document.selection.createRange().text;
    }
    return t;
}
.red { color: #f00; }
<p id="p">
  Hi , It's a new question in stackoverflow!
</p>
Abhitalks
  • 25,725
  • 4
  • 53
  • 74
  • 1
    Nice to see a *real* answer to this question! I thought of `execCommand`, but didn't think to just temporarily toggle `contenteditable` on. – T.J. Crowder Dec 07 '15 at 16:02
  • thanks , it's very good solution but now i wanna add class or later add another attributes in span so do you have another solution? – 2 ChangeZ Dec 07 '15 at 16:25
  • @2ChangeZ: Good that you added what you have attempted in your question. This makes it a good question. I have edited my answer to include the class related solution. – Abhitalks Dec 07 '15 at 16:40
-1

You can use the getSelection() method

Below is the example:

Repeated Question: How to get selected text in textarea?

Community
  • 1
  • 1
Gopi
  • 759
  • 1
  • 7
  • 12
-1

You can use CSS with :: selection http://caniuse.com/#search=%3A%3Aselection

::selection {
  background: #ffb7b7; /* WebKit/Blink Browsers */
}
::-moz-selection {
  background: #ffb7b7; /* Gecko Browsers */
}

Or javascript with range

Dux
  • 299
  • 1
  • 4