在开发地图相关的应用时,基本都会有按钮要浮在地图之上这种情况,按钮可能有一个,也可能有多个
那如何让元素方便的定位且在间隔的地方、空白的地方可以响应地图的拖拽呢?
(图片仅说明需求,并不指代微信小程序可以使用上述写法)
最常用的就是绝对定位,但如果每个元素都去写绝对定位的话,会很麻烦你需要计算下方的元素的 top 值是多少,如果悬浮按钮的个数不确定,个别悬浮按钮还会根据权限显隐,那么这个问题就会更复杂了
又或者如图,要求按钮垂直居中分布,那你计算的 top 值可能就不适用了
(当然如果你能想到 :nth-child()
选择器逐个去写 top 值,代码的通用性也会高一些)
但这些实现方案的维护性总归还是差一些的,后文我将介绍另一种写法,可以很好地适应上述情况
原理
给元素设置 pointer-events: none;
后,鼠标事件将“穿透”该元素并且指定该元素“下面”的任何东西。(ie11 以上支持)
- 设置过
pointer-events: none
后,元素本身以及子元素就无法响应点击事件了
那么我们可以将所有悬浮按钮都放在一个共同父级之下,父元素设置 pointer-events: none;
取消鼠标事件响应,子元素恢复鼠标事件响应,该父级设置好绝对定位,下面的按钮只需要调整间距就行了,不需要逐个设置绝对定位设置上下左右位置
- 想要子元素支持鼠标事件响应,就需要给子元素也设置
pointer-events
属性,属性的值要是非none
,一般设置为auto
,即pointer-events
属性的默认值(其他几个值,很多都是针对 svg 的)
案例
页面结构
<!-- 地图右侧竖向排列的地图控件 -->
<view class="controlsContianerRight">
<view class="controlsItem" bindtap="changeMap">
<image src="../../images/c_tuceng.png"></image>
<view>图层</view>
</view>
<view class="controlsItem" bindtap="clickRegionalSelectionItemOption" data-controls="yes" data-tag-index="{{0}}">
<image src="../../images/c_wucheng.png"></image>
<view>金开区</view>
</view>
</view>
样式代码
.controlsContianerRight {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
/* 设置父级绝对定位 */
position: fixed;
right: 15rpx;
top: 80rpx;
z-index: 8800;
height: calc(100% - 120rpx);
/* 取消父级的鼠标事件响应,让其真的“透明” */
pointer-events: none;
}
.controlsContianerRight .controlsItem {
width: 68rpx;
background-color: #ffffff;
border-radius: 8rpx;
font-size: 11px;
color: #000000;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
/* 恢复悬浮按钮的鼠标事件响应 */
pointer-events: auto;
}
/* 设置悬浮按钮之间的间距 */
.controlsContianerRight .controlsItem:not(:nth-last-child(1)) {
margin-bottom: 20rpx;
}
/* 增大悬浮按钮的可点击面积 */
.controlsContianer .controlsItem::before {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
}
.controlsContianer .controlsItem image {
width: 32rpx;
height: 44rpx;
margin: 6rpx 6rpx;
}