5

Ich entwickle eine Web App mit AngularJS. Ich hatte einen Fehler, der aus dem Nichts auftauchte, es funktionierte gut und ich weiß wirklich nicht, warum es nicht mehr funktioniert.Uncaught TypeError: Eigenschaft OffsetWidth von # <HTMLElement>, die nur einen Getter hat, kann nicht gesetzt werden

So ist es in einer Direktive, ich versuche, Eigenschaft offsetWidth eines Elements in der Richtlinie HTML-Vorlage zu setzen. Da ich wirklich nicht weiß, woher es kommen könnte, gebe ich dir den vollständigen Code meiner Direktive und Vorlage. Die Direktive erstellt eine App-Schaltfläche und behandelt deren visuellen Effekt beim Klicken. Es ist die Zeile $element[0].offsetWidth = $element[0].offsetWidth;, die den Fehler auslöst. (Es ist ein Trick, um die Animation neu zu starten)

Ich wiederhole noch einmal, dieser Code war in Ordnung und ich bin fast sicher, dass ich keine Änderungen vorgenommen habe. Ich verwende Chrome, um zu debuggen, vielleicht kommt es davon?

Fehler: Uncaught TypeError: Cannot set property offsetWidth of #<HTMLElement> which has only a getter

Richtlinie:

'use strict'; 

XVMApp.directive('appButton', ['$location', function($location){ 
    return { 
     restrict: 'E', 
     replace: true, 
     scope: { 
      img: '@', 
      fillPercent: '@?', 
      target: '@?' 
     }, 
     link: function ($scope, $element) { 

      // Image percentage fill button 
      if($scope.fillPercent === undefined) $scope.fillPercent = '100'; 

      // Click event 
      $element.on('click', function() { 

       // Url target 
       if($scope.target !== undefined){ 
        $scope.$apply(function() { 
         $location.path($scope.target); 
        }); 
       } 

       // Click effect 
       $element[0].preventDefault; 
       $element[0].classList.remove('app-button-click-effect'); 
       $element[0].offsetWidth = $element[0].offsetWidth; 
       $element[0].classList.add('app-button-click-effect'); 

      }); 

     }, 
     templateUrl: 'src/directive/appButton/app-button.html' 
    }; 
}]); 

Vorlage:

<div class="app-button" 
    style="background-size: {{fillPercent}}%; "> 
     <div style=" 
      background-image: url('src/assets/img/{{img}}'); 
      background-repeat: no-repeat; 
      background-position: center; 
      background-size: {{fillPercent}}%; 
      height: 100%; 
      width: 100%; "> 
     </div> 
</div> 
+0

Wenn ich nur offsetWidth Wert bekomme, funktioniert der Neustart Animation Trick trotzdem ($ element [0] .offsetWidth;), so ist mein Problem behoben. Aber ich frage mich immer noch, warum ich keinen Wert für die OffsetWidth-Eigenschaft festlegen kann? – sylvain1264

Antwort

6

Ich schätze, dass Sie vor kurzem zu Chrome aktualisiert haben 43. Ich traf nur das gleiche Problem. Es sieht so aus, als ob die neueste Version dom-Knoten mehr wie Standard-js-Klassen behandelt, und alle Eigenschaften, die nur gelesen werden können, werfen jetzt einen js-Fehler. Das Einstellen der offsetWidth hätte sowieso nie funktioniert, da es sich um eine schreibgeschützte Eigenschaft handelt, aber zuvor hätte Chrome sie ignoriert, während jetzt, wenn Sie den strikten Modus verwenden, dieser Fehler auftritt. Sehen Sie hier für weitere Details: http://updates.html5rocks.com/2015/04/DOM-attributes-now-on-the-prototype

0

Wenn in Ihrem Anwendungsfall ein temporäres Pflaster wirft akzeptabel wäre, könnten Sie nur die Fehlermeldung unterdrücken unter Verwendung der Technik weiter:

In jeder JS-Datei in der Bibliothek , suchen Sie nach "use strict" und kommentieren Sie die Zeile, die diese Zeile enthält. Zum Beispiel in der Datei jquery-1.9.1.js auf der Leitung 39, gibt es eine Linie, die ist:

"use strict"; 

ich es gemacht

//"use strict"; 

tat ich dies überall fand ich "use strict";

bearbeiten:

Wenn Sie den Fehler einfach ausblenden, wird das Problem nicht behoben, und möglicherweise werden auch weitere Probleme ausgeblendet. Wie in einer anderen Antwort erwähnt, wird ab Chrome 43 ein Fehler ausgelöst, wenn Sie versuchen, in schreibgeschützte DOM-Eigenschaften zu schreiben, unabhängig davon, ob Sie in Ihrem Code "use strict" explizit verwenden. Zusammenfassend, schreiben Sie nicht in schreibgeschützte DOM-Eigenschaften ...

+5

Wenn Sie "Use Strict" entfernen, verstecken Sie Fehler, anstatt sie zu beheben, ich denke, es ist eine schlechte Übung. – sylvain1264

5

Gemäß this answer müssen Sie nur auf die Eigenschaft zugreifen, um einen Reflow auszulösen.
So sollte dies ausreichen Ihre Animation zurück:

$element[0].classList.remove('app-button-click-effect'); 
$element[0].offsetWidth; 
$element[0].classList.add('app-button-click-effect'); 

I Schnelltests auf Chrom und Firefox und beide Werke getan haben.

Verwandte Themen