javascript - 如何为 JavaScript 的 HTML 元素创建幻灯片动画?
问题描述
在我的项目中,许多元素是通过 JavaScript 创建的。
代码笔: https ://codepen.io/Akash11166666/pen/JjRzqzp
您可以在下面看到一些带有复制按钮的报价 - 只需单击一次。将出现一个自定义复制警报,提示文本为“已复制!”。但是自定义警报只是弹出并消失。有什么办法可以让他们从左到右滑进去然后消失?
我知道这很容易,但是元素是从 JavaScript 创建的,所以对我来说很难。
const resultEl = document.querySelector('.allquotes');
const pageSize = document.querySelector('select[name="page-size"]');
const pageCurr = document.querySelector('input[name="page-curr"]')
const pageNoCurr = document.querySelector('.page-no-curr');
const pageNoCount = document.querySelector('.page-no-count')
const btnPrev = document.querySelector('.page-btn-prev');
const btnNext = document.querySelector('.page-btn-next');
let results = [];
const getResultCount = () => results.length;
const getPageSize = () => +pageSize.value;
const getCurrPage = () => +pageCurr.value;
const getPageCount = () => Math.ceil(getResultCount() / getPageSize());
const pageResponse = (records, pageSize, page) =>
(start => records.slice(start, Math.min(records.length, start + pageSize)))
(pageSize * (page - 1));
const btnJump = document.querySelector('.jump-btn');
const pageValue = document.querySelector('.value-page');
const main = async() => {
btnPrev.addEventListener('click', navPrev);
btnNext.addEventListener('click', navNext);
btnJump.addEventListener('click', navJump);
pageSize.addEventListener('change', changeCount);
results = await retrieveAllQuotes();
updatePager(results);
redraw();
};
const redraw = () => {
resultEl.innerHTML = '';
const paged = pageResponse(results, getPageSize(), getCurrPage());
const contents = document.createElement('div');
contents.classList.add("allStatus");
const quotes = paged.map((record) => `<div class='latestatus'><p class='copytxt'>${record.status}</p><div> <button class="copystatus btn">Copy</button><span class="status-copy-alert hidden" id="status-copy-alert">Copied!</span></div></div>`);
const quoteGroupNumer = Math.ceil(quotes.length / 2);
const groups = Array(quoteGroupNumer).fill('').map((value, index) => {
const groupQuoteFirst = quotes[2 * index]; // 0, 2, 4, 6
const groupQuoteSecond = quotes[2 * index + 1] || ''; // 1, 3, 5, 7
return `<div class="flex">${groupQuoteFirst}${groupQuoteSecond}</div>`;
});
contents.innerHTML = groups.join('');
resultEl.append(contents);
};
const navPrev = (e) => {
const pages = getPageCount();
const curr = getCurrPage();
const prevPage = curr > 1 ? curr - 1 : curr;
pageCurr.value = prevPage;
pageNoCurr.textContent = prevPage;
redraw();
}
const navNext = (e) => {
const pages = getPageCount();
const curr = getCurrPage();
const nextPage = curr < pages ? curr + 1 : curr;
pageCurr.value = nextPage;
pageNoCurr.textContent = nextPage;
redraw();
}
const navJump = (e) => {
const pages = getPageCount();
const curr = getCurrPage();
pageNoCurr.textContent = pageValue.value;
redraw();
}
const changeCount = () => {
updatePager();
redraw();
};
const updatePager = () => {
const count = getPageCount();
const curr = getCurrPage();
pageCurr.value = curr > count ? 1 : curr;
pageNoCurr.textContent = curr > count ? 1 : curr;
pageNoCount.textContent = count;
};
const retrieveAllQuotes = async function() {
return [{
quotes: "1The cat is better than dog."
},
{
quotes: "2Google is a open source library."
},
{
quotes: "3Cats are better than ferrets."
},
{
quotes: "4Love books."
},
{
quotes: "5Life is short make it possible."
},
{
quotes: "6The cat is better than dog"
},
{
quotes: "7Google is a open source library."
},
{
quotes: "8Cats are better than ferrets."
},
{
quotes: "9Love books."
},
{
quotes: "10Life is short make it possible."
},
];
}
document.querySelector('.allquotes').addEventListener('click',function(e) {
e.preventDefault();
if (e.target && e.target.matches('.copystatus')) {
const quote = e.target.parentNode.closest('.latestatus')
.childNodes[0].textContent;
const notify = e.target.nextSibling.closest('.status-copy-alert');
notify.classList.toggle('hidden');
setTimeout(() => {
notify.classList.add('hidden');
}, 600);
const textArea = document.createElement('textarea');
textArea.value = quote;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('Copy');
textArea.remove();
}
},
false
);
main();
/* Main Status */
.hidden {
display: none;
}
.pagable {
display: flex;
flex-direction: column;
border: var(--pageable-border);
background: var(--pageable-background);
}
.pagable .pagable-results {
display: flex;
flex-direction: column;
flex: 1;
padding: 0.25em;
}
.pagable .pagable-status {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 0.25em;
background: var(--pageable-status-background);
}
.pagable .pagable-actions {
display: grid;
grid-auto-flow: column;
grid-gap: 0.25em;
}
.pagable .pagable-actions input[name="page-curr"] {
width: 3em;
}
.btn {
display: inline-block;
padding: 10px 20px;
cursor: pointer;
background: #18b495;
color: #fff;
border: none;
border-radius: 30px;
}
.btn:hover {
transform: scale(0.98);
}
.status-copy-alert {
position: relative;
background-color: #18b495;
color: #ffffff;
padding: 10px 10px;
border-radius: 5px;
left: 8px;
text-transform: uppercase;
letter-spacing: 0.05em;
font-weight: 500;
visibility: visible;
}
.status-copy-alert:before {
content: "";
position: absolute;
height: 10px;
width: 10px;
background-color: #18b495;
left: -5px;
transform: rotate(45deg);
top: 39%;
}
<a href="hindinj.html">caeman</a>
<div class="mainStatus">
<h2 class="statusHeading">Latest English Status</h2>
<div class="allquotes"></div>
<div class="pagable-status">
<label>Page <span class="page-no-curr">1</span> of <span class="page-no-count">1</span></label>
<div class="pagable-actions">
<button class="page-btn-prev btn">PRE</button>
<input type="number" name="page-curr" min="1" value="1" />
<button class="page-btn-next btn">NEXT</button>
<select name="page-size">
<option>5</option>
<option>10</option>
<option>20</option>
</select>
</div>
<input class="value-page" />
<button class="jump-btn">Go</button>
</div>
解决方案
【编辑】使用css过渡
const resultEl = document.querySelector('.allquotes');
const pageSize = document.querySelector('select[name="page-size"]');
const pageCurr = document.querySelector('input[name="page-curr"]')
const resultCount = document.querySelector('.result-count')
const pageNoCurr = document.querySelector('.page-no-curr');
const pageNoCount = document.querySelector('.page-no-count')
const btnFirst = document.querySelector('.page-btn-first');
const btnPrev = document.querySelector('.page-btn-prev');
const btnNext = document.querySelector('.page-btn-next');
const btnLast = document.querySelector('.page-btn-last');
let results = [];
const getResultCount = () => results.length;
const getPageSize = () => +pageSize.value;
const getCurrPage = () => +pageCurr.value;
const getPageCount = () => Math.ceil(getResultCount() / getPageSize());
const pageResponse = (records, pageSize, page) =>
(start => records.slice(start, Math.min(records.length, start + pageSize)))
(pageSize * (page - 1));
const main = async() => {
btnFirst.addEventListener('click', navFirst);
btnPrev.addEventListener('click', navPrev);
btnNext.addEventListener('click', navNext);
btnLast.addEventListener('click', navLast);
pageSize.addEventListener('change', changeCount);
results = await retrieveAllQuotes();
updatePager(results);
redraw();
};
const redraw = () => {
resultEl.innerHTML = '';
const paged = pageResponse(results, getPageSize(), getCurrPage());
const contents = document.createElement('div');
contents.innerHTML = paged.map(record => `<div class='latestatus'><p class='copytxt'>${record.quotes}</p><div> <button class="copystatus btn">Copy</button><span class="status-copy-alert hidden" id="status-copy-alert">Copied</span>
</div></div>`).join('');
resultEl.append(contents);
};
const navFirst = (e) => {
pageNoCurr.textContent = 1;
pageCurr.value = 1;
redraw();
}
const navPrev = (e) => {
const pages = getPageCount();
const curr = getCurrPage();
const prevPage = curr > 1 ? curr - 1 : curr;
pageCurr.value = prevPage;
pageNoCurr.textContent = prevPage;
redraw();
}
const navNext = (e) => {
const pages = getPageCount();
const curr = getCurrPage();
const nextPage = curr < pages ? curr + 1 : curr;
pageCurr.value = nextPage;
pageNoCurr.textContent = nextPage;
redraw();
}
const navLast = (e) => {
pageNoCurr.textContent = getPageCount();
pageCurr.value = getPageCount();
redraw();
}
const changeCount = () => {
updatePager();
redraw();
};
const updatePager = () => {
const count = getPageCount();
const curr = getCurrPage();
pageCurr.value = curr > count ? 1 : curr;
pageNoCurr.textContent = curr > count ? 1 : curr;
pageNoCount.textContent = count;
resultCount.textContent = getResultCount();
};
const retrieveAllQuotes = async function() {
// write your asynchronous fetching here
return [{
quotes: "1The cat is better than dog."
},
{
quotes: "2Google is a open source library."
},
{
quotes: "3Cats are better than ferrets."
},
{
quotes: "4Love books."
},
{
quotes: "5Life is short make it possible."
},
{
quotes: "6The cat is better than dog"
},
{
quotes: "7Google is a open source library."
},
{
quotes: "8Cats are better than ferrets."
},
{
quotes: "9Love books."
},
{
quotes: "10Life is short make it possible."
},
];
}
document.querySelector('.allquotes').addEventListener(
'click',
function(e) {
e.preventDefault();
if (e.target && e.target.matches('.copystatus')) {
const quote = e.target.parentNode.closest('.latestatus')
.childNodes[0].textContent;
const notify = e.target.nextSibling.closest('.status-copy-alert');
notify.classList.add('animatedClass')
setTimeout(() => {
notify.classList.remove('animatedClass')
}, 1000);
const textArea = document.createElement('textarea');
textArea.value = quote;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('Copy');
textArea.remove();
}
},
false
);
main();
/* Main Status */
.hidden {
/* display:none; */
}
.mainStatus {
background-color: #fff;
border-radius: 10px;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2);
padding-bottom: 5px;
margin: 10px;
margin-top: 10px;
max-width: 95%;
width: 95%;
height: auto;
border-radius: 20px;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2);
}
.statusHeading {
text-align: center;
background-color: #18b495;
color: #ffffff;
padding: 10px 10px 10px 10px;
border-top-right-radius: 20px;
border-top-left-radius: 20px;
font-weight: 300;
font-size: 20px;
}
.latestatus {
display: grid;
height: auto;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2);
padding: 10px 20px 10px 20px;
border-radius: 30px;
margin: 10px 10px 10px 10px;
width: 445px;
min-height: 130px;
font-size: 15px;
}
.allStatus {
display: flex;
}
.latestatus p {
width: auto;
position: relative;
}
.copystatus {
font-weight: 500;
text-transform: uppercase;
width: 100px;
height: 40px;
}
.pagable {
display: flex;
flex-direction: column;
border: var(--pageable-border);
background: var(--pageable-background);
}
.pagable .pagable-results {
display: flex;
flex-direction: column;
flex: 1;
padding: 0.25em;
}
.pagable .pagable-status {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 0.25em;
background: var(--pageable-status-background);
}
.pagable .pagable-actions {
display: grid;
grid-auto-flow: column;
grid-gap: 0.25em;
}
.pagable .pagable-actions input[name="page-curr"] {
width: 3em;
}
.btn {
display: inline-block;
padding: 10px 20px;
cursor: pointer;
background: #18b495;
color: #fff;
border: none;
border-radius: 30px;
}
.btn:hover {
transform: scale(0.98);
}
.status-copy-alert {
position: relative;
background-color: #18b495;
color: #ffffff;
padding: 10px 10px;
border-radius: 5px;
left: -42px;
text-transform: uppercase;
letter-spacing: 0.05em;
font-weight: 500;
visibility: visible;
opacity: 0;
transition: left 0.4s, opacity 0.4s;
}
.animatedClass {
left: 8px;
opacity: 1;
}
.status-copy-alert:before {
content: "";
position: absolute;
height: 10px;
width: 10px;
background-color: #18b495;
left: -5px;
transform: rotate(45deg);
top: 39%;
}
<div class="mainStatus">
<h2 class="statusHeading">Latest English Status</h2>
<div class="allquotes"></div>
<div class="pagable-status">
<label>Page <span class="page-no-curr">1</span> of <span class="page-no-count">1</span></label>
<div class="pagable-actions">
<button class="page-btn-first">≪</button>
<button class="page-btn-prev"><</button>
<input type="number" name="page-curr" min="1" value="1" />
<button class="page-btn-next">></button>
<button class="page-btn-last">≫</button>
<select name="page-size">
<option>5</option>
<option>10</option>
<option>20</option>
</select>
</div>
<label>(<span class="result-count"></span> items)</label>
</div>
</div>
使用 jQuery
你想试试 jquery 吗?
代替
const notify = e.target.nextSibling.closest('.status-copy-alert');
notify.classList.toggle('hidden');
setTimeout(() => {
notify.classList.add('hidden');
}, 600);
和
const notify = e.target.nextSibling.closest('.status-copy-alert');
$(notify).removeClass('hidden')
$(notify).animate({
'left': '8px',
'opacity': '1'
}, 400, ()=> {
setTimeout(()=> {
$(notify).addClass('hidden')
$(notify).css({
'left': '-42px',
'opacity': '0'
})
}, 600)
})
并且在你的css
替换中
.status-copy-alert {
...
left: 8px;
}
和
.status-copy-alert {
...
left: -42px;
opacity: 0;
}
推荐阅读
- regex - 如何将正则表达式应用于 MongoDB 字段
- c# - 将 MongoDB.Driver 从 2.7.0 升级到 2.7.1 后连接超时
- javascript - 如何处理 Ajax/POST/PHP
- ios - 如何使用自定义 url 将捕获的 .mov 文件保存到自定义相册?
- python - 多列绘图Python
- javascript - Openlayers 地图图块最初未在单页应用程序中加载
- javascript - 如何确保始终显示至少一个 DIV?
- javascript - 转换字符串值的Javascript方法
- google-analytics - 如何从服务器使用 Google 跟踪代码管理器设置分析变量?
- swift - 为什么这段 Swift 代码编译和运行没有错误?