Clipboard.js loop buttons - javascript

I use clipboard.js and after a click on one of my buttons I want to show a success message under the button, but I am not able to loop throught.
This is the button:
<button type="button" class="clipboard-button button-rect" data-clipboard-text="{{ site.author.email|safe_email }}">
<span class="button-text">Get in touch</span>
<span class="clipboard-message">My E-Mail has been copied</span>
</button>
And this the js:
var clipboard = new ClipboardJS('.clipboard-button');
clipboard.on('success', function () {
var message = document.querySelectorAll('.clipboard-message');
message.style.opacity = '1';
setTimeout(function () {
message.style.opacity = '0';
}, 2000);
});
I want to show the message under the button which was pressed and not for every button.
I would appreciate your help, I tried so much. I'm an JS beginner btw, so be patient please. :)

On thing you should look at is achieving to retrieve the clicked DOM element (a button in this case). It will then be easy to find the corresponding .clipboard-message span element.
To retrieve the clicked element you can use the parameter given to the success event callback function, like stated here: https://clipboardjs.com/#events
Then your JavaScript code becomes:
var clipboard = new ClipboardJS('.clipboard-button');
clipboard.on('success', function (e) {
// e.trigger corresponds to the clipboard-button DOM element that triggered the event
// You can then use querySelector(...) to retrieve to first child element with the class clipboard-message
var message = e.trigger.querySelector('.clipboard-message');
message.style.opacity = '1';
setTimeout(function () {
message.style.opacity = '0';
}, 2000);
});
Here is a working code snippet for you to try:
var clipboard = new ClipboardJS('.clipboard-button');
clipboard.on('success', function (e) {
var message = e.trigger.querySelector('.clipboard-message');
message.style.opacity = '1';
setTimeout(function () {
message.style.opacity = '0';
}, 2000);
});
.clipboard-message {
color: green;
opacity: 0;
}
<script src="https://cdn.jsdelivr.net/npm/clipboard#2/dist/clipboard.min.js"></script>
<button type="button" class="clipboard-button button-rect" data-clipboard-text="{{ site.author.email|safe_email }}">
<span class="button-text">Get in touch</span>
<span class="clipboard-message">My E-Mail has been copied</span>
</button>
<button type="button" class="clipboard-button button-rect" data-clipboard-text="{{ site.author.email|safe_email }}">
<span class="button-text">Here is your ID</span>
<span class="clipboard-message">My ID has been copied</span>
</button>

Related

Callback Function does not work with for Loop

Why doesn't the callButtonTwo() function work on all buttons? Only button1 reacts to it?
document.querySelector("h1").addEventListener("click", function() {
alert("Working!");
})
var totalButton = document.querySelectorAll(".testSecond").length;
for (var i = 0; i < totalButton; i++) {
document.querySelectorAll(".testSecond")[i].addEventListener("click", function() {
var buttonNow = this.innerHTML;
callButtonOne(buttonNow);
callButtonTwo(buttonNow);
});
}
function callButtonOne() {
alert("I got clicked!");
};
function callButtonTwo() {
var changeRed = document.querySelector(".testSecond");
changeRed.classList.add("red");
setTimeout(function() {
changeRed.classList.remove("red");
}, 300);
};
.red {
background-color: red;
}
<h1 class="testFirst">Hello World!</h1>
<button class="testSecond button1" type="button" name="button">button1</button>
<button class="testSecond button2" type="button" name="button">button2</button>
<button class="testSecond button3" type="button" name="button">button3</button>
<button class="testSecond button4" type="button" name="button">button4</button>
<button class="testSecond button5" type="button" name="button">button5</button>
While, inside your click handler you have var buttonNow = this.innerHTML; which operates on that button, when you call callButtonTwo you say var changeRed = document.querySelector(".testSecond"); which operates on the first button (no matter which button you click).
You need to tell it which button you are dealing with (e.g. by passing this as an argument)
The problem is, that your querySelector in callButtonTwo just finds the first button because all of them have the same class .testSecond.
One possible solution is to add the reference of the button which should be colored red to the callButtonTwo function and use the reference to add the class name.
It would look like this:
function callButtonTwo(button) {
button.classList.add("red");
setTimeout(function() {
button.classList.remove("red");
}, 300);
};
And you would call it like this: callButtonTwo(this);
Here's a working example based on the code you provided.
Inside callButtonTwo you're querying .testSecond again which will always return the first element in the page with that class. If you want to handle each button differently you should pass the button element as a parameter to callButtonTwo, like so:
var totalButton = document.querySelectorAll(".testSecond").length;
for (var i = 0; i < totalButton; i++) {
document.querySelectorAll(".testSecond")[i].addEventListener("click", function() {
var buttonNow = this.innerHTML;
callButtonOne(buttonNow);
callButtonTwo(this); // 'this' in this case is the clicked button element
});
}
[...]
function callButtonTwo(button) {
button.classList.add("red");
setTimeout(function() {
button.classList.remove("red");
}, 300);
};
I would also consider to change the way you're iterating your elements in order to query the DOM less frequently:
// 'querySelectorAll' returns an array which can be directly iterated using its method 'forEach'
document.querySelectorAll(".testSecond").forEach(function(button) {
button.addEventListener("click", function() {
var buttonNow = this.innerHTML;
callButtonOne(buttonNow);
callButtonTwo(this);
});
});

