layui中tips的高级使用及如何正确获取div距离页面顶部的距离

创作场景

   公司近期有个需求是点击一个按钮后弹出一个气泡,里面需要根据页面上的条件动态展示一些数据,并且气泡中可以进行搜索及选择需要数据的功能,因为公司使用的是layui框架,所以这里采用layui的tips弹出层解决。

   在使用过程中因为气泡中的内容是动态渲染的,且渲染完成后还可以再气泡中选择条件重新请求数据并渲染tip中的内容,所以tip的位置是需要动态变化的,而且ui必须根据设计师的要求来,这就导致tip自带的属性area: 'auto'不能完全满足需求,还是需要我们根据程序动态判断,这里简单写一个例子说明一下在此场景如果正确使用tips。

tips的简单使用介绍

layer.tips(
	 // 渲染的dom元素,可以是字符串文本,也可以是dom标签,例如‘<h1>Hello World</h1>’
	 content, 	
	 // 吸附的元素,也就是你需要在哪个元素的周围展示气泡,用jQuery获取即可
	 // 除了直接传元素外,也可以指定选择器,id或者class等
	 elem,  
	 // 配置选项,类型为对象,可传入多个属性
	 options,
);

例如

var buttonDefaultDom = $("#buttonDefault");
layer.tips(
	  // 展示的内容
      '<h1 style="color: black">Hello World</h1>', 
      // 吸附的元素
      buttonDefaultDom, 
      // 配置
      {
        tips: [3, '#ffffff'],	// 3表示吸附在下方(1234分别对应上右下左),以及后面的tips背景颜色
        area: 'auto',	// tips宽高,这里设置为自动,也可自己设置为固定值
        time: 0,	// tips默认3秒后关闭,设置0将不会自动关闭
        id: 'buttonDefaultTip'	// 唯一标识
      }
    )
  })

展示效果
在这里插入图片描述
提示
   官网给的介绍比较简单,导致大家可能会认为tips只能传入一些文字提示,其实tips作为弹出层的一员,其中的大部分属性都可以设置,其中的option属性就是为了设置关于大小,弹出时间等设置的,和page层的设置大差不差,只是有一些方法无法作用于tips而已。

高级使用

一、不自动关闭,点击tips外关闭气泡

   上面的例子已经使用time: 0属性设置了tips不会自动关闭,如何实现点击tips外关闭气泡,如下:

  // 点击tips外关闭tips
  $(window).bind('click', function (event) {
    if (!(event.target.id.indexOf("buttonDefault") > -1
       || event.target.id.indexOf("#buttonDefaultTip") > -1
       || $(event.target).parents("#buttonDefaultTip").length > 0)) {
      layer.close(buttonDefaultTipIndex)
    }
  })

   这里给window绑定一个点击事件,包含三个判断:

  1. 当点击的对象id是按钮,也就是上面的默认按钮(id为buttonDefault)则不关闭tips
  2. 当点击的对象是tips本身(id为buttonDefaultTip)也不会关闭tips
  3. 当点击的是tips中的子级对象,这里就要找点击对象的父级,有则不关闭(很多人常常忘了这一点)

   layer.close(buttonDefaultTipIndex)是关闭指定下标的弹窗,原理就是layui在每次打开一个弹出层都会赋值一个唯一的id和下标,我们只需要把这个下标存起来,之后根据下标关闭即可。
在这里插入图片描述
   到这儿别以为就没什么问题了,有个bug是如果连续点击按钮就会无法关闭tips,这回事因为你每次点击就会重新走一次打开tips的方法,但是layui不会渲染生成新的tips,只是会给你返回一个新的index,这就导致你关闭的不是最开始打开的哪个tips。
在这里插入图片描述
   可以看到确实如此,这里对打开tips和关闭tips的方法进行优化,如下:

var buttonDefaultTipIndex = -1;
var buttonDefaultDom = $("#buttonDefault");

!function () {
  buttonDefaultDom.bind('click', function () {
    if (buttonDefaultTipIndex < 0 ) {
      buttonDefaultTipIndex = layer.tips(
        '<h1 style="color: black">Hello World</h1>', buttonDefaultDom, {
          tips: [3, '#ffffff'],
          area: 'auto',
          time: 0,
          id: 'buttonDefaultTip'
        }
      ) 
    }
    console.log("buttonDefaultTipIndex:>", buttonDefaultTipIndex)
  })
  // 点击tips外关闭tips
  $(window).bind('click', function (event) {
    if (!(event.target.id.indexOf("buttonDefault") > -1
       || event.target.id.indexOf("#buttonDefaultTip") > -1
       || $(event.target).parents("#buttonDefaultTip").length > 0)) {
      layer.close(buttonDefaultTipIndex);
      buttonDefaultTipIndex = -1;
    }
  })
}()

   在打开tips时判断index值,如果大于0则表示已经打开了,而关闭时将index赋值为-1即可。

