未捕获的TypeError:无法设置#<htmlelement>的属性offsetWidth,它只有一个getter

时间:2015-05-26 08:15:31

标签: javascript angularjs web-applications angularjs-directive

我正在使用AngularJS开发一个Web应用程序。我有一个错误,从无处出现,它工作正常,我真的不知道它为什么不再工作。

所以它在一个指令中,我尝试在指令html模板中设置一个元素的属性offsetWidth。由于我真的不知道它可能来自何处,我将为您提供我的指令和模板的完整代码。该指令创建一个app按钮并处理其对点击的视觉效果。它是触发错误的行$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>

4 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:5)

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

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

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

答案 2 :(得分:0)

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

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

"use strict";

我做到了

//"use strict";

我在找到"use strict";

的所有地方都这样做了

修改

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

答案 3 :(得分:0)

要解决此问题并避免出现jshint错误(预期分配或函数调用) 您应该这样做:

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

顺便说一句,//"use strict";之类的答案如何渗透进来? 这是该网站的一个很好的例子。假问题。假答案。假流量。真可悲。