Tanlash va Range
Hujjatdagi matn yoki elementlarni tanlash brauzerda ikki bosqichli tushuncha bilan ifodalanadi: Range โ hujjatning ma'lum bir qismi (boshlanish va tugash nuqtalari bilan), Selection esa โ foydalanuvchi yoki dastur belgilagan joriy tanlov. Ushbu darsda ular qanday ishlashini va dastur orqali qanday boshqarilishini ko'ramiz.
Range obyekti
Range โ hujjatdagi ikki nuqta orasidagi qismni ifodalaydi. Har bir nuqta ikkita qiymat bilan beriladi: tugun (node) va uning ichidagi siljish (offset).
let range = new Range();
Boshlanish va tugash nuqtalari setStart va setEnd bilan o'rnatiladi:
range.setStart(node, offset)โ boshlanish nuqtasini o'rnatadi;range.setEnd(node, offset)โ tugash nuqtasini o'rnatadi.
Bu yerda offset ikki xil ma'noga ega:
- Agar
nodeโ matn tuguni bo'lsa,offsetmatn ichidagi belgi (harf) pozitsiyasi; - Agar
nodeโ element bo'lsa,offsetuning bola tugunlari orasidagi pozitsiya.
setStart va setEnd
Aytaylik, sahifada <p id="matn">Salom, dunyo!</p> bor. Matndagi 'Salom' so'zini tanlaymiz โ bu <p>ning birinchi matn tuguni ichidagi 0-belgidan 5-belgigacha:
let p = document.getElementById('matn');
let textNode = p.firstChild; // matn tuguni: 'Salom, dunyo!'
let range = new Range();
range.setStart(textNode, 0); // 0-belgidan
range.setEnd(textNode, 5); // 5-belgigacha (S-a-l-o-m)
console.log(range.toString()); // 'Salom'
range.toString() tanlangan qismning matnli ko'rinishini qaytaradi.
setEnd(textNode, 5) โ bu "5-belgidan keyin" degani. Ya'ni 'Salom' so'zining beshta harfi (indekslari 0..4) tanlanadi, tugash nuqtasi esa 5-pozitsiyada turadi. Nuqtalar belgilar orasida joylashadi.Elementlarni qamrab olish
Nuqta faqat matn ichida emas, elementlar orasida ham bo'lishi mumkin. Masalan, <p> ichida <i> va <b> teglari bor deylik. Ularning bir qismini tanlash uchun offset bola tugun indeksini bildiradi:
// <p>Bu <i>muhim</i> va <b>qalin</b> matn</p>
let p = document.getElementById('matn');
let range = new Range();
range.setStart(p, 0); // birinchi bola tugundan oldin
range.setEnd(p, 2); // ikkinchi bola tugungacha
// natijada 'Bu <i>muhim</i>' qismi tanlanadi
console.log(range.toString());
Yana qulay usullar mavjud:
range.selectNode(node)โ tugunni butunlay (o'zi bilan birga) tanlaydi;range.selectNodeContents(node)โ tugunning faqat ichini tanlaydi;range.setStartBefore(node)/setStartAfter(node)โ tugundan oldin/keyin boshlaydi;range.setEndBefore(node)/setEndAfter(node)โ tugundan oldin/keyin tugatadi;range.collapse(toStart)โ Range'ni bir nuqtaga siqadi (bo'sh qiladi).
Range xususiyatlari
Range obyekti quyidagi asosiy xususiyatlarga ega:
startContainer,startOffsetโ boshlanish tuguni va siljishi;endContainer,endOffsetโ tugash tuguni va siljishi;collapsedโ agar boshlanish va tugash bir xil bo'lsa (bo'sh Range)true;commonAncestorContainerโ barcha tanlangan tugunlarning eng yaqin umumiy ajdodi.
Range bilan amallar
Range orqali tanlangan qismni nusxalash, o'chirish yoki chiqarib olish mumkin:
range.deleteContents()โ tanlangan qismni hujjatdan o'chiradi;range.extractContents()โ o'chiradi vaDocumentFragmentsifatida qaytaradi;range.cloneContents()โ hujjatga tegmasdan nusxasiniDocumentFragmentqilib qaytaradi;range.insertNode(node)โ Range boshiga yangi tugun kiritadi;range.surroundContents(node)โ tanlangan qismni berilgan tugun ichiga o'raydi.
let range = new Range();
range.setStart(textNode, 0);
range.setEnd(textNode, 5);
// tanlangan 'Salom' qismini <mark> ichiga o'raymiz
let mark = document.createElement('mark');
range.surroundContents(mark);
surroundContents talabchan: agar Range tugunlarni "yarim" kessa (masalan, bir elementning boshi tanlansa-yu, oxiri boshqa elementda qolsa), u xatolik beradi. Bunday holatda extractContents + insertNode kombinatsiyasini qo'llash kerak.Selection obyekti
Range โ bu shunchaki hujjatning bir qismi; u hali ekranda ko'rinmaydi. Foydalanuvchi ko'rgan haqiqiy tanlovni Selection obyekti ifodalaydi. Uni window.getSelection() yoki document.getSelection() orqali olamiz:
let selection = window.getSelection();
Nazariy jihatdan bir tanlov bir nechta Range'dan iborat bo'lishi mumkin (masalan, Firefox'da Ctrl bilan bir nechta qismni tanlash mumkin), ammo amalda ko'pchilik brauzerlarda bitta Range bo'ladi.
Selectionning asosiy xususiyatlari:
anchorNode,anchorOffsetโ tanlov boshlangan nuqta (foydalanuvchi bosgan joy);focusNode,focusOffsetโ tanlov tugagan nuqta (kursor hozir turgan joy);isCollapsedโ tanlov bo'shmi (faqat kursor turibdimi);rangeCountโ tanlovdagi Range'lar soni.
anchor (langar) va focus โ tanlovning boshi va oxiri, lekin ular hujjat tartibida oldinma-keyin bo'lishi shart emas. Agar foydalanuvchi o'ngdan chapga tanlasa, focus anchordan oldinda turadi. Rangeda esa doim start hujjat bo'yicha enddan oldin keladi.getSelection va matnni o'qish
Foydalanuvchi tanlagan matnni olishning eng oson yo'li โ Selectionni matnga aylantirish:
document.onselectionchange = function() {
let selection = document.getSelection();
console.log('Tanlangan matn: ' + selection.toString());
};
selectionchange hodisasi tanlov har o'zgarganda ishga tushadi. Bu tanlangan matnni real vaqtda kuzatish uchun qulay.
Agar Range darajasida ishlash kerak bo'lsa:
let selection = document.getSelection();
if (selection.rangeCount > 0) {
let range = selection.getRangeAt(0);
console.log(range.startContainer, range.startOffset);
console.log(range.endContainer, range.endOffset);
}
Dastur orqali tanlash
Tanlovni faqat o'qibgina qolmay, dastur orqali o'rnatish ham mumkin. Buning uchun avval Range tuzamiz, keyin uni tanlovga qo'shamiz:
let p = document.getElementById('matn');
let textNode = p.firstChild;
// 'Salom' so'zini qamrab oluvchi Range
let range = new Range();
range.setStart(textNode, 0);
range.setEnd(textNode, 5);
let selection = window.getSelection();
selection.removeAllRanges(); // avvalgi tanlovni tozalaymiz
selection.addRange(range); // yangi tanlovni o'rnatamiz
Selectionda bir necha qulay metodlar bor:
selection.addRange(range)โ tanlovga Range qo'shadi;selection.removeAllRanges()โ barcha tanlovni olib tashlaydi;selection.collapse(node, offset)โ tanlovni bir nuqtaga siqadi;selection.selectAllChildren(node)โ tugunning barcha bolalarini tanlaydi;selection.setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset)โ anchor va focusni bir yo'la o'rnatadi;selection.deleteFromDocument()โ tanlangan matnni hujjatdan o'chiradi.
selection.selectAllChildren(elem). Bu, masalan, "kod bo'lagini bosganda hammasini tanlansin" xatti-harakati uchun juda qulay.Form maydonlaridagi tanlash
Muhim istisno: <input> va <textarea> maydonlarida yuqoridagi Range/Selection ishlamaydi. Ular oddiy matndan iborat bo'lgani uchun o'zining alohida, soddaroq API'siga ega:
input.selectionStart,input.selectionEndโ tanlovning boshi va oxiri (belgi indekslari);input.selectionDirectionโ tanlov yo'nalishi;input.select()โ barcha matnni tanlaydi;input.setSelectionRange(start, end)โ tanlovni o'rnatadi;input.setRangeText(replacement, start, end)โ tanlangan qismni matn bilan almashtiradi.
let input = document.getElementById('maydon');
input.onclick = function() {
// birinchi 5 ta belgini tanlaymiz
input.setSelectionRange(0, 5);
input.focus();
};
Xulosa
Rangeโ hujjatning bir qismi;setStart(node, offset)vasetEnd(node, offset)bilan nuqtalari belgilanadi;offsetmatn tugunida โ belgi indeksi, elementda โ bola tugun indeksi;Rangeorqali qismni o'chirish, nusxalash, o'rash mumkin:deleteContents,extractContents,surroundContentsva h.k.;Selectionโ foydalanuvchi ko'rgan joriy tanlov;window.getSelection()orqali olinadi;selection.toString()โ tanlangan matn;getRangeAt(0)โ Range darajasi;- Dastur orqali tanlash:
removeAllRanges()+addRange(range), yokiselectAllChildren(node); <input>/<textarea>uchun alohida API:selectionStart,setSelectionRangeva boshqalar.