设置最小和最大宽度高度

   上面说过设计师是规定了tips的样式的,所以这里要设置一下tips宽高的阈值(因为实际tips中的值是根据接口中的数据动态渲染的,所以宽高会动态变化,不设置阈值会超出设计图的样式)。

最大宽高设置:
   layui提供了最大宽高的属性,即maxHeightmaxWidth,这里要注意:只有在area值为auto时生效,这也是为什么最开始设置area为auto的初衷。

<style>
    #buttonDefaultTip {
      overflow-y: auto;
    }
</style>
  buttonDefaultDom.bind('click', function () {
    if (buttonDefaultTipIndex < 0 ) {
      buttonDefaultTipIndex = layer.tips(
        buttonDefaultContent, buttonDefaultDom, {
          tips: [3, '#ffffff'],
          area: 'auto',
          time: 0,
          id: 'buttonDefaultTip',
          // 最大高度和宽度设置
          maxHeight: 200,
          maxWidth: 300,
        }
      )
    }
  })

效果图
在这里插入图片描述
   最大高度和宽度就已经实现了,假如现在接口请求没有收到数据,tips得展示一个没有数据的提示,这时候就需要用到最小宽高了(个人认为用最小宽高实现比较好,也可以直接设置无数据提示的样式,但是扩展性相对不好,如果后期需要改为展示一个图片或者其它改动的相对比较大)。
在这里插入图片描述
这是没有设置最小宽高的样子。
在这里插入图片描述
这是加了最小宽高的样子,看起来顺眼多了。

动态设置tips的位置

   为什么要说到动态设置tips的位置,其实layui是自带了这个功能,但是放在特定场景就不适用了,例如:设计师要求点击按钮之后就要弹出气泡,首先在气泡中展示加载数据的loading,待数据加载完成后展示内容,这就导致layui的自动位置定位失效了,因为layui的自动定位一定是你在打开之前就要把渲染的content传给layui,之后它才会自动计算位置,那么上面的需求实际操作肯定是在展示后才给tips中渲染数据(说起来这个设计也是挺烦人的),这就导致了这部分计算需要我们自己实现。

   在开始之前大家首先要了解一个知识点,layui的tips位置是基于整个窗口定位的,不像我们之前写的,父元素给relative,子元素给absolute,子元素根据父元素定位,这里的父元素是window窗口,所以实现起来较为麻烦。(提一嘴:layui这里当窗口大小变化后tips时不会跟着移动的,一次性就把位置定位死了,相对elementUI效果不是很好,elementUI是可以根据窗口大小变化,气泡的位置也是会变化的。

   OK,这里需要了解几个知识点:

  console.log("window窗口高度:", $(window).height(), "window窗口宽度:",$(window).width())
  console.log("默认按钮距离页面的宽高", $("#buttonDefault").offset())
  console.log("默认按钮距离父元素的宽高", $("#buttonDefault").position())
  console.log("默认按的高度,包含padding", $("#buttonDefault").outerHeight())

  // 给tips动态设置top值,left值同理
  $("#buttonDefaultTip").parent().css('top', '200px').css('left', '200px')

   因为坐的我腰疼,所以这里挑重点和大家说一下,干货干货一定要注意哦:

  1. offset方法是获取元素距离你页面的高度和宽度,position方法是获取元素距离父元素的宽高,一般是不使用position的,都是基于页面算的。
  2. 如何知道渲染的tips展示不全面,先获取页面的高度和宽度,在获取tips距离页面的宽高和本身的宽高,用window的宽高减去tips距离window顶部的高度和tips本身进行比较,如果大于tips本身的高度,则表示可以展示全面,小于则不够。
    window高度-tips距离页面toptips本身高度比较
  3. 在知道展示不全面后,可以用tips高度和tips距离页面顶部的top值比较,如果tips高度小则可以定位到按钮的上方,具体top值设置多少就是你的tips距离页面top减去你的按钮高度(这是最标准的top值,但是一般会多减去10-20px,留一点空隙),同样的道理也可以放在右边。

上面的三步骤其实已经满足大多数需求了,但是有一种情况比较恶心,就是我遇到的这种,我的tips是展示在一个弹窗中的,相当于多层弹窗,这时候用offset获取距离页面高度不对劲,为啥,因为你的页面可能已经滚动了,已经有scrollTop值了,一定要注意,减去scrollTop值才是你弹窗中距离页面高度的top值。也就是:

$(“#buttonDefault”).offset() - window.scrollTop()

这个东西很坑,也是我为啥要写这个博客的原因,直接就一整个离谱。
好了,老衲腰疼的受不了了,有些东西没有体现,如果有疑问评论或者私信我。

  • 32
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值