ელემენტის innerHTML თვისების დეტალები

innerHTML თვისება ერთერთი გარდაუვალი დეტალია დღევანდელი RIA პროგრამირებისათვის(მცირეოდენი შესავალი შესაძლებელია წაიკითხოთ შესაბამის პოსტში), იგი არის სწრაფი, ეფექტური და რაც მთავარია მისი მხარდაჭერა ყველა ძირითად ბრაუზერს გააჩნია. მიუხედავად ამისა მას გააჩნია გარკვეული ხარვეზები, განსაკუთრებით კი ეს ხარვეზები თვალშისაცემია IE – ს შემთხვევაში.

რაში გამოიხატება ეს ხარვეზები? პირველ რიგში აღსანიშნავია შემდეგი დეტალები:

  1. თუ ელემენტის შემადგენლობას შევცვლით არა DOM მეთოდების მეშვეობით არამედ innerHTML თვისების მეშვეობით ამ შემთხვევაში ირღვევა თვითონ DOM სტრუქტურა.
  2. თუ გვაქვს form ელემენტი და მის შემადგენლობას შევცვლით აღნიშნული თვისების მეშვეობით(მაგალითად: document.forms[0].innerHTML = ‘<input type=”text” name=”test”/><input type=”submit” value=”Submit”/>’;) ასეთი ფორმის სერვერზე გაგზავნის შემთხვევაში აღმოვაჩენთ რომ ფორმაში ახლად დამატებული არცერთი ელემენტის გაგზავნა არ მოხდება.
  3. innerHTML პრობლემატურია IE – ში, რადგან: ა) თუ ცხრილს არ აქვს განსაზღვრული
    ელემენტი შეუძლებელია დინამიურად ახალი სტრიქონების დამატება; ბ) innerHTML მაინც არ მუშაობს;

რა გამოსავალი არსებობს ჩამოთვლილი პრობლემებიდან? პასუხი ერთადერთია ვიმუშავოთ DOM მეთოდების მეშვეობით, თუმცა ეს ძალიან რუტინული და არასასიამოვნო პროცესია, გარდა ამისა თავად DOM მეთოდებით მუშაობის დროს ასევე ვაწყდებით გარკვეულ ხარვეზებს IE – ში. თუმცა თავის დროზე ამ საკითხებზე მუშაობის გამო წარმოქმნილი პრობლემების თავიდან ასარიდებლად გარკვეული გამოსავალს მივაგენი რაც ჩემის აზრით სასარგებლო იქნება სხვებისთვისაც:

[javascript]
/**
* @param String identifier of the element
* @param String html code to be inserted into the element
*/
function insertHTML(container, html) {

//კონტეინერი რომელშიც მოხდება html კოდის ჩასმა
var container = document.getElementById(container);
//დროებითი კონტეინერი
var wrapper = document.createElement(‘div’);

//წავშალოთ ელემენტის შიგნით არსებული ყველა ელემენტი
while(container.firstChild) {
container.removeChild(container.firstChild);
}

/*
თუ კონტეინერი ელემენტი არის TBODY საჭიროა დამატებითი მოქმედებების შესრულება
რადგან IE – ში innerHTML არც TBODY ტეგის შემთხვევაში არ მუშაობს
*/
if (container.tagName.toLowerCase() == ‘tbody’) {
wrapper.innerHTML = ‘

‘ + html + ‘

‘;
var rows = wrapper.getElementsByTagName(‘tr’);
for (var i = 0; i < rows.length; i++) {
container.appendChild(rows[i]);
}
rows = null;
} else {
/*
სხვა დანარჩენ შემთხვევაში შემდეგი კოდი იმუშავებს უპრობლემოდ
*/
wrapper.innerHTML = html;
while(wrapper.firstChild) {
container.appendChild(wrapper.firstChild);
}
}

//მივანიჭოთ null გამოყენებულ ელემენტებს რათა თავიდან ავიცილოთ მეხსიერების გადავსება
container = wrapper = null;

}
[/javascript]

ნაჩვენები insertHTML ფუნქცია ღებულობს ორ პარამეტრს: 1) ელემენტი რომელშიც გვინდა ახალი HTML კოდის ჩამატება; 2) თავად HTML კოდი;

როგორ მუშაობს ეს მეთოდი? თუ კოდს დავაკვირდებით დავინახავთ რომ HTML კოდის ჩასმა არ ხდება უშუალოდ სასურველ ელემენტში, ნაცვლად ამისა ვიყენებთ ახალ დროებით ელემენტს სახელად "wrapper". პირველ რიგში სწორედ wrapper ელემენტში ვათავსებთ ახალ HTML კოდს innerHTML თვისების მეშვეობით ხოლო შემდგომ ამ ელემენტის შიგთავსს DOM მეთოდების მეშვეობით ვამატებთ სასურველ ელემენტში (while(wrapper.firstChild) { კონსტრუქცია). თუმცა იმ შემთხვევაში კონტეინერი არის TBODY ტიპის ასეთ შემთხვევაში საჭიროა ოდნავ განსხვავებული ქმედება რათა თავიდან ავირიდოთ გაუგებრობები. ნაცვლად პირდაპირ HTML კოდის ჩასმისა wraper – ში, მას ვფუთავთ <table> ტეგში, ხოლო შემდგომ უკვე ყოველ TR ელემენტს ვამატებთ სასურველ კონტეინერში.

ტეგები: , ,

6 Responses to “ელემენტის innerHTML თვისების დეტალები”

  1. ოთო ამბობს:

    და რა მაინტერესებს…
    როდესაც ნესტედ ტეგები გვექნება html პარამეტრში, DOM სტრუქტურა მაინც არ დაირღვევა?..
    ანუ ამ გადაცემული ელემენტების შვილებს, როგორც node-ებს ისე აღიქვამს თუ რეკურსიული ფუნქციის გაკეთების საჭიროება იქნება?..

    P.S. შეიძლება უაზრობა ვიკითხე? :)

  2. იოსები ამბობს:

    ოთო

    P.S. შეიძლება უაზრობა ვიკითხე?

    უაზრობის კითხვის არ უნდა შეგრცხვეს ;)

    არა არ არის საჭირო რეკურსია და მსგავსი რამეები :) პირდაპირ გამოიყენებ მაგ ფუნქციას და ეგ არის :)

  3. Otto ამბობს:

    და მე კიდე რა მაინტერესებს:
    ამ Microsoft–ს ტვინი თუ ქონდა თავში ამ IE6-ს რო უშვებდნენ? დაეხვეწათ რა იქნებოდა. ყველაფერთან პრობლემატური და პრეტენზიულია :( ნეტავი სულ არ მოეგონათ ეს უჯიშობა. გამიმწარა (ალბათ მარტო მე არა) მთელი მოღვაწეობა …

  4. ოთო ამბობს:

    ანუ უაზრობა ვიკითხე? :D
    პასუხი გასაგებია ;)

  5. მიშა ამბობს:

    ძალიან საინტერესო ფუნქციაა, ასეთი სხვაგან არ მინახავს. ამ მეთოდს რამე უკუჩვენება არ აქვს?

დატოვე კომენტარი:

ქართული კლავიატურა, ჩართვა/გამორთვა კლავიშით "~"