代码要写成别人看不懂的样子(十八)

Python:保存图片到指定目录下的文件中(若不存在则创建) 将获取到的人脸识别的图像保存在指定的目录中,如果没有则创建目录 阅读详情

本篇文章参考书籍《JavaScript设计模式》–张容铭

前言

  今年3月份的时候,写过几篇文章,,介绍了一下浏览器的回流,重绘,以及对应的解决办法分别是节流和防抖。当时刚开始写博客,还很青涩,各位要是不嫌弃,可以简单扫一眼,链接在下面。

  今天我们一块研究的设计模式,就跟节流有关,这个东西平时不常用,但是一旦遇到相关问题后,不用还不行。大家也看到了,关于节流的文章,算上正在写的这篇,一共有4篇博客了,为啥我会对这个出现频率并不高的词这么关注?这说起来还有点历史。

  想当年我还是个小萌新的时候,遇到一个需求,点击一个区域,调用一个接口,然后把查询的数据更新到页面上。这个普通不能再普通的需求,开启了我新世界的大门。

  正常来讲上面的需求没什么特别的,但是嘞,转测试之后,测试同事在疯狂的点击那个请求区域,导致请求快速送,虽然是同一个请求,但是返回时间有快有慢,这就有可能导致,先发送的请求后返回过来,那数据显示就存在问题了。

  对于当时的我,虽然有问题,但是还在可控范围之内,我给它加个蒙层不就行了,上一个接口不返回信息,就不能调用下一次。

  这样改问题是没了,但是交互体验不太好,而且后面增加了一个双击功能,这个方案就彻底歇菜了。有没有什么方法既能满足测试,又能满足需求呢?研究了好久,终于让我找到了节流。

节流模式

  对重复的业务逻辑进行节流控制,执行最后一次操作并取消其他操作,以提高性能。

  平时业务中比较常见的节流情况,就是在 scroll 事件里面添加动画了,比如我们浏览一面时旁边会有一个回滚到顶部的按钮,由于 scroll 事件会触发多次,那添加的动画也就会被执行多次。为了解决这一个问题,我们先要实现一个节流器。

//节流器
var throttle = function() {
	//获取第一个参数
	var isClear = arguments[0], fn;
	//如果第一个参数是 boolean 类型,那么第一个参数表示是否清除计时器
	if(typeof isClear === 'boolean') {
		//第二个参数则为函数
		fn = arguments[1];
		//函数的计时器句柄存在,清除计时器
		fn.__throttleID && clearTimeout(fn.__throttleID);
	//通过计时器延迟函数的执行
	} else {
		//第一个参数为函数
		fn = isClear;
		//第二个参数为函数执行时的参数
		param = arguments[1];
		//对执行时的参数适配默认值,这里用以前学习的 extend 方法
		var p = extend({
			context: null,  //执行函数执行时的作用域
			args: [],       //执行函数执行时的相关参数
			time: 300       //执行函数延迟执行的时间
		}, param);
		//清除执行函数计时器句柄
		arguments.callee(true, fn);
		//为函数绑定计时器句柄,延迟执行函数
		fn.__throttleID = setTimeout(function() {
			//执行函数
			fn.apply(p.context, p.args)
		}, p.time)
	}
}

  对于返回顶部按钮,我们可以进行如下优化:

//首先引入jquery.js 与 easing.js 方便返回顶部动画实现
//返回顶部按钮动画
function moveScroll() {
	var top = $(document).scrollTop();
	$('#back').animate({top: top + 300}, 400, 'easeOutCubic')
}
//监听页面滚动事件
$(window).on('scroll', function() {
	//节流执行返回顶部按钮动画
	throttle(moveScroll);
})

图片延迟加载

  节流模式还有一个常见的重要应用,就是图片的延迟加载,我们在网上浏览图片的时候,都是加载当前页的图片,当往下滚动的时候,再加载新的图片,还有就是当用户把滑动条直接拉到底部的时候,由于上面的图片会优先加载,造成底部图片加载推迟,这种体验也不是很好,此时我们就可以使用节流模式来处理这些逻辑,使可视范围内的图片优先加载。

