IE6: მეხსიერების მენეჯმენტი და საინტერესო გამოსავალი

ამ ბოლო დროს საკმაოდ ბევრს ვმუშაობა IE6 – ის მეხსიერებასთან დაკავშირებულ პრობლემებზე ე.წ. “memory leaks”. გამოცდილი JavaScript(უფრო სწორად JScript IE – ს კონტექსტში) დეველოპერებისათვის ეს პრობლემა უცხო არ არის. იმაზე ლაპარაკი თუ რატომ არსებობს ეს პრობლემა შორს წაგვიყვანს, ამიტომ კონკრეტული პრობლემის აღწერითა და მოძებნილი გამოსავალით შემოვიფარგლები.

მიუხედავად იმისა, რომ მეხსიერებასთან დაკავშირებული გაუგებრობების თავიდან ასაცილებლად არსებობს გარკვეული წესები რომლებიც აუცილებლად უნდა დავიცვათ, მაინც ჩემის აზრით ძალიან უცნაურ პრობლემას და შესაბამისად გამოსავალს წავაწყდი.

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

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

ამ ამოცანის გადასაწყვეტად დავწერე შემდეგი კოდი:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//ფუნქცია რომელიც ქმნის ტექსტურ ველს
function getInput(value) {
    var input = document.createElement('input');
   
    input.type  = 'text';
    input.value = value || '';
   
    input.onclick = function(e) {
        try {
            e = window.event || e;
            if (e.stopPropagation) {
                e.stopPropagation();
                e.preventDefault();
            } else {
                e.cancelBubble = true;
                e.returnValue = false;
            }
        } catch(e) {}
    }
   
    input.onkeydown = function(e) {
        e = e || window.event;
        var key = e.which || e.keyCode;
        if (key == 13) {
            this.onblur();
            return false;
        }
    };
   
    input.onblur = function() {
        this.parentNode.innerHTML = this.value;
    };
   
    return input;
}

//ფუნქცია რომლის მეშვეობითაც კონკრეტული ელემენტს ვაქცევთ რედაქტირებად ველად
function makeEditable(obj) {
    var input = getInput(obj.innerHTML);
    while(obj.firstChild) {
        obj.removeChild(obj.firstChild);
    }
    obj.appendChild(input);
    input.select();
    input.focus();
}

ეს ორი ფუნქცია ძალიან მარტივია და მათი დეტალური აღწერით არ შეგაწყენთ თავს. რაც მთავარია ამ კოდმა იმუშავა და შედეგიც შესაბამისი მივიღე. თუმცა ნაჩვენები მაგალითის Memory Leak Detector – ით გატესტვის შემდეგ (IE6 რეჟიმში), აღმოჩნდა რომ input ელემენტზე რჩებოდა მიმთითებელი.

კერძოდ კი, ინსტრუმენტმა მიმითითა კოდის ამ ნაწილზე:

1
2
3
4
5
6
7
8
     input.onkeydown = function(e) {
        e = e || window.event;
        var key = e.which || e.keyCode;
        if (key == 13) {
            this.onblur();
            return false;
        }
    };

სიმართლე ითქვას საბოლოოდ ვერ გავერკვიე რა იყო ამის მიზეზი, იმიტომ რომ სხვა მსგავს შემთხვევებში ნამდვილად არ წავწყდომივარ იგივე პრობლემას.

რაც შეეხება გამოსავალს, ერთადერთი რასაც მივხვდი input ელემენტი როგორმე უნდა გამენადგურებინა თავად “getInput” ფუნქციაში. რამდენიმე ხერხი გამოვიყენე, და საბოლოო ჯამში მივედი ასეთ შედეგამდე რამაც საბოლოოდ მოაგვარა პრობლემა:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
function getInput(value) {

    var input = [document.createElement('input')];
   
    input[0].type  = 'text';
    input[0].value = value || '';
   
    input[0].onclick = function(e) {
        try {
            e = window.event || e;
            if (e.stopPropagation) {
                e.stopPropagation();
                e.preventDefault();
            } else {
                e.cancelBubble = true;
                e.returnValue = false;
            }
        } catch(e) {}
    }
   
    input[0].onkeydown = function(e) {
        e = e || window.event;
        var key = e.which || e.keyCode;
        if (key == 13) {
            this.onblur();
            return false;
        }
    };
   
    input[0].onblur = function() {
        this.parentNode.innerHTML = this.value;
    };
   
    return input.pop();
   
}

