Open vortesnail opened 5 years ago
前言: 这个问题是去一家公司面试的时候,技术经理问到我的,我第一想法是用CSS中的border去画,但是我们现在的要求是在那个三角形区域,才能进行事件的绑定,比如:click事件,那border所用到的transparent仅仅是透明度为0,那个区域还是在的,这就无法完成特定区域的事件绑定。
border
transparent
Html:
<div className="triangle"></div>
Css:
.triangle { width: 0px; height: 0px; border-left: 50px solid yellow; border-right: 50px solid blue; border-top: 50px solid red; border-bottom: 50px solid black; }
现在我们可以看到如下: 我们就选一个指向右边的箭头吧,修改Css样式: Css:
.triangle { width: 0px; height: 0px; border-left: 50px solid yellow; border-right: 50px solid transparent; border-top: 50px solid transparent; border-bottom: 50px solid transparent; }
现在我们得到了想要的三角形(具体形状自行调整border-size就行):
border-size
接下来,我们给这个 div 添加一个 onmouseover 事件:
div
onmouseover
const triangle = document.querySelector('.triangle'); triangle.addEventListener('mouseover', () => { console.log('你碰到我了!'); })
结果我们去测试的时候,不出所料地,透明的部分也会触发事件,如下所示:
那可咋办呢??
这个思路很简单,但是面试官坐在面前的时候,却怎么也想不出来。。
<div class="rectangle-1"></div> <div class="rectangle-2"></div> <div class="rectangle-3"></div>
.reactangle-container { position: relative; } .rectangle-mask1, .rectangle-mask2 { width: 200px; height: 80px; position: absolute; } .rectangle-mask1 { top: 11px; left: -5px; transform: rotate(50deg); background-color: lightblue; z-index: 2; } .rectangle-mask2 { bottom: 11px; left: -5px; transform: rotate(-50deg); background-color: lightgreen; z-index: 2; } .rectangle-tri { width: 100px; height: 100px; background-color: lightcoral; z-index: 1; }
得到如下图: 其中粉红的区域就是我们要的三角形区域,理论上你可以通过两个或许多个矩形构建出你想要的任何三角形!
那这个时候,我们怎么绑定事件到这个三角形上呢? 思路: 给 rectangle-tri 这个矩形绑定事件,也给 rectangle-mask1 和 rectangle-mask2 绑定事件,但是不做操作,这样的话,因为rectangle-tri 在最下面,移动非三角形区域的时候,触发的事件监听是另外两个遮罩矩形的事件。
rectangle-tri
rectangle-mask1
rectangle-mask2
const reactangleContainer = document.querySelector('.reactangle-container'); const rectangleMask1 = reactangleContainer.querySelector('.rectangle-mask1'); const rectangleMask2 = reactangleContainer.querySelector('.rectangle-mask2'); const rectangleTri = reactangleContainer.querySelector('.rectangle-tri'); rectangleTri.addEventListener('mouseover', () => { console.log('你碰到我了!'); }) rectangleMask1.addEventListener('mouseover', () => { // 不做任何行为 }) rectangleMask2.addEventListener('mouseover', () => { // 不做任何行为 })
此时,特定的区域才有事件绑定了:
现在,我们怎么把这两个遮罩矩形去掉呢????设置背景色为白色?那就是自欺欺人了
这里我真的还找不到方法啊,有哪位大佬能来说说吗???
clip-path CSS 属性可以创建一个只有元素的部分区域可以显示的剪切区域。区域内的部分显示,区域外的隐藏。剪切区域是被引用内嵌的URL定义的路径或者外部svg的路径,或者作为一个形状例如circle().。clip-path属性代替了现在已经弃用的剪切 clip属性。
clip-path
上看的引用出自MDN,我们只需要知道,这个属性可以让我们裁剪出想要的形状
基本形状裁剪:
.clip-me { clip-path: inset(); clip-path: circle(); clip-path: ellipse(); clip-path: polygon(); }
其中inset是矩形的剪切,circle是圆形的剪切,ellipse是椭圆的剪切,polygon是多边形的剪切。对于我们想要把矩形剪切成三角形,应该使用polygon这个语法。 Html:
<div class="triangle"></div>
.triangle { width: 100px; height: 100px; background-color: lightcoral; clip-path: polygon(0px 0px, 0px 100px, 100px 50px); }
clip-path: polygon(0px 0px, 0px 100px, 100px 50px); 这句话意思是,根据坐标轴上确定的三个点来进行裁剪:(0px, 0px),(0px 100px),(100px, 50px) ,这三个点构成了一个我们如下三角形:
clip-path: polygon(0px 0px, 0px 100px, 100px 50px);
现在我们可以来试试绑定事件好不好用来:
const tri = document.querySelector('.triangle'); tri.addEventListener('mouseover', () => { console.log("你碰到我了!"); })
以下为测试结果:
我只能说,这个真是太好用了,不过这个属性兼容性会有些不好,酌情使用把!
wonderful!
整挺好👍🏾
听我朋友说他 面试的时候碰到过一个这样类似的机试题,然后给我说了 我也想半天想不出来, 长见识了
牛!
长见识了
如何画一个只能在已显示区域进行事件绑定的三角形
前言: 这个问题是去一家公司面试的时候,技术经理问到我的,我第一想法是用CSS中的
border
去画,但是我们现在的要求是在那个三角形区域,才能进行事件的绑定,比如:click事件,那border
所用到的transparent
仅仅是透明度为0,那个区域还是在的,这就无法完成特定区域的事件绑定。1.先来试试border方法到底行不行吧!
Html:
Css:
现在我们可以看到如下: 我们就选一个指向右边的箭头吧,修改Css样式: Css:
现在我们得到了想要的三角形(具体形状自行调整
border-size
就行):接下来,我们给这个
div
添加一个onmouseover
事件:结果我们去测试的时候,不出所料地,透明的部分也会触发事件,如下所示:
那可咋办呢??
2.换个思路,用遮罩!
这个思路很简单,但是面试官坐在面前的时候,却怎么也想不出来。。
step1: 我们先画三个矩形:
Html:
Css:
得到如下图: 其中粉红的区域就是我们要的三角形区域,理论上你可以通过两个或许多个矩形构建出你想要的任何三角形!
step2: 进行绑定
那这个时候,我们怎么绑定事件到这个三角形上呢? 思路: 给
rectangle-tri
这个矩形绑定事件,也给rectangle-mask1
和rectangle-mask2
绑定事件,但是不做操作,这样的话,因为rectangle-tri
在最下面,移动非三角形区域的时候,触发的事件监听是另外两个遮罩矩形的事件。此时,特定的区域才有事件绑定了:
现在,我们怎么把这两个遮罩矩形去掉呢????设置背景色为白色?那就是自欺欺人了
step3: 只显示三角形
这里我真的还找不到方法啊,有哪位大佬能来说说吗???
3.用CSS3中的clip-path试试吧!
上看的引用出自MDN,我们只需要知道,这个属性可以让我们裁剪出想要的形状
基本形状裁剪:
其中inset是矩形的剪切,circle是圆形的剪切,ellipse是椭圆的剪切,polygon是多边形的剪切。对于我们想要把矩形剪切成三角形,应该使用polygon这个语法。 Html:
Css:
clip-path: polygon(0px 0px, 0px 100px, 100px 50px);
这句话意思是,根据坐标轴上确定的三个点来进行裁剪:(0px, 0px),(0px 100px),(100px, 50px) ,这三个点构成了一个我们如下三角形:现在我们可以来试试绑定事件好不好用来:
以下为测试结果:
我只能说,这个真是太好用了,不过这个属性兼容性会有些不好,酌情使用把!