使用CSS 3D变换时,点击区域会被破坏。

19
在OSX上的Chrome浏览器中,对一个元素进行3D旋转并在子元素上执行相反的旋转会破坏子元素上的鼠标事件(包括任何链接)。点击区域似乎错位了。
文档结构如下:
<div class='test'>
  <div><a href='http://www.google.com'>Click me</a></div>
</div>

以上的DOM结构也可在JSFiddle上找到。

有人知道是否有一种使用相同DOM结构的解决方法,可以保留正确的点击区域吗?


2
在Windows上的Chrome浏览器中,它并没有对齐错误;它被缩小到测试div的尺寸(也就是说,在a的中心有一条1像素高的线)。 - vals
在我的OS X上也是一样,高度只有1像素。 - David Winiecki
这有点晚了 :) 但是你找到解决方案了吗? 我在 jsFiddle 中看到 href 链接是 htpp 而不是 http。除此之外,一切似乎都正常工作。 - Furqan Rahamath
2个回答

1
如果一个DOM元素连接了一个事件,例如点击元素,并且你将其旋转90度,该元素仍然位于该位置,但由于它是平面的,所以无法单击它。DOM元素具有零深度,因此当您将DOM元素旋转90度时,您无法看到它。如果您将相同的元素旋转回来,您将看到它,并且单击事件起作用。从技术上讲,当元素旋转90度时,单击区域有效,但只有一个零点区域可供单击。
对于那些不相信事件仍然连接着的人,请测试一下并亲自查看。无论进行多少次转换,事件都将保持连接到元素。这也适用于Chrome。这也适用于链接。唯一删除事件或元素的时间是在删除事件或元素时。转换永远不会删除事件或元素。

document.getElementById("testButton").addEventListener("click", function() {
  alert("It works");
});
document.getElementById("flipButton").addEventListener("click", function() {
  if (document.getElementById("testButton").style.webkitTransform == "rotateX(0deg)") {
    document.getElementById("testButton").style.webkitTransform = "rotateX(90deg)";
    document.getElementById("test").style.webkitTransform = "rotateX(90deg)";
  } else {
    document.getElementById("testButton").style.webkitTransform = "rotateX(0deg)";
    document.getElementById("test").style.webkitTransform = "rotateX(0deg)";
  }
});
<html>

<body>
  <button id='testButton'>test button</button>
  <div id='test'>
    <div><a href='http://www.google.com'>Click me</a></div>
  </div>
  <button id='flipButton'>transform button</button>
</body>

</html>

这是一个使用你的示例的例子:

.test {
  -webkit-transform-style: preserve-3d;
  -webkit-transform: rotateX( 90deg);
}

.test>* {
  -webkit-transform: rotateX( -90deg);
}
<html>

<body>
  <div id='test'>
    <div><a href='http://www.google.com'>Click me</a></div>
  </div>
</body>

</html>

你会注意到它仍然可以工作。你的代码无法运行的原因是你的href中有href='htpp://boom'。URI htpp://boom 不是一个真实的地址。 htpp:// 并不存在,而且 boom 不是一个地址。你的代码错误与转换和CSS无关,而是没有使用真实的URI。

