name - selección de usuario de JavaScript resaltado
html body (6)
Aquí hay un código completo para resaltar y resaltar el texto
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.highlight
{
background-color: yellow;
}
#test-text::-moz-selection { /* Code for Firefox */
background: yellow;
}
#test-text::selection {
background: yellow;
}
</style>
</head>
<body>
<div id="div1" style="border: 1px solid #000;">
<div id="test-text">
<h1> Hello How are you </h1>
<p >
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry''s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</p>
</div>
</div>
<br />
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
mouseXPosition = 0;
$(document).ready(function () {
$("#test-text").mousedown(function (e1) {
mouseXPosition = e1.pageX;//register the mouse down position
});
$("#test-text").mouseup(function (e2) {
var highlighted = false;
var selection = window.getSelection();
var selectedText = selection.toString();
var startPoint = window.getSelection().getRangeAt(0).startOffset;
var endPoint = window.getSelection().getRangeAt(0).endOffset;
var anchorTag = selection.anchorNode.parentNode;
var focusTag = selection.focusNode.parentNode;
if ((e2.pageX - mouseXPosition) < 0) {
focusTag = selection.anchorNode.parentNode;
anchorTag = selection.focusNode.parentNode;
}
if (selectedText.length === (endPoint - startPoint)) {
highlighted = true;
if (anchorTag.className !== "highlight") {
highlightSelection();
} else {
var afterText = selectedText + "<span class = ''highlight''>" + anchorTag.innerHTML.substr(endPoint) + "</span>";
anchorTag.innerHTML = anchorTag.innerHTML.substr(0, startPoint);
anchorTag.insertAdjacentHTML(''afterend'', afterText);
}
}else{
if(anchorTag.className !== "highlight" && focusTag.className !== "highlight"){
highlightSelection();
highlighted = true;
}
}
if (anchorTag.className === "highlight" && focusTag.className === ''highlight'' && !highlighted) {
highlighted = true;
var afterHtml = anchorTag.innerHTML.substr(startPoint);
var outerHtml = selectedText.substr(afterHtml.length, selectedText.length - endPoint - afterHtml.length);
var anchorInnerhtml = anchorTag.innerHTML.substr(0, startPoint);
var focusInnerHtml = focusTag.innerHTML.substr(endPoint);
var focusBeforeHtml = focusTag.innerHTML.substr(0, endPoint);
selection.deleteFromDocument();
anchorTag.innerHTML = anchorInnerhtml;
focusTag.innerHTml = focusInnerHtml;
var anchorafterHtml = afterHtml + outerHtml + focusBeforeHtml;
anchorTag.insertAdjacentHTML(''afterend'', anchorafterHtml);
}
if (anchorTag.className === "highlight" && !highlighted) {
highlighted = true;
var Innerhtml = anchorTag.innerHTML.substr(0, startPoint);
var afterHtml = anchorTag.innerHTML.substr(startPoint);
var outerHtml = selectedText.substr(afterHtml.length, selectedText.length);
selection.deleteFromDocument();
anchorTag.innerHTML = Innerhtml;
anchorTag.insertAdjacentHTML(''afterend'', afterHtml + outerHtml);
}
if (focusTag.className === ''highlight'' && !highlighted) {
highlighted = true;
var beforeHtml = focusTag.innerHTML.substr(0, endPoint);
var outerHtml = selectedText.substr(0, selectedText.length - beforeHtml.length);
selection.deleteFromDocument();
focusTag.innerHTml = focusTag.innerHTML.substr(endPoint);
outerHtml += beforeHtml;
focusTag.insertAdjacentHTML(''beforebegin'', outerHtml );
}
if (!highlighted) {
highlightSelection();
}
$(''.highlight'').each(function(){
if($(this).html() == ''''){
$(this).remove();
}
});
selection.removeAllRanges();
});
});
function highlightSelection() {
var selection;
//Get the selected stuff
if (window.getSelection)
selection = window.getSelection();
else if (typeof document.selection != "undefined")
selection = document.selection;
//Get a the selected content, in a range object
var range = selection.getRangeAt(0);
//If the range spans some text, and inside a tag, set its css class.
if (range && !selection.isCollapsed) {
if (selection.anchorNode.parentNode == selection.focusNode.parentNode) {
var span = document.createElement(''span'');
span.className = ''highlight'';
span.textContent = selection.toString();
selection.deleteFromDocument();
range.insertNode(span);
// range.surroundContents(span);
}
}
}
</script>
</html>
Intento encontrar una forma de javascript para resaltar el texto que selecciona el usuario cuando hace clic en un botón de resaltado impar (como en <span style = "background-color: yellow"> texto resaltado </ span>). Solo tiene que funcionar con WebKit o Firefox, pero parece casi imposible porque tiene que funcionar en los siguientes casos:
<p>this is text</p>
<p>I eat food</p>
Cuando el usuario selecciona de "es texto" a "como" en el navegador (no puede simplemente poner un lapso allí).
y este caso:
<span><span>this is text</span>middle text<span>this is text</span></span>
Cuando el usuario selecciona de "es texto" a "esto es" en el navegador (aunque puede ajustar sus espacios de resaltado alrededor de cada elemento de la selección, me gustaría ver que intente obtener resaltado ese texto intermedio).
Este problema no parece resolverse en ningún lado, francamente dudo que sea posible.
Sería posible si pudieras obtener el Rango que obtienes de la selección como una cadena completa con html que podría ser analizada y luego reemplazada, pero por lo que yo sé, no puedes obtener el html crudo de un Rango ... lástima.
<html>
<head>
<script type="text/javascript">
function load(){
window.document.designMode = "On";
//run this in a button, will highlight selected text
window.document.execCommand("hiliteColor", false, "#000");
}
</script>
</head>
<body contentEditable="true" onload="load()">
this is text
</body>
</html>
Bueno, puedes hacerlo usando la manipulación DOM. Esto funciona en Firefox:
var selection = window.getSelection();
var range = selection.getRangeAt(0);
var newNode = document.createElement("span");
newNode.setAttribute("style", "background-color: pink;");
range.surroundContents(newNode);
Parece que funciona en la versión actual de Safari también. Ver https://developer.mozilla.org/en/DOM/range.surroundContents y http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113/ranges.html
Esta respuesta es probablemente algunos años demasiado tarde para ti, pero me enfrenté a un problema similar y quería documentarlo aquí, ya que es el primer éxito en google.
Para reiterar, el problema es que le gustaría simplemente capturar el objeto Range de la selección de usuario y rodearlo con un div con estilo, como ese:
function highlightSelection() {
var userSelection = window.getSelection().getRangeAt(0);
highlightRange(userSelection);
}
function highlightRange(range) {
var newNode = document.createElement("div");
newNode.setAttribute(
"style",
"background-color: yellow; display: inline;"
);
range.surroundContents(newNode);
}
Pero como dice Original Parent, esto no es seguro. Funcionará si la selección no cruza los límites del elemento, pero arrojará un DOM eror si el rango creado por la selección del usuario es un rango inseguro que cruza los límites de las etiquetas HTML.
La solución es producir una matriz de objetos Range más pequeños, ninguno de los cuales cruza individualmente una barrera de elementos, pero que colectivamente cubren el Rango seleccionado por el usuario. Cada uno de estos rangos seguros se puede resaltar como arriba.
function getSafeRanges(dangerous) {
var a = dangerous.commonAncestorContainer;
// Starts -- Work inward from the start, selecting the largest safe range
var s = new Array(0), rs = new Array(0);
if (dangerous.startContainer != a)
for(var i = dangerous.startContainer; i != a; i = i.parentNode)
s.push(i)
;
if (0 < s.length) for(var i = 0; i < s.length; i++) {
var xs = document.createRange();
if (i) {
xs.setStartAfter(s[i-1]);
xs.setEndAfter(s[i].lastChild);
}
else {
xs.setStart(s[i], dangerous.startOffset);
xs.setEndAfter(
(s[i].nodeType == Node.TEXT_NODE)
? s[i] : s[i].lastChild
);
}
rs.push(xs);
}
// Ends -- basically the same code reversed
var e = new Array(0), re = new Array(0);
if (dangerous.endContainer != a)
for(var i = dangerous.endContainer; i != a; i = i.parentNode)
e.push(i)
;
if (0 < e.length) for(var i = 0; i < e.length; i++) {
var xe = document.createRange();
if (i) {
xe.setStartBefore(e[i].firstChild);
xe.setEndBefore(e[i-1]);
}
else {
xe.setStartBefore(
(e[i].nodeType == Node.TEXT_NODE)
? e[i] : e[i].firstChild
);
xe.setEnd(e[i], dangerous.endOffset);
}
re.unshift(xe);
}
// Middle -- the uncaptured middle
if ((0 < s.length) && (0 < e.length)) {
var xm = document.createRange();
xm.setStartAfter(s[s.length - 1]);
xm.setEndBefore(e[e.length - 1]);
}
else {
return [dangerous];
}
// Concat
rs.push(xm);
response = rs.concat(re);
// Send to Console
return response;
}
Entonces es posible (parece) resaltar la Selección de usuario, con este código modificado:
function highlightSelection() {
var userSelection = window.getSelection().getRangeAt(0);
var safeRanges = getSafeRanges(userSelection);
for (var i = 0; i < safeRanges.length; i++) {
highlightRange(safeRanges[i]);
}
}
Tenga en cuenta que probablemente necesite un CSS más elegante para crear los diversos elementos dispares que un usuario podría ver juntos. ¡Espero que eventualmente esto ayude a otra alma cansada en internet!
Estaba teniendo el mismo problema hoy, destacando las etiquetas seleccionadas que abarcan varias etiquetas. La solución:
- Encuentre una forma de extraer la parte seleccionada junto con las etiquetas HTML .
- Envuelva la parte extraída con un elemento span y vuelva a colocarlo en el DOM .
Consulte el código a continuación, para mayor aclaración.
function getRangeObject(selectionObject){
try{
if(selectionObject.getRangeAt)
return selectionObject.getRangeAt(0);
}
catch(ex){
console.log(ex);
}
}
document.onmousedown = function(e){
var text;
if (window.getSelection) {
/* get the Selection object */
userSelection = window.getSelection()
/* get the innerText (without the tags) */
text = userSelection.toString();
/* Creating Range object based on the userSelection object */
var rangeObject = getRangeObject(userSelection);
/*
This extracts the contents from the DOM literally, inclusive of the tags.
The content extracted also disappears from the DOM
*/
contents = rangeObject.extractContents();
var span = document.createElement("span");
span.className = "highlight";
span.appendChild(contents);
/* Insert your new span element in the same position from where the selected text was extracted */
rangeObject.insertNode(span);
} else if (document.selection && document.selection.type != "Control") {
text = document.selection.createRange().text;
}
};
Esta es la primera vez que publico aquí, pero al revisar sus respuestas, ¿no funcionaría algo como esto? Tengo una muestra aquí: http://henriquedonati.com/projects/Extension/extension.html
function highlightSelection() {
var userSelection = window.getSelection();
for(var i = 0; i < userSelection.rangeCount; i++) {
highlightRange(userSelection.getRangeAt(i));
}
}
function highlightRange(range) {
var newNode = document.createElement("span");
newNode.setAttribute(
"style",
"background-color: yellow; display: inline;"
);
range.surroundContents(newNode);
}