Toon posts:

[JS] Browser raakt in infinite loop - hoe oplossen?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik ben bezig met een javascript editor die een document doorzoekt op textarea's en hier een UBB-like toolbar boven hangt en een "gutter" (met regelnummers) ernaast hangt. Deze gutter maak ik mbv een extra textarea. Relevante delen van de code:
JavaScript:
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
function editorInit() {
  var theTextareas = document.getElementsByTagName('textarea');
  var thisTextarea, i = 0;
  
  while ((thisTextarea = theTextareas[i++])) {
    if (thisTextarea.hasClass('form-text')) {
      if (thisTextarea.id == '') {
        thisTextarea.id = thisTextarea.name;
      }
      new textEditor(thisTextarea);
    }
  }
}

function textEditor(textarea) {
  var container = createNode('div', {'id' : textarea.name + '-txtContainer'});
  this.textarea = parent.removeChild(textarea);
  this.toolbar = this.createToolbar();
  this.gutter = this.createGutter();
  
  container.appendChild(this.toolbar);
  container.appendChild(this.gutter);
  container.appendChild(this.textarea);
}

Object.extend(textEditor.prototype, {
  createGutter : function() {
    var target = this.textarea;  
    gutter = createNode('textarea', {'id' : target.name + '-gutter'}); 
    return gutter;
  }
}

Regel 22 veroorzaakt alle ellende. Omdat ik hier een textarea aan de DOM toevoeg, raakt de loop uit regel 5 - 12 in een oneindige loop en bevriest mijn browser. Toch heb ik de gutter-textarea nodig. Hoe kan ik hier omheen werken?

Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 11:50
Je hoogt i niet op in de while-loop vanaf regel 5? Je klooit continue bij hetzelfde textarea.
He toevoegen van een textarea heeft ook helemaal geen invloed op je call naar getElementsByTagname, die is dan al lang gedaan en heeft ijn resultaat al terug gegeven.

Sowieso zou ik gebruikmaken van een for-loop
code:
1
2
3
4
for(i = 0; i < theTextareas.length; i++) {
   thisTextarea = theTextareas[i];
   [...]
}

[ Voor 57% gewijzigd door frickY op 05-01-2008 13:21 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
frickY schreef op zaterdag 05 januari 2008 @ 13:20:
Je hoogt i niet op in de while-loop vanaf regel 5? Je klooit continue bij hetzelfde textarea.
Nee hoor, een while loop verhoogt i wel (plaats maar eens een alert(i) in de loop). Ik klooi dus telkens bij een andere textarea.
He toevoegen van een textarea heeft ook helemaal geen invloed op je call naar getElementsByTagname, die is dan al lang gedaan en heeft ijn resultaat al terug gegeven.
Als dat zo is, waarom raakt 'ie dan in een infinite loop?
Sowieso zou ik gebruikmaken van een for-loop
code:
1
2
3
4
for(i = 0; i < theTextareas.length; i++) {
   thisTextarea = theTextareas[i];
   [...]
}
Dat kan ook, maar de werking is hetzelfde als van een while loop, imho :)

Acties:
  • 0 Henk 'm!

Verwijderd

Verwijderd schreef op zaterdag 05 januari 2008 @ 13:44:
Als dat zo is, waarom raakt 'ie dan in een infinite loop?
Geen idee, maar frickY heeft wel gelijk dat het niet uitmaakt als er textarea's worden toegevoegd, wanneer de getElementsByTagName al is uitgevoerd.

Weet je zeker dat de loop optreedt door regel 22?

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 15:40

crisp

Devver

Pixelated

getElementsByTagName geeft een 'live nodelist' terug, dus de extra textarea wordt daar wel degelijk aan toegevoegd!

Wat je dus moet doen is eerst het resultaat van getElementsByTagName statisch maken:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function editorInit() {
  var textareaNodes = document.getElementsByTagName('textarea');

  var theTextareas = [], thisTextarea, i = 0;
  while ((thisTextarea = textareaNodes[i++]))
    theTextareas.push(thisTextarea);

 i = 0; 
  while ((thisTextarea = theTextareas[i++])) {
    if (thisTextarea.hasClass('form-text')) {
      if (thisTextarea.id == '') {
        thisTextarea.id = thisTextarea.name;
      }
      new textEditor(thisTextarea);
    }
  }
} 


Dit kan ook, maar werkt alleen niet in IE:
JavaScript:
1
var theTextareas = [].slice.call(document.getElementsByTagName('textarea'), 0);

;)

Intentionally left blank


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
@crisp - thanks!

...en die IE oplossing had ik natuurlijk zelf ook al lang gevonden 8)7

Acties:
  • 0 Henk 'm!

Verwijderd

crisp schreef op zaterdag 05 januari 2008 @ 14:11:
getElementsByTagName geeft een 'live nodelist' terug, dus de extra textarea wordt daar wel degelijk aan toegevoegd!
Wauw, dat wist ik niet! Onbegrijpelijk dat ik hier nog nooit eerder last van heb gehad.

Dit opent trouwens wel prachtige mogelijkheden :P .

Kun je trouwens ook niet gewoon nog een keer i++ toevoegen na de regel
JavaScript:
1
new textEditor(thisTextarea);

? Dan spring je over de gutter/nieuwe textarea heen.

[ Voor 3% gewijzigd door Verwijderd op 05-01-2008 14:50 ]

Pagina: 1