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

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

我正在使用 AngularJS 开发网络应用程序。我有一个不知从哪里出现的错误,它工作正常,但我真的不知道为什么它不再工作了。

所以它在指令中,我尝试在指令 html 模板中设置元素的 属性 offsetWidth。因为我真的不知道它可能来自哪里,所以我会给你我的指令和模板的完整代码。该指令创建一个应用程序按钮并处理其点击时的视觉效果。触发错误的是 $element[0].offsetWidth = $element[0].offsetWidth; 行。 (重启动画是一招)

我再说一遍,这段代码工作正常而且我几乎可以肯定我没有做任何更改。我正在使用 Chrome 进行调试,也许它来自它?

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

指令:

'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'
    };
}]);

模板:

<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>

我猜你最近更新到 Chrome 43。我刚遇到同样的问题。看起来最新版本对待 dom 节点更像标准 js 类,任何只读的属性现在都会抛出 js 错误。设置 offsetWidth 无论如何都不会起作用,因为它是只读的 属性,但以前 Chrome 会默默地忽略它,而现在如果您使用严格模式,它会抛出此错误。详情请看这里:http://updates.html5rocks.com/2015/04/DOM-attributes-now-on-the-prototype

如果在您的用例中使用临时创可贴是可以接受的,您可以使用接下来描述的技术来抑制错误消息:

在库中的任何 .js 文件中,搜索 "use strict",并将包含此行的行注释掉。例如,在第 39 行的文件 jquery-1.9.1.js 中,有一行是:

"use strict";

我做到了

//"use strict";

我到处都这样做 "use strict";

编辑:

简单地隐藏错误并不能真正解决问题,还可能隐藏其他问题。正如在另一个答案中提到的,从 Chrome 43 开始,如果您尝试写入只读 DOM 属性,无论您是否明确使用 ,都会引发错误"use strict" 在您的代码中。总之,不要写入只读 DOM 属性...

根据 this answer,您只需访问 属性 即可触发回流。
所以这应该足以重置你的动画:

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

我已经对 chromium 和 firefox 进行了快速测试,两者都有效。

解决问题并避免 jshint 错误(需要赋值或函数调用) 你应该这样做:

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

BTW //"use strict";下面这样的答案怎么能渗透进去? 这是一个很好的例子来说明这个网站是关于什么的。假问题。假答案。虚假流量。很伤心的事情。

如果您只想设置 offsetWidth,只需执行以下操作:

$element[0].style.offsetWidth = $element[0].offsetWidth

而不是:

$element[0].offsetWidth = $element[0].offsetWidth;

这只是一个getter 属性.