赞
踩
最近遇到一个很棘手的bug,最初做需求的时候没考虑到通用,认为前端不会经常改架构,就写死了只对某个标签设置scrollbar的值,导致后面前端html架构改了之后,找不到相应的标签,触屏滑动失效。
先说环境和需求:
SUSE linux, qt5.15.0(内置Chrome浏览器内核), Elo触屏显示器。
用QWebEngineView加载网页,希望做到像在手机上一样,通过手指上下滑动达到屏幕滚动效果
最开始做的时候,前端把滚动条放在IFRAME中,通过document.activeElement可以得到IFRAME,所以,只需要识别到IFRAME 标签,然后调用document.activeElement.contentWindow.scrollBy(0,yOffet)就能实现屏幕滚动。
现在前端修改了html架构, 把IFRAME标签去掉了,这就导致当初的逻辑完全失效,屏幕无法滚动。
由于Chrome浏览器的特殊性,无论点击网页什么位置(除了输入框之类),document.activeElement.tagName始终返回BODY,无法得到BODY内部实际active的元素。Google各种资料,发现可以通过event获取当前事件的target。当前event事件的target可能是一个TD,DIV或者其他自定义标签,滚动条一般在其父节点上。尝试通过当前事件的target往上依次查找其父节点,直到得到有滚动条的元素。js脚本如下:
QString load = QStringLiteral( " function f(evt) {" \ "if(evt && evt.target) { " \ "var element = evt.target;" \ "while(element)" \ "{" "element = element.parentElement;" \ //依次得到父节点 "if(element)" \ "{" \ //判断当前元素是否带滚动条 "element.scrollBy(0,2);" "if(element.scrollTop > 0)" "{" "element.scrollBy(0,-2);" "window.scrollElt = element;" //保存在一个全局变量里,以便在后面设置滚动条位置。 "break; " "}" "else {" "element.scrollTo(0,0);}" "}" \ "}" \ "}" \ "}" \ " function f2(evt) {" \ "window.scrollElt = null;" \ "}" \ "document.addEventListener('mousedown',f,false);" \ "document.addEventListener('mouseup',f2,false);" \ );
有了带滚动条的元素对象,就能在Qt代码中的mouseMoveEvent() 中通过j调用脚本执行window.scrollElt.scrollBy()来设置滚动条位置了。
QString frameScrollCode = QStringLiteral("function frameScroll(){" \ "var divList = document.getElementsByTagName('div');" \ "var div;" \ "for(var index=0; index < divList.length; index++) {" \ "var bVisible = window.getComputedStyle(divList[index]).getPropertyValue('visibility');" \ "var isScroll =window.getComputedStyle(divList[index]).getPropertyValue('overflow-y');" \ "var height = window.getComputedStyle(divList[index]).getPropertyValue('height');" \ "var sHeight = divList[index].scrollHeight;" \ "var cHeight = divList[index].clientHeight;" \ "if((bVisible == 'visible') && (isScroll == 'auto' || isScroll=='scroll') && (sHeight>cHeight))" \ "{" \ "alert(divList[index]);" \ "divList[index].scrollBy(0,%1);" \ " break; " \ "}" \ "}" \ "}" \ "frameScroll();" \ ).arg(iGapy);
function _dom_trackActiveElement(evt) {
if (evt && evt.target) {
document.activeElement = evt.target == document ? null : evt.target;
}
}
function _dom_trackActiveElementLost(evt) {
document.activeElement = null;
}
if (!document.activeElement) {
document.addEventListener("focus",_dom_trackActiveElement,true);
document.addEventListener("blur",_dom_trackActiveElementLost,true);
}
"element.scrollBy(0,2);"
"if(element.scrollTop > 0)"
"{"
"element.scrollBy(0,-2);"
"window.scrollElt = element;" //保存在一个全局变量里,以便在后面设置滚动条位置。
"break; "
"}"
"else {"
"element.scrollTo(0,0);}"
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。