需求:实现一个图片懒加载指令 , 只加载浏览器可见区域的图片 。
思路:
- 图片懒加载的原理主要是判断当前图片是否到了可视区域这一核心逻辑实现的
- 拿到所有的图片 Dom , 遍历每个图片判断当前图片是否到了可视区范围内
- 如果到了就设置图片的 src 属性 , 否则显示默认图片
下面封装一个懒加载指令兼容两种方法 , 判断浏览器是否支持 IntersectionObserver API , 如果支持就使用 IntersectionObserver 实现懒加载 , 否则则使用 srcoll 事件监听 + 节流的方法实现 。
const LazyLoad = {// install方法install(Vue, options) {const defaultSrc = https://www.isolves.com/it/cxkf/qd/2022-02-25/options.defaultVue.directive('lazy', {bind(el, binding) {LazyLoad.init(el, binding.value, defaultSrc)},inserted(el) {if (IntersectionObserver) {LazyLoad.observe(el)} else {LazyLoad.listenerScroll(el)}},})},// 初始化init(el, val, def) {el.setAttribute('data-src', val)el.setAttribute('src', def)},// 利用IntersectionObserver监听elobserve(el) {var io = new IntersectionObserver((entries) => {const realSrc = el.dataset.srcif (entries[0].isIntersecting) {if (realSrc) {el.src = realSrcel.removeAttribute('data-src')}}})io.observe(el)},// 监听scroll事件listenerScroll(el) {const handler = LazyLoad.throttle(LazyLoad.load, 300)LazyLoad.load(el)window.addEventListener('scroll', () => {handler(el)})},// 加载真实图片load(el) {const windowHeight = document.documentElement.clientHeightconst elTop = el.getBoundingClientRect().topconst elBtm = el.getBoundingClientRect().bottomconst realSrc = el.dataset.srcif (elTop - windowHeight < 0 && elBtm > 0) {if (realSrc) {el.src = realSrcel.removeAttribute('data-src')}}},// 节流throttle(fn, delay) {let timerlet prevTimereturn function (...args) {const currTime = Date.now()const context = thisif (!prevTime) prevTime = currTimeclearTimeout(timer)if (currTime - prevTime > delay) {prevTime = currTimefn.apply(context, args)clearTimeout(timer)return}timer = setTimeout(function () {prevTime = Date.now()timer = nullfn.apply(context, args)}, delay)}},} export default LazyLoad复制代码使用 , 将组件内 标签的 src 换成 v-LazyLoad<img v-LazyLoad="xxx.jpg" />复制代码v-permission背景:在一些后台管理系统 , 我们可能需要根据用户角色进行一些操作权限的判断 , 很多时候我们都是粗暴地给一个元素添加 v-if / v-show 来进行显示隐藏 , 但如果判断条件繁琐且多个地方需要判断 , 这种方式的代码不仅不优雅而且冗余 。针对这种情况 , 我们可以通过全局自定义指令来处理 。需求:自定义一个权限指令 , 对需要权限判断的 Dom 进行显示隐藏 。
思路:
- 自定义一个权限数组
- 判断用户的权限是否在这个数组内 , 如果是则显示 , 否则则移除 Dom
function checkArray(key) {let arr = ['1', '2', '3', '4']let index = arr.indexOf(key)if (index > -1) {return true // 有权限} else {return false // 无权限}} const permission = {inserted: function (el, binding) {let permission = binding.value // 获取到 v-permission的值if (permission) {let hasPermission = checkArray(permission)if (!hasPermission) {// 没有权限 移除Dom元素el.parentNode && el.parentNode.removeChild(el)}}},} export default permission复制代码使用:给 v-permission 赋值判断即可<div class="btns"><!-- 显示 --><button v-permission="'1'">权限按钮1</button><!-- 不显示 --><button v-permission="'10'">权限按钮2</button></div>复制代码vue-waterMarker需求:给整个页面添加背景水印思路:
- 使用 canvas 特性生成 base64 格式的图片文件 , 设置其字体大小 , 颜色等 。
- 将其设置为背景图片 , 从而实现页面或组件水印效果
function addWaterMarker(str, parentNode, font, textColor) {// 水印文字 , 父元素 , 字体 , 文字颜色var can = document.createElement('canvas')parentNode.appendChild(can)can.width = 200can.height = 150can.style.display = 'none'var cans = can.getContext('2d')cans.rotate((-20 * Math.PI) / 180)cans.font = font || '16px Microsoft JhengHei'cans.fillStyle = textColor || 'rgba(180, 180, 180, 0.3)'cans.textAlign = 'left'cans.textBaseline = 'Middle'cans.fillText(str, can.width / 10, can.height / 2)parentNode.style.backgroundImage = 'url(' + can.toDataURL('image/png') + ')'} const waterMarker = {bind: function (el, binding) {addWaterMarker(binding.value.text, el, binding.value.font, binding.value.textColor)},} export default waterMarker复制代码
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 文职|军队文职招聘遇“滑铁卢”,高薪铁饭碗为何不吃香?原因过于现实
- 怀孕时喝了红茶怎么办,红豆薏米芡实茶的功效与作用孕妇可以喝吗
- 怀孕后期少量喝红茶吗,红豆薏米芡实茶的功效与作用孕妇可以喝吗
- 抽烟后抱新生儿的危害
- 基于Kali的一次DDos攻击实践
- 自动驾驶的摄像头是如何实现测距的
- 18个NAS使用妙招丨系统、域名、配件,设置好起飞
- pyecharts绘制地图实战案例
- 为什么Java中的const关键字没有实现?
- 翡翠|一刀穷,一刀富,一刀披麻布,两个实例告诉你,赌石到底有多疯狂
