QQ空间缓存图片_QQ空间原图

QQ空间缓存图片_QQ空间原图不知各位遇到特别长的图片时是怎么处理的?是截取符合长宽的部分做临时展示?还是硬要长宽100%模糊(啥也看不清)展示?还是先拿一个压缩的图片做占位,在鼠标移入或点击时放大预览?今天偶然打开PC端QQ空间时,我发现了一种似乎更好的方式——鼠标移入时在范围内上下滚动图片预览,移出时停止滚动。直到用户点击图片跳转到详情展示:分析这种方式着实让我“眼前一亮”,一定程度上带给了用户新奇的体验感。顺着思路,一键f12打开源码,我看到了这样的代码:显而易见,QQ应该是采用了js监听鼠标位

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

不知各位遇到特别长的图片时是怎么处理的?
是 截取符合长宽的部分做临时展示?
还是 硬要长宽100%模糊(啥也看不清)展示?
还是 先拿一个压缩的图片做占位,在鼠标移入或点击时放大预览?

今天偶然打开PC端QQ空间时,我发现了一种似乎更好的方式 —— 鼠标移入时在范围内上下滚动图片预览,移出时停止滚动。直到用户点击图片跳转到详情展示:
test_0


分析

这种方式着实让我“眼前一亮”,一定程度上带给了用户新奇的体验感。顺着思路,一键 f12 打开源码,我看到了这样的代码:
test0
test1
显而易见,QQ应该是采用了js监听鼠标位置的做法,动态改变 img 标签中自定义属性的值,并根据此去改变图片的 margin-top 值,用 transition 属性去制造动画效果。


模拟实现

为了方便些,这里笔者采用两个空标签分割“包裹图片的元素”,然后分别在上面监听鼠标事件的做法,实现效果如下:
test_2

首先,“科普”几个API,它们将会是你的助力:

  1. image.naturalHeight :看到前面的image没?这是用来获取图片原始高度的(同系的还有 image.naturalWidth ,你可以用它来确定包裹元素的最大/最小宽度);
  2. dom.offsetTop :offset系的API,用来获取dom元素和离它最近的父元素顶部的距离(同系的还有 offsetLeftoffsetWidth/offsetHeight (返回元素的像素宽高,包含该元素的内边距和边框,是一个整数且不包含:before或:after等伪类元素的宽高)、offsetParent (获取父元素));
  3. dom.getBoundingClientRect() :它有四个常用值:left、top、right、bottom,分别是相对于当前视口(即此tab网页窗口左侧、顶部、右侧、底部)的位置;
  4. dom.scrollHeight :scroll系的API,用来获取元素的真实高度(同系的还有scrollWidth/scrollLeft/scrollTop ),一般不会用它来作用于图片上,因为它必须等元素加载出来才能确定;
  5. window.innerHeight :inner系的API,它们只作用在window对象上,返回窗口的文档显示区的高度(同系的还有一个 window.innerWidth ) <-> 相对的两个 outerWidthouterHeight ,用于获取加上工具条与滚动条窗口的宽度与高度;

顺便说一句,像 img.getBoundingClientRect().topimg.offsetTop 这些都是 只读 值,所以不要妄想用它们来改变元素位置!

布局如下:

<div class="box">
	<i class="before"></i>
	<img src="img/nan.png" class="img" />
	<i class="after"></i>
</div>

这里class为before和after的两个标签就是前面所说的“占位”元素(至于QQ是怎么实现的,等笔者稍作研究后再回来更新),它们负责判断“图片是应该向上滑还是向下滑”!

本来这里笔者想采用伪元素的方式:用 ::before::after 占位并触发事件,但是在查遍资料以后我突然想到一件事:不是经常说伪元素的优势是脱离文档流吗?那还如何能够获取到?
唉,大意了,,,

html,body{ 
   
	margin: 0;
	padding: 0;
}

.box{ 
   
	width: 400px;
	height: 200px;
	overflow: hidden;
	position: relative;
}
.lang::after{ 
   
	content: "长图";
	position: absolute;
	right: 0;
	bottom: 0;
	padding: 2px 3px;
	background-color: rgba(0,0,0,.36);
	color: white;
}
i{ 
   
	position: absolute;
	width: 100%;
	height: 50%;
	left: 0;
}
i.before{ 
   
	top: 0;
}
i.after{ 
   
	bottom: 0;
}
.img{ 
   
	margin-top: 0;
	transition: all 2s linear;
}

对img元素设置一个初始的margin-top,就是为了配合下面的transition使得在js中改变top值时能够有动画效果!

有了上面的布局方式和API解读,其实js实现就非常简单了 —— 根据上面分析的按部就班来就行:

