【问题标题】:Watch element size in Chrome在 Chrome 中查看元素大小
【发布时间】:2023-03-12 03:44:01
【问题描述】:

因此,当手动调整元素大小时,Chrome apparently has a bug 无法使用 MutationObserver 观察元素的大小。

在修复错误之前,我应该使用什么来代替或补充它才能在 Chrome 中进行这项工作?我应该使用deprecated mutation events 还是有其他更好的选择?

有没有办法在 AngularJS 中做到这一点而不使用元素对象?

【问题讨论】:

    标签: javascript google-chrome angularjs mutation-observers


    【解决方案1】:

    要查看元素的大小,您有以下选项:

    • 使用MutationObserver,您可以观察手动调整元素大小时元素的属性变化。这个is a bug in Chrome

    • 您可以使用 JavaScript 在计时器间隔内不断轮询元素大小,但您已表明这不是您希望使用的东西。

    • 我知道的最后一个选项是使用CSS element queries

    最后一个选项的工作原理是所有浏览器都支持元素的溢出事件。它将改变您现有页面的布局,强制您正在调整的元素相对或绝对定位。如果你有一个简单的页面和简单的 css 完全没有问题,但更复杂的布局可能会遇到问题。

    【讨论】:

    • 用 Angular 做这件事只是可选的。我的主要问题是如何在没有 MutationObserver 的情况下做到这一点,如果可能的话,可能没有突变事件。必须有比使用超时更好的方法。
    • 好吧,那么没有角度。用我找到的marcj.github.io/css-element-queries 的链接修改了我的答案。
    • 我倾向于相信这里使用 css 元素查询的所有答案是MutationObserver 的唯一有效替代方案,谢谢。
    【解决方案2】:

    在 Angular 的作用域上使用观察器

    $scope.$watch(function() {
      // whatever element you want to watch
      return $element.height();
    }, function(newVal, oldVal) {
      // do something
    });
    

    我的最佳出价是,当您调整任何元素的大小时,如果您在页面上完全使用 Angular,则可能会在另一个摘要周期内完成。要解决此问题,您可以在手动调整元素或窗口大小时使用 $scope.$apply() 手动触发消化。

    // example to manual trigger digest with $apply()
    app.run(function($window, $rootScope) {
      angular.element($window).on('resize', function() {
        $rootScope.$apply();
      });
    });
    

    这比setTimeout 好,因为它确实浪费了很多函数调用来检索高度。它仅在状态可能发生变化时检索。在跨浏览器使用时,这也比MutationObserverMutationEvents 更可靠。更何况我 不要相信MutationObserverMutationEvents 会监控元素的尺寸。

    【讨论】:

    • 如果我使用$element[0].clientHeight,这是否也有效,或者我是否会遇到跨浏览器问题?它只需要在较新的 Chrome/Firefox 中运行。
    • @Mouagip 你可以使用clientHeight,我知道没有任何问题。
    • 正如here 所说,这种方法的问题是,手动调整元素大小不会触发摘要。
    • @Mouagip 我最好的出价是,当您调整任何元素的大小时,如果您在页面上完全使用角度,则很可能在另一个摘要周期内完成。要解决此问题,您可以在手动调整元素或窗口大小时使用 $scope.$apply() 手动触发消化。
    • 我可以告诉你,MutationObserver 和突变事件可以在手动调整元素大小的情况下监控元素的尺寸。我认为MutationObserver 将是这里介绍的所有其他解决方案中最好的解决方案,如果不是因为 Chrome 中的错误...
    【解决方案3】:

    我的建议,

    首先,为要观察高度的元素设置一个指令

    其次,在指令中添加一个空的观察者,如doc 所说的这样

    If you want to be notified whenever $digest is called, 
    you can register a watchExpression function with no listener.(Since 
    watchExpression can execute multiple times per $digest cycle when a 
    change is detected, be prepared for multiple calls to your listener.)
    

    指令

    scope.$watch( function(){
      scope.elHeight = element.height(); // or element.offsetHeight;
    };
    

    第三,在控制器中为这个高度设置一个观察者

    控制器

    $scope.$watch('elHeight',  function(newVal, oldVal){
      console.log(newVal, oldVal)
    };
    

    每一个 $digest 意味着范围内每一个 Angular 相关的变化。

    --- 编辑 ---
    这涵盖了大多数 angular-js 相关事件。但是它不包括手动调整大小,即窗口大小调整、香草 JavaScript 大小调整等。

    如果我使用 AngularJS,我会在整个页面中完全使用 Angular。因此,
    对于这种情况,我会触发小事件来调用 $digest。

    【讨论】:

    • 如果我可以在不使用 jQuery 的情况下获得元素的高度,这将起作用(请参阅我的 comments here)。
    • 手动调整元素大小时不会触发摘要
    • 如果没有 jquery,我会使用 element[0].offsetHeight。对于手动调整大小,我会使用 $element.on(...) 触发事件
    • $element.on() 将使用已弃用的突变事件。但也许我会在 Chrome 中的错误修复之前使用它。
    • @allenhwkim 你会使用哪些事件?
    【解决方案4】:

    我在制作一些响应式元素时遇到了类似的问题,所以我最终使用了 window.onresize:

    window.onresize = function(){
            //do element changes here
            $scope.$apply();
        };
    

    不确定这是否是您正在寻找的,但这种方法对我来说效果很好。

    【讨论】:

    • 如果您想查看窗口大小,这将是一个解决方案。但是我必须注意可以独立于窗口调整大小的元素的大小。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 2020-05-08
    • 1970-01-01
    • 2019-11-17
    相关资源
    最近更新 更多