Javascript object methods evaluate functions

first of all, I'm new to javascript.
my question is how can I add an event listener to the button and call the function from the myObj script. I tried to google but I don't know what is the keyword for that. thank you
<div id="my-btn"></div>
<script>
myObj.button('my-btn',{
onClick: function() {
alert('Button is clicked !');
},
onCancel: function() {
alert('You cancel the process !');
}
});
</script>
and my object
var myObj = {
button: function(btnId, methods)
{
var btn = document.getElementById(btnId);
for (var method in methods)
{
if (method.toLowerCase() == 'onclick')
{
//btn.addEventListener('click', function(e) {
//}
// i want to add listener
// and call the function "onClick"
}
}
// render button
btn.innerHTML = '<input type="button" value="My Button"></button>';
}
}
thank you for your advice.
Here's one way.
<html>
<head></head>
<body>
<div id="my-btn"></div>
</body>
<script>
const myObj = {
button: (btnId, methods) => {
const btn = document.getElementById(btnId);
for (let method in methods) {
const nameLower = method.toLowerCase();
if (nameLower.startsWith('on')) {
btn.addEventListener(nameLower.substr(2), function(e) {
methods[method]();
});
}
}
// render button
btn.innerHTML = '<input type="button" value="My Button"></button>';
}
};
myObj.button('my-btn',{
onClick: () => alert('Button is clicked !'),
onCancel: () => alert('You cancel the process !')
});
</script>
</html>
We can map the function names to their events by converting to lowercase and stripping off the "on" prefix. So onClick becomes click. You could simplify things by just using the standard event names in your call to myObj.button.
Start by iterating over the functions, map the name and add the event listener. Inside the event listener all we do is call the function provided in the arguments.

Javascript - use callback with addEventListener for "remove all" button

I'm adding a "remove all" button to my chrome extension which as the name suggests should serve to remove all saved links.
The button works only after I have performed some other action first (adding a link, removing a link etc) but of course, I want it to work right away.
I have read that this may be due to the code being asynchronous so I tried introducing a callback function with the help of this question: Add callback to .addEventListener however, it's still performing the same way it did before so maybe that wasn't the issue after all, or I may have read the other question wrong. I appreciate any tips so thank you in advance. I will try to figure it out myself in the meantime.
var urlList = [];
var i = 0;
document.addEventListener('DOMContentLoaded', function() {
getUrlListAndRestoreInDom();
// event listener for the button inside popup window
document.getElementById('save').addEventListener('click', addLink);
});
function addLink() {
var url = document.getElementById("saveLink").value;
addUrlToListAndSave(url);
addUrlToDom(url);
}
function getUrlListAndRestoreInDom() {
chrome.storage.local.get({
urlList: []
}, function(data) {
urlList = data.urlList;
urlList.forEach(function(url) {
addUrlToDom(url);
});
});
}
function addUrlToDom(url) {
// change the text message
document.getElementById("saved-pages").innerHTML = "<h2>Saved pages</h2>";
var newEntry = document.createElement('li');
var newLink = document.createElement('a');
var removeButton = document.createElement('button');
removeButton.textContent = "Remove";
removeButton.type = "button";
removeButton.className = "remove";
removeButton.addEventListener("click", function() {
var anchor = this.previousElementSibling;
var url = anchor.getAttribute("href");
removeUrlAndSave(url);
this.parentNode.remove();
});
newLink.textContent = url;
newLink.setAttribute('href', url);
newLink.setAttribute('target', '_blank');
newEntry.appendChild(newLink);
newEntry.appendChild(removeButton);
newEntry.className = "listItem";
document.getElementById("list").appendChild(newEntry);
}
function removeUrlAndSave(url) {
var index = urlList.indexOf(url);
if (index != -1) {
urlList.splice(index, 1);
saveUrlList();
}
}
function addUrlToListAndSave(url) {
urlList.push(url);
saveUrlList();
//}
}
function saveUrlList(callback) {
chrome.storage.local.set({
urlList
// }, function() {
// if (typeof callback === 'function') {
// //If there was no callback provided, don't try to call it.
// callback();
// }
// });
});
function removeMe(i) {
var fullList = documents.getElementsByClassName('listItem');
listItem[i].parentNode.removeChild(listItem[i]);
}
function removeAll() {
var removeList = document.getElementsByClassName("listItem");
while (removeList[0]) {
removeList[0].parentNode.removeChild(removeList[0]);
};
}
function registerElement(callback) {
var element = document.getElementById("remove-all-button");
element.addEventListener("click", callback);
}
registerElement(removeAll);
#list {
min-height: 360px;
max-height: 360px;
width: 300px;
margin: auto;
overflow: scroll;
}
<head>
<script type="text/javascript" src="popup.js"></script>
<link rel="stylesheet" href="popup.css">
</head>
<body>
<div>
<span id="hot-button">Hot Drops</span>
<li id="removeAll">
<button id="remove-all-button"> Remove All</button>
</li>
<span id="saved-pages"></span>
<div>
<ul id="list"></ul>
</div>
</div>
<input type="button" id="save" value="Add">
<input type="text" id="saveLink" name="member" value=""><br/>
<span id="settings-button">Settings</span>
</body>
</html>
there you go
jsfiddle
had to write this line to post link
http://jsfiddle.net/1w69bo8k/ - you made a lot of mistakes, where you put certain code, to using variables I never saw them defined anywhere in code
(you keep editing the question, I went from this fiddle you provided)
change back to your getUrlListAndRestoreInDom function, deleted the storage code
you update the storage and the urlList manually, rather do it after the update of local is successful