let box=document.querySelector('.box');
let img=document.querySelector('.img');
let i_before=document.querySelector('i.before');
let i_after=document.querySelector('i.after');
let box_height=box.offsetHeight;
let img_height=img.naturalHeight;
// 只有图片高度大于盒子高度时才有下面的事件
if(img_height>box_height){ 
   
	console.log(1)
	box.classList.add('lang');
	let img_top=0;
	// 鼠标移入下半部分时图片向下滑动
	i_after.addEventListener('mouseenter',(e)=>{ 
   
		console.log(img.offsetTop)
		img.style.marginTop=-(img_height-box_height)+'px';
	},false)
	i_after.addEventListener('mouseout',(e)=>{ 
   
		console.log(img.offsetTop)
		img_top=img.offsetTop;
		img.style.marginTop=img.offsetTop+'px';
	},false)
	// 鼠标移入上半部分时图片向上滑动
	i_before.addEventListener('mouseenter',(e)=>{ 
   
		if(img_top){ 
   
			img.style.marginTop=0;
		}
	},false)
	i_before.addEventListener('mouseout',(e)=>{ 
   
		if(img_top){ 
   
			img.style.marginTop=img.offsetTop+'px';
		}
	},false)
}

至此,效果就全部实现了。
但是如果你仔细看,你会发现由于transition动画效果的时间是固定的,在向上/下滑动过短的情况下再向下/上滑动那么滑动的会特别慢!

当然,我们可以改变策略,让图片的 margin-top 不断--++ 直到临界值,但这样势必会带来巨大的性能开销。

再回到PC端QQ空间 —— 我们发现,它的transition时间竟然是动态变化的:
test_3

这…我猜测可能是设定了一个从上到下固定的时间,然后在JS中按照滑出部分高度(已经滑动的距离)占总高度的比例动态调节时间。。。相关代码笔者正在尝试ing


当然,本文对QQ前端团队对图片的处理来说也许只是沧海一粟,,,更多的还有比如:根据图片整体平均色差调整说明文字的颜色黑/白(canvas-getImageData API)、图片内容的延迟展示、多图上传性能调优(promise API)等等。

那咱就 再见了?

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/169336.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 提高机器学习模型准确率的八大方法

    提高机器学习模型准确率的八大方法

    2021年11月21日
    42
  • idea2022 license server激活【2021最新】

    (idea2022 license server激活)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年3月30日
    1.9K
  • 物联网用什么系统(物联网技术)

    前言  操作系统是物联网时代的战略制高点,今天PC和手机时代的操作系统霸主未必能在物联网时代延续霸业。操作系统产业的规律是,当垄断已经形成,后来者就很难颠覆,只有等待下一次产业浪潮。如今,一个全新的、充满想象空间的操作系统市场机会正在开启。  如此关键的产业环节必然是兵家必争之地。ARM、谷歌、微软、华为、阿里、海尔等国内外著名的IT企业纷纷推出物联网操作系统,整个产业呈现出群雄逐鹿的壮

    2022年4月13日
    218
  • 3nf和bcnf分解_如何分解成3nf

    3nf和bcnf分解_如何分解成3nf1.3NF分解先求出正则覆盖Fc对于Fc里面的所有函数依赖a->b,均转化为Ri=ab对于所有的模式Ri如果包含候选码,进行第4如果都不包含候选码,将任意一个候选码添加到模式Ri里面如果一个模式被另一个模式包含,则去掉此被包含的模式。例子:…

    2025年7月8日
    2
  • 损失函数与代价函数区别

    损失函数与代价函数区别各种损失函数的优缺点详解损失函数或者代价函数的目的是:衡量模型的预测能力的好坏。损失函数(Lossfunction):是定义在单个训练样本上的,也就是就算一个样本的误差,比如我们想要分类,就是预测的类别和实际类别的区别,是一个样本的哦,用L表示。代价函数(Costfunction):是定义在整个训练集上面的,也就是所有样本的误差的总和的平均,也就是损失函数的总和的平均,有没有这个平…

    2022年5月12日
    62
  • linux挂马检测,检测网站挂马程序(Python)

    linux挂马检测,检测网站挂马程序(Python)系统管理员通常从svn/git中检索代码,部署站点后通常首先会生成该站点所有文件的MD5值,如果上线后网站页面内容被篡改(如挂马)等,可以比对之前生成MD5值快速查找去那些文件被更改,为了使系统管理员第一时间发现,可结合crontab或nagios等工具。程序测试如下:#pythoncheck_change.pyUsage:pythoncheck_change.pyupdate/hom…

    2022年9月30日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号