【问题标题】:Uncaught TypeError: Cannot set property offsetWidth of #<HTMLElement> which has only a getter未捕获的类型错误:无法设置只有 getter 的 #<HTMLElement> 的属性 offsetWidth
【发布时间】:2015-05-26 08:15:31
【问题描述】:

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

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

我再重复一遍,这段代码运行良好,我几乎可以肯定我没有进行任何更改。我是用Chrome调试的,可能是来源于它吧?

错误:Uncaught TypeError: Cannot set property offsetWidth of #&lt;HTMLElement&gt; 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>

【问题讨论】:

  • 如果我只获得 offsetWidth 值,重新启动动画技巧仍然有效($element[0].offsetWidth;),所以我的问题得到了解决。但我仍然想知道为什么我不能为 offsetWidth 属性设置值?

标签: javascript angularjs web-applications angularjs-directive


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

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

      "use strict";
      

      我做到了

      //"use strict";
      

      我在找到"use strict";的所有地方都这样做了

      编辑

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

      【讨论】:

      • 如果你删除“use strict”,你会隐藏错误而不是修复它们,我认为这是不好的做法。
      【解决方案4】:

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

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

      顺便说一句,像下面//"use strict"; 这样的答案怎么会渗透到? 这是这个网站的一个很好的例子。假问题。虚假的答案。虚假流量。很伤心的事。

      【讨论】:

        【解决方案5】:

        如果你只是想设置 offsetWidth 就这样做:

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

        代替:

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

        这只是一个 getter 属性。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-06-02
          • 1970-01-01
          • 2021-11-27
          • 2019-02-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多