问题描述:
中的句子移动结束javascript范围,IE提供moveEnd
方法,该方法可将范围的末尾移动给定数量的句子单位。如何在javascript <a href="https://developer.mozilla.org/en-US/docs/Web/API/Range" rel="nofollow">range</a>对象上使用Chrome
这怎么能在Chrome中完成?
这是我的代码,它有点不错,但正如你所看到的,它也突出了句子的结尾。
var range = document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : new Range();
var startNode = document.getElementsByTagName("p")[0];
var endNode = document.getElementsByTagName("p")[0];
var endOffset = endNode.childNodes.length;
range.setStart(startNode, 0);
for (i = 0; i <= endNode.childNodes.length; i++) {
range.setEnd(endNode, i);
if (/.+\./.test(range.toString()))
break;
}
var newNode = document.createElement("span");
newNode.setAttribute('class', 'highlight');
range.surroundContents(newNode);
.highlight {
background-color:yellow;
}
<p><b>John Fitzgerald</b> "<b>Jack</b>" <b>Kennedy</b> (May 29, 1917 – November 22, 1963), commonly referred to by his initials <b>JFK</b>, was an American politician who served as the <a href="/wiki/List_of_Presidents_of_the_United_States" title="List of Presidents of the United States">35th President of the United States</a> from January 1961 until <a href="/wiki/Assassination_of_John_F._Kennedy" title="Assassination of John F. Kennedy">his assassination</a> in November 1963. The <a href="/wiki/Cuban_Missile_Crisis" title="Cuban Missile Crisis">Cuban Missile Crisis</a>, <a href="/wiki/The_Bay_of_Pigs_Invasion" class="mw-redirect" title="The Bay of Pigs Invasion">The Bay of Pigs Invasion</a>, the <a href="/wiki/Partial_Nuclear_Test_Ban_Treaty" title="Partial Nuclear Test Ban Treaty">Nuclear Test Ban Treaty</a>, the establishment of the <a href="/wiki/Peace_Corps" title="Peace Corps">Peace Corps</a>, developments in the <a href="/wiki/Space_Race" title="Space Race">Space Race</a>, the building of the <a href="/wiki/Berlin_Wall" title="Berlin Wall">Berlin Wall</a>, the <a href="/wiki/Trade_Expansion_Act" title="Trade Expansion Act">Trade Expansion Act</a> to lower tariffs, and the <a href="/wiki/African-American_Civil_Rights_Movement_(1955%E2%80%931968)" class="mw-redirect" title="African-American Civil Rights Movement (1955–1968)">Civil Rights Movement</a> all took place during his presidency. A member of the <a href="/wiki/Democratic_Party_(United_States)" title="Democratic Party (United States)">Democratic Party</a>, his <a href="/wiki/New_Frontier" title="New Frontier">New Frontier</a> domestic program was largely enacted as a memorial to him after his death.</p>
答
这里是我的答案。工作很好。
WebPageReader.Sentence = class extends Range {
/* Sentence understance everything about sentences
It has a starting and ending character, and ends with a sentence terminator
It can navigate itself around the page
*/
constructor() {
super();
this.dom = new WebPageReader.Dom();
this.regex = new WebPageReader.Regex();
this.highlighted = false;
this.backupHtml = '';
this.dom.LoadAllTextNodes();
this.AlignToRange(this.dom.GetSelectedRange() || this.dom.GetFirstRange())
this.collapse(true);
this.AlignEndPoints();
this.Expand();
}
/* public properties */
get CanPrevious() {
return !this.StartCharacter.Bof;
}
get CanNext() {
return !this.EndCharacter.Eof;
}
set Highlighted(value) {
if (value == this.highlighted) return;
if (value)
this.Highlight();
else
this.Unhighlight();
this.highlighted = value;
}
/* public methods */
Expand() {
this.StartCharacter.Search(this.regex.SentenceTerminator, false);
this.StartCharacter.Search(this.regex.NonWhitespace, true);
this.EndCharacter.Search(this.regex.SentenceTerminator, true);
this.Align();
}
Next() {
this.EndCharacter.Next();
this.Align();
this.collapse(false); // collapse to end
this.AlignEndPoints();
this.Expand();
}
Previous() {
this.StartCharacter.Search(this.regex.SentenceTerminator, false);
this.StartCharacter.Previous();
this.Align();
this.collapse(true); // collapse to start
this.AlignEndPoints();
this.Expand();
}
Align() {
this.setStart(this.StartCharacter.TextNode, this.StartCharacter.Offset);
this.setEnd(this.EndCharacter.TextNode, this.EndCharacter.Offset);
}
AlignToRange(range) {
this.setStart(range.startContainer, range.startOffset);
this.setEnd(range.endContainer, range.endOffset);
}
AlignEndPoints() {
this.StartCharacter = new WebPageReader.Character(this.dom, this);
this.EndCharacter = new WebPageReader.Character(this.dom, this);
}
Highlight() {
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(this);
this.highlighted = true;
}
Unhighlight() {
this.highlighted = false;
}
ScrollToMiddle() {
var el = $(this.startContainer.parentElement);
var elOffset = el.offset().top;
var elHeight = el.height();
var windowHeight = window.innerHeight;
var documentHeight = document.documentElement.offsetHeight;
var offset;
if (elHeight < windowHeight) {
offset = elOffset - ((windowHeight/4) - (elHeight/2));
}
else {
offset = elOffset;
}
window.scrollTo(0, offset);
}
Visualize(label) {
const BeginRangeMarker = '\u25BA';
const EndRangeMarker = '\u25C4';
const TextNodeBoundary = '\u2551';
const NewLineIndicator = '\u21B5';
var allTextNodes = this.dom.AllTextNodes;
var msg = '';
var intersects = false;
for (var t = 0; t < allTextNodes.length; t++) {
var textNode = allTextNodes[t];
var value = textNode.nodeValue.replace(/[\n]/g, NewLineIndicator);
if (this.intersectsNode(textNode)) {
if (!intersects) {
if (!allTextNodes[t + 1] || !this.intersectsNode(allTextNodes[t + 1]))
// I begin and finish inside this first node
msg += `${TextNodeBoundary}${value.substring(0, this.startOffset)}${BeginRangeMarker}${value.substring(this.startOffset, this.endOffset)}${EndRangeMarker}${value.substring(this.endOffset)}`;
else
// I only begin inside this first node
msg += `${TextNodeBoundary}${value.substring(0, this.startOffset)}${BeginRangeMarker}${value.substring(this.startOffset)}`;
} else if (!allTextNodes[t + 1] || !this.intersectsNode(allTextNodes[t + 1]))
// I end in this node
msg += `${TextNodeBoundary}${value.substring(0, this.endOffset)}${EndRangeMarker}${value.substring(this.endOffset)}`;
else
// I completely contain this node
msg += `${TextNodeBoundary}${value}`;
intersects = true;
} else if (intersects) {
break;
}
}
// txtVisualization.value = `${msg}║`;
msg = `${label} = ${msg}║`;
console.log(msg);
}
}
/* Classes */
WebPageReader.Character = class {
/* the textual surface of a web page is completely tiled over with text nodes
a character has the text node on which it sits and the character position (Offset) within that node's text
*/
constructor(dom, range) {
this.dom = dom;
this.TextNode = range.startContainer;
this.Offset = range.startOffset;
this.Bof = false;
this.Eof = false;
}
Search(regex, forward) {
var found = false;
var buffer = '';
do {
if (forward) {
buffer += this.toString();
found = regex.test(buffer);
regex.lastIndex = 0;
if (!this.Next()) return false;
} else {
if (!this.Previous()) return false;
buffer = this.toString() + buffer;
found = regex.test(buffer);
regex.lastIndex = 0;
}
} while (!found);
// roll it one character (get off the match)
if (forward) this.Previous();
else this.Next();
return true; // found it
}
Previous() {
this.Bof = false;
this.Offset--;
if (this.Offset < 0) {
if (!this.dom.getPreviousTextNode(this.TextNode)) {
this.Bof = true;
this.Offset = 0;
return false;
}
this.TextNode = this.dom.getPreviousTextNode(this.TextNode);
this.Offset = this.TextNode.nodeValue.length - 1;
}
return true;
}
Next() {
this.Eof = false;
this.Offset++;
if (this.Offset > this.TextNode.nodeValue.length - 1) {
if (!this.dom.getNextTextNode(this.TextNode)) {
this.Eof = true;
this.Offset = this.TextNode.nodeValue.length - 1;
return false;
}
this.TextNode = this.dom.getNextTextNode(this.TextNode);
this.Offset = 0;
}
return true;
}
toString() {
return this.TextNode.nodeValue.substring(this.Offset, this.Offset + 1);
}
}
.highlight {
background-color: yellow;
outline: 1px solid green;
}
<input type="button" onclick="prevSentence();" value="Previous" />
<input type="button" onclick="nextSentence();" value="Next" />
<input type="button" onclick="getSelectionRange();" value="Get Selection" />
<input type="text" id="sentenceIndex" />
<input type="text" id="sentence" />
<div>
<p><b>John Fitzgerald</b> "<b>Jack</b>" <b>Kennedy</b> (May 29, 1917 – November 22, 1963), commonly referred to by his initials <b>JFK</b>, was an American politician who served as the <a href="/wiki/List_of_Presidents_of_the_United_States" title="List of Presidents of the United States">35th President of the United States</a> from
January 1961 until <a href="/wiki/Assassination_of_John_F._Kennedy" title="Assassination of John F. Kennedy">his assassination</a> in November 1963. The <a href="/wiki/Cuban_Missile_Crisis" title="Cuban Missile Crisis">Cuban Missile Crisis</a>, <a href="/wiki/The_Bay_of_Pigs_Invasion"
class="mw-redirect" title="The Bay of Pigs Invasion">The Bay of Pigs Invasion</a>, the <a href="/wiki/Partial_Nuclear_Test_Ban_Treaty" title="Partial Nuclear Test Ban Treaty">Nuclear Test Ban Treaty</a>, the establishment of the <a href="/wiki/Peace_Corps"
title="Peace Corps">Peace Corps</a>, developments in the <a href="/wiki/Space_Race" title="Space Race">Space Race</a>, the building of the <a href="/wiki/Berlin_Wall" title="Berlin Wall">Berlin Wall</a>, the <a href="/wiki/Trade_Expansion_Act" title="Trade Expansion Act">Trade Expansion Act</a> to
lower tariffs, and the <a href="/wiki/African-American_Civil_Rights_Movement_(1955%E2%80%931968)" class="mw-redirect" title="African-American Civil Rights Movement (1955–1968)">Civil Rights Movement</a> all took place during his presidency. A member
of the <a href="/wiki/Democratic_Party_(United_States)" title="Democratic Party (United States)">Democratic Party</a>, his <a href="/wiki/New_Frontier" title="New Frontier">New Frontier</a> domestic program was largely enacted as a memorial to him after
his death.</p>
<p>Kennedy's time in office was marked by high tensions with <a href="/wiki/Communist_states" class="mw-redirect" title="Communist states">Communist states</a>. Kennedy increased the number of American military advisers in <a href="/wiki/South_Vietnam" title="South Vietnam">South Vietnam</a> by
a factor of 18 over Eisenhower. In <a href="/wiki/Cuba" title="Cuba">Cuba</a>, a failed attempt was made at the <a href="/wiki/Bay_of_Pigs" title="Bay of Pigs">Bay of Pigs</a> to overthrow the country's dictator <a href="/wiki/Fidel_Castro" title="Fidel Castro">Fidel Castro</a> in
April 1961. Kennedy's administration subsequently rejected plans by the Joint Chiefs of Staff to <a href="/wiki/Operation_Northwoods" title="Operation Northwoods">orchestrate false-flag attacks on American soil in order to gain public approval for a war against Cuba</a>.
In October 1962, it was discovered Soviet <a href="/wiki/Ballistic_missiles" class="mw-redirect" title="Ballistic missiles">ballistic missiles</a> had been deployed in Cuba; the resulting period of unease, termed the <a href="/wiki/Cuban_Missile_Crisis"
title="Cuban Missile Crisis">Cuban Missile Crisis</a>, is seen by many historians as the closest the human race has ever come to <a href="/wiki/Nuclear_war" class="mw-redirect" title="Nuclear war">nuclear war</a> between nuclear armed belligerents.</p>
</div>