我正在嘗試創建一個slideUp和slideDown函式來隱藏和顯示帶有 javascript 影片的元素。我在這里為 height 屬性設定影片,但它只能作業一次。
div 最初是隱藏的。我使用slideDown它計算它的自然高度并將其從 0px 影片到該高度,然后洗掉 height 屬性。To slideUp,它將其從自然高度影片化回 0px,然后洗掉 height 屬性。
第二次,JS 無法測量 div 的正確高度。似乎瀏覽器會記住 div 的最后一個高度,它是 0 并堅持下去。
這是我的代碼: https ://jsfiddle.net/VeeK727/2ufnsx61/
這里發生了什么?
uj5u.com熱心網友回復:
- 主要問題是您正在使用填充影片 (
fill: 'forwards')。一旦影片結束,元素的影片樣式仍然是最后一個值并且不能被覆寫。
解決方案是cancel影片。
天真的示范
顯示代碼片段
const box = document.querySelector('#box');
let animation;
document.querySelector('#cancel').addEventListener('click', () => {
animation.cancel();
});
document.querySelector('#setHeight').addEventListener('click', () => {
box.style.marginTop = '100px';
});
document.querySelector('#animate').addEventListener('click', () => {
animation = box.animate([
{
marginTop: '50px'
},
], {
fill: 'forwards',
duration: 500
});
});
#box {
background: red;
width: 50px;
height: 50px;
}
<pre>
1. Click on "Set Box's margin-top 100px"
2. Click on "Animate"
3. Click on "Set Box's margin-top 100px" again ?? Doesn't work
4. Click on "Cancel" ?? Now the element is "free" and back to its place
</pre>
<button id="setHeight">Set Box's margin-top 100px</button>
<button id="animate">Animate</button>
<button id="cancel">Cancel</button>
<hr />
<div id="box"></div>
- 另一個小問題是元素的高度不斷增長,因為您將高度設定為
offsetHeight包括填充,因此每次切換高度都會增加填充數。
解決方案是設定box-sizing: border-box.
function slideDown(el, duration = 500) {
// momentarily show element to calculate dimensions
Object.assign(el.style, {
position: 'absolute',
display: 'block',
visibility: 'hidden',
height: 'auto',
overflow: 'hidden'
});
const elHeight = el.offsetHeight;
el.style.removeProperty('position');
el.style.removeProperty('visibility');
el.style.height = '0px';
console.log(elHeight);
el.animate([{
height: '0px'
},
{
height: elHeight 'px'
}
], {
duration: duration,
fill: 'forwards'
});
setTimeout(function() {
el.style.removeProperty('height');
el.style.removeProperty('overflow');
}, duration);
}
function slideUp(el, duration = 500) {
el.style.overflow = 'hidden';
console.log(el.offsetHeight);
const animation = el.animate([{
height: el.offsetHeight 'px'
},
{
height: '0px'
}
], {
duration: duration,
fill: 'forwards'
});
setTimeout(function() { // callback not yet supported enough
el.style.removeProperty('height');
el.style.removeProperty('overflow');
el.style.display = 'none';
animation.cancel();
}, duration);
}
const button = document.getElementById('trigger'),
content = document.querySelector('.content');
button.addEventListener('click', function() {
if (this.classList.contains('active')) {
this.classList.remove('active');
this.textContent = 'Drop It';
slideUp(content);
} else {
this.classList.add('active');
this.textContent = 'Retract It';
slideDown(content);
}
});
.content {
display: none;
position: relative;
padding: 1rem 1.5rem;
border: 1px solid #000;
border-radius: 5px;
box-sizing: border-box;
}
<button id="trigger">
Drop It
</button>
<br><br>
<div class="content">
<p class="no-margin"><strong>This content is revealed by a dropdown.</strong> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
https://jsfiddle.net/moshfeu/ca1Lmx5b/6/
一些評論
- 如果您唯一想要的是向上/向下滑動效果,那么使用 css 會更容易、更干凈、更短。這是一個示例:https ://stackoverflow.com/a/33931219/863110
- 而不是使用
setTimeoutwhich is inaccurate,使用onfinish
顯示代碼片段
document.querySelector('button').addEventListener('click', () => {
document
.querySelector('div')
.animate([{
marginTop: '50px'
}], {
duration: 500,
fill: 'forwards'
})
.addEventListener('finish', () => {
console.log('animation finished')
});
});
#box {
width: 50px;
height: 50px;
background: red;
}
<button>Animate</button>
<div id="box"></div>
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/413035.html
標籤:
