A way to stop redraws when modifying the DOM?

R

rob.nikander

Hi,

I'm working on a web page that uses the DOM API to move elements within
the page in response to an onclick event. My problem is that in
Firefox (but not in Safari and IE) I can see everything move, almost
like an animation -- not what I want in this case. It appears that the
other browsers are not reflowing/redrawing the page until my event
handler returns. So my question: is there a function to explicitly
control this? Something like:

function handleClick() {
document.dontRedrawInResponseToDOMChanges();
... move 20 elements ...
document.okayNowYouCanRedrawAllAtOnce();
}

thanks,
Rob
 
Y

Yanick

For you problem, I'd think that you're trying to sort table rows (or
div), am I right ? In any case, you should keep a separate array of the
elements you whish to have control over ; this will speed things up as
you won't have to do a document.getElement...(...); call all the time.
As this :

-------------- cut here ------------------------

<input type="button" onclick="sortedTable.sort(true);" value="Sort
(increase) !" />
<input type="button" onclick="sortedTable.sort(false);" value="Sort
(decrease) !" />

<table id="table">
<tr>
<td>1</td>
</tr>
</table>

<script language=javascript>

var MoveableRow = {};
MoveableRow = function( element ) {
this.element = element;
this.html = element.innerHTML;

// add whatever you like for properties... here, I set the "weight"
of the
// MoveableRow by the content of the first cell...
this.weight = parseInt( element.cells[0].innerHTML ); // make sure it
is an int
};
MoveableRow.prototype = {

getElement: function() {
return this.element;
},
getHTML: function() {
return this.html;
},
getWeight: function() {
return this.weight;
}

};

var SortableTable = {};
SortableTable = function( element ) {
// element = parent element to sort the childrens
this.element = element;
this.sortable = [];

// references all rows into an array
for ( var i=0; i<this.element.rows.length; i++ ) {
this.sortable.push( new MoveableRow( this.element.rows ) );
};
};
SortableTable.prototype = {

sort: function( sortOption ) {
// your sort algorith on this.sortable here
// I just did a simple bubble sort in this case
for ( var i=0; i<this.sortable.length - 1; i++ ) {
for ( var j=i+1; j<this.sortable.length; j++ ) {
var e1 = this.sortable;
var e2 = this.sortable[j];
if ( (sortOption && e1.getWeight() > e2.getWeight())
|| (!sortOption && e1.getWeight() < e2.getWeight()) ) {
this.sortable[j] = this.sortable;
this.sortable = e2;
}
}
}

for ( var i=0; i<this.sortable.length; i++ ) {
this.element.rows.innerHTML = this.sortable.getHTML();
}
}

};

var table = document.getElementById('table');

// make sure we have a 1000 rows...
for (var i=table.rows.length; i<1000; i++) {
var row=table.insertRow(i);
row.innerHTML = "<td>" + (i+1) + "</td>";
}

var sortedTable = new SortableTable( table );

</script>
-------------- end of code --------------------------

Hope this helps.
 
R

rob.nikander

Yanick said:
For you problem, I'd think that you're trying to sort table rows (or
div), am I right ?

Yes, I'm sorting table rows.
In any case, you should keep a separate array of the
elements you whish to have control over ; this will speed things up as
you won't have to do a document.getElement...(...); call all the time.

Thanks, this helped. I did have a call to getElementsByTagName()
inside the loop that was reinserting the elements. I removed this, and
the annoying animation effect disappeared. At first I was worried that
this was only because getElements...() was slow, and that the effect
would still exist on slower machines. But it appears the call to
getElement...() is what actually triggers the reflow in Firefox,
because this test code, which has an inner loop just to slow it down,
still works -- the new DOM structure appears in a flash, despite the
outer loop taking 2 seconds.

var body = document.getElementById("chapters");
var len = rows.length;
for (var i=0; i<len; i++) {
body.appendChild(rows);
var sum;
for (var j=0; j<10000; j++) { sum += j; }
}

thanks,
Rob
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,434
Messages
2,571,690
Members
48,796
Latest member
Greg L.

Latest Threads

Top