我们遇到了一个非常奇怪的问题,它似乎无法在屏幕上获得正确的元素位置和大小。该代码在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)来获得球场中某处的元素大小。