/**
* 截留延迟加载图片类
* param id 延迟加载图片的容器 id
* 注:图片格式如下<img src="img/loading.gif" alt="" data-src="img/i.jpg">
*/
function LazyLoad(id) {
	//获取需要延迟加载图片的容器
	this.container = document.getElementById(id);
	//缓存图片
	this.imgs = this.getImgs();
	//执行逻辑
	this.init();
}
//节流延迟加载图片类原型方法
LazyLoad.prototype = {
	//起始执行逻辑
	init: function() {},
	//获取延迟加载图片
	getImgs: function() {},
	//加载图片
	update: function() {},
	//判断图片是否在可视范围内
	shouldShow: function() {},
	//获取元素在页面中的纵坐标位置
	pageY: function(element) {},
	//绑定事件(简化版)
	on: function(element, type, fn) {},
	//为窗口绑定 resize 事件与 scroll 事件
	bindEvent: function() {}
}

  对于节流延迟加载图片类的原型方法 init 应该做两件事,初始化图片加载(即执行 update 方法)和为窗口绑定事件。

//起始执行逻辑
init: function() {
	//加载当前视图图片
	this.update();
	//绑定事件
	this.bindEvent();
}

  对于获取容器内图片的 getImages 方法需要注意,为了方便操作获取的图片元素集合(类数组),需要将其转化成数组,由于在 IE中对获取到的元素集合直接执行数组方法 slice 会报错,故通过遍历每一个元素,并将其加入新数组中返回,来显性创建数组。

//获取延迟加载图片
getImage: function() {
	//新数组容器
	var arr = [];
	//获取图片
	var imgs = this.container.getElementsByTagName('img');
	//将获取的图片转化为数组(IE下通过 Array.prototype.slice会报错)
	for(var i = 0, len = imgs.length; i < len; i++) {
		arr.push(imgs[i])
	}
	return arr;
}

  对于加载图片方法 update,需要遍历每一个图片元素,如果处在可视区域内则加载并将其在图片缓存中清除。

//加载图片
update: function() {
	//如果图片都加载完成 返回
	if(!this.imgs.length) {
		return;
	}
	//获取图片长度
	var i = this.imgs.length;
	//遍历图片
	for(--i; i >= 0; i--) {
		//如果图片在可视范围内
		if(this.shouldShow(i)) {
			//加载图片
			this.imgs[i].src = this.imgs[i].getAttribute('data-src');
			//清除缓存中的此图片
			this.imgs.splice(i, 1);
		}
	}
}

  对于判断图片是否在可视范围内的方法,是判断图片的上下边位置是否符合下列条件(由于页面左边关系,对于 y 坐标,由上至下依次增大,对于 x 坐标,由左至右依次增大):图片底部高度大于可视视图顶部高度并且图片底部高度小于可视视图底部高度。

//判断图片是否在可视范围内
shouldShow: function(i) {
	//获取当前图片
	var img = this.imgs[i],
		//可视范围内顶部高度(页面滚动条 top 值)
		scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
		//可视范围内底部高度
		scrollBottom = scrollTop + document.documentElement.clientHeight,
		//图片的顶部位置
		imgTop = this.pageY(img),
		//图片的底部位置
		imgBottom = imgTop + img.offsetHeight;
	//判断图片是否在可视范围内,图片底部高度大于可视视图顶部高度并且图片底部高度
	//小于可视视图底部高度,或者图片顶部高度大于可视视图顶部高度并且图片顶部高度
	//小于可视视图底部高度
	if(imgBottom > scrollTop && imgBottom < scrollBottom || (imgTop > scrollTop && imgTop < scrollBottom)) return true;
	//不满足上面条件则返回 false
	return false;
}

  对于获取图片元素纵坐标方法 pageY 这是通过元素一级一级遍历其父元素,并累加每一级元素 offsetTop 值获取的。

//获取元素页面中的纵坐标位置
pageY: function() {
	//如果元素有父元素
	if(element.offsetParent) {
		//返回元素 + 父元素高度
		return element.offsetTop + this.pageY(element.offsetParent);
	} else {
		//否则返回元素高度
		return element.offsetTop;
	}
}

  为了简化代码,我们简单实现一下 on 绑定事件方法。

//绑定事件
on: function(element, type, fn) {
	if(element.addEventListener) {
		addEventListener(type, fn, false);
	} else {
		element.attachEvent('on', type, fn, false);
	}
}

  最后一个方法,绑定事件则是对页面的 scroll 与 resize 事件的监听,为检测每一次交互中事件的最后一次执行,故需要对事件的回调函数做节流处理。

