У ÑÑÐ¾Ð¼Ñ ÑоздÑÐ»Ñ Ð¼Ð¸ ÑозглÑнемо видÑÐ»ÐµÐ½Ð½Ñ Ñ Ð´Ð¾ÐºÑменÑÑ Ñа в полÑÑ
ÑоÑми, напÑиклад, в <input>.
JavaScript може оÑÑимаÑи доÑÑÑп до наÑвного видÑÐ»ÐµÐ½Ð½Ñ ÑекÑÑÑ, вибиÑаÑи/ÑкаÑовÑваÑи видÑÐ»ÐµÐ½Ð½Ñ Ð²ÑзлÑв DOM повнÑÑÑÑ Ð°Ð±Ð¾ ÑаÑÑково, видалÑÑи видÑлений вмÑÑÑ Ñз докÑменÑа, або обгоÑнÑÑи його в Ñег ÑоÑо.
РкÑнÑÑ ÑоздÑÐ»Ñ Ð¼Ð¸ пÑдгоÑÑвали кÑлÑка гоÑÐ¾Ð²Ð¸Ñ ÑÑÑÐµÐ½Ñ Ð´Ð»Ñ ÑÐ¸Ð¿Ð¾Ð²Ð¸Ñ Ð·Ð°Ð´Ð°Ñ (ÑоздÑл âÐÑдÑÑмкиâ). ЦÑлком можливо, ÑÑого бÑде доÑÑаÑнÑо Ñоб задоволÑниÑи вÑÑ Ð²Ð°ÑÑ Ð¿Ð¾ÑоÑÐ½Ñ Ð¿Ð¾ÑÑеби, пÑоÑе ви оÑÑимаÑÑе набагаÑо бÑлÑÑе, ÑкÑо пÑоÑиÑаÑÑе ÑÑаÑÑÑ Ð¿Ð¾Ð²Ð½ÑÑÑÑ.
РобâÑкÑами Range Ñа Selection можна ÑозÑбÑаÑиÑÑ Ð´Ð¾ÑиÑÑ Ð»ÐµÐ³ÐºÐ¾, Ñ ÑÐ¾Ð´Ñ Ð²Ð°Ð¼ не знадоблÑÑÑÑÑ Ð³Ð¾ÑÐ¾Ð²Ñ ÑÑÑÐµÐ½Ð½Ñ Ð´Ð»Ñ ÑозвâÑÐ·Ð°Ð½Ð½Ñ Ð·Ð°Ð´Ð°Ñ.
Range
ÐÑÐ½Ð¾Ð²Ð¾Ñ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ñ Range, Ñкий по ÑвоÑй ÑÑÑÑ Ñ Ð¿Ð°ÑÐ¾Ñ âгÑаниÑÐ½Ð¸Ñ ÑоÑокâ: поÑаÑком Ñ ÐºÑнÑем дÑапазонÑ.
ÐбâÑÐºÑ Range(дÑапазон) ÑÑвоÑÑÑÑÑÑÑ Ð±ÐµÐ· паÑамеÑÑÑв:
let range = new Range();
ÐÐ°Ð»Ñ Ð¼Ð¸ можемо вÑÑановиÑи Ð¼ÐµÐ¶Ñ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ð·Ð° Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ range.setStart(node, offset) Ñ range.setEnd(node, offset).
Як ви могли здогадаÑиÑÑ, ми бÑдемо викоÑиÑÑовÑваÑи обâÑкÑи Range Ð´Ð»Ñ Ð²Ð¸Ð´ÑленнÑ, але ÑпоÑаÑÐºÑ Ð´Ð°Ð²Ð°Ð¹Ñе ÑÑвоÑимо декÑлÑка ÑакиÑ
обâÑкÑÑв.
ЧаÑÑкове видÑÐ»ÐµÐ½Ð½Ñ ÑекÑÑÑ
ЦÑкаво Ñе, Ñо пеÑÑий аÑгÑÐ¼ÐµÐ½Ñ node в обоÑ
меÑодаÑ
може бÑÑи або ÑекÑÑовим вÑзлом, або вÑзлом елеменÑом, Ñ Ð²Ñд ÑÑого залежиÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ Ð´ÑÑгого аÑгÑменÑÑ.
ЯкÑо node â Ñе ÑекÑÑовий вÑзол, Ñо offset Ð¼Ð°Ñ Ð±ÑÑи позиÑÑÑÑ Ð² його ÑекÑÑÑ.
ÐапÑиклад, в елеменÑÑ <p>Hello</p>, ми можемо ÑÑвоÑиÑи дÑапазон, Ñо мÑÑÑиÑÑ Ð»ÑÑеÑи âllâ Ñаким Ñином:
<p id="p">Hello</p>
<script>
let range = new Range();
range.setStart(p.firstChild, 2);
range.setEnd(p.firstChild, 4);
// toString дÑÐ°Ð¿Ð°Ð·Ð¾Ð½Ñ Ð¿Ð¾Ð²ÐµÑÑÐ°Ñ Ð¹Ð¾Ð³Ð¾ вмÑÑÑ Ñк ÑекÑÑ
console.log(range); // ll
</script>
ТÑÑ Ð¼Ð¸ беÑемо пеÑÑий доÑÑÑнÑй ÐµÐ»ÐµÐ¼ÐµÐ½Ñ Ð²ÑеÑÐµÐ´Ð¸Ð½Ñ <p> (Ñе ÑекÑÑовий вÑзол) Ñ Ð²ÐºÐ°Ð·ÑÑмо позиÑÑÑ Ð² ÑекÑÑÑ Ð´Ð»Ñ Ð²Ð¸Ð´ÑленнÑ:
ÐидÑÐ»ÐµÐ½Ð½Ñ Ð²ÑзлÑв елеменÑÑв
ÐÑоÑе, ÑкÑо node Ñ Ð²Ñзлом елеменÑом, ÑÐ¾Ð´Ñ offset Ð¼Ð°Ñ Ð±ÑÑи номеÑом доÑÑÑнÑого елеменÑÑ.
Це зÑÑÑно Ð´Ð»Ñ ÑÑвоÑÐµÐ½Ð½Ñ Ð´ÑапазонÑв, ÑÐºÑ Ð¼ÑÑÑÑÑÑ Ð²Ñзли в ÑÑломÑ, а не зÑпинÑÑÑÑÑÑ Ð´ÐµÑÑ ÑÑеÑÐµÐ´Ð¸Ð½Ñ ÑÑ Ð½Ñого ÑекÑÑÑ.
ÐапÑиклад, маÑмо бÑлÑÑ Ñкладний ÑÑÐ°Ð³Ð¼ÐµÐ½Ñ Ð´Ð¾ÐºÑменÑÑ:
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
ÐÑÑ Ð¹Ð¾Ð³Ð¾ ÑÑÑÑкÑÑÑа DOM з вÑзлами елеменÑами Ñа ÑекÑÑовими вÑзлами:
ÐÑобимо дÑапазон Ð´Ð»Ñ "Example: <i>italic</i>".
Як ми баÑимо, ÑÑ ÑÑаза ÑкладаÑÑÑÑÑ ÑÑвно з двоÑ
наÑадкÑв <p> з ÑндекÑами 0 Ñ 1:
-
ÐоÑаÑкова ÑоÑка маÑ
<p>Ñк баÑÑкÑвÑÑкийnodeÑ0Ñкoffset.Ð¢Ð¾Ð¼Ñ Ð¼Ð¸ можемо вÑÑановиÑи його Ñк
range.setStart(p, 0). -
ÐÑнÑева ÑоÑка Ñакож маÑ
<p>Ñк баÑÑкÑвÑÑкийnode, але2Ñкoffset(вона вказÑÑ Ð´Ñапазон до, але не вклÑÑаÑÑиoffset).Ð¢Ð¾Ð¼Ñ Ð¼Ð¸ можемо вÑÑановиÑи його Ñк
range.setEnd(p, 2).
ÐижÑе ми пÑдгоÑÑвали пÑиклад з демонÑÑÑаÑÑÑÑ. ЯкÑо ви запÑÑÑиÑе його, Ñо ÑекÑÑ Ð±Ñде видÑлено:
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
<script>
let range = new Range();
range.setStart(p, 0);
range.setEnd(p, 2);
// toString дÑÐ°Ð¿Ð°Ð·Ð¾Ð½Ñ Ð¿Ð¾Ð²ÐµÑÑÐ°Ñ Ð¹Ð¾Ð³Ð¾ вмÑÑÑ Ñ Ð²Ð¸Ð³Ð»ÑÐ´Ñ ÑекÑÑÑ Ð±ÐµÐ· ÑегÑв
console.log(range); // Example: italic
// заÑÑоÑÑÑмо Ñей дÑапазон Ð´Ð»Ñ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ð² document (поÑÑнÑÑÑÑÑÑ Ð½Ð¸Ð¶Ñе)
document.getSelection().addRange(range);
</script>
ÐÑÑ Ð³Ð½ÑÑкÑÑий ÑеÑÑовий пÑиклад, де ви можеÑе вÑÑановиÑи поÑаÑковÑ/кÑнÑÐµÐ²Ñ ÑоÑки дÑÐ°Ð¿Ð°Ð·Ð¾Ð½Ñ Ñа доÑлÑдиÑи ÑнÑÑ Ð²Ð°ÑÑанÑи:
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
From <input id="start" type="number" value=1> â To <input id="end" type="number" value=4>
<button id="button">Click to select</button>
<script>
button.onclick = () => {
let range = new Range();
range.setStart(p, start.value);
range.setEnd(p, end.value);
// заÑÑоÑÑваÑи видÑленнÑ, поÑÑненÑÑÑÑÑÑ Ð½Ð¸Ð¶Ñе
document.getSelection().removeAllRanges();
document.getSelection().addRange(range);
};
</script>
ÐапÑиклад, видÑÐ»ÐµÐ½Ð½Ñ Ñ ÑÐ¾Ð¼Ñ ÑÐ°Ð¼Ð¾Ð¼Ñ <p> вÑд offset 1 до 4 Ð´Ð°Ñ Ð½Ð°Ð¼ дÑапазон <i>italic</i> Ñ <b>bold</b>:
Ðам не поÑÑÑбно викоÑиÑÑовÑваÑи однаковий вÑзол Ñ setStart Ñ setEnd. ÐÑапазон може оÑ
оплÑваÑи багаÑо неповâÑзаниÑ
вÑзлÑв. Ðажливо лиÑе, Ñоб кÑнеÑÑ Ð±Ñв ÑозÑаÑований в докÑменÑÑ Ð¿ÑÑÐ»Ñ Ð¿Ð¾ÑаÑкÑ.
ÐидÑÐ»ÐµÐ½Ð½Ñ Ð±ÑлÑÑого ÑÑагменÑа
ÐавайÑе збÑлÑÑемо ÑозмÑÑ Ð²Ð¸Ð´Ñленого ÑÑагменÑа:
Ðи вже знаÑмо, Ñк Ñе зÑобиÑи. Ðам пÑоÑÑо поÑÑÑбно вÑÑановиÑи поÑаÑок Ñ ÐºÑнеÑÑ Ñк вÑдноÑне змÑÑÐµÐ½Ð½Ñ Ð² ÑекÑÑÐ¾Ð²Ð¸Ñ Ð²ÑÐ·Ð»Ð°Ñ .
Ðам поÑÑÑбно ÑÑвоÑиÑи дÑапазон, Ñкий:
- поÑинаÑÑÑÑÑ Ð· позиÑÑÑ 2 Ñ Ð¿ÐµÑÑÐ¾Ð¼Ñ Ð´Ð¾ÑÑÑнÑÐ¾Ð¼Ñ Ð²ÑÐ·Ð»Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñа
<p>(беÑÑÑи вÑÑ, кÑÑм Ð´Ð²Ð¾Ñ Ð¿ÐµÑÑÐ¸Ñ Ð»ÑÑÐµÑ "Example: ") - закÑнÑÑÑÑÑÑÑ Ð½Ð° позиÑÑÑ 3 Ñ
<b>в пеÑÑÐ¾Ð¼Ñ Ð´Ð¾ÑÑÑнÑÐ¾Ð¼Ñ Ð²ÑÐ·Ð»Ñ (беÑе пеÑÑÑ ÑÑи лÑÑеÑи âboldâ, але не бÑлÑÑе):
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
<script>
let range = new Range();
range.setStart(p.firstChild, 2);
range.setEnd(p.querySelector('b').firstChild, 3);
console.log(range); // ample: italic and bol
// заÑÑоÑÑÑмо Ñей дÑапазон Ð´Ð»Ñ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ð² document (поÑÑнÑÑÑÑÑÑ Ð½Ð¸Ð¶Ñе)
window.getSelection().addRange(range);
</script>
Як баÑиÑе, доÑиÑÑ Ð»ÐµÐ³ÐºÐ¾ ÑÑвоÑиÑи дÑапазон Ð´Ð»Ñ Ð±ÑдÑ-Ñого.
Ðа бÑлÑÑе, ÑкÑо ми Ñ
оÑемо взÑÑи вÑзли Ñк ÑÑле, ÑÑеба пеÑедаÑи елеменÑи замÑÑÑÑ ÑекÑÑовиÑ
вÑзлÑв в setStart/setEnd. ÐнакÑе Ñе бÑде пÑаÑÑваÑи на ÑÑÐ²Ð½Ñ ÑекÑÑÑ.
ÐлаÑÑивоÑÑÑ Range
ÐбâÑÐºÑ Ð´ÑапазонÑ, Ñкий ми викоÑиÑÑовÑвали Ñ Ð¿ÑÐ¸ÐºÐ»Ð°Ð´Ñ Ð²Ð¸Ñе, Ð¼Ð°Ñ ÑÐ°ÐºÑ Ð²Ð»Ð°ÑÑивоÑÑÑ:
startContainer,startOffsetâ node Ñ offset поÑаÑкÑ,- Ñ Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ð¾Ð¼Ñ Ð²Ð¸Ñе пÑикладÑ: пеÑÑий ÑекÑÑовий вÑзол вÑеÑединÑ
<p>Ñ2.
- Ñ Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ð¾Ð¼Ñ Ð²Ð¸Ñе пÑикладÑ: пеÑÑий ÑекÑÑовий вÑзол вÑеÑединÑ
endContainer,endOffsetâ node Ñ offset кÑнÑÑ,- Ñ Ð¿ÑÐ¸ÐºÐ»Ð°Ð´Ñ Ð²Ð¸Ñе: пеÑÑий ÑекÑÑовий вÑзол вÑеÑединÑ
<b>Ñ3.
- Ñ Ð¿ÑÐ¸ÐºÐ»Ð°Ð´Ñ Ð²Ð¸Ñе: пеÑÑий ÑекÑÑовий вÑзол вÑеÑединÑ
collapsedâ знаÑÐµÐ½Ð½Ñ Ð»Ð¾Ð³ÑÑного ÑипÑ,trueÑкÑо дÑапазон поÑинаÑÑÑÑÑ Ñ Ð·Ð°ÐºÑнÑÑÑÑÑÑÑ Ð² однÑй ÑоÑÑÑ (ÑÐ¾Ð¼Ñ Ð²ÑеÑÐµÐ´Ð¸Ð½Ñ Ð´ÑÐ°Ð¿Ð°Ð·Ð¾Ð½Ñ Ð½ÐµÐ¼Ð°Ñ Ð²Ð¼ÑÑÑÑ),- Ñ Ð¿ÑÐ¸ÐºÐ»Ð°Ð´Ñ Ð²Ð¸Ñе:
false
- Ñ Ð¿ÑÐ¸ÐºÐ»Ð°Ð´Ñ Ð²Ð¸Ñе:
commonAncestorContainerâ найближÑий ÑпÑлÑний пÑедок ÑÑÑÑ Ð²ÑзлÑв Ñ Ð´ÑапазонÑ,- Ñ Ð¿ÑÐ¸ÐºÐ»Ð°Ð´Ñ Ð²Ð¸Ñе:
<p>
- Ñ Ð¿ÑÐ¸ÐºÐ»Ð°Ð´Ñ Ð²Ð¸Ñе:
ÐеÑоди видÑÐ»ÐµÐ½Ð½Ñ Ð² Range
ÐÑнÑÑ Ð±Ð°Ð³Ð°Ñо зÑÑÑÐ½Ð¸Ñ Ð¼ÐµÑодÑв по ÑобоÑÑ Ð· дÑапазонами.
Ðи вже баÑили setStart Ñ setEnd, оÑÑ ÑнÑÑ Ð¿Ð¾Ð´ÑÐ±Ð½Ñ Ð¼ÐµÑоди.
ÐÑÑановиÑи поÑаÑок дÑапазонÑ:
setStart(node, offset)вÑÑановиÑи поÑаÑок Ñ: позиÑÑÑoffsetвnodesetStartBefore(node)вÑÑановиÑи поÑаÑок: безпоÑеÑеднÑо пеÑедnodesetStartAfter(node)вÑÑановиÑи поÑаÑок: вÑдÑÐ°Ð·Ñ Ð¿ÑÑлÑnode
ÐÑÑановиÑи кÑнеÑÑ Ð´ÑÐ°Ð¿Ð°Ð·Ð¾Ð½Ñ (подÑÐ±Ð½Ñ Ð¼ÐµÑоди):
setEnd(node, offset)вÑÑановиÑи кÑнеÑÑ Ñ: позиÑÑÑoffsetвnodesetEndBefore(node)вÑÑановиÑи кÑнеÑÑ: безпоÑеÑеднÑо пеÑедnodesetEndAfter(node)вÑÑановиÑи кÑнеÑÑ: одÑÐ°Ð·Ñ Ð¿ÑÑлÑnode
ТеÑ
нÑÑно setStart/setEnd можÑÑÑ ÑобиÑи Ñо завгодно, але бÑлÑÑе меÑодÑв забезпеÑÑÑÑÑ Ð±ÑлÑÑÑ Ð·ÑÑÑнÑÑÑÑ.
У вÑÑÑ
ÑиÑ
меÑодаÑ
node може бÑÑи Ñк ÑекÑÑовим, Ñак Ñ Ð²Ñзлом елеменÑом: Ð´Ð»Ñ ÑекÑÑовиÑ
вÑзлÑв offset пÑопÑÑÐºÐ°Ñ ÑÐ°ÐºÑ ÐºÑлÑкÑÑÑÑ ÑимволÑв, ÑÐ¾Ð´Ñ Ñк Ð´Ð»Ñ Ð²ÑзлÑв елеменÑÑв ÑÑÑлÑки ж доÑÑÑнÑÑ
вÑзлÑв.
Ще бÑлÑÑе меÑодÑв ÑÑвоÑÐµÐ½Ð½Ñ Ð´ÑапазонÑв:
selectNode(node)вÑÑановиÑи дÑапазон Ð´Ð»Ñ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ð²ÑÑогоnodeselectNodeContents(node)вÑÑановиÑи дÑапазон Ð´Ð»Ñ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ð²ÑÑого вмÑÑÑÑnodecollapse(toStart)ÑкÑоtoStart=trueвÑÑановиÑи кÑнеÑÑ=поÑаÑок, ÑнакÑе вÑÑановиÑи поÑаÑок=кÑнеÑÑ, Ñаким Ñином згоÑнÑвÑи дÑапазонcloneRange()ÑÑвоÑÑÑ Ð½Ð¾Ð²Ð¸Ð¹ дÑапазон Ñз Ñим Ñамим поÑаÑком/кÑнÑем
ÐеÑоди ÑедагÑÐ²Ð°Ð½Ð½Ñ Range
ÐÑÑÐ»Ñ ÑÑвоÑÐµÐ½Ð½Ñ Ð´ÑÐ°Ð¿Ð°Ð·Ð¾Ð½Ñ Ð¼Ð¸ можемо манÑпÑлÑваÑи його вмÑÑÑом за Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ ÑÐ°ÐºÐ¸Ñ Ð¼ÐµÑодÑв:
deleteContents()â видалиÑи вмÑÑÑ Ð´ÑÐ°Ð¿Ð°Ð·Ð¾Ð½Ñ Ð· докÑменÑаextractContents()â видалиÑи вмÑÑÑ Ð´ÑÐ°Ð¿Ð°Ð·Ð¾Ð½Ñ Ð· докÑменÑа Ñа повеÑнÑÑи Ñк DocumentFragmentcloneContents()â клонÑваÑи вмÑÑÑ Ð´ÑÐ°Ð¿Ð°Ð·Ð¾Ð½Ñ Ñа повеÑнÑÑи Ñк DocumentFragmentinsertNode(node)â вÑÑавиÑиnodeв докÑÐ¼ÐµÐ½Ñ Ð½Ð° поÑаÑÐºÑ Ð´ÑапазонÑsurroundContents(node)â обеÑнÑÑиnodeнавколо вмÑÑÑÑ Ð´ÑапазонÑ. Щоб Ñе пÑаÑÑвало, дÑапазон Ð¼Ð°Ñ Ð¼ÑÑÑиÑи вÑдкÑиваÑÑÑ Ñа закÑиваÑÑÑ Ñеги Ð´Ð»Ñ Ð²ÑÑÑ ÐµÐ»ÐµÐ¼ÐµÐ½ÑÑв Ñ Ð½ÑомÑ: Ð¶Ð¾Ð´Ð½Ð¸Ñ ÑаÑÑÐºÐ¾Ð²Ð¸Ñ Ð´ÑапазонÑв, Ñк-оÑ<i>abc.
Ðа Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ ÑÐ¸Ñ Ð¼ÐµÑодÑв ми можемо ÑобиÑи Ñо завгодно з видÑленними вÑзлами.
ÐÑÑ ÑеÑÑовий пÑиклад, Ñоб побаÑиÑи ÑÑ Ñ Ð´ÑÑ:
ÐаÑиÑнÑÑÑ ÐºÐ½Ð¾Ð¿ÐºÐ¸, Ñоб запÑÑÑиÑи меÑоди Ð´Ð»Ñ Ð²Ð¸Ð´ÑленнÑ, "resetExample", Ñоб ÑкинÑÑи його.
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
<p id="result"></p>
<script>
let range = new Range();
// Ðожен пÑодемонÑÑÑований меÑод пÑедÑÑавлений ÑÑÑ:
let methods = {
deleteContents() {
range.deleteContents()
},
extractContents() {
let content = range.extractContents();
result.innerHTML = "";
result.append("extracted: ", content);
},
cloneContents() {
let content = range.cloneContents();
result.innerHTML = "";
result.append("cloned: ", content);
},
insertNode() {
let newNode = document.createElement('u');
newNode.innerHTML = "NEW NODE";
range.insertNode(newNode);
},
surroundContents() {
let newNode = document.createElement('u');
try {
range.surroundContents(newNode);
} catch(e) { console.log(e) }
},
resetExample() {
p.innerHTML = `Example: <i>italic</i> and <b>bold</b>`;
result.innerHTML = "";
range.setStart(p.firstChild, 2);
range.setEnd(p.querySelector('b').firstChild, 3);
window.getSelection().removeAllRanges();
window.getSelection().addRange(range);
}
};
for(let method in methods) {
document.write(`<div><button onclick="methods.${method}()">${method}</button></div>`);
}
methods.resetExample();
</script>
ÐÑнÑÑÑÑ Ñакож меÑоди поÑÑвнÑÐ½Ð½Ñ Ð´ÑапазонÑв, але вони викоÑиÑÑовÑÑÑÑÑÑ ÑÑдко. Ðоли вони вам знадоблÑÑÑÑÑ, ви можеÑе з ними познайомиÑиÑÑ Ð¾ÑÑ ÑÑÑ spec, або ÑÑÑ MDN manual.
Selection
Range â Ñе загалÑний обâÑÐºÑ Ð´Ð»Ñ ÐºÐµÑÑÐ²Ð°Ð½Ð½Ñ Ð´Ñапазонами видÑленнÑ. ХоÑа ÑÑвоÑÐµÐ½Ð½Ñ Range не ознаÑаÑ, Ñо ми баÑимо видÑÐ»ÐµÐ½Ð½Ñ Ð½Ð° екÑанÑ.
Ðи можемо ÑÑвоÑÑваÑи обâÑкÑи Range, пеÑедаваÑи ÑÑ
â вони ÑÐ°Ð¼Ñ Ð¿Ð¾ ÑÐ¾Ð±Ñ Ð½ÑÑого вÑзÑалÑно не видÑлÑÑÑÑ.
ÐидÑÐ»ÐµÐ½Ð½Ñ Ð² докÑменÑÑ Ð¿ÑедÑÑавлено обâÑкÑом Selection, Ñкий можна оÑÑимаÑи Ñк window.getSelection() або document.getSelection(). ÐидÑÐ»ÐµÐ½Ð½Ñ Ð¼Ð¾Ð¶Ðµ мÑÑÑиÑи нÑÐ»Ñ Ð°Ð±Ð¾ бÑлÑÑе дÑапазонÑв. ÐÑинаймнÑ, Selection API specification каже Ñаме Ñак. Ðднак на пÑакÑиÑÑ Ð»Ð¸Ñе Firefox дозволÑÑ Ð²Ð¸Ð±Ð¸ÑаÑи кÑлÑка дÑапазонÑв Ñ Ð´Ð¾ÐºÑменÑÑ Ð·Ð° Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ Ctrl+click (Cmd+click Ð´Ð»Ñ Mac).
ÐÑÑ ÑкÑÑнÑÐ¾Ñ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ð· 3-Ñома дÑапазонами, зÑоблений Ñ Firefox:
ÐнÑÑ Ð±ÑаÑзеÑи пÑдÑÑимÑÑÑÑ Ð¼Ð°ÐºÑимÑм 1 дÑапазон. Як ми побаÑимо, деÑÐºÑ Ð· меÑодÑв Selection ознаÑаÑÑÑ, Ñо може бÑÑи багаÑо дÑапазонÑв, але Ð·Ð½Ð¾Ð²Ñ Ð¶ Ñаки, Ñ Ð²ÑÑÑ
бÑаÑзеÑаÑ
, кÑÑм Firefox, ÑÑ
не бÑлÑÑе 1.
ÐÑÑ Ð½ÐµÐ²ÐµÐ»Ð¸ÐºÐ¸Ð¹ пÑиклад, Ñкий показÑÑ Ð¿Ð¾ÑоÑне видÑÐ»ÐµÐ½Ð½Ñ (видÑлÑÑÑ ÑоÑÑ Ñ Ð½Ð°ÑиÑнÑÑÑ) Ñк ÑекÑÑ:
ÐлаÑÑивоÑÑÑ Selection
Як бÑло Ñказано, обâÑÐºÑ Selection ÑеоÑеÑиÑно може мÑÑÑиÑи кÑлÑка дÑапазонÑв. Ðи можемо оÑÑимаÑи ÑÑ Ð´Ñапазони за Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ Ð¼ÐµÑодÑ:
getRangeAt(i)â оÑÑимаÑи i-й дÑапазон, поÑинаÑÑи з0. У вÑÑÑ Ð±ÑаÑзеÑÐ°Ñ , кÑÑм Firefox, викоÑиÑÑовÑÑÑÑÑÑ Ð»Ð¸Ñе0.
ÐÑÑм Ñого, ÑÑнÑÑÑÑ Ð·ÑÑÑнÑÑÑ Ð²Ð»Ð°ÑÑивоÑÑÑ.
ÐодÑбно до дÑапазонÑ, обâÑÐºÑ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ð¼Ð°Ñ Ð¿Ð¾ÑаÑок, Ñкий називаÑÑÑÑÑ âanchorâ, Ñ ÐºÑнеÑÑ, Ñкий називаÑÑÑÑÑ âfocusâ.
ÐÑновними влаÑÑивоÑÑÑми Selection Ñ:
anchorNodeâ вÑзол, де поÑинаÑÑÑÑÑ Ð²Ð¸Ð´ÑленнÑ,anchorOffsetâ змÑÑÐµÐ½Ð½Ñ Ð²anchorNode, де поÑинаÑÑÑÑÑ Ð²Ð¸Ð´ÑленнÑ,focusNodeâ вÑзол, де закÑнÑÑÑÑÑÑÑ Ð²Ð¸Ð´ÑленнÑ,focusOffsetâ зÑÑв ÑfocusNode, де закÑнÑÑÑÑÑÑÑ Ð²Ð¸Ð´ÑленнÑ,isCollapsedâtrueÑкÑо нÑÑого не видÑлено (поÑожнÑй дÑапазон) або не ÑÑнÑÑ.rangeCountâ кÑлÑкÑÑÑÑ Ð´ÑапазонÑв Ñ Ð²Ð¸Ð´ÑленнÑ, макÑимÑм1Ñ Ð²ÑÑÑ Ð±ÑаÑзеÑÐ°Ñ , кÑÑм Firefox.
ÐÑнÑÑÑÑ Ð²Ð°Ð¶Ð»Ð¸Ð²Ñ Ð²ÑдмÑнноÑÑÑ Selection anchor/focus поÑÑвнÑно з Range start/end.
Як ми знаÑмо, обâÑкÑи Range завжди маÑÑÑ Ð¿Ð¾ÑаÑок(start) пеÑед кÑнÑем(end).
ÐÐ»Ñ Selection Ñе не завжди Ñак.
ÐидÑлÑÑи ÑоÑÑ Ð·Ð° Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ Ð¼Ð¸ÑÑ Ð¼Ð¾Ð¶Ð½Ð° в Ð¾Ð±Ð¾Ñ Ð½Ð°Ð¿ÑÑÐ¼ÐºÐ°Ñ : або âзлÑва напÑавоâ, або âÑпÑава налÑвоâ.
ÐнÑими Ñловами, коли ÐºÐ½Ð¾Ð¿ÐºÑ Ð¼Ð¸ÑÑ Ð½Ð°ÑиÑнÑÑо, а поÑÑм вона пеÑемÑÑÑÑÑÑÑÑ Ð²Ð¿ÐµÑед Ñ Ð´Ð¾ÐºÑменÑÑ, Ñо ÑÑ ÐºÑнеÑÑ (focus) бÑде пÑÑÐ»Ñ ÑÑ Ð¿Ð¾ÑаÑÐºÑ (anchor).
ÐапÑиклад ÑкÑо коÑиÑÑÑÐ²Ð°Ñ Ð¿Ð¾ÑÐ¸Ð½Ð°Ñ Ð²Ð¸Ð´ÑлÑÑи миÑÐµÑ Ñа пеÑÐµÑ Ð¾Ð´Ð¸ÑÑ Ð²Ñд âExampleâ до âitalicâ:
â¦Ðле Ñе Ñаме видÑÐ»ÐµÐ½Ð½Ñ Ð¼Ð¾Ð¶Ð½Ð° зÑобиÑи Ñ Ð² звоÑоÑÐ½Ð¾Ð¼Ñ Ð½Ð°Ð¿ÑÑмкÑ: поÑинаÑÑи вÑд âitalicâ до âExampleâ (напÑÑмок назад), ÑÐ¾Ð´Ñ Ð¹Ð¾Ð³Ð¾ кÑнеÑÑ (focus) бÑде пеÑед поÑаÑком (anchor):
ÐодÑÑ Selection
ÐÑнÑÑÑÑ Ð¿Ð¾Ð´ÑÑ, Ñоб ÑлÑдкÑваÑи за видÑленнÑм:
elem.onselectstartâ коли видÑÐ»ÐµÐ½Ð½Ñ Ð¿Ð¾ÑинаÑÑÑÑÑ Ñаме на елеменÑÑelem(або вÑеÑÐµÐ´Ð¸Ð½Ñ Ð½Ñого). ÐапÑиклад, коли коÑиÑÑÑÐ²Ð°Ñ Ð½Ð°ÑиÑÐºÐ°Ñ Ð½Ð° нÑÐ¾Ð¼Ñ ÐºÐ½Ð¾Ð¿ÐºÑ Ð¼Ð¸ÑÑ Ñа поÑÐ¸Ð½Ð°Ñ ÑÑÑ Ð°Ñи вказÑвник.- ÐапобÑÐ³Ð°Ð½Ð½Ñ ÑÐ¸Ð¿Ð¾Ð²Ð¾Ñ Ð´ÑÑ ÑкаÑовÑÑ Ð¿Ð¾ÑаÑок видÑленнÑ. Таким Ñином, поÑаÑи видÑÐ»ÐµÐ½Ð½Ñ Ð· ÑÑого елеменÑа ÑÑÐ°Ñ Ð½ÐµÐ¼Ð¾Ð¶Ð»Ð¸Ð²Ð¾, але ÐµÐ»ÐµÐ¼ÐµÐ½Ñ Ð²Ñе Ñе доÑÑÑпний Ð´Ð»Ñ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ð·Ð°Ð³Ð°Ð»Ð¾Ð¼. ÐоÑиÑÑÑваÑÑ Ð¿ÑоÑÑо поÑÑÑбно поÑаÑи видÑÐ»ÐµÐ½Ð½Ñ Ð· ÑнÑого мÑÑÑÑ.
document.onselectionchangeâ кожного ÑазÑ, коли видÑÐ»ÐµÐ½Ð½Ñ Ð·Ð¼ÑнÑÑÑÑÑÑ Ð°Ð±Ð¾ поÑинаÑÑÑÑÑ.- ÐвеÑнÑÑÑ ÑвагÑ: Ñей обÑобник можна вÑÑановиÑи лиÑе на
document, вÑн вÑдÑÑежÑÑ Ð²ÑÑ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ð² нÑомÑ.
- ÐвеÑнÑÑÑ ÑвагÑ: Ñей обÑобник можна вÑÑановиÑи лиÑе на
ÐÑиклад з вÑдÑÑеженнÑм Selection
ÐÑÑ Ð½ÐµÐ²ÐµÐ»Ð¸ÐºÐ° демонÑÑÑаÑÑÑ, Ñка показÑÑ Ð¿Ð¾ÑоÑний вибÑÑ Ñа його Ð¼ÐµÐ¶Ñ Ñ document:
<p id="p">Select me: <i>italic</i> and <b>bold</b></p>
From <input id="from" disabled> â To <input id="to" disabled>
<script>
document.onselectionchange = function() {
let selection = document.getSelection();
let {anchorNode, anchorOffset, focusNode, focusOffset} = selection;
// anchorNode Ñ focusNode зазвиÑай Ñ ÑекÑÑовими вÑзлами
from.value = `${anchorNode?.data}, offset ${anchorOffset}`;
to.value = `${focusNode?.data}, offset ${focusOffset}`;
};
</script>
ÐидÑÐ»ÐµÐ½Ð½Ñ Ð· копÑÑваннÑм
Рдва пÑÐ´Ñ Ð¾Ð´Ð¸ до копÑÑÐ²Ð°Ð½Ð½Ñ Ð²Ð¸Ð´Ñленного вмÑÑÑÑ:
- Ðи можемо викоÑиÑÑаÑи
document.getSelection().toString(), Ñоб оÑÑимаÑи його Ñк ÑекÑÑ. - Ð ÑнÑÐ¾Ð¼Ñ Ð²Ð¸Ð¿Ð°Ð´ÐºÑ, Ñоб ÑкопÑÑваÑи повний DOM, напÑ. ÑкÑо нам поÑÑÑбно пÑодовжиÑи ÑоÑмаÑÑваннÑ, ми можемо оÑÑимаÑи видÑÐ»ÐµÐ½Ð½Ñ Ð´Ñапазони за допомогоÑ
getRangeAt(...). ÐбâÑкÑRange, Ñ ÑÐ²Ð¾Ñ ÑеÑгÑ, Ð¼Ð°Ñ Ð¼ÐµÑодcloneContents(), Ñкий клонÑÑ Ð¹Ð¾Ð³Ð¾ вмÑÑÑ Ñ Ð¿Ð¾Ð²ÐµÑÑÐ°Ñ Ñк обâÑкÑDocumentFragment, Ñкий ми можемо вÑÑавиÑи в ÑнÑе мÑÑÑе.
ÐÑÑ Ð¿Ñиклад копÑÑÐ²Ð°Ð½Ð½Ñ Ð²Ð¸Ð´Ñленого вмÑÑÑÑ Ñк ÑекÑÑÑ Ñ Ñк вÑзлÑв DOM:
<p id="p">Select me: <i>italic</i> and <b>bold</b></p>
Cloned: <span id="cloned"></span>
<br>
As text: <span id="astext"></span>
<script>
document.onselectionchange = function() {
let selection = document.getSelection();
cloned.innerHTML = astext.innerHTML = "";
// ÐлонÑваÑи вÑзли DOM Ñз дÑапазонÑв (ÑÑÑ Ð¼Ð¸ пÑдÑÑимÑÑмо множинне видÑленнÑ)
for (let i = 0; i < selection.rangeCount; i++) {
cloned.append(selection.getRangeAt(i).cloneContents());
}
// ÐÑÑимаÑи Ñк ÑекÑÑ
astext.innerHTML += selection;
};
</script>
ÐеÑоди Selection
Ðи можемо пÑаÑÑваÑи з видÑленнÑм, додаÑÑи/вилÑÑаÑÑи дÑапазони:
getRangeAt(i)â оÑÑимаÑи i-й дÑапазон, поÑинаÑÑи з0. У вÑÑÑ Ð±ÑаÑзеÑÐ°Ñ , кÑÑм Firefox, викоÑиÑÑовÑÑÑÑÑÑ Ð»Ð¸Ñе0.addRange(range)â додаÑиrangeдо видÑленнÑ. УÑÑ Ð±ÑаÑзеÑи, кÑÑм Firefox, ÑгноÑÑÑÑÑ Ð²Ð¸ÐºÐ»Ð¸Ðº, ÑкÑо Ñ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ð²Ð¶Ðµ Ñ Ð´Ñапазон.removeRange(range)â видалиÑиrangeз видÑленнÑ.removeAllRanges()â видалиÑи вÑÑ Ð´Ñапазони.empty()â меÑод аналогÑÑнийremoveAllRanges.
ÐÑнÑÑÑÑ Ñакож зÑÑÑÐ½Ñ Ð¼ÐµÑоди Ð´Ð»Ñ Ð±ÐµÐ·Ð¿Ð¾ÑеÑеднÑого кеÑÑÐ²Ð°Ð½Ð½Ñ Ð´Ñапазоном вибоÑÑ Ð±ÐµÐ· пÑомÑжниÑ
викликÑв Range:
collapse(node, offset)â замÑниÑи дÑапазон видÑÐ»ÐµÐ½Ð½Ñ Ð½Ð° новий, Ñкий поÑинаÑÑÑÑÑ Ñ Ð·Ð°ÐºÑнÑÑÑÑÑÑÑ Ð½Ð° заданомÑnode, на позиÑÑÑoffset.setPosition(node, offset)â меÑод аналогÑÑнийcollapse.collapseToStart()â згоÑнÑÑи (замÑниÑи поÑожнÑм дÑапазоном) до поÑаÑÐºÑ Ð²Ð¸Ð´ÑленнÑ,collapseToEnd()â згоÑнÑÑи до кÑнÑÑ Ð²Ð¸Ð´ÑленнÑ,extend(node, offset)â пеÑемÑÑÑиÑи ÑокÑÑ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ð½Ð° заданийnode, положеннÑoffset,setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset)â замÑниÑи дÑапазон видÑÐ»ÐµÐ½Ð½Ñ Ð·Ð°Ð´Ð°Ð½Ð¸Ð¼ поÑаÑковимanchorNode/anchorOffsetÑ ÐºÑнÑевимfocusNode/focusOffset. ÐеÑÑ Ð²Ð¼ÑÑÑ Ð¼Ñж ними бÑде видÑлено.selectAllChildren(node)â видÑлиÑи вÑÑ Ð´Ð¾ÑÑÑÐ½Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñиnode.deleteFromDocument()â видалиÑи видÑлений вмÑÑÑ Ñз докÑменÑа.containsNode(node, allowPartialContainment = false)â пеÑевÑÑÑÑ, Ñи мÑÑÑиÑÑ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ð·Ð°Ð´Ð°Ð½Ð¸Ð¹node(або ÑаÑÑково, ÑкÑо дÑÑгий аÑгÑменÑtrue)
ÐÐ»Ñ Ð±ÑлÑÑоÑÑÑ Ð·Ð°Ð²Ð´Ð°Ð½Ñ ÑÑ Ð¼ÐµÑоди ÑÑдово пÑдÑ
одÑÑÑ, Ð½ÐµÐ¼Ð°Ñ Ð½ÐµÐ¾Ð±Ñ
ÑдноÑÑÑ Ð·Ð²ÐµÑÑаÑиÑÑ Ð´Ð¾ базового обâÑкÑа Range.
ÐапÑиклад, видÑÐ»ÐµÐ½Ð½Ñ Ð²ÑÑого вмÑÑÑÑ Ð°Ð±Ð·Ð°ÑÑ <p>:
<p id="p">Select me: <i>italic</i> and <b>bold</b></p>
<script>
// видÑлиÑи вÑд 0-го доÑÑÑнÑого елеменÑа <p> до оÑÑаннÑого доÑÑÑнÑого
document.getSelection().setBaseAndExtent(p, 0, p, p.childNodes.length);
</script>
Те Ñаме з викоÑиÑÑаннÑм дÑапазонÑв:
<p id="p">Select me: <i>italic</i> and <b>bold</b></p>
<script>
let range = new Range();
range.selectNodeContents(p); // або selectNode(p), Ñоб Ñакож видÑлиÑи Ñег <p>
document.getSelection().removeAllRanges(); // ÑкинÑÑи наÑвне видÑленнÑ, ÑкÑо воно Ñ
document.getSelection().addRange(range);
</script>
ЯкÑо вже ÑоÑÑ Ð²Ð¸Ð´Ñлене, ÑпоÑаÑÐºÑ Ð¿ÑибеÑÑÑÑ Ñе за Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ removeAllRanges(). РпоÑÑм додавайÑе дÑапазони. Ð ÑнÑÐ¾Ð¼Ñ Ð²Ð¸Ð¿Ð°Ð´ÐºÑ Ð²ÑÑ Ð±ÑаÑзеÑи, кÑÑм Firefox, ÑгноÑÑÑÑÑ Ð½Ð¾Ð²Ñ Ð´Ñапазони.
ÐинÑÑок ÑÑановлÑÑÑ Ð´ÐµÑÐºÑ Ð¼ÐµÑоди, ÑÐºÑ Ð·Ð°Ð¼ÑнÑÑÑÑ ÑÑнÑÑÑе видÑленнÑ, напÑиклад setBaseAndExtent.
ÐидÑÐ»ÐµÐ½Ð½Ñ Ð² ÑнÑеÑакÑÐ¸Ð²Ð½Ð¸Ñ ÐµÐ»ÐµÐ¼ÐµÐ½ÑÐ°Ñ ÑоÑми
Ð¢Ð°ÐºÑ ÐµÐ»ÐµÐ¼ÐµÐ½Ñи ÑоÑми, Ñк input Ñ textarea, надаÑÑÑ ÑпеÑÑалÑний API Ð´Ð»Ñ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ð±ÐµÐ· обâÑкÑÑв Selection або Range. Ðа бÑлÑÑе, оÑкÑлÑки на вÑ
Ð¾Ð´Ñ Ð·Ð°Ð²Ð¶Ð´Ð¸ ÑиÑÑий ÑекÑÑ, а не HTML, ÑÐ°ÐºÑ Ð¾Ð±âÑкÑи пÑоÑÑо не поÑÑÑбнÑ, вÑе пÑаÑÑÑ Ð·Ð½Ð°Ñно пÑоÑÑÑÑе.
ÐлаÑÑивоÑÑÑ:
input.selectionStartâ позиÑÑÑ Ð¿Ð¾ÑаÑÐºÑ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ (пÑаÑÑÑ Ð½Ð° запиÑ),input.selectionEndâ позиÑÑÑ ÐºÑнÑÑ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ (пÑаÑÑÑ Ð½Ð° запиÑ),input.selectionDirectionâ напÑÑмок видÑленнÑ, одне з: âforwardâ, âbackwardâ або ânoneâ (ÑкÑо напÑ. видÑлено подвÑйним клаÑаннÑм миÑÑ),
ÐодÑÑ:
input.onselectâ запÑÑкаÑÑÑÑÑ, коли ÑоÑÑ Ð²Ð¸Ð´Ñлено.
ÐеÑоди:
-
input.select()â видÑлÑÑ Ð²Ñе в ÑекÑÑÐ¾Ð²Ð¾Ð¼Ñ ÐµÐ»ÐµÐ¼ÐµÐ½ÑÑ (може бÑÑиtextareaзамÑÑÑÑinput), -
input.setSelectionRange(start, end, [direction])â змÑниÑи видÑÐ»ÐµÐ½Ð½Ñ Ð½Ð° дÑапазон вÑд позиÑÑÑstartдоendÑ Ð²ÐºÐ°Ð·Ð°Ð½Ð¾Ð¼Ñdirection(необовâÑзковий паÑамеÑеÑ). -
input.setRangeText(replacement, [start], [end], [selectionMode])â замÑниÑи дÑапазон ÑекÑÑÑ Ð½Ð¾Ð²Ð¸Ð¼ ÑекÑÑом.ÐеобовâÑÐ·ÐºÐ¾Ð²Ñ Ð°ÑгÑменÑи
startÑend, ÑкÑо вони наданÑ, вÑÑановлÑÑÑÑ Ð¿Ð¾ÑаÑок Ñ ÐºÑнеÑÑ Ð´ÑапазонÑ, ÑнакÑе викоÑиÑÑовÑÑÑÑÑÑ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ð²Ñд коÑиÑÑÑваÑа.ÐÑÑаннÑй аÑгÑменÑ,
selectionMode, визнаÑаÑ, Ñк бÑде вÑÑановлено видÑÐ»ÐµÐ½Ð½Ñ Ð¿ÑÑÐ»Ñ Ð·Ð°Ð¼Ñни ÑекÑÑÑ. ÐÐ¾Ð¶Ð»Ð¸Ð²Ñ Ð·Ð½Ð°ÑеннÑ:"select"â бÑде видÑлено Ñойно вÑÑавлений ÑекÑÑ."start"â дÑапазон видÑÐ»ÐµÐ½Ð½Ñ Ð·Ð³Ð¾ÑÑаÑÑÑÑÑ Ð±ÐµÐ·Ð¿Ð¾ÑеÑеднÑо пеÑед вÑÑавленим ÑекÑÑом (кÑÑÑÐ¾Ñ Ð±Ñде пеÑед ним)."end"â дÑапазон видÑÐ»ÐµÐ½Ð½Ñ Ð·Ð³Ð¾ÑÑаÑÑÑÑÑ Ð²ÑдÑÐ°Ð·Ñ Ð¿ÑÑÐ»Ñ Ð²ÑÑавленого ÑекÑÑÑ (кÑÑÑÐ¾Ñ Ð±Ñде вÑдÑÐ°Ð·Ñ Ð·Ð° ним)."preserve"â ÑпÑобÑÑ Ð·Ð±ÐµÑегÑи видÑленнÑ. Це Ñипове знаÑеннÑ.
Ð¢ÐµÐ¿ÐµÑ Ð´Ð°Ð²Ð°Ð¹Ñе подивимоÑÑ Ð½Ð° ÑÑ Ð¼ÐµÑоди в дÑÑ.
ÐÑиклад: вÑдÑÑÐµÐ¶ÐµÐ½Ð½Ñ Ð²Ð¸Ð´ÑленнÑ
ÐапÑиклад, Ñей код викоÑиÑÑовÑÑ Ð¿Ð¾Ð´ÑÑ onselect Ð´Ð»Ñ Ð²ÑдÑÑÐµÐ¶ÐµÐ½Ð½Ñ Ð²Ð¸Ð´ÑленнÑ:
<textarea id="area" style="width:80%;height:60px">
Selecting in this text updates values below.
</textarea>
<br>
From <input id="from" disabled> â To <input id="to" disabled>
<script>
area.onselect = function() {
from.value = area.selectionStart;
to.value = area.selectionEnd;
};
</script>
ÐÑÐ´Ñ Ð»Ð°Ñка, звеÑнÑÑÑ ÑвагÑ:
onselectÑпÑаÑÑовÑÑ, коли ÑоÑÑ Ð²Ð¸Ð´Ñлено, але не коли його пÑибÑано.- подÑÑ
document.onselectionchangeвÑдповÑдно до spec не Ð¼Ð°Ñ ÑнÑÑÑÑваÑи видÑÐ»ÐµÐ½Ð½Ñ Ð²ÑеÑÐµÐ´Ð¸Ð½Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñа ÑоÑми, оÑкÑлÑки вона не повâÑзана з видÑленнÑм Ñ Ð´Ñапазонами вdocument. ÐеÑÐºÑ Ð±ÑаÑзеÑи генеÑÑÑÑÑ ÑÑ, але ми не маÑмо покладаÑиÑÑ Ð½Ð° Ñе.
ÐÑиклад: ÑÑÑ ÐºÑÑÑоÑÑ
Ðи можемо змÑниÑи selectionStart Ñ selectionEnd, ÑÐºÑ Ð²ÑÑановлÑÑÑÑ Ð²Ð¸Ð´ÑленнÑ.
Ðажливим гÑаниÑним випадком Ñ ââколи selectionStart Ñ selectionEnd доÑÑвнÑÑÑÑ Ð¾Ð´Ð¸Ð½ одномÑ. Ð¢Ð¾Ð´Ñ Ñе ÑоÑно Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð½Ñ ÐºÑÑÑоÑа. Ðбо, ÑкÑо пеÑеÑÑазÑваÑи, коли нÑÑого не видÑлено, видÑÐ»ÐµÐ½Ð½Ñ Ð·Ð³Ð¾ÑÑаÑÑÑÑÑ Ð² позиÑÑÑ ÐºÑÑÑоÑа.
ÐÑже, вÑÑановивÑи selectionStart Ñ selectionEnd Ð¾Ð´Ð½Ð°ÐºÐ¾Ð²Ñ Ð·Ð½Ð°ÑеннÑ, ми пеÑемÑÑÑÑмо кÑÑÑоÑ.
ÐапÑиклад:
<textarea id="area" style="width:80%;height:60px">
Focus on me, the cursor will be at position 10.
</textarea>
<script>
area.onfocus = () => {
// setTimeout з нÑлÑÐ¾Ð²Ð¾Ñ Ð·Ð°ÑÑÐ¸Ð¼ÐºÐ¾Ñ Ð´Ð»Ñ Ð·Ð°Ð¿ÑÑÐºÑ Ð¿ÑÑÐ»Ñ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð½Ñ Ð´ÑÑ "focus"
setTimeout(() => {
// ми можемо вÑÑановиÑи бÑдÑ-Ñке видÑленнÑ
// ÑкÑо start=end, кÑÑÑÐ¾Ñ Ð·Ð½Ð°Ñ
одиÑÑÑÑ Ñаме в ÑÑÐ¾Ð¼Ñ Ð¼ÑÑÑÑ
area.selectionStart = area.selectionEnd = 10;
});
};
</script>
ÐÑиклад: змÑна видÑленнÑ
Щоб змÑниÑи вмÑÑÑ Ð²Ð¸Ð´ÑленнÑ, ми можемо викоÑиÑÑаÑи меÑод input.setRangeText(). ÐвиÑайно, ми можемо взÑÑи selectionStart/End Ñ, знаÑÑи видÑленнÑ, змÑниÑи вÑдповÑдний пÑдÑÑдок value, але меÑод setRangeText Ñ Ð¿Ð¾ÑÑжнÑÑим Ñ ÑаÑÑо зÑÑÑнÑÑим.
ÐÑоÑе Ñе деÑо Ñкладний меÑод. У ÑвоÑй найпÑоÑÑÑÑÑй ÑоÑÐ¼Ñ Ð· одним аÑгÑменÑом вÑн замÑнÑÑ Ð²Ð¸Ð´Ñлений коÑиÑÑÑваÑем дÑапазон Ñ Ð²Ð¸Ð´Ð°Ð»ÑÑ Ð²Ð¸Ð´ÑленнÑ.
ÐапÑиклад, ÑÑÑ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ð²Ñд коÑиÑÑÑваÑа бÑде обгоÑнÑÑо в *...*:
<input id="input" style="width:200px" value="Select here and click the button">
<button id="button">Wrap selection in stars *...*</button>
<script>
button.onclick = () => {
if (input.selectionStart == input.selectionEnd) {
return; // нÑÑого не видÑлено
}
let selected = input.value.slice(input.selectionStart, input.selectionEnd);
input.setRangeText(`*${selected}*`);
};
</script>
ÐаÑÑи бÑлÑÑе аÑгÑменÑÑв, ми можемо вÑÑановиÑи дÑапазон start Ñ end.
У ÑÑÐ¾Ð¼Ñ Ð¿ÑÐ¸ÐºÐ»Ð°Ð´Ñ Ð¼Ð¸ знаÑ
одимо "THIS" Ñ Ð²Ñ
ÑÐ´Ð½Ð¾Ð¼Ñ ÑекÑÑÑ, замÑнÑÑмо його Ñа залиÑаÑмо видÑÐ»ÐµÐ½Ð¾Ñ Ð·Ð°Ð¼ÑнÑ:
<input id="input" style="width:200px" value="Replace THIS in text">
<button id="button">Replace THIS</button>
<script>
button.onclick = () => {
let pos = input.value.indexOf("THIS");
if (pos >= 0) {
input.setRangeText("*THIS*", pos, pos + 4, "select");
input.focus(); // ÑокÑÑ, Ñоб зÑобиÑи видÑÐ»ÐµÐ½Ð½Ñ Ð²Ð¸Ð´Ð¸Ð¼Ð¸Ð¼
}
};
</script>
ÐÑиклад: вÑÑавиÑи пÑд кÑÑÑоÑ
ЯкÑо нÑÑого не видÑлено або ми викоÑиÑÑовÑÑмо Ð¾Ð´Ð½Ð°ÐºÐ¾Ð²Ñ start Ñ end Ñ setRangeText, ÑÐ¾Ð´Ñ Ð½Ð¾Ð²Ð¸Ð¹ ÑекÑÑ Ð¿ÑоÑÑо вÑÑавлÑÑÑÑÑÑ, нÑÑого не видалÑÑÑÑÑÑ.
Ðи Ñакож можемо вÑÑавиÑи ÑоÑÑ âза кÑÑÑоÑомâ, викоÑиÑÑовÑÑÑи setRangeText.
ÐÑÑ ÐºÐ½Ð¾Ð¿ÐºÐ°, Ñка вÑÑавлÑÑ "HELLO" на позиÑÑÑ ÐºÑÑÑоÑа Ñа ÑозмÑÑÑÑ ÐºÑÑÑÐ¾Ñ Ð¾Ð´ÑÐ°Ð·Ñ Ð¿ÑÑÐ»Ñ Ð½Ñого. ЯкÑо видÑÐ»ÐµÐ½Ð½Ñ Ð½Ðµ поÑожнÑ, воно замÑнÑÑÑÑÑÑ (ми можемо виÑвиÑи Ñе, поÑÑвнÑвÑи selectionStart!=selectionEnd Ñ Ð½Ð°ÑомÑÑÑÑ Ð·ÑобиÑи ÑоÑÑ ÑнÑе):
<input id="input" style="width:200px" value="Text Text Text Text Text">
<button id="button">Insert "HELLO" at cursor</button>
<script>
button.onclick = () => {
input.setRangeText("HELLO", input.selectionStart, input.selectionEnd, "end");
input.focus();
};
</script>
ÐабоÑона видÑленнÑ
Щоб забоÑониÑи видÑленнÑ, Ñ ÑÑи ÑпоÑоби:
-
ÐадайÑе CSS влаÑÑивÑÑÑÑ
user-select: none.<style> #elem { user-select: none; } </style> <div>Selectable <div id="elem">Unselectable</div> Selectable</div>Це не дозволÑÑ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ð¿Ð¾ÑинаÑиÑÑ Ð·
elem. Ðле коÑиÑÑÑÐ²Ð°Ñ Ð¼Ð¾Ð¶Ðµ поÑаÑи з ÑнÑого мÑÑÑÑ Ñ Ð²Ð¶Ðµ поÑÑм вклÑÑиÑи до нÑогоelem.ТодÑ
elemÑÑане ÑаÑÑиноÑdocument.getSelection(), ÑÐ¾Ð¼Ñ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ ÑакÑиÑно вÑдбÑваÑÑÑÑÑ, але його вмÑÑÑ Ð·Ð°Ð·Ð²Ð¸Ñай ÑгноÑÑÑÑÑÑÑ Ð¿Ñд ÑÐ°Ñ ÐºÐ¾Ð¿ÑÑÐ²Ð°Ð½Ð½Ñ Ñа вÑÑавки. -
ÐапобÑÐ³Ð°Ð½Ð½Ñ ÑÐ¸Ð¿Ð¾Ð²Ð¾Ñ Ð´ÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð´Ñй
onselectstartабоmousedown.<div>Selectable <div id="elem">Unselectable</div> Selectable</div> <script> elem.onselectstart = () => false; </script>Це запобÑÐ³Ð°Ñ ÑÑаÑÑÑ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ Ð·
elem, але коÑиÑÑÑÐ²Ð°Ñ Ð¼Ð¾Ð¶Ðµ поÑаÑи його з ÑнÑого елеменÑа, а поÑÑм пÑодовжиÑи доelem.Це зÑÑÑно, коли Ð´Ð»Ñ ÑÑÑÑ ÑÐ°Ð¼Ð¾Ñ Ð´ÑÑ Ñ ÑнÑий обÑобник подÑÑ, Ñкий ÑнÑÑÑÑÑ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ñ (напÑиклад,
mousedown). Ð¢Ð¾Ð¼Ñ Ð¼Ð¸ забоÑонÑÑмо видÑленнÑ, Ñоб ÑникнÑÑи конÑлÑкÑÑ, але вÑе Ñе дозволÑÑмо копÑÑваÑи вмÑÑÑelem. -
Ðи Ñакож можемо оÑиÑÑиÑи видÑÐ»ÐµÐ½Ð½Ñ Ð¿Ð¾ÑÑÑакÑÑм пÑÑÐ»Ñ Ñого, Ñк Ñе вже ÑÑалоÑÑ, за допомогоÑ
document.getSelection().empty(). Це ÑÑдко викоÑиÑÑовÑÑÑÑÑÑ, оÑкÑлÑки Ñе ÑпÑиÑинÑÑ Ð½ÐµÐ±Ð°Ð¶Ð°Ð½Ðµ Ð±Ð»Ð¸Ð¼Ð°Ð½Ð½Ñ Ð¿Ñд ÑÐ°Ñ Ð¿Ð¾Ñви Ñа Ð·Ð½Ð¸ÐºÐ½ÐµÐ½Ð½Ñ Ð²Ð¸Ð´ÑленнÑ.
ÐоÑиланнÑ
ÐÑдÑÑмки
Ðи ÑозглÑнÑли два ÑÑÐ·Ð½Ð¸Ñ API Ð´Ð»Ñ Ð²Ð¸Ð´ÑленнÑ:
- ÐÐ»Ñ Ð´Ð¾ÐºÑменÑа: обâÑкÑи
SelectionÑRange. - ÐлÑ
input,textarea: додаÑÐºÐ¾Ð²Ñ Ð¼ÐµÑоди Ñа влаÑÑивоÑÑÑ.
ÐÑÑгий API дÑже пÑоÑÑий, оÑкÑлÑки пÑаÑÑÑ Ð· ÑекÑÑом.
СеÑед найбÑлÑÑ ÑÐ¸Ð¿Ð¾Ð²Ð¸Ñ Ð·Ð°Ð´Ð°Ñ:
- ÐÑÑÐ¸Ð¼Ð°Ð½Ð½Ñ Ð¿Ð¾ÑоÑного видÑленнÑ:
let selection = document.getSelection(); let cloned = /* ÐµÐ»ÐµÐ¼ÐµÐ½Ñ Ð´Ð»Ñ ÐºÐ»Ð¾Ð½ÑÐ²Ð°Ð½Ð½Ñ Ð²Ð¸Ð´ÑÐ»ÐµÐ½Ð½Ð¸Ñ Ð²ÑзлÑв */; // поÑÑм заÑÑоÑÑйÑе меÑоди Range до selection.getRangeAt(0) // або, Ñк ÑÑÑ, до вÑÑÑ Ð´ÑапазонÑв Ð´Ð»Ñ Ð¿ÑдÑÑимки множинного видÑÐ»ÐµÐ½Ð½Ñ for (let i = 0; i < selection.rangeCount; i++) { cloned.append(selection.getRangeAt(i).cloneContents()); } - ÐалаÑÑÑÐ²Ð°Ð½Ð½Ñ Ð²Ð¸Ð´ÑленнÑ:
let selection = document.getSelection(); // безпоÑеÑеднÑо: selection.setBaseAndExtent(...from...to...); // або ми можемо ÑÑвоÑиÑи дÑапазон Ñ: selection.removeAllRanges(); selection.addRange(range);
РнаÑеÑÑÑ Ð¿Ñо кÑÑÑоÑ. ÐозиÑÑÑ ÐºÑÑÑоÑÑ Ð² елеменÑаÑ
, ÑÐºÑ Ð¼Ð¾Ð¶Ð½Ð° ÑедагÑваÑи, напÑиклад <textarea>, завжди знаÑ
одиÑÑÑÑ Ð½Ð° поÑаÑÐºÑ Ð°Ð±Ð¾ в кÑнÑÑ Ð²Ð¸Ð´ÑленнÑ. Ðи можемо викоÑиÑÑовÑваÑи його, Ñоб оÑÑимаÑи позиÑÑÑ ÐºÑÑÑоÑÑ Ð°Ð±Ð¾ пеÑемÑÑÑиÑи кÑÑÑоÑ, вÑÑановивÑи elem.selectionStart Ñ elem.selectionEnd.
ÐоменÑаÑÑ
<code>, Ð´Ð»Ñ ÐºÑлÑÐºÐ¾Ñ ÑÑдкÑв â обгоÑнÑÑÑ ÑÑ Ñегом<pre>, Ð´Ð»Ñ Ð¿Ð¾Ð½Ð°Ð´ 10 ÑÑдкÑв â викоÑиÑÑовÑйÑе пÑÑоÑниÑÑ (plnkr, jsbin, codepenâ¦)