I'm trying to highlight text based on whether it's matched with a string recieved from a database or not. To show the problem, here's an example.
Given this text:
<div class='text'>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
And this text:
<div id='matchingHighlight'>
Lorem ipsum <!-- Highlight this text within <div id='text'></div> !-->
</div>
How would I highlight the text within .text that matches with the text from #matchingHighlight (Lorem ipsum)?
To 'highlight' the keyword / phrases, you will need to wrap it around any inline element. I'm suggesting you use <span> tag.
The following logic will replace the text with the same text wrapped inside a span tag with a class of .highlight
$(document).ready(function() {
var $text = $('.text');
var textToHighlight = $('#matchingHighlight').text().trim();
var textCurrent = $text.html().trim();
var isTextExists = textCurrent.indexOf(textToHighlight) > -1;
if(isTextExists) {
textCurrent = textCurrent.replace(textToHighlight, "<span class='highlight'>" + textToHighlight + "</span>");
$text.html(textCurrent);
}
});
You can then style it using css, for example
.highlight {
background: yellow;
}
https://pastebin.com/vaB3wa96
Related
I have some plain text content in paragraphs inside a <main> HTML element.
the paragraphs are separated by new lines (\n), not in <p> tags, and I would like to automatically wrap them in <p> tags using JavaScript.
Example content:
<main>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
<img src="img/testimg.jpg"> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</main>
Inside of <main> there may be <img> elements.
I want the script to watch for these and leave them untouched. It breaks the HTML (no image is rendered, and dev tools show overflow) if the script tries to wrap them like: <p><img src="img/testimg.jpg"></p> (assuming that is what it is doing).
My script so far:
var maintext = document.getElementsByTagName('main')[0]; // get the first (0th) <main> element
var arr = maintext.textContent.split(/[\r?\n]+/); // split the text inside into an array by newline
// regex matches one OR MORE consecutive newlines, which prevents empty <p></p> being captured
arr.forEach(function(part, index) {
if (!this[index].includes("<img ")) {
this[index] = "<p>" + this[index] + "</p>"; // wrap each paragraph with <p> tags
}
}, arr);
var rejoined = arr.join("\r\n"); // join the array to remove commas, with newlines as separators
maintext.innerHTML = rejoined; // replace contents of our <main> element with the new text
I believe the problem may be that <img> is not captured as text along with the textContent of <main>, but instead remains recognized as a child node and it's messing up the array.
You can see my attempt to only wrap in <p> if that array element does not (!) contain "<img " ...however, this is not working. It seems the enclosed HTML elements do not get matched as string data by includes.
What's the best way to go about this?
To retain non-text content like images, you'll need to process the text nodes of the main element rather than using textContent, since that's just the text content of the element.
Assuming you only want to do this with the text nodes, you can loop through the element's nodes, split text nodes on line breaks, and if you get more than one segment, insert paragraphs for them. Something like this (see inline comments):
function convertLineBreaksToParagraphs(element) {
// Get a snapshot of the child nodes of the element; we want
// a snapshot because we may change the element's contents
const nodes = [...element.childNodes];
// Loop through the snapshot
for (const node of nodes) {
// Is this a text node?
if (node.nodeType === Node.TEXT_NODE) {
// Yes, split it on line breaks
const parts = node.nodeValue.split(/\r\n|\r|\n/);
// Did we find any?
if (parts.length > 1) {
// Yes, loop through the "paragraphs"
for (const part of parts) {
// Create an actual paragraph for it
const p = document.createElement("p");
p.textContent = part;
// Insert in in front of the text node it came from
element.insertBefore(p, node)
}
// Remove the text node we've replaced with paragraphs
element.removeChild(node);
}
}
}
}
convertLineBreaksToParagraphs(document.querySelector("main"));
<main>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
<img src="img/testimg.jpg"> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</main>
You may need to tweak that a bit, depending on how you want to handle that image just before the fifth paragraph. The above leaves the image outside the paragraph. But if you wanted it to be inside the paragraph, you could add some logic to do that.
function convertLineBreaksToParagraphs(element) {
let img = null;
// Get a snapshot of the child nodes of the element; we want
// a snapshot because we may change the element's contents
const nodes = [...element.childNodes];
// Loop through the snapshot
for (const node of nodes) {
// Is this a text node?
if (node.nodeType === Node.TEXT_NODE) {
// Yes, split it on line breaks
const parts = node.nodeValue.split(/\r\n|\r|\n/);
// Did we find any?
if (parts.length > 1) {
// Yes, loop through the "paragraphs"
for (const part of parts) {
// Create an actual paragraph for it
const p = document.createElement("p");
p.textContent = part;
// If we *just* saw an image before this text node,
// move it into the paragraph
if (img) {
p.insertBefore(img, element.firstChild);
img = null;
}
// Insert in in front of the text node it came from
element.insertBefore(p, node)
}
// Remove the text node we've replaced with paragraphs
element.removeChild(node);
}
} else if (node.nodeName === "IMG") {
img = node;
} else {
img = null;
}
}
}
convertLineBreaksToParagraphs(document.querySelector("main"));
<main>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
<img src="img/testimg.jpg"> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</main>
You may have people telling you to do this by manipulating the HTML from innerHTML, but the problem with doing that is you run the risk of introducing tags in the middle of a tag (and you will remove any event handlers when you set innerHTML on main). For instance, if you have:
<img
src="/path/to/something">
you'd end up with
<img
<p> src="/path/to/something"></p>
...which is obviously not good.
I am trying to wrap the first letter of each word in my heading tags with a span class so that I can style them using CSS. I have tried to use a snippet I've found on here, but I have 2 h1 tags and it is taking the first one and repeating it for the second!
The function is this:
<script>
$(document).ready(function() {
var words = $('h1').text().split(' ');
var html = '';
$.each(words, function() {
html += '<span class="firstLetter">' + this.substring(0, 1) + '</span>' + this.substring(1) + ' ';
$('h1').html(html);
});
});
</script>
So I have an h1 in the banner at the top, and another one at the start of the content, but the function is taking the top banner heading and replacing the content heading with it, but the span class is working!
I know you shouldn't have 2 h1s, but I want to target all headings anyway, and its a CMS for a client so I can't guarantee they won't use multiple h1 going forwards, so I am testing it out!
Recursively loop over the text nodes inside the headings and then wrap the words within a span and replace the text node with a container span that holds all the wrapped words.
Then style the first letter of these spans using the ::first-letter CSS pseudo element.
NOTE:
Directly replacing the innerHTML of the headings might cause bugs if the headings have elements in them.
For ex: In the snippet below, the headings have some elements within them. The first one has an anchor element and the second one has an svg and these are common use cases. But if you directly replace the innerHTML of these headings that would eliminate these elements inside them, which is not desired. So, it's essential that you only wrap the text nodes within a span.
::first-letter only works with block-level elements, so you need to set the display property of spans to inline-block.
const headingEls = document.querySelectorAll("h1");
function wrapWithSpan(node) {
if (node.nodeName === "#text") {
const containerSpan = document.createElement("span");
containerSpan.innerHTML = node.textContent
.split(" ")
.map((word) => `<span class="word-span">${word}</span>`)
.join(" ");
node.parentNode.replaceChild(containerSpan, node);
} else {
Array.from(node.childNodes).forEach(wrapWithSpan);
}
}
headingEls.forEach(wrapWithSpan);
a[href^="#"] {
display: inline-block;
text-decoration: none;
color: #000;
}
a[href^="#"]:hover,
a[href^="#"]:hover *,
a[href^="#"]:focus,
a[href^="#"]:focus * {
text-decoration: underline;
}
a[href^="#"]:hover::after,
a[href^="#"]:focus::after {
color: #aaa;
content: "#";
margin-left: 0.25rem;
font-size: 0.75em;
}
h1 .word-span {
display: inline-block;
}
h1 .word-span::first-letter {
color: palevioletred;
text-transform: uppercase;
}
<h1 id="heading">Heading with link</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<h1>Heading with SVG <svg height="20" width="20"><circle cx="10" cy="10" r="10" fill="green" /></svg></h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
If you just want to style the first letter of each heading, you don't need JS, you can do it by using only the ::first-letter CSS pseudo element.
a[href^="#"] {
text-decoration: none;
color: #000;
}
a[href^="#"]:hover,
a[href^="#"]:focus {
text-decoration: underline;
}
a[href^="#"]:hover::after,
a[href^="#"]:focus::after {
color: #aaa;
content: "#";
margin-left: 0.25rem;
font-size: 0.75em;
}
h1::first-letter {
color: palevioletred;
text-transform: uppercase;
}
<h1 id="heading">Heading with link</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<h1>Heading with SVG <svg height="20" width="20"><circle cx="10" cy="10" r="10" fill="green" /></svg></h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
const h1 = document.getElementsByTagName("H1");
for (const item of h1) item.innerHTML = item.innerText.split(" ").map(word => "<span style='color: red !important;'>" + word[0] + "</span>" + word.slice(1)).join(" ")
Assuming that the your h1 tags have no children. Its easy to modify this to get the correct result though.
As per OP's request, this will "wrap the first letter of each word".
Since there are two <h1> elements (as OP said, very wrong), one should iterate them using each too, same way OP did with the words array.
$(document).ready(function() {
$('h1').each( function(index, heading) {
const words = $(heading).text().split(' ')
let html = '';
$.each(words, function() {
html += '<span class="firstLetter">'+this.substring(0,1)+'</span>'+this.substring(1) + ' ';
})
$(heading).html(html);
})
});
span.firstLetter {
color: violet;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>Lorem ipsum dolor sit amet</h1>
<hr>
<h1>Bacon ipsum dolor amet biltong pork chop bacon</h1>
This should work:
.firstLetter
{
color:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>Hello World</h1>
<h1>Goodbye World</h1>
<script>
var h1s = document.getElementsByTagName('h1');
for(const h1 of h1s)
{
let text = h1.innerText.split(' ');
let html = "";
for(const word of text)
{
html += '<span class="firstLetter">' + word.substring(0, 1) + '</span>' + word.substring(1) + ' ';
}
h1.innerHTML = html;
}
</script>
To style each first letter of every word in every heading, you can use jQuery's .html() (as you're using jQuery in your question). This will loop over each h1, and replace the text within it with the returned value. The new value replaces the first letter of each word (referred to using $& in the replacement argument) matched using the regular expression \b\w (which matches a word boundary (\b) followed by a character (\w)) with the character itself wrapped in <span> tags:
$("h1").html(function(i, txt) {
return txt.replace(/\b\w/g, '<span class="firstLetter">$&</span>');
});
.firstLetter {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>This is a heading</h1>
<h1>This is another heading</h1>
I have a variable called output in Javascript, which has the following content.
var output = "something."
I want to search and highlight the words "word1" and "word2" in them when I display the content of output. The above content is dynamic. Assuming I have a variable output which has the text and an array called arr1 which has the elements to be searched and highlighted, how can I display the entire content with words highlighted in javascript?Please let me know. Thanks in advance.
Assuming you want literal phrases that are generally just words (no special characters or punctuation), you could use a regular expression similar to this (I've also added case insensitivity):
var output = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
var arr1 = ['eiusmod tempor', 'consectetur'];
var regex = new RegExp('('+arr1.join('|')+')', 'gi');
output = output.replace(regex, "<b>$1</b>");
// the following line is for debug purposes only. I've added it
// to better display what's happening just for the Stackoverflow
// code snippet editor.
document.body.innerHTML = output;
b {
background: yellow;
font-weight: normal;
}
Edit:
Quick edit to include logic that ensures "consectrtur" is matched, but "consecteturs" is not. It just needs a simple look ahead of (?!\\w) and a "look behind" (not a real look behind because javascript doesn't support it) of (\\W+|^) ensuring the matched term is not surrounded by word characters, and thus not part of a different word.
var output = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse consecteturs cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum";
var arr1 = ['eiusmod tempor', 'consectetur', 'orem', 'laborum'];
var regex = new RegExp('(\\W+|^)('+arr1.join('|')+')(?!\\w)', 'gi');
output = output.replace(regex, "$1<b>$2</b>");
// the following line is for debug purposes only. I've added it
// to better display what's happening just for the Stackoverflow
// code snippet editor.
document.body.innerHTML = output;
b {
background: yellow;
font-weight: normal;
}
You can wrap the words you want highlighted with a <span> tag then add a class or inline styling to the tag for your highlight color. This would require that you identify the words you want highlighted and add the opening tag before and closing tag after with a String.replace(word, tag + word + closing_tag) or something similar.
To wrap something in HTML using Javascript, you should be looking at Regex. For example:
str = str.replace(/(neoplasm)/ig, "<b>$1</b>");
To replace from an array, you could do something like connecting your strings with a join using the regex OR: | to generate a custom regex string, matching those words.
EDIT: Like Joseph just suggested, just one minut before me.
Here is what I have so far and here is the link to see it online.
p { line-height: 2; }
.highlight { background-color: yellow; }
The goal is to wrap the quoted content like below (no border is necessary but I want the whole background including the space between lines to be colored)
I see that the picture isn't clear but I hope you can figure out the idea.
The current version only highlights the lines and the space between lines(due to line height being taller than 1) is not highlighted.
Is there any way to achieve this either in CSS or in JavaScript?
One way to do this is to give the marked text a top and bottom padding.
p {line-height:2}
mark {padding:.5em 0}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
<mark>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</mark>
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
Hi you can use the span tag and set the background of that span so it will work like
<p>this is the dummy text without any background <span style='background:yellow'> This text with the background colour</span> this text have no background</p>
After highlighting text, I would like to obtain the paragraph in which the selected text resides.
var select = window._content.document.getSelection();
Any pointers please?
This is actually rather hard to do because you have to consider six cases:
The selection is not within a paragraph (easy);
The entire selection is within one paragraph (easy);
The entire selection crosses one or more sibling paragraphs (harder);
The selection starts or ends in an element not within a paragraph (harder);
The paragraphs spanned are at different levels eg one is within a list item while two others are siblings of the list (even harder); and
Some combination of the above.
So firstly you have to decide how complete you want the solution to be. I'll only cover the simplest cases of (1) and (2).
function getSelectedParagraphText() {
if (window.getSelection) {
selection = window.getSelection();
} else if (document.selection) {
selection = document.selection.createRange();
}
var parent = selection.anchorNode;
while (parent != null && parent.localName != "P") {
parent = parent.parentNode;
}
if (parent == null) {
return "";
} else {
return parent.innerText || parent.textContent;
}
}
Note: If you're after tags too replace textContent with innerHTML.
Edit: Better version put in, including better browser compatibility.
I found this useful example.
It seems that some browsers support window.getSelection() while others support document.getSelection(). The example handle all these cases.
select.anchorNode.parentNode will return the parent node, in your case the tag and you can then get the text of that node.
var x = window.getSelection()
var z = x.anchorNode.parentNode
alert(z.innerHTML)
Make sure you look at window.getSelection() as well since document.getSelection is depreciated in firefox.
$.event.props.push('onTextSelect');
$(document).click(function(){
var str=window.getSelection().anchorNode.data;
var str=str.substring(window.getSelection().anchorOffset,window.getSelection().focusOffset);
if(str)
$(window.getSelection().focusNode.parentNode).trigger({type:'onTextSelect',text:str});
});
$('p').on('onTextSelect',function(e){
console.log($(this).attr('class'))
$('p:last').text(e.text);
});
html
<div><p class="p">some text</p></div>
<p></p>
You can find the fiddle here https://jsfiddle.net/q9nkc0fd/6/
A new project is born from jsmatita:
http://takenotes.sourceforge.net/
(it's in italian language)
I reproduced code from answer above from #Thiago Souza and created a snippet for that purpose for those who can provide a correct answer.
function getSelectedParagraph(){
const selection = window.getSelection();
let parent = selection.anchorNode;
while (parent != null && parent.nodeName != "P") {
parent = parent.parentNode;
};
console.log(parent);
return parent;
};
window.onload = getSelectedParagraph();
<div class='paragraph-container'>
<p id='paragraph-01'>
Paragraph 1: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<p id='paragraph-02'>
Paragraph 2: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<p id='paragraph-03'>
Paragraph 3: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
function getSelectedParagraph(){
const selection = window.getSelection();
let parent = selection.anchorNode;
while (parent != null && parent.nodeName != "P") {
parent = parent.parentNode;
}
return parent;
}