使用视图过渡 API(web)来过渡不是同一 DOM 元素的元素?

huangapple go评论80阅读模式
英文:

How to use the View Transition API (web) for transition elements that are not the same DOM element?

问题

I have a thumbnail DOM element that needs to transition into the modal DOM element that opens when that thumbnail is clicked. The thumbnail and the modal are NOT the same DOM element. For this I want to use the View Transitions API.

使用视图过渡 API(web)来过渡不是同一 DOM 元素的元素?

关于使用不同的 DOM 元素进行过渡的话题在 Chrome 文章"使用 View Transitions API 实现平滑简单的过渡" 的其中一章中有介绍。

当我尝试构建缩略图到模态的过渡时,我发现过渡元素的行为与我的预期不同。我做错了什么?

我已经编写了我希望能工作的简化代码示例在this codepen中。

<!-- HTML -->
<div id="thumbnail">点击我</div>

<div id="modal">您已打开模态<div id="closer">X</div></div>

<div id="comment">粉色轮廓=::view-transition-old<br> 绿色轮廓=::view-transition-new</div>

/* CSS */
#thumbnail {
  position: relative;
  border: 2px solid darkred;
  display: inline-block;
  padding: 40px;
  cursor: pointer;
}

#thumbnail:hover {
  background-color: #74747444;
}

#modal {
  display: none;
  position: absolute;
  translate: -50% -50%;
  top: 50%;
  left: 50%;
  padding: 80px;
  border: 2px solid blue;
}

#closer {
  position: absolute;
  top: 4px;
  right: 4px;
  cursor: pointer;
}

::view-transition-old(modal),
::view-transition-new(modal) {
  animation-duration: 5s;
}

::view-transition-old(modal) {
  outline: 4px solid pink;
}

::view-transition-new(modal) {
  outline: 4px solid green;
  outline-offset: 4px;
}

// JavaScript
const thumbnail = document.querySelector("#thumbnail")

const modal = document.querySelector("#modal")

const closer = document.querySelector("#closer")

thumbnail.addEventListener("click", () => openModal())

closer.addEventListener("click", () => {
  modal.style.display = "none";
})

function openModal() {
  // 针对不支持的浏览器的回退处理
  if (!document.startViewTransition) {
    modal.style.display = "block";
    return;
  }
  
  thumbnail.style.viewTransitionName = "modal";
  modal.style.viewTransitionName = "";

  const transition = document.startViewTransition(() => {
    modal.style.display = "block";
  })
  
  transition.updateCallbackDone.then(() => {
    thumbnail.style.viewTransitionName = "";
    modal.style.viewTransitionName = "modal";
  })
  
  transition.finished.finally(() => {
    modal.style.viewTransitionName = "";
  })
}
英文:

I have a thumbnail DOM element that needs to transition into the modal DOM element that opens when that thumbnail is clicked. The thumbnail and the modal are NOT the same DOM element. For this I want to use the View Transitions API.

使用视图过渡 API(web)来过渡不是同一 DOM 元素的元素?

The topic of using transition elements that are not the same DOM element is covered in one of the chapters of the Chrome article "Smooth and simple transitions with the View Transitions API".

I was surprised to find the transition element behave differently from what I expected, when trying to build the thumbnail-to-modal transition. What am I doing wrong?

I have written a simple variant of the code I expected to work in this codepen.

&lt;!-- HTML --&gt;
&lt;div id=&quot;thumbnail&quot;&gt;Click me&lt;/div&gt;

&lt;div id=&quot;modal&quot;&gt;You have opened the modal&lt;div id=&quot;closer&quot;&gt;X&lt;/div&gt;&lt;/div&gt;

&lt;div id=&quot;comment&quot;&gt;
pink outline = ::view-transition-old&lt;br&gt; green outline = ::view-transition-new&quot;
&lt;/div&gt;

/* CSS */
#thumbnail {
  position: relative;
  border: 2px solid darkred;
  display: inline-block;
  padding: 40px;
  cursor: pointer;
}

#thumbnail:hover {
  background-color: #74747444;
}

#modal {
  display: none;
  position: absolute;
  translate: -50% -50%;
  top: 50%;
  left: 50%;
  padding: 80px;
  border: 2px solid blue;
}

#closer {
  position: absolute;
  top: 4px;
  right: 4px;
  cursor: pointer;
}

::view-transition-old(modal),
::view-transition-new(modal) {
  animation-duration: 5s;
}

::view-transition-old(modal) {
  outline: 4px solid pink;
}

::view-transition-new(modal) {
  outline: 4px solid green;
  outline-offset: 4px;
}