განსხვავებით პირველი ვარიანტისგან, თუ ყურადღებით დააკვირდებით კოდს დაინახავთ რომ ნაცვლად ცვლადზე პირდაპირ DOM ელემენტის მინიჭებისა, ამისათვის გამოვიყენე ჩვეულებრივი მასივი. ხოლო ფუნქციიდან მნიშვნელობის დაბრუნების დროს მასივის “pop” მეთოდი რომელიც მასივიდან ამოაგდებს ბოლო ელემენტს და აბრუნებს მას.

ამ მიდგომით ფაქტიურად ფუნქციაშივე მოვახდინეთ ელემენტის ე.წ. dereference, რამაც საბოლოო ჯამში მეხსიერების პრობლემა მოაგვარა. იგივე ინსტრუმენტით სკრიპტის გატესტვის შემდგომ აღარავითარი მიმთითებელი “input” ელემენტზე აღარ დარჩა.

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

იმედია ეს პატარა მაგრამ საინტერესო(ჩემის აზრით) დეტალი თქვენთვისაც სასარგებლო იქნება :)

ტეგები: ,

3 Responses to “IE6: მეხსიერების მენეჯმენტი და საინტერესო გამოსავალი”

  1. DjHardanger says:

    მეგობარო მართლა საინტერესო სტატიებს წერ, კაია ეგრე გააგრძელე ;)

  2. Dv0rsky says:

    BarCamp Caucasus 2008 ორგანიზატორები იწვევენ ბლოგერებს, ჟურნალისტებს, IT სპეციალისტებსა და ყველა დაინტერესებულ პირს ბლოგერთა პირველ არაკონფერენციაზე კავკასიაში!

    უახლოესი შეხვედრა: სამშაბათს, 25 მარტს, სასტუმრო “ატლანტა”-ს საკონფერენციო დარბაზი (რჩეულიშვილის 13)

    დასაწყისი: საღამოს 8:00

    მონაწილეები: BarCamp Caucasus-ის ორგანიზატორები, BarCamp Baltics და BlogCamp CIS (კიევი) ორგანიზატორები, ჟურნალისტები, ბლოგერები და BarCamp Caucasus-ის მონაწილეები.

    სადისკუსიო თემები:

    * რა არის ბარკემპი?
    * ბარკემპის საწყისები
    * ბარკემპის ორგანიზება

    BarCamp – საზოგადოდ განიხილება, როგორც არაკონფერენცია – თავშეყრის სრულიად ახალი ფორმაა, რომელიც ჩაისახა “სილიკონის ველზე” 2005 წელს და გავრცელდა მთელ მსოფლიოში. არაკონფერენცია არაოფიციალური ნაწილია კონფერენციისა, რომელიც ღია დისკუსიების, იდეებისა და მოსაზრებების გაცვლას ემსახურება

    ძირითადი თემები:

    * ახალი მედია-საშუალებები
    * ჟურნალისტიკა
    * ვების განვითარება
    * სოციალური ქსელები
    * ღია კოდი და ა.შ.

    შეკითხვები გაქვს?

    დამიკავშირდი

    http://www.barcamp-kavkaz.org

  3. აშკარად გული დამწყდა რომ ვერ მივიღებ მონაწილეობას მაგ შეხვედრაში :(

    სამწუხაროდ დღე გაწერილი მაქვს უკვე… ძალიან ცუდია რომ თუნდაც 2 დღით ადრე არ ვიცოდი ამის შესახებ…

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

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