iOS Safari上的getBoundingClientRect值不正确

时间:2017-07-23 22:24:32

标签: javascript jquery ios css safari

我们遇到了一个非常奇怪的问题,它似乎无法在屏幕上获得正确的元素位置和大小。该代码在Android上完美运行,但iOS上的值总是太大,通常在屏幕上返回超过一半的空间,因为元素不到三分之一。返回的值通常在屏幕下方比元素低,并且比元素高得多。 除以devicePixelRatio之后

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
    <style>
        #text-container > p {
            text-align: justify;

            transition: background-color 1s;

			      font-size: 3vh;
        }

        .selected {
            background-color: rgba(253, 230, 65, 0.5);
        }
    </style>


    <script src="jquery.min.js"></script>
    <script src="jquery.scrollTo.min.js"></script>


    <!-- Custom double-tap detector, couldn't get other solutions to work -->
    <script>

        function onElementsDoubleTap($els, callback) {
            var doubleTapThresholdMs = 250;

            var asArray = [];
            for (var i = 0; i < $els.length; i++)
                asArray.push($els[i]);

            asArray.forEach(function (el) {

                var lastTouchTime = Date.now();

                el.addEventListener('touchstart', function (e) {

                    if (e.touches > 1)
                        return;

                    var touchTime = Date.now();
                    if (touchTime.valueOf() - lastTouchTime.valueOf() < doubleTapThresholdMs) {
                        callback(el);
                    }

                    lastTouchTime = touchTime;

                });
            });
        }
    </script>


    

    <!-- Data templates -->

    <script id="paragraph-template" type="text/template">
        <p class="para-<%= index %>">
            <% _.each(words, function (wordObj) { %>
                <span class="in-paragraph-<%= wordObj.paragraphIndex %> in-sentence-<%= wordObj.sentenceIndex %> word-<%= wordObj.index %>"><%= wordObj.word %></span>
            <% }); %>
        </p>
    </script>


</head>
<body>
    <div id="text-container"></div>


    <!-- Generate DOM elements using templates -->
    <script>
        function Generate(textAdapter) {
            var paragraphTemplate = _.template($('#paragraph-template').html());
            var container = $('#text-container');

            Paragraphs.forEach(function (paragraph) {
                container.append(paragraphTemplate(paragraph));
            });

            var $sections = $('p');
            console.log($sections.length);



            onElementsDoubleTap($sections, function (s) {
                selectAndScrollTo($(s), function () {
                    csInvokeAction('userSelectedWord', $(s).attr('class'));


                    console.log('Capturing bounds for class=' + $(s).attr('class'));

                    console.log('Offset=' + JSON.stringify($(s).offset()));
                    console.log('Position=' + JSON.stringify($(s).position()));

                    var sectionPos;

                    setTimeout(function () {
                        var bounds = s.getBoundingClientRect();

                        console.log('Raw bounds = ' + JSON.stringify(bounds));

                        sectionPos = {};


                        //sectionPos.left     = bounds.left / (window.devicePixelRatio * 1.5);
                        //sectionPos.right    = bounds.right / (window.devicePixelRatio * 1.5);
                        //sectionPos.top      = bounds.top / (window.devicePixelRatio * 1.5);
                        //sectionPos.bottom   = bounds.bottom / (window.devicePixelRatio * 1.5);

                        var position = $(s).position();

                        position.top -= scrollTop;

                        sectionPos.left = position.left / window.devicePixelRatio;
                        sectionPos.top = position.top / window.devicePixelRatio;
                        sectionPos.right = position.left + ($(s).innerWidth() / window.devicePixelRatio);
                        sectionPos.bottom = position.top + ($(s).innerHeight() / window.devicePixelRatio);





                        console.log('Using sectionPos=' + JSON.stringify(sectionPos));

                        var dataString = '';
                        dataString += sectionPos.top + ',';
                        dataString += sectionPos.right + ',';
                        dataString += sectionPos.bottom + ',';
                        dataString += sectionPos.left;
                        csInvokeAction('readerSectionCaptured', dataString);
                    }, 5000);
                });
            });
        }

        function selectAndScrollTo($el, callback) {
            $('.selected').removeClass('selected');

            $el.addClass('selected');

            var windowHeight = window.innerHeight;
            $(window).scrollTo($el, {
                offset: {
                    'top': -windowHeight * 0.5
                },
                onAfter: callback,
                duration: 250
            });

            
        }
    </script>
</body>
</html>

(不完整的代码)

我们尝试了getBoundingClientRect,从jQuery获取数据,延迟调用直到滚动完成,并考虑devicePixelRatio。在这一点上,我唯一能做的就是应用一些魔术数字(即乘以devicePixelRatio乘以1.5)来获得球场中某处的元素大小。

0 个答案:

没有答案