首页 > 解决方案 > 如何为 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>

标签: javascripthtmlcss

解决方案


【编辑】使用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">&#x226A;</button>
      <button class="page-btn-prev">&#60;</button>
      <input type="number" name="page-curr" min="1" value="1" />
      <button class="page-btn-next">&#62;</button>
      <button class="page-btn-last">&#x226B;</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;
}

推荐阅读