问题搞明白了,顺便了解下背后的本质原因===_设备像素比_。当我们修改了缩放比例,实际上修改的就是设备像素比,假如我们设定了150%,实际上设备像素比就是15,也就是比如普通的文本12px,但实际上物理显示的大小会是18px,当然我们CSS里提示的还会是12px。这就说明了,为什么有时网页看上去字体比别人大。通过JS脚本执行,我们也可以获取实际上的设备像素比
这么严重的bug怎么能放过它,于是我开始了疯狂的百度而得到的答案就是给table的每一列添加固定的宽或者使用百分比,于是我就怀着成功的心态试了很多次最后的结果就是fail,我的心态顿时崩了难道就没办法解决了吗?当然不是的下面开始说解决办法
安全起见另外需添加额外的样式
整体展示
或
然后这样就解决了最终的效果图是这样子的
这样子才对嘛工工整整的漂漂亮亮的就是这么nice
了解view的滑动必须要先了解以下几个概念:
view的位置参数:
(1)、left、top、right、bottom分别表示view相对于父控件的左上顶点的坐标和右下顶点的坐标;分别通过getLeft()、getTop()、getRight()、getBottom()获得。
(2)、x、y、translationX、translationY。x、y表示view的左上顶点的坐标;translationX、translationY表示view的左上顶点相对于父控件的偏移量。
(3)、getX()、getY()获取的是相对于父控件的坐标;getRawX()、getRawY()获取的是相对于手机屏幕的坐标。
TouchSlop:常量;和手机设备有关;表示系统所能识别的最小的滑动距离。可以通过ViewConfigurationget(getContext())getScaledTouchSlop()获取;
由于手机屏幕小,所以需要通过滑动来对内容进行显示和隐藏。view的滑动主要有三种方式:1、通过view的scrollTo/scrollBy方法实现;2、通过动画给view进行平移 *** 作;3、改变view的Layoutparmes参数,是view进行重新布局,实现滑动。
(1)、scrollTo/scrollBy:mScrollX是view的左边缘和内容的左边缘的距离;mScrollY是view的上边缘和内容的上边缘的距离。当view的左边缘在内容的左边缘的右边的时候,mScrollX是正值;当view的上边缘在内容的上边缘的下边时,mScrollY为正值;scrollTo和scrollBy方法不会改变view在布局中的位置,改变的是内容的位置。scrollTo()方法让View相对于初始的位置滚动某段距离,scrollBy()方法则是让View相对于当前的位置滚动某段距离。同时可以发现scrollBy()是通过scrollTo()方法实现的。
(2)、通过动画:系统动画并不能真正改变view的位置参数,如果希望动画执行完后状态得以保留,那么必须将fillAfter属性设为true;使用属性动画就不会有这些问题,但是属性动画在android30无法使用,必须使用nineoldandroids兼容库。注意使用兼容库中的ViewHelper帮助类中的方法。
(3)、通过改变Layoutparmes:viewsetLayoutParams();
d性滑动:1、通过Scroller。2、通过动画。3、通过延时策略。
首先看一下Scroller的典型用法:
mScrollerstartScroll(scrollX, 0, deltaX, 0, 500);只是启动滑动,但是控件并不会滑动,真正造成滑动的是下面的invalidate()方法,invalidate()的调用会使得view重绘,调用computeScroll()方法,在computeScroll()方法里面会判断滑动是否结束,computeScrollOffset返回值为true表示滑动未结束,返回false表示滑动结束;滑动未结束的时候调用scrollTo()进行滑动,并调用invalidate(),如此循环直到computeScrollOffset返回true为止。
延时策略:通过Handler发送并接收延时消息,每次接收到消息便完成一次ScrollTo *** 作,从而实现d性滑动的效果。但是需要注意的是,由于系统的消息调度需要时间,完成这次d性滑动的时间总是大于if条件判断为true的次数乘以20ms(延迟消息的发送时间间隔)。因此对d性滑动完成总时间有精确要求的使用场景下,使用延时策略是一个不太合适的选择。
public void handleMessage(Message msg) {
switch(magwhat){
case SCROLL_FRACTION:{
//if判断滑动还没有结束,结束则不再滑动和发送消息
if(){
//通过滑动完成比例计算该次滑动片段的位置点scrollX,scrollY
ViewscrollTo(scrollX,scrollY);
mHandlersendEmptyMessageDelayed(SCROLL_FRACTION, 20);
}
break;
}
default:
break;
}
}
documentdocumentElementscrollTop
获取当前页面的滚动条纵坐标
网页被卷去的高: documentbodyscrollTop;
在标准w3c下,documentbodyscrollTop恒为0,需要用documentdocumentElementscrollTop来代替;
如果你想定位鼠标相对于页面的绝对位置时,你会发现google里面1000篇文章里面有99999篇会让你使用 eventclientX+documentbodyscrollLeft,eventclientY+documentbodyscrollTop, 如果你发现你的鼠标定位偏离了你的想象,请不要奇怪,这是再正常不过的事情。
ie55之后已经不支持documentbodyscrollX对象了。
所以在编程的时候,请加上这样的判断
if (documentbody && documentbodyscrollTop && documentbodyscrollLeft)
{
top=documentbodyscrollTop;
left=documentbodyscrollleft;
}
if (documentdocumentElement && documentdocumentElementscrollTop && documentdocumentElementscrollLeft)
{
top=documentdocumentElementscrollTop;
left=documentdocumentElementscrollLeft;
}
找到两个前端就能解决的方法,最后因为各种原因采用了方法二。
方法一:
找到地图上的全部点,然后在canvas上面重绘一次。
html2canvas(this$refstarget, {
useCORS: true, // 如果截图的内容里有,可能会有跨域的情况,加上这个参数,解决文件跨域问题
})then((canvas) => {
let cans = canvasgetContext("2d");
//批量地图重新打点 加载
documentquerySelectorAll("#mapView_layers image")forEach((item) => {
var obj = item;
var x = itemgetAttribute("x");
var y = itemgetAttribute("y");
var itemWidth = itemgetAttribute("width");
var itemHeight = itemgetAttribute("height");
consolelog("item", item, x, y);
if (width == 8) {
cansdrawImage(obj, x, y, itemWidth, itemHeight);
} else {
cansdrawImage(
obj,
x ,
y - 1 - itemHeight / 2 ,
itemWidth,
itemHeight
);
}
});
//下面是截图代码
})
登录后复制
因为本身目标dom的position定位问题,最后打的点可能会出现偏移。
所以还要给html2canvas加几个属性: x , y , scrollX , scrollY。保险起见,再加上两个参数 width 和 height 。
本人是后面chrome测着没问题,但是给小伙伴测试的时候,他用的360浏览器还有个xx浏览器有点问题。干脆参数全加上。
screenShot() {
let canvasBox = this$refstarget;
//获取目标div位置;
var tPosition = canvasBoxgetBoundingClientRect();
consolelog("size", tPosition);
// 获取父级的宽高
const width = parseInt(windowgetComputedStyle(canvasBox)width);
const height = parseInt(windowgetComputedStyle(canvasBox)height);
html2canvas(this$refstarget, {
width: width,
height: height,
x: 0,
y: 0,
scrollY: -tPositiony,
scrollX: -tPositionx,
useCORS: true, // 如果截图的内容里有,可能会有跨域的情况,加上这个参数,解决文件跨域问题
})then((canvas) => {
})
}
登录后复制
要是项目的地图是不可移动的,基本到这里就可以了。
但是地图只要一挪动。。一个新的bug出现了。。。。。整个地图画线打点层的偏移量和截图之前不一样。。。。 截图后,画线层偏的比原地图还要远,打点却还在原位没动过。。
这个问题需要修正svg的偏移,然后这个标注点绘制的时候也要加上一个偏移量。
地图偏移的bug后面再讲。
方法二:(最后采用)
把svg中所有的<image>的href路径转换为base64编码格式。简单方便,不用考虑位置什么的问题,就是有些浏览器里面加载慢。。。setTimeout有时候要设置大一点。。
screenShot() {
let canvasBox = this$refstarget;
//获取目标div位置;
var tPosition = canvasBoxgetBoundingClientRect();
consolelog("size", tPosition);
// 获取父级的宽高
const width = parseInt(windowgetComputedStyle(canvasBox)width);
const height = parseInt(windowgetComputedStyle(canvasBox)height);
//---------------------
//解决svg 内部image加载不了的问题,把image改为base64,配合setTimeout html2canvas使用
documentquerySelectorAll("#mapView_layers image")forEach((item) => {
consolelog("item", item);
var img = itemgetAttribute("xlink:href");
consolelog("href", img);
var image = new Image();
imagecrossOrigin = "";
imagesrc = img;
imageonload = () => {
var base64 = getBase64Image(image);
itemsetAttribute("xlink:href", base64); //更改href属性
};
});
//地址转为base64编码
function getBase64Image(img) {
var canvas = documentcreateElement("canvas");
canvaswidth = imgwidth;
canvasheight = imgheight;
var ctx = canvasgetContext("2d");
ctxdrawImage(img, 0, 0, imgwidth, imgheight);
var ext = imgsrcsubstring(imgsrclastIndexOf("") + 1)toLowerCase();
var dataURL = canvastoDataURL("image/" + ext);
return dataURL;
}
setTimeout(() => {
html2canvas(this$refstarget, {
width: width,
height: height,
x: 0,
y: 0,
scrollY: -tPositiony,
scrollX: -tPositionx,
useCORS: true, // 如果截图的内容里有,可能会有跨域的情况,加上这个参数,解决文件跨域问题
})then((canvas) => {
})
}, 200);
}
登录后复制
以上就是关于React使用scroll-x之后导致表头和表内容对不齐全部的内容,包括:React使用scroll-x之后导致表头和表内容对不齐、view的滑动和d性滑动、请问js中 document.documentElement.scrollTop document.body.scrollTop window.scrollY 分别是什么意思等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)