უკვე აღარავისათვის აღარ წარმოადგენს სიურპრიზს ის რომ Internet Explorer 6 საშინლად გაუმართავი ბრაუზერია და მას ძალიან ბევრი ხარვეზი გააჩნია. თუმცა ძალიან საწყენია ის რომ ამ ბრაუზერის მეშვიდე ვერსიაშიც ძალიან ბევრი ისეთი ხარვეზი მეორდება რაც ჩემის აზრით უკვე აღმოფხვრილი უნდა ყოფილიყო.
პრობლემათაგან ერთერთი ყველაზე არასასიამოვნო და ნიუანსური ჩემის აზრით არის HTML ფორმებთან და ფორმის ელემენტებთან მუშაობა JavaScript – ის DOM მეთოდებით.
არასასიამოვნო იმიტომ რომ თითქმის ყველა არსებული ბრაუზერებისაგან განსხვავებით(რომლებიც გამართულად მუშაობენ სპეციფიკაციის მიხედვით) IE – ს გააჩნია ისეთი პრობლემა რაც თავისთავად კოდის გაყოფას იწვევს, და კვლავ ვღებულობთ: IE vs სხვა დანარჩენი ბრაუზერები!
პრობლემა ფორმასთან
ძალიან ხშირად, გარდა ელემენტებთან ჩვეულებრივი(მოპოვება, შეცვლა, ამოგდება დოკუმენტიდან) მუშაობისას ხშირად გვიწევს ელემენტების შექმნაც და შემდგომ უკვე დოკუმენტში ჩამატება. გამონაკლისი თავისთავად არც HTML ფორმაა, თავისთავად ფორმის შექმნა და მისი შემდგომი დამუშავება არ წარმოადგენს პრობლემას.. მაგრამ… IE – ში ეს ყველაფერი პრობლემაა…
მარტივეი ტესტ კეისი:
1 2 3 4 5 6 7 8 9 | var form = document.createElement('form'); form.name = 'test-form'; form.action = '/test'; form.enctype = 'multipart/form-data'; //ფორმის დოკუმენტში დამატება document.body.appendChild(form); alert(document.forms['test-form']); |
IE – ში ამ კოდის გაშვების შემდეგ, შეტყობინება გამოგვიტანს… “undefined”
რაოდენ უცნაურიც არ უნდა იყოს, მიუხედავად იმისა რომ ფორმა შევქმენით და ჩავამატეთ დოკუმენტში იგი არ მოხვდა document ობიექტის forms მასივში…
გამოსავალი 1
ამ პრობლემის გამოსავალი მარტივია თუმცა უცნაური… IE – სთვის დამახასიათებელი
1 2 3 4 | var form = document.createElement('<form name="test-form" enctype="multipart/form-data" action="/w" method="post"></form>'); document.body.appendChild(form); alert(document.forms['test-form'].method); //გამობეჭდავს ფორმის method ატრიბუტის მნიშვნელობას |
უცნაურია ხომ?
createElement – მეთოდს გადავეცით მთლიანი HTML კოდი ნაცვლად იმისა რომ მიგვეთითებინა უბრალოდ ელემენტის სახელი… თუმცა ეს გამოსავალი მუშაობს და მთლიანად ხსნის პრობლემას… თუმცა უნდა აღინიშნოს რომ ეს გზა მხოლოდ IE – სთვის არის მისაღები და “მშობლიური”
გამოსავალი 2
პირველი გამოსავალი თავისთავად გვიბიძგებს ახალი მოსაზრებისკენ… რომელიც თურმე ასევე კარგად და ეფექტურად მუშაობს, კერძოდ კი:
1 2 3 4 | var form = '<form name="test-form" enctype="multipart/form-data" action="/w" method="post"></form>'; document.getElementById('form-container').innerHTML = form; alert(document.forms['test-form'].method); |
ამ შემთხვევაში საერთოდ არ გამოვიყენეთ createElement მეთოდი, ნაცვლად ამისა კონკრეტულ “form-container” ელემენტში(იგულისხმება რომ ეს ელემენტი უკვე არსებობს დოკუმენტში) მისი innerHTML თვისების მეშვეობით პირდაპირ ჩავსვით ფორმის შესაბამისი HTML კოდი… შედეგი სავსებით დამაკმაყოფილებელია რადგან იგი მუშაობს…
პრობლემა ფორმის ელემენტებთან
გამომდინარე წინა პრობლემიდან ცხადია რომ გასაკვირი არ უნდა იყოს თუ ფორმის ელემენტებსაც იგივე პრობლემა ექნებათ… და ეს ასეც არის. პრობლემა თითქმის ანალოგიურია და გამოსავალიც შესაბამისად წინა შემთხვევის მსგავსია.
მარტივი ტესტ კეისი
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //ფორმის შექმნა var form = document.createElement('<form name="test-form" enctype="multipart/form-data" action="/w" method="post"></form>'); document.body.appendChild(form); //ფორმის input ელემენტის შექმნა var input = document.createElement('input'); input.name = 'test-field'; input.value = 'test field value'; //ელემენტის ფორმაში ჩამატება form.appendChild(input); //ახალ ელემენტზე მიმართვა alert(document.forms['test-form']['test-field']); //შედეგი არის რა თქმა უნდა "undefined" |
ამ შემთხვევაში ვქმნით ფორმას, ვქმნით ფორმის ელემენტს, ვამატებთ ახალ ელემენტს ფორმაში და შემდგომ უკვე მივმართავთ ამ ელემენტს… შედეგი არის კვლავ “undefined”…
გამოსავალი 1
გამოსავალი ამ შემთხვევაშიც მარტივია, თუმცა IE – სთვის განკუთვნილი:
1 2 3 4 5 6 7 8 9 10 11 12 13 | //ფორმის შექმნა var form = document.createElement('<form name="test-form" enctype="multipart/form-data" action="/w" method="post"></form>'); document.body.appendChild(form); //ფორმის input ელემენტის შექმნა IE - სთვის მისაღები გზით var input = document.createElement('<input name="test-field"/>'); input.value = 'test field value'; //ელემენტის ფორმაში ჩამატება form.appendChild(input); //ახალ ელემენტზე მიმართვა alert(document.forms['test-form']['test-field'].value); //გამოიბეჭდება ველის value ატრიბუტის მნიშვნელობა |
ამ შემთხვევაში ყველაფერი რიგზეა. ელემენტსი შექმნისასა გამოყენებული იქნა ისეთივე კონსტრუქცია როგორც ეს გავაკეთეთ ფორმის შექმნის დროს… ანუ createElement მეთოდს გადავეცით პარამეტრად არა მხოლოდ ელემენტის სახელი, არამედ შესაბამისი HTML კოდი. ყურადღება მიაქციეთ რომ კოდში მთავარია მითითებული იყოს name ატრიბუტი.
გამოსავალი 2
ცხადია ფორმის მსგავსად, ველისთვისაც არსებობს მეორე გამოსავალი რომლის შესახებაც შეგიძლიათ წაიკითხოთ შესაბამის პოსტში სადაც ეს პრობლემა უფრო ვრცლად არის განხილული, რადგან ამ შემთხვევაში მხოლოდ innerHTML თვისების გამოყენება ვერ გვიშველის და საჭიროა დამატებითი ქმედებები.
დასკვნა
აღწერილი პრობლემა საკმაოდ არასასიამოვნოა, თუმცა გამოსავალი საკმაოდ მარტივია და ადვილად რეალიზებადი. თავის დროზე ამ პრობლემებზე საკმაოდ ბევრი დრო დავხარჯე, თუმცა იმედია ოდნავ მაინც შეგიმსუბუქებთ საქმეს და ეს პოსტი დაგეხმარებათ IE – სთან ბრძოლაში.
ტეგები: IE Sucks, JavaScript, JavaScript DOM
[...] IE6/7 BUG(s): დინამიური ფორმები და ფორმის ელე… [...]