这个问题对之前的答案有什么补充? - Zach Saucier
这是不正确的,至少在Chrome上不正确。根据原始帖子,点击区域在多个变换下不会被保留。 - Mark Lundin
马克,你是不正确的。请在单击事件上测试几个转换,您会发现该事件将保持连接到元素。我已经更新了我的帖子,以展示一个简单的例子,您可以测试以证明我是正确的。 - Patrick W. McMahon
感谢@PatrickW.McMahon,我已将您的示例添加为[fiddle](http://jsfiddle.net/8aLm5cnv/)。但是,这并没有回答我的问题。您的解决方案似乎表明在稍后阶段重置变换确实可以成功地保持单击区域,但我需要一个保持单击区域的答案,其中父/子变换的总和= 0。 - Mark Lundin
无论您转换元素还是其父元素,单击事件仍然不会被删除。基于我的回答,我明确声明转换元素不会删除单击事件。因此,基于这个声明,转换元素也不会从子元素中删除点击事件。我的示例可能显示直接元素上的单击,但简单地将一个元素包裹在另一个元素中并转换其父元素,您会发现同样的情况成立。转换只是转换,没有更多也没有更少。 - Patrick W. McMahon
在我的示例中,您会看到转换带有A标签的div对A标签没有任何更改。这同样适用于所有元素的所有属性。您还会注意到我的示例使用了您的示例,并显示它仍然有效。 - Patrick W. McMahon

0

-webkit-transform 属性可能在将元素以 rotateX(90deg)rotateX(-90deg) 的方式显示时正常工作。

然而,在 rotateX(90deg) 的情况下,不应该期望元素能够被呈现为“可见”的。

元素将沿其 X 轴“压扁”,就像是一样。

rotateX(90deg) 时,CSS 可能会将元素的 transform 设为 - 90 度的弧度。

请参见链接的 jsfiddle,其中 css 的 transform 属性设置为分别为 rotateX(45deg)rotateX(-45deg),以查看在 45deg 时的潜在 rotateX((n)deg) 进度。

再次强调,transform 属性可能仅是试图实现一个真正的 90 度 (ree) sic 角度,如果可见,沿着 X 轴可能会类似于 -。

_

或者是一个“地平线”。

| - Y

_ - X

jsfiddle http://jsfiddle.net/guest271314/3XpFG/

编辑(更新,解决方法)

您的答案没有提到可点击区域。此外,您的演示文稿没有提供保留单击区域的解决方法。-Mark Lundin

如果要求将 css 属性 rotateX() 的值设置为 90deg,则 element 可能会呈现类似于 display:none; 的状态,即在屏幕上呈现出虚拟的“不可见”状态。 请参见 http://jsfiddle.net/guest271314/N6MdE/

解决方法

1)适用于以下两个选项 a) 和 b)

HTML

<!-- add `tabindex` attribute to `.test > a`,
     whether `element` rendered "visible", or "invisible",
     pressing `Tab` `key` possible to select `a` `element`,
     possibly add `title` attribute, 
     both `attributes` added for "notification", 
     of `a` `element` ("link") presence at that `position` in `document`,
     still possible to `navigate` to `a` `link`, utilizing `Tab` `key`
-->
<a href='htpp://boom' tabindex="1">Click me</a>

a) 在 css 属性 rotateX(89deg)rotateX(-89deg) 下呈现元素,这应该会在屏幕上呈现出 element 的一些“效果”,可以通过 ndeg 的“rotateX()”进行偏移,偏移量为 1deg。jsfiddle http://jsfiddle.net/guest271314/bzdak/

    .test{
    -webkit-transform-style: preserve-3d;
    -webkit-transform: rotateX( 89deg );
    height : 50px;
    opacity : 1.0;
}

.test > a{
    -webkit-transform: rotateX( -89deg );
}

.test:hover, .test a:hover {  
    -webkit-transform : rotateX(0deg);
     outline : thin solid blue;
     opacity : 1.0;
     cursor : pointer;
}

.test a:link, .test a:active {
    color : #c17d11; 
    font-size : 24px;
}

b) 在 css 属性 rotateX(89deg)rotateX(-89deg) 下渲染元素,包括将 css 属性 opacity 值设置为 0.9,这应该使得 element 元素在视觉上“隐形”,类似于 rotateX(90deg) 的渲染效果(参见 http://jsfiddle.net/guest271314/N6MdE/),添加 css :hover 和/或 :active 伪元素,或者两者都添加,以便在文档中的该位置上“通知” a 元素(“链接”)的存在,jsfiddle http://jsfiddle.net/guest271314/De7P6/
    .test{
    -webkit-transform-style: preserve-3d;
    -webkit-transform: rotateX( 89deg );
    display : block;
    height : 50px;
    opacity : 0.9;
}

.test > a{
    -webkit-transform: rotateX( -89deg );
}

.test:hover, .test a:hover {  
    -webkit-transform : rotateX(0deg);
     outline : thin solid blue;
    opacity : 1.0;
     cursor : pointer;
}

.test a:link, .test a:active {
    color : #c17d11; 
    font-size : 24px;
}

你的回答没有提到可点击区域。此外,你的演示没有提供保留点击区域的解决方法。 - Mark Lundin
@MarkLundin 注意:最初尝试传达的是原始元素通过rotate(90deg)本质上被“隐藏”,或者甚至小于1px,但不确定是否完全可能。 click或可点击区域的尺寸要求是什么? - guest271314

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接