- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的目标:
Let users highlight different substring in a single long string.
但是,一旦我用 range.surroundContents(newNode)
突出显示了一个子字符串(newNode 是一个黄色背景的 span
),innerHTML
整个长字符串的一部分发生了变化——它开始包含 span
元素;因此,如果用户想要在同一个长字符串中突出显示前一个突出显示的子字符串之后的子字符串,则 anchorOffset
将返回从 after
开始的索引上一个跨度。
例如,在这个长字符串中:
"Mr. and Mrs. Dursley, of number four, Privet Drive, were proud to say that they were perfectly normal, thank you very much."
这个长句子被p
包裹起来类名是noting
.如果range.surroundContents()
方法子字符串“女贞路”,然后,当我想得到 window.getSelection().anchorOffset
子串“thank”的错误答案是53,而正确答案应该是102。我应该怎么做?谢谢!!
附言我不想用substring方法找位置,谢谢!
$(".noting").mouseup(function(e){
$("#noteContent").val("");/*flushing*/
curSentNum = $(this).attr("id").split("-")[1];
$('#curSentNum').val(curSentNum);
highlightLangName = $(this).attr("id").split("-")[2];
$('#highlightLangName').val(highlightLangName);
//console.log(".noting $(this).html()"+$(this).html()+" "+$(this).attr("id"));//id, for example: p-2-French
if (window.getSelection) {
highlightedText = window.getSelection().toString();
curAnchorOffset = window.getSelection().anchorOffset;
$('#anchorAt').val(curAnchorOffset);
$('#highlightLen').val(highlightedText.length);
}
else if (document.selection && document.selection.type != "Control") {
highlightedText = document.selection.createRange().text;
}
});
然后我将保存 anchorAt
信息到数据库;在 db 操作之后,我将立即使用之前保留的变量调用此函数:
function highlightNoteJustSaved(){
var curI = noteCounter;
var anchorAt = parseInt($("#anchorAt").val());
var highlightLen = parseInt($("#highlightLen").val());
/*p to find, for example: p-2-French*/
var curP = document.getElementById('p-'+curSentNum.toString()+"-"+$("#highlightLangName").val());
var range = document.createRange();
root_node = curP;
range.setStart(root_node.childNodes[0], anchorAt);
range.setEnd(root_node.childNodes[0], anchorAt+highlightLen);
var newNode = document.createElement("span");
newNode.style.cssText="background-color:#ceff99";//yellow
newNode.className = alreadyNoteStr;
newNode.setAttribute('id','already-note-'+curI.toString());
range.surroundContents(newNode);
}
对于HTML树节点结构,请看下面的评论(我没有弄清楚如何在这个提问区复制粘贴代码)。
最佳答案
我用两种方法替换了您突出显示文本的方法。 highlightTextNodes
查找节点内容中的单词。寻找每个 child 。我还实现了一个高光去除器来展示它是如何工作的。我用 mark
标签替换了 span
。
let alreadyNoteStr = 'already';
let noteCounter = 0;
let elementId;
$('p.noting').mouseup(function(e) {
elementId = $(this).attr('id');
$('#noteContent').val(''); /*flushing*/
curSentNum = elementId.split('-')[1];
$('#curSentNum').val(curSentNum);
highlightLangName = elementId.split('-')[2];
$('#highlightLangName').val(highlightLangName);
//console.log(".noting $(this).html()"+$(this).html()+" "+$(this).attr("id"));//id, for example: p-2-French
if (window.getSelection) {
highlightedText = window.getSelection().toString();
curAnchorOffset = window.getSelection().anchorOffset;
$("#noteContent").val(highlightedText);
$('#anchorAt').val(curAnchorOffset);
$('#highlightLen').val(highlightedText.length);
highlight(elementId, highlightedText);
} else if (document.selection && document.selection.type != "Control") {
highlightedText = document.selection.createRange().text;
}
});
function highlightNoteJustSaved() {
let curI = noteCounter;
let anchorAt = parseInt($("#anchorAt").val());
let highlightLen = parseInt($("#highlightLen").val());
/*p to find, for example: p-2-French*/
let curP = document.getElementById('p-' + curSentNum.toString() + "-" + $("#highlightLangName").val());
let range = document.createRange();
rootNode = curP;
let childNode = rootNode.childNodes[0];
range.setStart(rootNode.childNodes[0], anchorAt);
range.setEnd(rootNode.childNodes[0], anchorAt + highlightLen);
var newNode = document.createElement("span");
newNode.style.cssText = "background-color:#ceff99"; //yellow
newNode.className = alreadyNoteStr;
newNode.setAttribute('id', 'already-note-' + curI.toString());
range.surroundContents(newNode);
}
/*
* Takes in an array of consecutive TextNodes and returns a document fragment with `word` highlighted
*/
function highlightTextNodes(nodes, word) {
if (!nodes.length) {
return;
}
let text = '';
// Concatenate the consecutive nodes to get the actual text
for (var i = 0; i < nodes.length; i++) {
text += nodes[i].textContent;
}
let fragment = document.createDocumentFragment();
while (true) {
// Tweak this if you want to change the highlighting behavior
var index = text.toLowerCase().indexOf(word.toLowerCase());
if (index === -1) {
break;
}
// Split the text into [before, match, after]
var before = text.slice(0, index);
var match = text.slice(index, index + word.length);
text = text.slice(index + word.length);
// Create the <mark>
let mark = document.createElement('mark');
mark.className = 'found';
mark.appendChild(document.createTextNode(match));
// Append it to the fragment
fragment.appendChild(document.createTextNode(before));
fragment.appendChild(mark);
}
// If we have leftover text, just append it to the end
if (text.length) {
fragment.appendChild(document.createTextNode(text));
}
// Replace the nodes with the fragment
nodes[0].parentNode.insertBefore(fragment, nodes[0]);
for (var i = 0; i < nodes.length; i++) {
let node = nodes[nodes.length - i - 1];
node.parentNode.removeChild(node);
}
}
/*
* Highlights all instances of `word` in `$node` and its children
*/
function highlight(id, word) {
let node = document.getElementById(id);
let children = node.childNodes;
let currentRun = [];
for (var i = 0; i < children.length; i++) {
let child = children[i];
if (child.nodeType === Node.TEXT_NODE) {
// Keep track of consecutive text nodes
currentRun.push(child);
} else {
// If we hit a regular element, highlight what we have and start over
highlightTextNodes(currentRun, word);
currentRun = [];
// Ignore text inside of our <mark>s
if (child.nodeType === Node.ELEMENT_NODE && child.className !== 'found') {
highlight(child, word);
}
}
}
// Just in case we have only text nodes as children
if (currentRun.length) {
highlightTextNodes(currentRun, word);
}
}
/*
* Removes all highlighted <mark>s from the given node
*/
function unhighlight(id) {
let node = document.getElementById(id);
let marks = [].slice.call(node.querySelectorAll('mark.found'));
for (var i = 0; i < marks.length; i++) {
let mark = marks[i];
// Replace each <mark> with just a text node of its contents
mark.parentNode.replaceChild(document.createTextNode(mark.childNodes[0].textContent), mark);
}
}
label {
display: block;
position: relative;
padding-left: 100px;
}
button {
margin-top: 20px;
margin-bottom: 20px;
padding: 10px;
}
label>span {
position: absolute;
left: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" onclick="unhighlight(elementId);">Unhighlight</button>
<div id="div-0" class="only-left-border">
<p class="lan-English noting" id="p-1-English">Mr. and Mrs. Dursley, of number four, Privet Drive, were proud to say that they were perfectly normal, thank you very much.</p>
</div>
<label><span>Content:</span><input type="text" id="noteContent"></input></label>
<label><span>Numer:</span><input type="text" id="curSentNum"></input></label>
<label><span>Language:</span><input type="text" id="highlightLangName"></input></label>
<label><span>Anchor:</span><input type="text" id="anchorAt"></input></label>
<label><span>Length:</span><input type="text" id="highlightLen"></input></label>
关于javascript 在遇到意外的 anchorOffset 时执行多个 createrange(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54393815/
请帮帮我 div.foo{border:1px solid red;} Ext.onReady(function(){ Ext.create('Ext.panel.
以下代码在我升级到 Windows 8.1/Internet Explorer 11 之前一直运行良好,现在抛出错误:“无法获取未定义或空引用的属性‘createRange’” var Selecte
我有以下 JavaScript,我试图用它来将图像插入到我的内容中: var imgHtml = ''; var $rte = document.parentWindow.document.getEl
我编写了以下代码来从当前网页中检索所选文本: IHTMLDocument2 mainDoc = ... for ( int i = 0; i < mainDoc.frames.length; i++
我的目标: Let users highlight different substring in a single long string. 但是,一旦我用 range.surroundContent
我有一个文本框。当我写第一个文本时,java脚本函数将触发以检查它是否是数字。 对于 IE ,以下代码返回 -1 值,但其他浏览器不会警告任何值。请帮助我 var selected = documen
这适用于 IE9,但不适用于 Chrome。我想在 Chrome 中运行它。这是当我将单词放入文本框中时找到我要查找的单词。谁能帮我解决这个问题吗? var n = 0; var str = '';
Jest,通过我想象的 JSDom,没有定义 document.createRange。我如何覆盖或提供此行为? 我们为自定义 JSDom + mocha 设置(在所有测试之前运行)编写的版本如下所示
我的 summernote 编辑器中的一些文本包含 HTML。我想获取用户选择的文本,与编辑器中的文本完全一样。 到目前为止我看到的所有答案都告诉我使用这个 $('#summernote').summ
尝试使用酵素时 mount在呈现 MaterialUI 工具提示的组件上,停止我的测试时出错: TypeError: document.createRange is not a function 最佳
这个问题已经有答案了: Insert html at caret in a contenteditable div (4 个回答) 已关闭10 年前。 我试图让 IE 粘贴到 contentedita
在Javascript中,似乎有两种方法可以创建Range对象: var range = document.createRange() : 调用 createRange()在 Document目的。
在 IE11 中,createRange() 方法抛出以下错误:“无法获取未定义或空引用的属性‘createRange’”。我调用了 createRange() 方法如下:this._document
我正在尝试制作一个简单的 ubb 编辑器,但 document.selection.createRange() 在 IE 中不起作用,它不会获得任何突出显示的文本(尝试提醒突出显示的文本但什么也得不到
我使用 createRange 函数编写了一个简单的脚本,但它在 IE9 中不起作用。 function Select () { var srcObj = document.b
我正在尝试从文本区域中提取准确的选择和光标位置。像往常一样,在大多数浏览器中容易的事情在 IE 中并不容易。 我正在使用这个: var sel=document.selection.createRan
我目前正在使用与此类似的代码: try { // IE ONLY var theElement = "myElementName"; window.frames[theElement].focu
我有一个带有单个内部节点的 div: test 我正在尝试使用 document.createRange() 和 document.createTreeWalker() 获取其
我使用文本模式作为多行选项的文本框,它在 IE 中工作正常,Mozilla 在 Chrome 和 safari 中出现问题。示例代码如下 function DoPaste(control) { ma
我正在使用 Ajax Control Toolkit 中的 ComboBox。以下所有代码均由 VisualStudio 2013(使用 asp.net 4.5)生成。我只选择了数据连接。为什么我会收
我是一名优秀的程序员,十分优秀!