一种处理弹出信息非常棒的方式

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200美元免费额度!

Doug Neiner 在今年的 前端设计大会 上做了一个精彩的演讲。他在演讲中涵盖了很多内容,您可以在 他的幻灯片 中看到,但我想特别强调其中一点:他在演示中处理弹出信息的方式。我将尝试重新解释一下……

假设我们的目标是:**将鼠标悬停在图像上以显示额外信息**(如图像标题和 URL)。

非常简单的设计模式,对吧?其实不然。有很多细微之处需要考虑。让我们从最简单的方法开始,然后逐步改进。

最简单的方法:使用 CSS 隐藏/显示

如果我们的标记是

<figure>
   <img src="image.jpg" alt="cool image">
   <figcaption>
        <h3>Cool Image</h3>
        <a href="http://coolplace.com">http://coolplace.com</a>
   </figcaption>
</figure>

我们将使用<figcaption> 作为弹出信息。默认情况下我们将隐藏它,然后在鼠标悬停在图像上时显示它。

figcaption {
   display: none;
}
figure:hover figcaption {
   display: block;
}

但是……它太**突然**了。

淡入/淡出

我们可以使用 CSS 过渡来缓和它。

ficaption {
   opacity: 0;
   transition: opacity 0.3s ease-out;  
}
figure:hover figcaption {
   opacity: 1; 
}

如果需要,我们可以通过 应用不同的持续时间 来使其更加花哨。

但是……即使我们只是快速地将鼠标移过图像,也可能会弹出弹出窗口,而我们可能并不想看到弹出窗口。

“悬停意图”

如果我们使用 JavaScript,可以实现更花哨的效果。有一个名为 hoverIntent 的 jQuery 插件,它可以帮助防止不必要的悬停行为。它在事件触发之前会引入一点延迟,因此快速将鼠标悬停在事物上不会触发弹出窗口,但如果放慢速度并在图像上停留,则会触发。

您可以像这样应用它。

$("figure").hoverIntent(function() {
   $("figcaption", this).fadeTo(400, 1);
}, function() {
   $("figcaption", this).fadeTo(400, 0);
});

但是……现在所有图像都使用了 hoverIntent,这意味着**如果要专门浏览图像并查看信息,则看到弹出窗口的轻微延迟可能会非常烦人**。正如 Doug 所说,“我的大脑思考速度比这快。”

最后:非常棒的方式 (doTimeout)

我们喜欢 hoverIntent 的第一部分,即快速鼠标悬停不会触发弹出窗口,但一旦我们触发了一个弹出窗口,我们就希望后续的弹出窗口快速出现,没有任何延迟。如果用户离开图像区域一段时间,则会再次引入延迟。

这使用了 Ben Alman 的 doTimeout 插件。不可否认,这有点复杂。

var li_cache, over = false;

$( "figure" )
	.delegate( "figcaption", "mouseenter", function ( e ) {
		var $li = $( this ), speed;

		if ( li_cache === this && over ) {
			$.doTimeout( "hoverOut" );
			return;
		}

		if ( over ) {
			$.doTimeout( "hoverOut", true );
			speed = 0;
		} else {
			$.doTimeout( "hoverOut" );
			speed = 500;
		}

		$.doTimeout( "hoverIn", speed, function () {
			over = true;
			$li.find( "div" ).fadeTo( 200, 1.0 );
		});
	})
	.delegate( "figcaption", "mouseleave", function ( e ) {
		var $li = $( this );

		$.doTimeout( "hoverIn" );
		$.doTimeout( "hoverOut", 500, function () {
			over = false;
			$li.find( "div" ).stop( true ).fadeOut();
		});
	});

非常棒。这以一种自然而微妙的方式改善了弹出信息的显示,以至于它有点可惜实现起来如此困难。但它值得一试。

Doug 的 GitHub 仓库

获取此 GitHub 仓库。Doug 做了很棒的工作,它很有教育意义。您可以通过注释/取消注释一些函数名称来查看所有不同悬停功能的演变过程。除此之外,此示例还涵盖了使用 jQuery 模板、“Mockjax”(劫持 AJAX 请求以进行本地开发)等。

说真的,我甚至不会发布一个实时演示,请下载他的仓库并在浏览器中打开 index.html 文件。