如何修改从左到右的选择白色 space
how to modify selection from left to right white space
在下面的示例中,请将光标放在 story
内,例如在字母 b
.
之后
单击按钮时,我需要向左和向右扩展选择,直到出现白色 space - 或 start/end 行。
所以应该选择 https://tumblr.com
并在控制台中写入。
我的尝试有问题 - 只选择了 tumblr
$(btngo).on('click', function(){
var sel = window.getSelection();
sel.modify("move", "backward", "word");
sel.modify("extend", "right", "word");
console.log(sel.toString()); // tumblr - I need - https://tumblr.com
});
.story{outline:none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='story' id='story' contenteditable>
lorem - https://tumblr.com
</div>
<br>
<button id='btngo'>GO</button>
使用 Javascript Selection, Range and split()
此解决方案将整个文本块拆分为行,然后将行拆分为单词。它首先逐行搜索光标位置,然后,一旦找到该行,就在该行中搜索包含光标的单词。文本块越大,查找和突出显示目标词所需的处理就越多。 请参阅我的其他答案。
将光标放在任何单词中,然后单击“开始”。该词被返回以供进一步处理,并突出显示。如果光标未放在单词中,或者文本已被选中,则不会搜索文本块并返回消息“无光标位置”。
要查找包含光标的单词(一串没有空格的连续字符),整个文本块按空格或行 returns 拆分。该数组循环搜索光标位置。一旦找到,返回数组中对应的词,然后用于在文本块中定位该词,然后突出显示。
// document.getElementById("btngo").addEventListener('click', function () { // vanilla
$(btngo).on('click', function(){
var sel = window.getSelection();
// get beginning and end of selection
let ao = sel.anchorOffset;
let fo = sel.focusOffset;
// make sure there is a cursor position but not a selected range
if ( 1 < fo && ao === fo ) {
// get node containing cursor
let fn = sel.focusNode;
// trim whitespace at beginning and end of block of text,
// then split on spaces into an array
let fn_arr = fn.textContent.trim().split(/\r?\n|\s/);
// loop array and search for cursor position
// when found use position to determine word in array containing cursor
let [strt,end,wrd] = fn_arr.reduce(function (acc, txt) {
return (fo > acc[1]) // have we reached the cursor position?
? [acc[1] + 1, acc[1] + txt.length + 1, txt] // if not keep track of location
: acc; // if so, keep returning location information
}, [0,0,""]);
console.log(wrd); // display word containing cursor
// select word containing cursor
let range = new Range();
range.setStart(fn, strt);
range.setEnd(fn, end);
sel.addRange(range);
}
else { console.log('no cursor position') }
});
.story{outline:none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='story' id='story' contenteditable>
lorem - https://tumblr.com
more text to@select from
</div>
<br>
<button id='btngo'>GO</button>
对于LONG的文本块,可以逐行查找,然后只查找光标所在的行:
document.getElementById("btngo").addEventListener('click', function () {
var sel = window.getSelection();
// get beginning and end of selection
let [ao, fo] = [sel.anchorOffset, sel.focusOffset];
// make sure there is a cursor position but not a selected range
if ( 1 < fo && ao === fo ) {
// get node containing cursor
let fn = sel.focusNode;
// FIND LINE
// split on *line returns* into an array
let fn_arr = fn.textContent.trim().split(/\r?\n/);
// when found use position to determine *line* in array containing cursor
let [strt,end,wrd] = fn_arr.reduce(findCursor(fo), [0,0,""]);
// FIND WORD IN LINE
// split on *spaces* into an array
fn_arr = wrd.trim().split(' ');
// when found use position to determine *word* in array containing cursor
[strt,end,wrd] = fn_arr.reduce(findCursor(fo), [strt,strt-1,""]);
console.log(wrd); // display word containing cursor
// select word containing cursor
let range = new Range();
range.setStart(fn, strt);
range.setEnd(fn, end);
sel.addRange(range);
}
else { console.log('no cursor position')}
});
const findCursor = function (fo) {
return function (acc, txt) {
return (fo > acc[1]) // have we reached the cursor position?
? [acc[1] + 1, acc[1] + txt.length + 1, txt] // if not keep track of location
: acc; // if so, keep returning location information
}
}
您可以使用范围将光标定位在您需要的位置,然后从那里 select,在这种情况下,selection 将从第 9 个位置到行尾。
$(btngo).on('click', function(){
var range = document.createRange()
var sel = window.getSelection()
//place the cursor to 9th position
range.setStart($("#story")[0].childNodes[0], 9)
range.collapse(true)
sel.removeAllRanges()
sel.addRange(range)
sel.modify("extend", "right", "lineboundary");
console.log(sel.toString());
});
.story{outline:none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='story' id='story' contenteditable>
lorem - https://tumblr.com
</div>
<br>
<button id='btngo'>GO</div>
使用 Javascript Selection and Selection.setBaseAndExtent():
这个解决方案从anchorNode
and focusNode
to locate the cursor, then Selection.setBaseAndExtent()开始逐渐扩大选区,直到找到白色space。这种方法的好处是速度和性能不受光标所在文本块大小的影响。
将光标放在任何单词中,然后单击“开始”。
选区的前端,通常是 anchorNode
(起始)位置,逐渐向后移动,直到找到 space 或行 return。选择的后侧,通常是 focusNode
(结束)位置,逐渐向前移动,直到找到 space 或行 return。该选择文本现在可以作为 sel.toString()
.
进行进一步处理
Actually, the anchorNode
and anchorOffset
are where the users
start their cursor selection, and the focusNode
and focusOffset
is where they end their selection. So the anchor...
is typically
before, and the focus...
after, but not necessarily. So these are
sorted in order to move them in the corresponding direction they were
selected.
document.getElementById("btngo").addEventListener('click', function () { // vanilla...why not?
const sel = window.getSelection();
let [bws,aws] = [false,false]; // before whitespace, after whitespace
// sort because direction user makes selection determines node/offset order
let [[bn,bo],[an,ao]] // before node/offset (backward), and after node/offset (forward)
= [[sel.anchorNode, sel.anchorOffset],[sel.focusNode, sel.focusOffset]]
.sort(function (aa,bb) { return aa[1] - bb[1]; }); // sort by offset
// move BEFORE position backward until whitespace or beginning of node
while ( !bws && 0 < bo ) {
sel.setBaseAndExtent(bn,--bo,an,ao); // move backward 1 character
// don't include whitespace, and assign result to bws
if ( (bws = (-1 !== sel.toString().search(/\r?\n| /))) ) {
++bo; // prepare to move forward 1 to remove space
}
}
// move AFTER position forward until whitespace or end of node
while ( !aws && an.length >= ao + 1 ) {
sel.setBaseAndExtent(bn,bo,an,++ao); // move forward 1 character
if ( (aws = (-1 !== sel.toString().search(/\r?\n| /))) ) { // don't include whitespace, and assign result to aws
--ao; // prepare to move backward to remove space
}
}
sel.setBaseAndExtent(bn,bo,an,ao); // remove whitespace
console.log(sel.toString());
});
.story{outline:none;}
<div class="story" id="story" contenteditable>
lorem - https://tumblr.com
more text to@select from
</div>
<br>
<button id="btngo">GO</button>
在下面的示例中,请将光标放在 story
内,例如在字母 b
.
单击按钮时,我需要向左和向右扩展选择,直到出现白色 space - 或 start/end 行。
所以应该选择 https://tumblr.com
并在控制台中写入。
我的尝试有问题 - 只选择了 tumblr
$(btngo).on('click', function(){
var sel = window.getSelection();
sel.modify("move", "backward", "word");
sel.modify("extend", "right", "word");
console.log(sel.toString()); // tumblr - I need - https://tumblr.com
});
.story{outline:none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='story' id='story' contenteditable>
lorem - https://tumblr.com
</div>
<br>
<button id='btngo'>GO</button>
使用 Javascript Selection, Range and split()
此解决方案将整个文本块拆分为行,然后将行拆分为单词。它首先逐行搜索光标位置,然后,一旦找到该行,就在该行中搜索包含光标的单词。文本块越大,查找和突出显示目标词所需的处理就越多。
将光标放在任何单词中,然后单击“开始”。该词被返回以供进一步处理,并突出显示。如果光标未放在单词中,或者文本已被选中,则不会搜索文本块并返回消息“无光标位置”。
要查找包含光标的单词(一串没有空格的连续字符),整个文本块按空格或行 returns 拆分。该数组循环搜索光标位置。一旦找到,返回数组中对应的词,然后用于在文本块中定位该词,然后突出显示。
// document.getElementById("btngo").addEventListener('click', function () { // vanilla
$(btngo).on('click', function(){
var sel = window.getSelection();
// get beginning and end of selection
let ao = sel.anchorOffset;
let fo = sel.focusOffset;
// make sure there is a cursor position but not a selected range
if ( 1 < fo && ao === fo ) {
// get node containing cursor
let fn = sel.focusNode;
// trim whitespace at beginning and end of block of text,
// then split on spaces into an array
let fn_arr = fn.textContent.trim().split(/\r?\n|\s/);
// loop array and search for cursor position
// when found use position to determine word in array containing cursor
let [strt,end,wrd] = fn_arr.reduce(function (acc, txt) {
return (fo > acc[1]) // have we reached the cursor position?
? [acc[1] + 1, acc[1] + txt.length + 1, txt] // if not keep track of location
: acc; // if so, keep returning location information
}, [0,0,""]);
console.log(wrd); // display word containing cursor
// select word containing cursor
let range = new Range();
range.setStart(fn, strt);
range.setEnd(fn, end);
sel.addRange(range);
}
else { console.log('no cursor position') }
});
.story{outline:none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='story' id='story' contenteditable>
lorem - https://tumblr.com
more text to@select from
</div>
<br>
<button id='btngo'>GO</button>
对于LONG的文本块,可以逐行查找,然后只查找光标所在的行:
document.getElementById("btngo").addEventListener('click', function () {
var sel = window.getSelection();
// get beginning and end of selection
let [ao, fo] = [sel.anchorOffset, sel.focusOffset];
// make sure there is a cursor position but not a selected range
if ( 1 < fo && ao === fo ) {
// get node containing cursor
let fn = sel.focusNode;
// FIND LINE
// split on *line returns* into an array
let fn_arr = fn.textContent.trim().split(/\r?\n/);
// when found use position to determine *line* in array containing cursor
let [strt,end,wrd] = fn_arr.reduce(findCursor(fo), [0,0,""]);
// FIND WORD IN LINE
// split on *spaces* into an array
fn_arr = wrd.trim().split(' ');
// when found use position to determine *word* in array containing cursor
[strt,end,wrd] = fn_arr.reduce(findCursor(fo), [strt,strt-1,""]);
console.log(wrd); // display word containing cursor
// select word containing cursor
let range = new Range();
range.setStart(fn, strt);
range.setEnd(fn, end);
sel.addRange(range);
}
else { console.log('no cursor position')}
});
const findCursor = function (fo) {
return function (acc, txt) {
return (fo > acc[1]) // have we reached the cursor position?
? [acc[1] + 1, acc[1] + txt.length + 1, txt] // if not keep track of location
: acc; // if so, keep returning location information
}
}
您可以使用范围将光标定位在您需要的位置,然后从那里 select,在这种情况下,selection 将从第 9 个位置到行尾。
$(btngo).on('click', function(){
var range = document.createRange()
var sel = window.getSelection()
//place the cursor to 9th position
range.setStart($("#story")[0].childNodes[0], 9)
range.collapse(true)
sel.removeAllRanges()
sel.addRange(range)
sel.modify("extend", "right", "lineboundary");
console.log(sel.toString());
});
.story{outline:none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='story' id='story' contenteditable>
lorem - https://tumblr.com
</div>
<br>
<button id='btngo'>GO</div>
使用 Javascript Selection and Selection.setBaseAndExtent():
这个解决方案从anchorNode
and focusNode
to locate the cursor, then Selection.setBaseAndExtent()开始逐渐扩大选区,直到找到白色space。这种方法的好处是速度和性能不受光标所在文本块大小的影响。
将光标放在任何单词中,然后单击“开始”。
选区的前端,通常是 anchorNode
(起始)位置,逐渐向后移动,直到找到 space 或行 return。选择的后侧,通常是 focusNode
(结束)位置,逐渐向前移动,直到找到 space 或行 return。该选择文本现在可以作为 sel.toString()
.
Actually, the
anchorNode
andanchorOffset
are where the users start their cursor selection, and thefocusNode
andfocusOffset
is where they end their selection. So theanchor...
is typically before, and thefocus...
after, but not necessarily. So these are sorted in order to move them in the corresponding direction they were selected.
document.getElementById("btngo").addEventListener('click', function () { // vanilla...why not?
const sel = window.getSelection();
let [bws,aws] = [false,false]; // before whitespace, after whitespace
// sort because direction user makes selection determines node/offset order
let [[bn,bo],[an,ao]] // before node/offset (backward), and after node/offset (forward)
= [[sel.anchorNode, sel.anchorOffset],[sel.focusNode, sel.focusOffset]]
.sort(function (aa,bb) { return aa[1] - bb[1]; }); // sort by offset
// move BEFORE position backward until whitespace or beginning of node
while ( !bws && 0 < bo ) {
sel.setBaseAndExtent(bn,--bo,an,ao); // move backward 1 character
// don't include whitespace, and assign result to bws
if ( (bws = (-1 !== sel.toString().search(/\r?\n| /))) ) {
++bo; // prepare to move forward 1 to remove space
}
}
// move AFTER position forward until whitespace or end of node
while ( !aws && an.length >= ao + 1 ) {
sel.setBaseAndExtent(bn,bo,an,++ao); // move forward 1 character
if ( (aws = (-1 !== sel.toString().search(/\r?\n| /))) ) { // don't include whitespace, and assign result to aws
--ao; // prepare to move backward to remove space
}
}
sel.setBaseAndExtent(bn,bo,an,ao); // remove whitespace
console.log(sel.toString());
});
.story{outline:none;}
<div class="story" id="story" contenteditable>
lorem - https://tumblr.com
more text to@select from
</div>
<br>
<button id="btngo">GO</button>