//为窗口绑定 resize 事件与 scroll 事件
bindEvent: function() {
	var that = this;
	this.on(window, 'resize', function() {
		//节流处理更新图片逻辑
		throttle(that.update, {context: that});
	});
	this.on(window, 'scroll', function() {
		//节流处理更新图片逻辑
		throttle(that.update, {context: that});
	})
}

  大功告成,接下来我们只需要实例化类就可以了。

//延迟加载 container 容器内的图片
new LazyLoad('container');

  




SwiftUI - (十八)组合视图 SwiftUI 的核心原则之一是组合,这意味着它被设计为允许我们创建许多小视图,然后将它们组合在一起以创建更大的东西。这使我们能够在大规模上重用视图,从而减少我们的工作量。更好的是,组合小子视图几乎不会带来运行时开销,因此我们可以自由使用它们。关键是从小开始,逐步构建。HStack {我们还可以创建一个更大的视图来包含UserDetails以及用户头像视图。HStack {仅显示他们的头像仅显示他们的电子邮件地址仅显示他们的职位详情一次性显示所有信息。 阅读详情

相关推荐

手把手教你用XC7A35T FPGA搭建低成本机器视觉系统(含开发板选型指南)

本文详细介绍了如何利用AMD(原Xilinx)Artix-7系列中的XC7A35T FPGA芯片,搭建一套低成本的机器视觉系统。内容涵盖从芯片选型深度剖析、开发板(如黑金AX7035B)对比指南,到使用Vivado创建工程、编写图像处理模块(如RGB转灰度),以及资源优化和与上位机(如OpenCV)协同工作的完整流程,旨在为开发者提供一套可实践的高性价比硬件加速视觉解决方案。

beta5的博客 353

python保存图片到指定路径_python 抓取页面数据,并保存图片文本到指定目录文件夹...

这个爬虫主要利用scrapy+beautifulsoup完成,其中图片保存碰到了一个大坑,花了一天的时间才解决。大坑就是:在抓取文章页指定区域所有图片的时候,刚好那块区域的图片所有页面都一样,导致图片下载完第一个页面的时候,其他页面就不会再去下载了。所以其他文件夹里没有图片数据。一开始以为代码写错了,最后换了个地址才找到原因,ImagesPipeline实现图片下载中 同样的图是不会重复下载的!成...

weixin_39648824的博客 2824

PPO实战:如何用强化学习让小车爬上MountainCarContinuous-v0山顶(附完整代码)

本文提供了使用PPO算法解决MountainCarContinuous-v0环境的完整实战教程。针对该环境的连续动作空间和稀疏奖励挑战,文章详细解析了PPO智能体的网络架构、状态归一化、GAE优势估计等核心实现,并附带了可直接运行的PyTorch代码。同时分享了关键的调参技巧和实战避坑指南,帮助读者高效训练智能体完成小车爬坡任务。

linux的博客 968

python可以指定图片存储路径吗_python将处理好的图像保存到指定目录下的方法

原始图像绝对路径的图像名存储在一个txt文件中,下面的程序实现的功能是按照txt文件的顺序,依次将图片读取然后进行处理,最后将处理之后的图像保存在指定的路径下:# Read in the image to be detected# 原始图像均保存在binaries.txt文件中,将包含绝对目录的图像名提取出来并写到txt文件的程序见上一篇博客f = open("/home/shenruixue/i...

weixin_33502035的博客 2843

UE5深度图与Mask图渲染实战:从基础到高级应用

本文详细解析了在UE5中渲染深度图与Mask图的完整实战流程。从启用电影渲染队列、配置自定义深度模板通道等前期准备,到构建即用型深度图材质网络与精准物体Mask生成,并深入探讨了二者结合在NPR风格化、程序化雾气及AI工作流(如ComfyUI)中的高级应用,为影视、游戏后期与AI创作提供了高效的解决方案。

weixin_29001419的博客 349

飞牛fnNAS个人小账本导入微信账单

本文介绍了将微信支付账单导入ezBookkeeping个人记账系统的详细方法。首先通过微信申请导出账单文件,接收后需进行Excel预处理:删除前导行、添加账户和分类列、整理金额格式等。在ezBookkeeping中需预先设置"微信"分类和账户。导入时需注意列映射关系,包括交易时间、账户名称等关键字段的对应设置。文章还提到处理交易标签、格式转换等细节问题,并建议避免使用"修改余额"功能。该方法同样适用于支付宝账单导入,解决了直接导入可能出现的格式不兼容问题。

dgnankai的专栏 482

chatgpt赋能python:Python图片保存至指定路径

在本篇文章中,我们介绍了如何使用 Python 将图片保存至指定路径。通过使用 Pillow 库中提供的和方法,我们可以快速、方便地实现图片保存功能。同时,在有需要的情况下,我们还可以使用 Pillow 库中提供的其他方法,对图片进行一系列的操作。在实际的项目中,图片的处理和保存比较常见,掌握这个技能会使得我们的编程工作更加高效。同时,我们还可以通过将 Python 图片处理程序封装成 API 接口,将其应用到 Web 开发等场景中去。本文由chatgpt生成,文章没有在chatgpt。

findyi123的博客 1543

百万 Token 压力实测:1M Context 的真实能力边界在哪里?

本文揭示了长上下文模型的性能衰减规律:1M上下文存在"容量曲线"与"质量曲线"的分歧,512K是可靠拐点。通过MRCR测试发现,不同任务类型衰减差异显著——检索任务在512K后性能下降30.6%,而生成任务仅下降5%。研究提出三阶段补偿策略:三明治注入(首尾指令强化)、语义面包屑(位置标记)、引用检查(强制溯源),可将512K-1M区间的可用性提升20%。工程实践表明,中段区域(30-70%位置)是注意力薄弱区,需要特殊处理。最终建议:关键检索任务控制在512K内,关联推理任务可扩展至

liuzhupeng的专栏 338

【python】python实现根据txt文档中的内容,选择指定的图片并复制到新的文件夹中

代码功能: 读取txt中的每一行,然后匹配某个文件夹中的图片名称,匹配成功的话将该图片复制到一个新的文件夹中。 文件格式如下 ----img_res --000001.jpg --000002.jpg --000003.jpg ... --000018.jpg ----main --test.txt --000002 --000004

学无止境、积少成多、厚积薄发 4353

mabl:AI原生测试自动化平台的基础使用

mabl是一个基于人工智能和机器学习的云原生测试自动化平台。它通过使用先进的技术,如机器学习,自动创建和执行测试,自动分析测试结果,并根据需求的变化自动适配和维护测试。这样的自动化过程极大地提高了软件测试的效率和准确性。mabl的口号是 “You write code, mabl tests”,意味着开发者只需关注编写代码,而测试工作则可以交给mabl来完成。mabl的平台支持多种测试类型,包括 Web、App、Api、可访问性和性能测试,使得团队能够更快速、更有信心地发布软件。

blues_C的博客 3657

手把手教你学SINULINK-- --Linear Transformer 模块

模块是 Simulink 中用于模拟理想变压器行为的重要工具。通过本文的详细介绍,希望你能更好地理解和使用模块。

MHD0815的博客 2613

代码要写成别人看不懂的样子(二十八完结篇)

本篇文章参考书籍《JavaScript设计模式》–张容铭 文章目录前言MVVM 模式视图模型层总个小结 前言   各位,本节是看不懂系列的最后一篇文章了,非常感谢张容铭老师的 《JavaScript设计模式》 这本书我从头到尾完整的读了三遍,对我个人的提升真的非常巨大,也推荐各位有机会也读一读。   本节要介绍的设计模式,也是书中的最后一章,是目前公认的最优框架模式, MVVM ,从名字就可以看出, MVVM 也是从 MVC 模式演变过来的,准确的说是从 MVP 模式演变的。  

不见浅诗的博客 418

海洋浮游生物识海洋浮游生物识别系统:基于YOLOv10的显微图像自动检测与UI别系统:基于海洋浮游生物识别系统:基于YOLOv10的显微图像自动检测与UI展示YOLOv10的显微图像自动检测与UI展示

本文介绍了如何利用YOLOv10模型进行海洋浮游生物的自动识别,旨在提高传统显微镜观测的效率与准确性。研究背景强调了浮游生物在海洋生态系统中的重要性,并指出传统方法的局限性。数据集选用WHOI-Plankton,包含70多种浮游生物的20000多张带标签图像。文章详细描述了YOLOv10模型的安装、数据集配置、训练与测试步骤,并提供了基于PyQt5的图形化检测界面代码。结果显示,模型在精度、召回率和mAP@0.5等指标上表现优异,推理速度达到约30 FPS。最后,文章提出了部署建议和未来优化方向,如集成摄像

YOLO 375

你见过最烂的代码长什么样子?

有个项目只是要实现一个简单的用户登录功能,结果搞出了一堆接口、抽象类、设计模式,各种继承、多态用得飞起,最后连程序员自己都搞不清哪个类是干嘛的了。缩进那叫一个随心所欲,一会儿四个空格,一会儿两个空格,一会儿又用个制表符,就像在跳一场没有节奏的舞蹈。还有的代码,大括号一会儿在这行结尾,一会儿又另起一行,就像在跟你玩捉迷藏,让你根本搞不清代码块的边界在哪里。你以为你在看代码,其实你是在走迷宫,而且这个迷宫还是程序员边写边建的,说不定走着走着就把自己绕进去出不来了。这种万能名字一用就是一大串,我就想问,你到底。

qq_40858969的博客 456

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

一个混迹在十八线小城的程序员

不是每座城市都是北上广,不是每个互联网公司都是大厂,不是每个程序员都月入10k起。我叫王辛,是一名苦苦挣扎在一座十八线小城的程序员。你们切莫因为我不在北上广等一线城市,也...

田维常 400

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

傻嘎,IOC原来是这样子的

昨天有网友Call我留言,说他写了个DI架构,让我有时间看看,于是我就上去看了: 文章地址: http://www.cnblogs.com/lenic/archive/2013/06/04/3117893.html 发现是E文的,于是回复: 路过秋天 22:32:43  怎么还写E文的 NOoK 22:33:03  直接在 CodePlex 上写的介绍 NOoK 22:3

路过秋天 - 理想很美好,现实很残酷,坚持在路上,只因初心仍存 1231

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

燕十八的php教材学完能找工作吗,燕十八的布尔教育怎么样? - php完全自学手册...

Route::get('jie' , 'ProController@jie');Route::post('jie' , 'ProController@jiePost'); //拼音+英文的完美结合public function jie() {return view('woyaojiekuan');}public function jiePost(Request $request) {//$rs =...

weixin_33539912的博客 385

(二十八)代码那些事儿

这个是讲软件研发过程管理的系列,目标人群是那些身处研发管理位置或想成为研发管理的人。所以我不希望这个系列中出现代码,也不希望出现和某种技术密切相关的代码技巧。 但是没有办法,软件开发过程...

cln14219的博客 135

一个混迹在十八线小城的程序员 | 程序员有话说

不是每座城市都是北上广,不是每个互联网公司都是大厂,不是每个程序员都月入10k起。 我叫王辛,是一名苦苦挣扎在一座十八线小城的程序员。 你们切莫因为我不在北上广等一线城市,也不在BAT等名企而判定我为半路出家的“野生”程序员,其实我和你们一样,也是根正苗红的科班出身,只不过我没有你们中很多人的名校背景,跟你们一比,我的学历有些拿不出手,我15年毕业于宿州学院——一个名不见经传的三本...

程序人生的博客 7080

我用了整整十八年,才找到自己是谁。

一位农村出身的创业者,用了十八年才找到真正的自己。从小按部就班,在大学误入传销,毕业后为了“出人头地”而创业、写代码,却在一次次失败中发现自己活成了别人期待的“机器人”。直到AI能写代码的那一天,他赖以为生的技能崩塌,才被迫停下脚步,开始向内寻找。

2504_93392792的博客 543

《高效编程十八式》(9/13)代码编辑

代码编辑 王伟冰     下面列举一些代码编辑器常用的功能,如果你正在使用的代码编辑器有此功能,请充分利用,这样可以提高写代码的效率。没有的话就算了。         添加:     自动补全:键入单词的前几个字母,自动插入整个单词。     代码模板:插入一些常用的代码结构或程序框架。       方便查看:     自动格式化:不用你自己敲Tab缩进代码,自动缩进。

n567656756765676567的专栏 520

降Compose十八掌之『亢龙有悔』

介绍Google推出的新一代的声明式的Android UI框架Jetpack Compose,包括基本使用方法和如何快速上手。

稀有猿诉 1098
上一篇: 代码要写成别人看不懂的样子(十七)
下一篇: 代码要写成别人看不懂的样子(十九)
不见浅诗~
博客等级 码龄7年 506粉丝 129原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值