// JavaScript
const thumbnail = document.querySelector(&quot;#thumbnail&quot;)

const modal = document.querySelector(&quot;#modal&quot;)

const closer = document.querySelector(&quot;#closer&quot;)

thumbnail.addEventListener(&quot;click&quot;, () =&gt; openModal())

closer.addEventListener(&quot;click&quot;, () =&gt; {
  modal.style.display = &quot;none&quot;
})

function openModal() {
  // Fallback for non-supporting browsers
  if (!document.startViewTransition) {
    modal.style.display = &quot;block&quot;
    return
  }
  
  thumbnail.style.viewTransitionName = &quot;modal&quot;
  modal.style.viewTransitionName = &quot;&quot;

  const transition = document.startViewTransition(() =&gt; {
    modal.style.display = &quot;block&quot;
  })
  
  transition.updateCallbackDone.then(() =&gt; {
    thumbnail.style.viewTransitionName = &quot;&quot;
    modal.style.viewTransitionName = &quot;modal&quot;
  })
  
  transition.finished.finally(() =&gt; {
    modal.style.viewTransitionName = &quot;&quot;
  })
}

答案1

得分: 3

将代码thumbnail.style.viewTransitionName = null; modal.style.viewTransitionName = &quot;modal&quot;updateCallbackDone promise回调移到startViewTransition回调中就解决了问题。

所以新代码如下(也请参阅此codepen)。

<div id="thumbnail">点击我</div>

<div id="modal">你已经打开了模态框<div id="closer">X</div></div>
#thumbnail {
  position: relative;
  border: 2px solid darkred;
  display: inline-block;
  padding: 40px;
  cursor: pointer;
}

#thumbnail:hover {
  background-color: #74747444;
}

#modal {
  display: none;
  position: absolute;
  translate: -50% -50%;
  top: 50%;
  left: 50%;
  padding: 80px;
  border: 2px solid blue;
  background-color: white;
}

#closer {
  position: absolute;
  top: 4px;
  right: 4px;
  cursor: pointer;
}
const thumbnail = document.querySelector("#thumbnail")

const modal = document.querySelector("#modal")

const closer = document.querySelector("#closer")

thumbnail.addEventListener("click", () => openModal())

closer.addEventListener("click", () => {
  modal.style.display = "none";
})

function openModal() {
  // 不支持的浏览器的回退
  if (!document.startViewTransition) {
    modal.style.display = "block";
    return;
  }
  
  thumbnail.style.viewTransitionName = "modal";

  const transition = document.startViewTransition(() => {
    thumbnail.style.viewTransitionName = null;
    modal.style.viewTransitionName = "modal";
    modal.style.display = "block";
  })
    
  transition.finished.finally(() => {
    modal.style.viewTransitionName = null;
  })
}
英文:

Moving the code thumbnail.style.viewTransitionName = null; modal.style.viewTransitionName = &quot;modal&quot; from the updateCallbackDone promise callback to the startViewTransition callback did the trick.

So the new code is as follows (also see this codepen).

&lt;div id=&quot;thumbnail&quot;&gt;Click me&lt;/div&gt;

&lt;div id=&quot;modal&quot;&gt;You have opened the modal&lt;div id=&quot;closer&quot;&gt;X&lt;/div&gt;&lt;/div&gt;
#thumbnail {
  position: relative;
  border: 2px solid darkred;
  display: inline-block;
  padding: 40px;
  cursor: pointer;
}

#thumbnail:hover {
  background-color: #74747444;
}

#modal {
  display: none;
  position: absolute;
  translate: -50% -50%;
  top: 50%;
  left: 50%;
  padding: 80px;
  border: 2px solid blue;
  background-color: white;
}

#closer {
  position: absolute;
  top: 4px;
  right: 4px;
  cursor: pointer;
}
const thumbnail = document.querySelector(&quot;#thumbnail&quot;)

const modal = document.querySelector(&quot;#modal&quot;)

const closer = document.querySelector(&quot;#closer&quot;)

thumbnail.addEventListener(&quot;click&quot;, () =&gt; openModal())

closer.addEventListener(&quot;click&quot;, () =&gt; {
  modal.style.display = &quot;none&quot;
})

function openModal() {
  // Fallback for non-supporting browsers
  if (!document.startViewTransition) {
    modal.style.display = &quot;block&quot;
    return
  }
  
  thumbnail.style.viewTransitionName = &quot;modal&quot;

  const transition = document.startViewTransition(() =&gt; {
    thumbnail.style.viewTransitionName = null
    modal.style.viewTransitionName = &quot;modal&quot;
    modal.style.display = &quot;block&quot;
  })
    
  transition.finished.finally(() =&gt; {
    modal.style.viewTransitionName = null
  })
}

huangapple
  • 本文由 发表于 2023年5月15日 01:26:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76248818.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定