2016-04-27 4 views
1

Ich bin ein Neuling, der eine kleine Webanwendung entwickelt, die HTML, JavaScript (Angular 1.5.0) & CSS verwendet. Ich benutze Grunt, um meine Javascript- und CSS-Dateien zu verarbeiten, jslint, zu minimieren. Mein Javascript-Code enthält ein SVG-Bild, das von d3.js erstellt wurde.Wie schreibe ich diesen Javascript-Code um JSHint Warnung zu vermeiden?

ich zur Zeit die folgende Warnung von jshint bekommen:

line 1932 col 32 Don't make functions within a loop. 

Wie kann ich den Code neu schreiben, diese Warnung zu beseitigen?

Line #1924  for (var j = 0; j <= 5; j++) { 
Line #1925   var myVarX = j * 100; 
Line #1926   var myVarY = j * 200; 
Line #1927   var myText = self.svgContainer.append("text") 
Line #1928   .attr("x", myVarX) 
Line #1929   .attr("y", myVarY) 
Line #1930   .text("Hello World") 
Line #1931   .attr("fill", "black") 
Line #1932   .attr("transform", function(d){ 
Line #1933    var bb = this.getBBox(); 
Line #1934    leftBoundary = bb.x + (bb.width/(-2)); 
Line #1935    return "translate(" + (bb.width/(-2)) + ", 0)"; 
Line #1936    } 
Line #1937   ) 
Line #1938   if (leftBoundary > centerX + 5) 
Line #1939   myText.style("display", "block"); 
Line #1940   else 
Line #1941   myText.remove(); 
Line #1942  } 
+3

Definieren Sie es außerhalb der Schleife und rufen Sie es mit '.attr ('transform', NAMEOFYOURFUNCTION)'. – str

+1

jshint warnt, da jede neue Funktion für die Schleifeniteration erstellt wird und sich die Leistung stark unterscheidet. @str hat Recht, nur diese Funktion außerhalb der Schleife Bereich definieren und rufen Sie –

Antwort

4

Verschiebe diesen

function(d){ 
    var bb = this.getBBox(); 
    leftBoundary = bb.x + (bb.width/(-2)); 
    return "translate(" + (bb.width/(-2)) + ", 0)"; 
} 

außerhalb des Umfangs der for-Schleife. Wie:

var transformCallback = function(d) { 
    var bb = this.getBBox(); 
    ... 

und dann transformCallback anstelle der Funktion verwenden.

.attr("transform", transformCallback) 
+0

Oder ignorieren Sie einfach die Nachricht mit der Option loopfunc: – codetoshare

+1

@codetoshare Die Nachricht gibt es aus einem Grund. Sie sollten es vermeiden, Funktionen in einer Schleife zu definieren, da jede Schleifeniteration im obigen Fall eine neue anonyme Funktion erzeugt, obwohl in Wirklichkeit nur 1 Funktion ausreichen sollte. –

+0

@AdarshKonchady, Mein Kommentar ist eine Ergänzung zu Stephens Antwort. Ich bin mir der Existenz der Nachricht bewusst. – codetoshare

1
Function.prototype.getTransform = function() { 
    var bb = this.getBBox(); 
    leftBoundary = bb.x + (bb.width/(-2)); 
    return "translate(" + (bb.width/(-2)) + ", 0)"; 
}; 

... 

for (var j = 0; j <= 5; j++) { 
    var myVarX = j * 100; 
    var myVarY = j * 200; 
    var myText = self.svgContainer.append("text") 
    .attr("x", myVarX) 
    .attr("y", myVarY) 
    .text("Hello World") 
    .attr("fill", "black") 
    .attr("transform", this.getTransform()) 
    if (leftBoundary > centerX + 5) 
    myText.style("display", "block"); 
    else 
    myText.remove(); 
} 
+4

Es ist besser zu vermeiden, den eingebauten 'Function'-Prototyp zu modifizieren. –

+0

Ja natürlich. Mein Beispiel ist ein eher objektorientierter Ansatz, bei dem "Funktion" durch seine "Klasse" ersetzt werden soll. –

0
Line 1924 : Change `j++` to `j+=1` 
Line 1932: Take out the function def outside the loop. Define it outside and use it here 

// function defined outside the loop 
function transformFn(d) { 
    var bb = this.getBBox(); // if using jQuery replace this with $(this) or that/self to ensure correct this binding 
    leftBoundary = bb.x + (bb.width/(-2)); 
    return "translate(" + (bb.width/(-2)) + ", 0)"; 
} 


// function used at Line1932 
.attr('transform', transformFn) 

Erholung scheint mir gut.

1

Ein weiterer mehr D3- ish Ansatz wird die äußere for-Schleife insgesamt loswerden. Wann immer Sie auf eine For-Schleife um eine D3-Aussage stoßen, sollte dies ernsthaften Verdacht aufkommen lassen. Um dies zu umgehen, können Sie die leistungsstarke Datenbindung Eigenschaften:

d3.selectAll("text") 
    .data(d3.range(6).map(function(d) {   // data binding replaces for-loop 
    return { 
     x: d * 100, 
     y: d * 200, 
     remove: false       // used to mark the texts for removal 
    }; 
    }))        
    .enter().append("text") 
    .text("Hello World") 
    .attr("x", function(d) { return d.x; }) // replaces myVarX 
    .attr("y", function(d) { return d.y; }) // replaces myVarY 
    .attr("fill", "black") 
    .attr("transform", function(d){ 
     var bb = this.getBBox(); 
     // mark texts for removal based on the condition 
     d.remove = (bb.x + (bb.width/(-2))) <= centerX + 5; 
     return "translate(" + (bb.width/(-2)) + ", 0)"; 
    }) 
    .style("display", "block") 
    .filter(function(d) { return d.remove; }) // select all texts marked for removal 
    .remove(); 

Dies ist die Art und Weise ist ein D3 puristische nehmen würde: es ist alles in den Daten! Der Ansatz verwendet Datenobjekte, um alle Informationen für die Positionen x und y sowie ein Flag remove zu speichern, das verwendet wird, um anzuzeigen, ob ein Text basierend auf einer Bedingung entfernt werden soll. Abgesehen von der Entfernung der for-Schleife, wird dies einige andere Variablen wie myVarX und myVarY los, und wird auch den Block zum Entfernen einiger der Elemente integrieren.

Verwandte Themen