How to create a "load" until the function is fully executed?

4

Hello. Going straight to the point: assuming I have a function with repeating structures that, depending on what the user completes, the process in that function may take a certain amount of time, and until it is fully completed, the page hangs. Is there a resource I can use, so that instead of the page crashing, this loading can happen "internally", and meanwhile the page works normally?

For example: link

In the above situation, there is an automatic creation of a table, from the order (n x m), indicated by the user. But if the user chooses 100 x 100, for example, the system will create the table, however, it will require a rather extensive loading time, and meanwhile the page will remain locked. I need somehow this does not happen, that during the process of creating the table, the page continues to function normally and for example a gif load appears until the complete completion.

This is a question that has persisted for some time, but I did not find anything about it or could not find it. If anyone can help me, thank you in advance.

    
asked by anonymous 15.11.2015 / 00:55

1 answer

3

Come on ...

Your code has some bad practices. But I'll stick to the main one. Whenever working with js and mass manipulation of data, avoid making too many hits to the DOM. Let me cite an example:

document.getElementByQualquerCoisa().innerHTML = 'Algo';

Whenever you do this a baby seal dies in Antarctica

And why does this happen?

Because every time an access to the DOM is made the browser has to traverse ALL the structure to find the element that it is looking for. This Kills the browser. Ex.:

<div>
    <table>
        <tr>
            <td><input type="text" id="ipTeste"/></td>
        </tr>
    </table>
</div>

In this example, to get to ipTest you will need:

Access div - > table - > tr - > td - > input

Does it seem like little? Yes it really is! But do not forget that in your case you will have a mega structure. In that case the performance will be felt from a distance.

Another thing, in case you get a table then it is even worse, as well as having to go through the DOM you will have lots of information that you probably will not need. Another thing, information like style, class and etc are also returned, ie all attributes.

So what to do?

It seems obvious and it is. Avoid access to the DOM in cases like yours that try to use a framework that abstracts this type of behavior. I'll cite one that I use and I get one of the best: link

Here is an example of your program using angular:

var app = angular.module('App', []);
app.controller('AppController', function($scope){
    $scope.column = 5;
    $scope.row = 5;
    
    $scope.range = function(count){
        var ratings = []; 
        for (var i = 0; i < count; i++) { 
            ratings.push(1) 
        } 
        return ratings;
    }   
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script><divng-app="App" ng-controller="AppController">
    <form id="create_table" action="javascript:process()">
        <input type="text" id="column" ng-model="column"> x <input type="text" id="row" ng-model="row"> 
        <input type="submit" value="Criar Matriz">
    </form>
   <div>
        <table class="tg">
            <tr ng-repeat="r in range(row) track by $index">
                <td ng-repeat="c in range(column) track by $index">
                    <input type="text" class="cells" style="width: 12px;" value="1"/>
                </td>
            </tr>
        </table>
    </div>
</div>

And with pure js. I used a time out to not crash the browser:

function ps(n) {
  return parseFloat(n);
}

var MTZ = document.getElementsByClassName("tg");
var statusInProcess = false;

function createTable() {
  
  rows = document.getElementById("row");
  columns = document.getElementById("column");

  var N = 0;
  var Column = [];
  var Row = [];

  var table = document.createElement('table');
  table.setAttribute('class', 'tg');

  for (var g = 0; g < columns.value; g++) {
    var fnAsync = function(g) {
      Row.push(table.insertRow(g));
      Row[g].setAttribute('class', 'spine');

      for (var q = 0; q < rows.value; q++) {
        Column[q] = Row[g].insertCell(q);
        Column[q].setAttribute('class', 'line');
        var input = document.createElement("input");
        input.type = "text";
        input.value = 1;
        input.setAttribute('class', 'cells');
        Column[q].appendChild(input);
        input.style.width = (input.value.length * 12) + "px";
        N++;
      };
    };

    setTimeout(fnAsync(g), 1);
  };
  var div = document.getElementById('divTable');
  div.appendChild(table);
}

function setMatriz(number, type) {

  var Mz = MTZ[number];

  var Rows = parseFloat(order(Mz)[0]);
  var Columns = parseFloat(order(Mz)[1]);

  var n = 0;
  var cell = new Array();
  var lines = [];

  for (var j = 0; j < Columns; j++) {

    cell[j] = [];

    for (var i = 0; i < Rows; i++) {

      lines.push(document.getElementsByClassName('cells')[n]);
      cell[j] = lines;
      n++;
    };
    lines = [];
  }
  statusInProcess = false;
}

function process() {
  createTable();
}
<input type="text" id="column">x
<input type="text" id="row">
<input type="button" value="Criar Matriz" onclick="process()">


<div id="divTable">

</div>
    
15.11.2015 / 19:36