wnr / element-resize-detector

Optimized cross-browser resize listener for elements.
MIT License
1.32k stars 118 forks source link

Resize detection is very flaky in RTL in Chrome and IE11 #56

Closed rasmusvhansen closed 8 years ago

rasmusvhansen commented 8 years ago

Try this in Chrome, it should add "lt" and "gte" classes to the elements for breakpoints 400 and 800.

It works some of the time, but often it does not. If you set dir="ltr" it works flawlessly.

<!DOCTYPE html>
<html dir="rtl">

<head>
    <style>
        body {
            box-sizing: border-box;
            height: 100%;
        }

        .maincontainer {
            width: 70%;
            height: 100%;
            float: left;
        }

        .sidebar {
            width: 30%;
            height: 100%;
            float: left;
        }

        .box.gte800 {
            background-color: grey;
        }

        .box.lt800.gte400 {
            background-color: lightgoldenrodyellow;
        }

        .box.lt400 {
            background-color: lightblue;
        }
    </style>
</head>

<body ng-app="cq">
    <h1>Hello Plunker!</h1>

    <div class="maincontainer">
        <box>Box1 content (70% width)</box>
        <box>Box2 content (70% width)</box>
    </div>

    <div class="sidebar">
        <box>Box3 content (30% width)</box>
        <box>Box4 content (30% width)</box>
    </div>

    <script data-require="jquery@2.1.3" data-semver="2.1.3" src="http://code.jquery.com/jquery-2.1.3.min.js"></script>

    <script src="https://rawgit.com/wnr/element-resize-detector/master/dist/element-resize-detector.js"></script>
    <script data-require="angular.js@1.5.3" data-semver="1.5.3" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>

    <script>

angular.module('cq', [])
    .service('ElementWidthDetector', function () {
        var erd = elementResizeDetectorMaker({
            strategy: "scroll" //<- For ultra performance.
        });
        this.listenTo = erd.listenTo;
        this.removeListener = erd.removeListener;
    })

    .directive('cqBreakpoints', ['ElementWidthDetector', function (ElementWidthDetector) {
        return {
            restrict: 'A',
            scope: {
                onResize: '&',
            },
            link: function (scope, element, attrs) {
                var breakpoints = attrs.cqBreakpoints.split(' ');
                var listener = function () {
                    calculateCssClasses(element, breakpoints);
                    scope.onResize({width: element[0].offsetWidth})
                }
                ElementWidthDetector.listenTo(element, listener);
                element.on('$destroy', function () {
                    ElementWidthDetector.removeListener(element, listener);
                })
            }
        };
    }])

    .component('box', {
        template: '<div class="box" ng-transclude cq-breakpoints="400 800" on-resize="$ctrl.resized(width)"></div>',
        transclude: true,
        controller: function () {
            this.resized = function(width) {
                console.log('Box resized to: ' + width);
            };
        }
    });

// Code goes here
function calculateCssClasses(el, breakpoints) {
    var classesToRemove = breakpoints.reduce(function (a, b) { return a + ' lt' + b + ' gte' + b; }, '');
    el.removeClass(classesToRemove);
    var w = el[0].offsetWidth;

    breakpoints.forEach(function (val) {
        var b = parseFloat(val);
        if (w < b) {
            el.addClass("lt" + val);
        } else {
            el.addClass("gte" + val);
        }
    });
}
    </script>
</body>

</html>
wnr commented 8 years ago

Hi, and thanks for the report!

Hmm yes it seems to be very flaky indeed when dir="rtl". I had not idea that dir could affect the behavior that much. I'll look into it to see if I can come up with a solution.

wnr commented 8 years ago

I pushed a potential fix to the release/1.1.5 branch, could you try if using it solves the problems?

rasmusvhansen commented 8 years ago

It seems to work a lot better. Thanks alot for the quick response!

wnr commented 8 years ago

Thanks :) I've published version 1.1.5 now.