Bu bobda biz hujjatdagi tanlashni, shuningdek <input> kabi forma maydonlaridagi tanlashni koârib chiqamiz.
JavaScript mavjud tanlashga kirishishi, DOM tugunlarini toâliq yoki qisman tanlashi/tanlamasligini bekor qilishi, tanlangan kontentni hujjatdan olib tashlashi, uni tegga oârashi va hokazolarni amalga oshirishi mumkin.
Bobning oxiridagi âXulosaâ qismida umumiy vazifalar uchun baâzi retseptlarni topishingiz mumkin. Balki bu sizning hozirgi ehtiyojlaringizni qondiradi, lekin butun matnni oâqisangiz koâproq narsalarni olasiz.
Asosiy Range va Selection obyektlari tushunish oson va keyin ulardan xohlagan narsangizni qildirish uchun hech qanday retseptga ehtiyoj qolmaydi.
Range
Tanlashning asosiy kontseptsiyasi Range boâlib, u asosan bir juft "chegara nuqtalari"dir: range boshlanishi va range tugashi.
Range obyekti parametrlarsiz yaratiladi:
let range = new Range();
Keyin biz range.setStart(node, offset) va range.setEnd(node, offset) yordamida tanlash chegaralarini oârnatishimiz mumkin.
Taxmin qilganingizdek, keyinroq biz Range obyektlarini tanlash uchun ishlatamiz, lekin avval bunday bir necha obyektlarni yaratamiz.
Matnni qisman tanlash
Qiziqarli tomoni shundaki, ikkala usuldagi birinchi argument node matn tuguni yoki element tuguni boâlishi mumkin va ikkinchi argumentning maânosi bunga bogâliq.
Agar node matn tuguni boâlsa, u holda offset uning matndagi pozitsiya boâlishi kerak.
Masalan, <p>Hello</p> elementi berilgan boâlsa, biz âllâ harflarini oâz ichiga olgan range yaratishimiz mumkin:
<p id="p">Hello</p>
<script>
let range = new Range();
range.setStart(p.firstChild, 2);
range.setEnd(p.firstChild, 4);
// range ning toString usuli uning kontentini matn sifatida qaytaradi
console.log(range); // ll
</script>
Bu yerda biz <p> ning birinchi bolasini olamiz (bu matn tuguni) va uning ichidagi matn pozitsiyalarini belgilaymiz:
Element tugunlarini tanlash
Muqobil ravishda, agar node element tuguni boâlsa, u holda offset bola raqami boâlishi kerak.
Bu tugunlarni toâliq oâz ichiga olgan range yaratish uchun qulay, ularning matnining biror joyida toâxtab qolmaslik uchun.
Masalan, bizda yanada murakkab hujjat fragmenti bor:
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
Mana uning element va matn tugunlari bilan DOM tuzilishi:
Keling, "Example: <i>italic</i>" uchun range yarataylik.
Koârib turganimizdek, bu ibora aniq <p> ning ikkita bolasidan iborat, indekslari 0 va 1:
-
Boshlanish nuqtasi
<p>ni otanodesifatida va0ni offset sifatida oladi.Shuning uchun biz uni
range.setStart(p, 0)deb oârnatishimiz mumkin. -
Tugash nuqtasi ham
<p>ni otanodesifatida oladi, lekin2ni offset sifatida oladi (u range nioffsetgacha, lekin uni oâz ichiga olmasdan belgilaydi).Shuning uchun biz uni
range.setEnd(p, 2)deb oârnatishimiz mumkin.
Mana demo. Agar uni ishga tushirsangiz, matnning tanlanganini koârishingiz mumkin:
<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);
// range ning toString usuli uning kontentini teglar o'chirilgan holda matn sifatida qaytaradi
console.log(range); // Example: italic
// bu range ni hujjat tanlashi uchun qo'llang (keyinroq tushuntiriladi)
document.getSelection().addRange(range);
</script>
Bu yerda range boshlanishi/tugashi raqamlarini oârnatishingiz va boshqa variantlarni oârganishingiz mumkin boâlgan yanada moslashuvchan test standidir:
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
Dan <input id="start" type="number" value=1> â Gacha <input id="end" type="number" value=4>
<button id="button">Tanlash uchun bosing</button>
<script>
button.onclick = () => {
let range = new Range();
range.setStart(p, start.value);
range.setEnd(p, end.value);
// tanlashni qo'llash, keyinroq tushuntiriladi
document.getSelection().removeAllRanges();
document.getSelection().addRange(range);
};
</script>
Masalan, bir xil <p> da 1 dan 4 gacha offset bilan tanlash bizga <i>italic</i> and <b>bold</b> range beradi:
setStart va setEnd da bir xil tugunni ishlatishimiz shart emas. Range koâplab bogâliq boâlmagan tugunlar boâylab choâzilishi mumkin. Faqat tugash hujjatda boshlanishdan keyin kelishi muhim.
Kattaroq fragmentni tanlash
Misolimizda kattaroq tanlov qilaylik:
Buni qanday qilishni allaqachon bilamiz. Faqat boshlanish va tugashni matn tugunlaridagi nisbiy offset sifatida oârnatishimiz kerak.
Bizga quyidagicha range yaratish kerak:
<p>birinchi bolasining 2-pozitsiyasidan boshlanadi ("Example: " dan dastlabki ikkita harfni olib tashlab)<b>birinchi bolasining 3-pozitsiyasida tugaydi (âboldâ dan dastlabki uchta harfni olib, boshqasini olmasdan):
<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
// bu range ni tanlash uchun ishlating (keyinroq tushuntiriladi)
window.getSelection().addRange(range);
</script>
Koârib turganimizdek, xohlagan range yaratish juda oson.
Agar tugunlarni toâliq olmoqchi boâlsak, setStart/setEnd ga elementlarni berishimiz mumkin. Aks holda, matn darajasida ishlashimiz mumkin.
Range xossalari
Yuqoridagi misolda yaratilgan range obyektining quyidagi xossalari bor:
startContainer,startOffsetâ boshlanishning tuguni va offseti,- yuqoridagi misolda:
<p>ichidagi birinchi matn tuguni va2.
- yuqoridagi misolda:
endContainer,endOffsetâ tugashning tuguni va offseti,- yuqoridagi misolda:
<b>ichidagi birinchi matn tuguni va3.
- yuqoridagi misolda:
collapsedâ boolean, agar range bir xil nuqtada boshlanib tugasatrue(shuning uchun range ichida hech qanday kontent yoâq),- yuqoridagi misolda:
false
- yuqoridagi misolda:
commonAncestorContainerâ range ichidagi barcha tugunlarning eng yaqin umumiy ajdodi,- yuqoridagi misolda:
<p>
- yuqoridagi misolda:
Range tanlash usullari
Range larni boshqarish uchun koâplab qulay usullar mavjud.
Biz allaqachon setStart va setEnd ni koârdik, mana boshqa shunga oâxshash usullar.
Range boshlanishini oârnatish:
setStart(node, offset)boshlanishni oârnatish:nodedagioffsetpozitsiyasidasetStartBefore(node)boshlanishni oârnatish:nodedan darhol oldinsetStartAfter(node)boshlanishni oârnatish:nodedan darhol keyin
Range tugashini oârnatish (shunga oâxshash usullar):
setEnd(node, offset)tugashni oârnatish:nodedagioffsetpozitsiyasidasetEndBefore(node)tugashni oârnatish:nodedan darhol oldinsetEndAfter(node)tugashni oârnatish:nodedan darhol keyin
Texnik jihatdan, setStart/setEnd har qanday narsani qila oladi, lekin koâproq usullar koâproq qulaylik beradi.
Barcha bu usullarda node ham matn ham element tuguni boâlishi mumkin: matn tugunlari uchun offset shuncha belgilarni oâtkazib yuboradi, element tugunlari uchun esa shuncha bola tugunlarni.
Range yaratishning yana ham koâp usullari:
selectNode(node)butunnodeni tanlash uchun range ni oârnatishselectNodeContents(node)butunnodekontentini tanlash uchun range ni oârnatishcollapse(toStart)agartoStart=trueboâlsa end=start oârnatish, aks holda start=end oârnatish, shu tariqa range ni yigâishcloneRange()bir xil start/end bilan yangi range yaratish
Range tahrirlash usullari
Range yaratilgandan soâng, biz uning kontentini quyidagi usullar yordamida boshqarishimiz mumkin:
deleteContents()â range kontentini hujjatdan olib tashlashextractContents()â range kontentini hujjatdan olib tashlash va DocumentFragment sifatida qaytarishcloneContents()â range kontentini nusxalash va DocumentFragment sifatida qaytarishinsertNode(node)ânodeni hujjatga range boshida kiritishsurroundContents(node)â range kontenti atrofidanodeni oârash. Buning ishlashi uchun range oâz ichidagi barcha elementlar uchun ochilish va yopilish teglarini oâz ichiga olishi kerak:<i>abckabi qisman range lar yoâq.
Bu usullar yordamida biz tanlangan tugunlar bilan deyarli har qanday narsani qila olamiz.
Mana ularni amalda koârish uchun test standi:
Tanlashda usullarni ishga tushirish uchun tugmalarni bosing, uni tiklash uchun "resetExample".
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
<p id="result"></p>
<script>
let range = new Range();
// Har bir ko'rsatilgan usul bu yerda ifodalangan:
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>
Range larni solishtirish usullari ham mavjud, lekin ular kamdan-kam ishlatiladi. Ular kerak boâlganda, spec yoki MDN qoâllanma ga murojaat qiling.
Selection
Range tanlash range larini boshqarish uchun umumiy obyektdir. Garchi, Range yaratish ekranda tanlashni koârishimizni anglatmaydi.
Biz Range obyektlarini yaratishimiz, ularni oâtkazishimiz mumkin â ular oâz-oâzidan vizual ravishda hech narsani tanlamaydi.
Hujjat tanlashi Selection obyekti bilan ifodalanadi, uni window.getSelection() yoki document.getSelection() sifatida olish mumkin. Tanlash nol yoki koâproq range larni oâz ichiga olishi mumkin. Hech boâlmaganda, Selection API spetsifikatsiyasi shunday deydi. Amalda esa, faqat Firefox Ctrl+click (Cmd+click Mac uchun) yordamida hujjatda bir nechta range larni tanlashga imkon beradi.
Mana Firefox da yaratilgan 3 ta range bilan tanlashning skrinshotı:
Boshqa brauzerlar maksimal 1 ta range ni qoâllab-quvvatlaydi. Koârib turganimizdek, baâzi Selection usullari koâplab range lar boâlishi mumkinligini nazarda tutadi, lekin yana, Firefox bundan mustasno barcha brauzerlarda maksimal 1 ta range bor.
Mana joriy tanlashni (biror narsani tanlab, bosing) matn sifatida koârsatadigan kichik demo:
Selection xossalari
Aytilganidek, tanlash nazariy jihatdan bir nechta range larni oâz ichiga olishi mumkin. Biz bu range obyektlarini quyidagi usul yordamida olishimiz mumkin:
getRangeAt(i)â i-chi range ni olish,0dan boshlab. Firefox bundan mustasno barcha brauzerlarda faqat0ishlatiladi.
Shuningdek, koâpincha yaxshiroq qulaylikni taqdim etadigan xossalar mavjud.
Range ga oâxshab, selection obyekti âlangarâ deb ataladigan boshlanish va âfokusâ deb ataladigan tugashga ega.
Asosiy selection xossalari:
anchorNodeâ selection boshlangan tugun,anchorOffsetâ selection boshlangananchorNodedagi offset,focusNodeâ selection tugagan tugun,focusOffsetâ selection tugaganfocusNodedagi offset,isCollapsedâ agar selection hech narsani tanlamasa (boâsh range) yoki mavjud boâlmasatrue.rangeCountâ selection dagi range lar soni, Firefox bundan mustasno barcha brauzerlarda maksimal1.
Selection langar/fokusi bilan Range boshlanish/tugashi oârtasida muhim farqlar bor.
Bilganimizdek, Range obyektlari har doim tugashdan oldin boshlanishga ega.
Selection lar uchun bu har doim ham unday emas.
Sichqoncha bilan biror narsani tanlash ikkala yoânalishda ham amalga oshirilishi mumkin: âchapdan-oânggaâ yoki âoângdan-chapgaâ.
Boshqacha qilib aytganda, sichqoncha tugmasi bosilganda va keyin hujjatda oldinga siljisa, uning tugashi (fokus) boshlanishidan (langar) keyin boâladi.
Masalan, agar foydalanuvchi sichqoncha bilan tanlashni boshlasa va âExampleâ dan âitalicâ ga oâtsa:
â¦Lekin bir xil tanlash teskari yoânalishda ham amalga oshirilishi mumkin: âitalicâ dan âExampleâ ga (teskari yoânalish), keyin uning tugashi (fokus) boshlanishidan (langar) oldin boâladi:
Selection hodisalari
Selection ni kuzatib borish uchun hodisalar mavjud:
elem.onselectstartâ tanlash aniqelemelementida (yoki uning ichida) boshlanganda. Masalan, foydalanuvchi sichqoncha tugmasini ustiga bosib, koârsatkichni harakatlantira boshlasa.- Standart harakatni oldini olish tanlash boshlanishini bekor qiladi. Shuning uchun bu elementdan tanlashni boshlash imkonsiz boâladi, lekin element hali ham tanlanishi mumkin. Tashrif buyuruvchi faqat tanlashni boshqa joydan boshlashi kerak.
document.onselectionchangeâ tanlash oâzgarganda yoki boshlanganda.- Esda tuting: bu ishlov beruvchi faqat
documentda oârnatilishi mumkin, u undagi barcha tanlashlarni kuzatadi.
- Esda tuting: bu ishlov beruvchi faqat
Selection kuzatuv demosi
Mana kichik demo. U document dagi joriy tanlashni kuzatadi va uning chegaralarini koârsatadi:
<p id="p">Meni tanla: <i>italic</i> and <b>bold</b></p>
Dan <input id="from" disabled> â Gacha <input id="to" disabled>
<script>
document.onselectionchange = function() {
let selection = document.getSelection();
let {anchorNode, anchorOffset, focusNode, focusOffset} = selection;
// anchorNode va focusNode odatda matn tugunlari
from.value = `${anchorNode?.data}, offset ${anchorOffset}`;
to.value = `${focusNode?.data}, offset ${focusOffset}`;
};
</script>
Selection nusxalash demosi
Tanlangan kontentni nusxalashning ikkita yondashuvi mavjud:
- Uni matn sifatida olish uchun
document.getSelection().toString()dan foydalanishimiz mumkin. - Aks holda, toâliq DOM ni nusxalash uchun, masalan formatlashni saqlashimiz kerak boâlsa,
getRangesAt(...)bilan asosiy range larni olishimiz mumkin.Rangeobyekti, oâz navbatida, uning kontentini nusxalaydigan vaDocumentFragmentobyekti sifatida qaytaradigancloneContents()usuliga ega, buni boshqa joyga kiritishimiz mumkin.
Mana tanlangan kontentni ham matn, ham DOM tugunlari sifatida nusxalash demosi:
<p id="p">Meni tanla: <i>italic</i> and <b>bold</b></p>
Nusxalangan: <span id="cloned"></span>
<br>
Matn sifatida: <span id="astext"></span>
<script>
document.onselectionchange = function() {
let selection = document.getSelection();
cloned.innerHTML = astext.innerHTML = "";
// Range lardan DOM tugunlarini nusxalash (bu yerda multiselect ni qo'llab-quvvatlaymiz)
for (let i = 0; i < selection.rangeCount; i++) {
cloned.append(selection.getRangeAt(i).cloneContents());
}
// Matn sifatida olish
astext.innerHTML += selection;
};
</script>
Selection usullari
Biz range lar qoâshish/olib tashlash orqali tanlash bilan ishlashimiz mumkin:
getRangeAt(i)â i-chi range ni olish,0dan boshlab. Firefox bundan mustasno barcha brauzerlarda faqat0ishlatiladi.addRange(range)â tanlashgarangeqoâshish. Agar tanlash allaqachon bogâlangan range ga ega boâlsa, Firefox bundan mustasno barcha brauzerlar chaqiruvni eâtiborsiz qoldiradi.removeRange(range)â tanlashdanrangeni olib tashlash.removeAllRanges()â barcha range larni olib tashlash.empty()âremoveAllRangesning taxallusi.
Oraliq Range chaqiruvlarisiz toâgâridan-toâgâri tanlash range ni boshqarish uchun qulay usullar ham mavjud:
collapse(node, offset)â tanlangan range ni berilgannodeda,offsetpozitsiyasida boshlanib tugaydigan yangi bilan almashtirish.setPosition(node, offset)âcollapsening taxallusi.collapseToStart()â tanlash boshiga yigâish (boâsh range bilan almashtirish),collapseToEnd()â tanlash oxiriga yigâish,extend(node, offset)â tanlashning fokusini berilgannodega,offsetpozitsiyasiga oâtkazish,setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset)â tanlash range ni berilgan boshlangâichanchorNode/anchorOffsetva oxirgifocusNode/focusOffsetbilan almashtirish. Ular orasidagi barcha kontent tanlanadi.selectAllChildren(node)ânodening barcha bolalarini tanlash.deleteFromDocument()â tanlangan kontentni hujjatdan olib tashlash.containsNode(node, allowPartialContainment = false)â tanlashnodeni oâz ichiga olgan-olmaganligini tekshiradi (ikkinchi argumenttrueboâlsa qisman ham).
Koâpgina vazifalar uchun bu usullar etarli, asosiy Range obyektiga kirish kerak emas.
Masalan, <p> paragrafning butun kontentini tanlash:
<p id="p">Meni tanla: <i>italic</i> and <b>bold</b></p>
<script>
// <p> ning 0-bolasidan oxirgi bolagacha tanlash
document.getSelection().setBaseAndExtent(p, 0, p, p.childNodes.length);
</script>
Range lar yordamida bir xil narsa:
<p id="p">Meni tanla: <i>italic</i> and <b>bold</b></p>
<script>
let range = new Range();
range.selectNodeContents(p); // yoki <p> tegini ham tanlash uchun selectNode(p)
document.getSelection().removeAllRanges(); // agar mavjud tanlash bor bo'lsa tozalash
document.getSelection().addRange(range);
</script>
Agar hujjatda tanlash allaqachon mavjud boâlsa, avval uni removeAllRanges() bilan boâshating. Va keyin range lar qoâshing. Aks holda, Firefox bundan mustasno barcha brauzerlar yangi range larni eâtiborsiz qoldiradi.
Istisno baâzi tanlash usullari boâlib, ular mavjud tanlashni almashtiradi, masalan setBaseAndExtent.
Forma boshqaruvlarida tanlash
input va textarea kabi forma elementlari Selection yoki Range obyektlarisiz tanlash uchun maxsus API taqdim etadi. Input qiymati HTML emas, balki sof matn boâlgani uchun bunday obyektlarga ehtiyoj yoâq, hamma narsa ancha sodda.
Xossalar:
input.selectionStartâ tanlash boshlanish pozitsiyasi (yozish mumkin),input.selectionEndâ tanlash tugash pozitsiyasi (yozish mumkin),input.selectionDirectionâ tanlash yoânalishi, quyidagilardan biri: âforwardâ, âbackwardâ yoki ânoneâ (masalan ikki marta sichqoncha bosish bilan tanlangan boâlsa),
Hodisalar:
input.onselectâ biror narsa tanlanganida ishga tushadi.
Usullar:
-
input.select()â matn boshqaruvida hamma narsani tanlaydi (inputoârnigatextareaboâlishi mumkin), -
input.setSelectionRange(start, end, [direction])â tanlashnistartpozitsiyasidanendgacha, berilgan yoânalishda (ixtiyoriy) oâzgartirishadi. -
input.setRangeText(replacement, [start], [end], [selectionMode])â matn oraligâini yangi matn bilan almashtirish.Ixtiyoriy argumentlar
startvaend, agar berilgan boâlsa, oraliq boshlanishi va tugashini belgilaydi, aks holda foydalanuvchi tanlashi ishlatiladi.Oxirgi argument,
selectionMode, matn almashtirilgandan keyin tanlash qanday oârnatilishini belgilaydi. Mumkin boâlgan qiymatlar:"select"â yangi kiritilgan matn tanlanadi."start"â tanlash oraligâi kiritilgan matndan darhol oldin yigâiladi (kursor uning darhol oldida boâladi)."end"â tanlash oraligâi kiritilgan matndan darhol keyin yigâiladi (kursor uning darhol keyin boâladi)."preserve"â tanlashni saqlashga harakat qiladi. Bu standart.
Endi bu usullarni amalda koâraylik.
Misol: tanlashni kuzatish
Masalan, bu kod tanlashni kuzatish uchun onselect hodisasidan foydalanadi:
<textarea id="area" style="width:80%;height:60px">
Bu matndagi tanlash quyidagi qiymatlarni yangilaydi.
</textarea>
<br>
Dan <input id="from" disabled> â Gacha <input id="to" disabled>
<script>
area.onselect = function() {
from.value = area.selectionStart;
to.value = area.selectionEnd;
};
</script>
Esda tuting:
onselectbiror narsa tanlanganida ishga tushadi, lekin tanlash olib tashlanganida emas.- spec ga koâra, forma boshqaruvi ichidagi tanlashlar uchun
document.onselectionchangehodisasi ishga tushmasligi kerak, chunki udocumenttanlashi va range lari bilan bogâliq emas. Baâzi brauzerlar uni hosil qiladi, lekin biz unga tayanmasligimiz kerak.
Misol: kursorni harakatlantirish
Biz selectionStart va selectionEnd ni oâzgartirishimiz mumkin, bu tanlashni oârnatadi.
Muhim chegara holati â selectionStart va selectionEnd bir-biriga teng boâlganda. U holda bu aniq kursor pozitsiyasidir. Yoki boshqacha qilib aytganda, hech narsa tanlanmaganda, tanlash kursor pozitsiyasida yigâilgan.
Shunday qilib, selectionStart va selectionEnd ni bir xil qiymatga oârnatish orqali kursorni harakatlantiramiz.
Masalan:
<textarea id="area" style="width:80%;height:60px">
Menga fokuslan, kursor 10-pozitsiyada bo'ladi.
</textarea>
<script>
area.onfocus = () => {
// brauzer "focus" harakat tugagandan keyin ishga tushishi uchun nol kechikish setTimeout
setTimeout(() => {
// biz har qanday tanlash o'rnatishimiz mumkin
// agar start=end bo'lsa, kursor aniq o'sha joyda
area.selectionStart = area.selectionEnd = 10;
});
};
</script>
Misol: tanlashni oâzgartirish
Tanlash kontentini oâzgartirish uchun input.setRangeText() usulidan foydalanishimiz mumkin. Albatta, biz selectionStart/End ni oâqishimiz va tanlash haqida maâlumot bilan value ning tegishli pastki qatorini oâzgartirishimiz mumkin, lekin setRangeText kuchliroq va koâpincha qulayroq.
Bu biroz murakkab usul. Eng oddiy bir argumentli shaklida u foydalanuvchi tanlagan oraliqni almashtiradi va tanlashni olib tashlaydi.
Masalan, bu yerda foydalanuvchi tanlashi *...* bilan oâraladi:
<input id="input" style="width:200px" value="Bu yerdan tanlab tugmani bosing">
<button id="button">Tanlashni yulduzchalar bilan o'rash *...*</button>
<script>
button.onclick = () => {
if (input.selectionStart == input.selectionEnd) {
return; // hech narsa tanlanmagan
}
let selected = input.value.slice(input.selectionStart, input.selectionEnd);
input.setRangeText(`*${selected}*`);
};
</script>
Koâproq argumentlar bilan biz start va end oraligâini oârnatishimiz mumkin.
Bu misolda biz input matnida "BU" ni topamiz, uni almashtiramiz va almashtirishni tanlangan holda saqlaymiz:
<input id="input" style="width:200px" value="Matndagi BU so'zni almashtiring">
<button id="button">BU ni almashtirish</button>
<script>
button.onclick = () => {
let pos = input.value.indexOf("BU");
if (pos >= 0) {
input.setRangeText("*BU*", pos, pos + 2, "select");
input.focus(); // tanlashni ko'rinadigan qilish uchun fokus
}
};
</script>
Misol: kursor joyiga kiritish
Agar hech narsa tanlanmagan boâlsa yoki setRangeText da teng start va end ishlatilsa, yangi matn shunchaki kiritiladi, hech narsa olib tashlanmaydi.
setRangeText yordamida âkursor joyigaâ biror narsani kiritishimiz ham mumkin.
Mana kursor pozitsiyasiga "SALOM" kiritadigan va kursorni uning darhol keyin qoâyadigan tugma. Agar tanlash boâsh boâlmasa, u almashtiriladi (buni selectionStart!=selectionEnd ni solishtirib aniqlashimiz va oârniga boshqa narsa qilishimiz mumkin):
<input id="input" style="width:200px" value="Matn Matn Matn Matn Matn">
<button id="button">Kursor joyiga "SALOM" kiritish</button>
<script>
button.onclick = () => {
input.setRangeText("SALOM", input.selectionStart, input.selectionEnd, "end");
input.focus();
};
</script>
Tanlab boâlmasligini taâminlash
Biror narsani tanlab boâlmasligi uchun uchta yoâl bor:
-
user-select: noneCSS xossasidan foydalanish.<style> #elem { user-select: none; } </style> <div>Tanlanuvchi <div id="elem">Tanlanmaydigan</div> Tanlanuvchi</div>Bu tanlashning
elemda boshlanishiga imkon bermaydi. Lekin foydalanuvchi tanlashni boshqa joydan boshlashi vaelemni unga kiritishi mumkin.Keyin
elemdocument.getSelection()ning bir qismiga aylanadi, shuning uchun tanlash haqiqatda sodir boâladi, lekin uning kontenti odatda nusxa-joylashtirish da eâtiborga olinmaydi. -
onselectstartyokimousedownhodisalaridagi standart harakatni oldini olish.<div>Tanlanuvchi <div id="elem">Tanlanmaydigan</div> Tanlanuvchi</div> <script> elem.onselectstart = () => false; </script>Bu
elemda tanlashni boshlashga toâsqinlik qiladi, lekin tashrif buyuruvchi uni boshqa elementda boshlashi, keyinelemga kengaytirishi mumkin.Bu bir xil harakatda tanlashni ishga tushiradigan boshqa hodisa ishlov beruvchisi boâlganida qulay (masalan
mousedown). Shuning uchun biz ziddiyatni oldini olish uchun tanlashni oâchiramiz, lekinelemkontentlarini nusxalashga imkon beramiz. -
Shuningdek, tanlash sodir boâlgandan keyin
document.getSelection().empty()bilan uni tozalashimiz mumkin. Bu kamdan-kam ishlatiladi, chunki tanlash paydo boâlib-yoâqolishi natijasida istalmagan miltillashga sabab boâladi.
Havolalar
Xulosa
Biz tanlashlar uchun ikkita turli API ni koârib chiqdik:
- Hujjat uchun:
SelectionvaRangeobyektlari. input,textareauchun: qoâshimcha usullar va xossalar.
Ikkinchi API juda oddiy, chunki u matn bilan ishlaydi.
Eng koâp ishlatiladigan retseptlar, ehtimol:
- Tanlashni olish:
let selection = document.getSelection(); let cloned = /* tanlangan tugunlarni nusxalash uchun element */; // keyin selection.getRangeAt(0) ga Range usullarini qo'llang // yoki bu kabi, multi-select ni qo'llab-quvvatlash uchun barcha range larga for (let i = 0; i < selection.rangeCount; i++) { cloned.append(selection.getRangeAt(i).cloneContents()); } - Tanlashni oârnatish:
let selection = document.getSelection(); // to'g'ridan-to'g'ri: selection.setBaseAndExtent(...from...to...); // yoki biz range yaratishimiz va: selection.removeAllRanges(); selection.addRange(range);
Va nihoyat, kursor haqida. <textarea> kabi tahrirlash mumkin boâlgan elementlardagi kursor pozitsiyasi har doim tanlashning boshida yoki oxirida boâladi. Biz uni kursor pozitsiyasini olish yoki elem.selectionStart va elem.selectionEnd ni oârnatish orqali kursorni harakatlantirish uchun ishlatishimiz mumkin.
Izohlar
<code>yorlig'ini ishlating, bir nechta satrlar uchun - ularni<pre>yorlig'i bilan o'rab qo'ying, 10 satrdan ortiq bo'lsa - sandbox (plnkr, jsbin, codepenâ¦)