如何解决从javascript创建复制按钮警报
您好,我是新的网络开发人员,正在从事报价网站项目。
我创建了一个 Html 页面,其中有一些引号,所有引号下方都有一个复制按钮。
您可以访问我的 CodePen 来清楚地了解问题 https://codepen.io/Akash11166666/pen/JjRzqzp
(我已经显示了 Javascript 中的复制按钮和引号,因此您无法在 HTML 中找到这些元素。)
正如您所看到的我的 CodePen,它们运行良好,但我们不知道文本是否被复制。所以我需要一个 <span>copied</span>
在点击每个复制按钮时可见,而不直接将 <span>copied</span>
插入到 HTML,即来自与创建复制按钮相同的 javascript。它们应该是动态的,以至于对于相应的复制按钮,span
元素应该在几秒钟后可见和不可见。
我尝试了很多方法来解决这个问题,但我知道它们可以工作,尽管我是 JavaScript 的新手,我对此知之甚少。
我的 CodePen 项目供参考
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></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 textArea = document.createElement('textarea');
textArea.value = quote;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
textArea.remove();
}
},false
);
main();
.mainStatus {
background-color: #fff;
border-radius: 10px;
Box-shadow: 0 3px 10px rgba(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.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.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;
}
<!DOCTYPE html>
<html>
<head>
<style>
/* Main Status */
</style>
</head>
<body>
<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-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>20</option>
<option>10</option>
<option>20</option>
</select>
</div>
<label>(<span class="result-count"></span> items)</label>
</div>
<script>
</script>
</body>
</html>
再次我要告诉我的问题,当点击每个复制按钮时,我需要一个 <span>copied</span>
可见,而不直接将 <span>copied</span>
插入 HTML,即来自 javascript与创建复制按钮相同。
非常感谢回答这个问题的人。
解决方法
您可以通过在调用 document.execCommand('Copy')
后立即调用函数来实现此目的。检查下面的代码片段以了解 showCopied
和 CSS 类 hasCopied
。这应该会暂时显示跨度,并使用 setTimeout
可以在给定的时间(以毫秒为单位)(2000 = 2 秒)后将其删除。
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></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 textArea = document.createElement('textarea');
textArea.value = quote;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('Copy');
showCopied();
textArea.remove();
}
},false
);
function showCopied() {
const copiedElement = document.createElement('span');
copiedElement.innerHTML = "Copied";
copiedElement.setAttribute("class","hasCopied");
resultEl.appendChild(copiedElement);
setTimeout(() => {
resultEl.removeChild(copiedElement);
},2000);
}
main();
/* Main Status */
.mainStatus {
background-color: #fff;
border-radius: 10px;
box-shadow: 0 3px 10px rgba(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.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.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;
}
.hasCopied {
color: black;
position: absolute;
top: 30%;
right: 10%;
}
<!DOCTYPE html>
<html>
<body>
<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-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>20</option>
<option>10</option>
<option>20</option>
</select>
</div>
<label>(<span class="result-count"></span> items)</label>
</div>
</body>
</html>
您可以向按钮添加一个函数 onclick
,每当点击它时,它都会在 x 秒后使用 span
添加和删除 setTimout()
。
此外,我在 class
上添加了一个 css
以设置跨度样式,但您可以随时删除或编辑它。
我在 js
上添加的代码只是函数 showCopied()
,它将创建 element
并添加到 body
。还添加了 fade()
和 unfade()
方法,它们将执行这两种方法使用 fade
的元素的 unfade
和 setInterval()
。
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,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" onclick="showCopied();">Copy</button></div></div>`).join('');
resultEl.append(contents);
};
function showCopied() {
let spanCopied = document.createElement('span');
spanCopied.innerHTML = "Copied!";
spanCopied.classList.add("spanCopied");
document.body.appendChild(spanCopied);
fade(spanCopied);
setTimeout(function() {
document.body.removeChild(spanCopied);
},1400);
}
function fade(element) {
var op = 1; // initial opacity
var timer = setInterval(function () {
if (op <= 0.1){
clearInterval(timer);
element.style.display = 'none';
}
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op -= op * 0.1;
},50);
}
function unfade(element) {
var op = 0.1; // initial opacity
element.style.display = 'block';
var timer = setInterval(function () {
if (op >= 1){
clearInterval(timer);
}
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op += op * 0.1;
},10);
}
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."
},];
}
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 textArea = document.createElement('textarea');
textArea.value = quote;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('Copy');
textArea.remove();
}
},false
);
main();
/* Main Status */
body {
position: relative;
}
.mainStatus{
background-color: #fff;
border-radius: 10px;
box-shadow: 0 3px 10px rgba(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.2);
}
.spanCopied {
background-color: #f2f2f2;
border: 1px solid #f2f2f2;
border-radius: 50px;
position: fixed;
left: 0;
right: 0;
top: 80vh;
margin: auto;
padding: 10px;
z-index: 3;
max-width: 90px;
height: 20px;
text-align: center;
box-shadow: 0 1px 9px 0 rgba(0,.2);
transition: .3s;
opacity: 0;
}
.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.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;
}
<html>
<body>
<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>
可以在此处找到有关 setTimout
的更多信息:https://www.w3schools.com/jsref/met_win_settimeout.asp
可以在此处找到有关 setInterval 的更多信息:https://www.w3schools.com/jsref/met_win_setinterval.asp
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。