jquery - jQuery mouseenter/leave 事件触发器的行为并不总是相同
问题描述
使用 gsap、clip-path 和覆盖,我的目标是将鼠标悬停在单词“.image-title”上,然后会出现一个图像,效果是仅由图像框起来的文本将变为具有白色轮廓。(显示比解释更容易..)
Codepen 在这里:https ://codepen.io/tallulahh/pen/bGgOpXd
let container, text, img, title;
function showImage(id){
switch(id){
case 'portfolio':
title = $(".portfolio .image-title");
container = $(".portfolio .overlay-container")
text = $(".portfolio .image-overlay");
img = $(".portfolio img");
break;
case 'arcade':
title = $(".arcade .image-title");
container = $(".arcade .overlay-container")
text = $(".arcade .image-overlay");
img = $(".arcade img");
break;
case 'sailing':
title = $(".sailing .image-title");
container = $(".sailing .overlay-container")
text = $(".sailing .image-overlay");
img = $(".sailing img");
break;
default:
}
var t = new gsap.timeline({duration:0.2});
t.to(title, {
zIndex: 0,
});
t.to( container, {
opacity: 1,
zIndex: 200,
});
t.to(img, {
opacity: 1,
zIndex: 200,
});
t.to(text, {
opacity:0.5,
zIndex: 300,
}, "-0.3");
}
function reverseImage(id){
switch(id){
case 'portfolio':
title = $(".portfolio .image-title");
container = $(".portfolio .overlay-container")
text = $(".portfolio .image-overlay");
img = $(".portfolio img");
break;
case 'arcade':
title = $(".arcade .image-title");
container = $(".arcade .overlay-container")
text = $(".arcade .image-overlay");
img = $(".arcade img");
break;
case 'sailing':
title = $(".sailing .image-title");
container = $(".sailing .overlay-container")
text = $(".sailing .image-overlay");
img = $(".sailing img");
break;
default:
}
var t = new gsap.timeline();
t.to(container, {
opacity: 0,
zIndex: 0,
duration:1
});
t.to(img, {
opacity: 0,
zIndex: 0,
duration:1
});
t.to(title, {
zIndex: 200,
duration: 0
});
t.to(text, {
opacity: 0,
zIndex: 0,
duration:0
});
}
$(".projects .content ul li p.image-title").on("mouseenter", function(){
showImage($(this)[0].id);
});
$(".projects .content ul li p.image-title").on("mouseleave", function(){
reverseImage($(this)[0].id);
});
body {
box-sizing:border-box;
}
.main section{
width: 75%;
min-height: 100vh;
margin: 0 auto;
position: relative;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: flex-start;
}
.project-list {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100vw;
left: 50%;
transform: translateX(-75%);
position: relative;
text-align: center;
margin-top: 100px;
}
.project-list li {
font-size: 100px;
list-style-type: none;
width: 100vw;
border-top: 2px solid black;
font-weight: bold;
}
.project-list li p {
margin-top: 50px;
}
.project-list:last-child {
border-bottom: 2px solid black;
}
.image {
width: 100%;
height: 300px;
position: relative;
margin: 0 auto;
display: flex;
flex-direction: row;
justify-content:center;
align-items:center;
}
.image img {
width: 500px;
height: 300px;
clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
overflow: hidden;
z-index: 0;
}
.image-title {
-webkit-text-fill-color: transparent;
-webkit-text-stroke-width: 3px;
-webkit-text-stroke-color: black;
cursor: pointer;
font-family: "Raleway"!important;
font-size: 110px;
font-weight: bold;
width: 100%;
display: flex;
position: absolute;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 200;
cursor: pointer;
height:100px;
}
.overlay-container {
width: 500px;
height: 300px;
display: flex;
position: relative;
justify-content: center;
align-items: center;
overflow:hidden;
clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
opacity: 0;
z-index: 0;
pointer-events: none;
}
.image-overlay{
-webkit-text-fill-color: transparent;
-webkit-text-stroke-width: 1px;
-webkit-text-stroke-color: white;
font-family: "Raleway"!important;
font-size: 110px;
font-weight: bold;
height: 100%;
width: 200%;
display: flex;
position: absolute;
flex-direction: column;
justify-content: center;
align-items: center;
overflow: hidden;
opacity: 0;
z-index: 0;
pointer-events: none;
}
<link href="https://fonts.googleapis.com/css2?family=Raleway:wght@100;800&display=swap" rel="stylesheet">
<div class="main">
<section class="projects">
<div class="heading">
<h1>Projects</h1>
</div>
<div class="content">
<p>To see some of my featured projects, click on the following titles to launch.. </p>
<ul class="project-list">
<li>
<div class="portfolio">
<div class="image" id="portfolio-img">
<p class="image-title" id="portfolio">Portfolio</p>
<div class="overlay-container">
<p class="image-overlay">Portfolio</p>
<img src="https://upload.wikimedia.org/wikipedia/commons/5/59/500_x_300_Ramosmania_rodriguesii_%28Rubiaceae%29.jpg" alt="portfolio">
</div>
</div>
</div>
</li>
<li>
<div class="arcade">
<div class="image" id="arcade-img">
<p class="image-title" id="arcade">Arcade</p>
<div class="overlay-container">
<p class="image-overlay">Arcade</p>
<img src="https://upload.wikimedia.org/wikipedia/commons/5/59/500_x_300_Ramosmania_rodriguesii_%28Rubiaceae%29.jpg" alt="arcade">
</div>
</div>
</div>
</li>
<li>
<div class="sailing">
<div class="image" id="sailing-img">
<p class="image-title" id="sailing">Sailing Barcelona</p>
<div class="overlay-container">
<p class="image-overlay">Sailing Barcelona</p>
<img src="https://upload.wikimedia.org/wikipedia/commons/5/59/500_x_300_Ramosmania_rodriguesii_%28Rubiaceae%29.jpg" alt="sailing">
</div>
</div>
</div>
</li>
</ul>
</div>
</section>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js"></script>
我的问题是 jQuery 事件触发器,有时白色轮廓出现在图像顶部,有时却没有。这很棘手,因为我希望图像和白色轮廓出现在原始文本的顶部,但原始文本需要监听事件触发器并且在图像可见时可点击。
有人可以解释为什么有时会出现白色的 ouline 文本,为什么有时不会出现,以及我该如何解决这个问题?
解决方案
有人在 GreenSock 论坛中向我提供了这个答案:
“这里发生的一些事情有时会相互竞争,产生意想不到的结果。我可以指出一些技巧,以帮助减少出现意外结果的机会。
- 尽可能依赖 DOM 层次结构来处理堆叠顺序。虽然修改 z-indexes 以更改堆叠顺序是合理的,但很多时候这并不是必需的。从等式中删除它大大降低了发生意外的可能性。在我的 fork 中,我翻转了 .image-overlay 和 .overlay-container 中的 img 的顺序。
- 如果您希望 Javascript 更改元素上的 CSS 属性,也请使用 Javascript 设置其初始呈现值;不要使用 CSS 来定义将被补间的初始属性(如不透明度和可见)。你可以看到我浏览了 CSS 并删除了所有的东西 z-index、不透明度、可见等。这也有助于在 Javascript 不执行的情况下优雅地降级。
- 如果可能,请创建一次时间线(不要在每个事件触发器中一遍又一遍)。
- 如果可能,不要使用两条时间线来控制相同的元素。在您的示例中,为每个输入/输出状态创建了一个时间线。但是我们可以创建一个时间线并根据悬停事件的需要向前/向后播放。
最后,通过为时间线动态创建变量名,我们可以(一次)创建它们并重复处理它们,而不需要不断地重新创建它们,也不需要 switch 语句的笨重逻辑。"
推荐阅读
- python - 我在我的 macOS 上下载 discord.py 时出错
- multithreading - 如何实现可以在具有 N 个内核的机器上运行多个线程的哈希表?
- java - 如何在 JavaFX 中异步显示从左到右移动的文本?
- c# - C# 在 Windows 窗体中显示控制台输出
- css - Chrome中带有字母间距的SVG绘制顺序
- python - BeautifulSoup 给我列表空
- c++ - 使用 OpenGL 时,我尝试渲染的正方形没有显示
- r - 将随机效应表达式从 SAS 转换为 R lmer 语法
- reactjs - 切片创建二维数组
- sql - 尝试子查询时出现不明确的列名错误