Change image of button when pressed, using javascript

I am trying to set a value in variable when a specific button is pressed. I want this button to be in pressed state when i again reload the page. I am trying to check the value of variable in pageloaded function but i don't know that how can change the state of button in javascript. Pls help
HTML:
<button onclick="changeit()"><img src="bla.jpg" id="changevalue"></button>
JS:
function changeit(){
document.getElementById("changevalue").src = "newimg.jpg";
}
HTML:
<button id="myButton"><img src="myImage.jpg" id="myImage"></button>
JS:
var NEW_IMAGE_URI = "myNewImage.jpg";
var buttonState = false;
function changeButtonImage(){
if (buttonState) {
return;
}
document.querySelector("#myImage").src = NEW_IMAGE_URI;
buttonState = true;
}
document.addEventListener("DOMContentLoaded", function(event) {
var buttonElement = document.querySelector('#myButton');
buttonElement.addEventListener('click',changeButtonImage);
});

Adding a timed delay after pressing a button to prevent button spam

Say I have 4 buttons
<button id="one">One</button>
<button id="two">Two</button>
<button id="three">Three</button>
<button id="four">Four</button>
and to prevent spam, I want to make it so that whenever any of the buttons are pressed, none of them are able to be pressed again for the next 0.6 seconds.
How might I achieve this?
You can use this javascript code:
var btns = document.getElementsByTagName('button');
for(var i=0;i<btns.length;i++){
btns[i].addEventListener('click', function(){
disableButtons(true);
setTimeout(function(){disableButtons(false);}, 600);
});
}
function disableButtons(state){
for(var i=0;i<btns.length;i++){
btns[i].disabled = !!state;
}
}
Of course, you need to run this code after your page is loaded.
One way to do this is with a "click shield".
Here's how you can do it with jQuery.
var clickShield = false;
$('button').on('click', function() {
if (!clickShield) {
clickShield = true;
console.log('handle click event');
setTimeout(function() {
clickShield = false;
}, 600);
}
});
With jQuery you can do something like:
<button id="one">One</button>
<button id="two">Two</button>
<button id="three">Three</button>
<button id="four">Four</button>
$("button").on("click", function(e) {
$("button").attr('disabled', 'disabled');
setTimeout(function() {
$("button").removeAttr('disabled');
}, 600);
});
// Get button elements
var els = document.getElementByTagName('button');
// Add an event handler to click event
// that triggers settimeout to set the disable value
els.addListener('click', function(){
setTimeout(els.disable, 600);
}, true);
not tested
Like prasadmadanayake says in his comment you can do it by disable/enable the button.
Here is a working example:
var intVal = 0;
$('button').on('click',function (e) {
var id = $(this).attr('id');
$('#'+id).attr('disabled', 'disabled');
setTimeout(function(){enable(id)}, 3000);
return true;
});
function enable (id) {
$('#'+id).removeAttr('disabled');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button id="one">One</button>
<button id="two">Two</button>
<button id="three">Three</button>
<button id="four">Four</button>

Categories

Resources