I have created a function which is used in an event listener function so when the user clicks the left arrow icon on the webpage, a different character image is displayed. The first click works fine and the image is changed, however on the second click, nothing happens. I can't figure out why as from what I can see, the condition of the 'else if' of the statement is true so therefore the src code should change accordingly and change the image.
There are no error messages in the console.
Here is the Event listener:
document.querySelector(".left").addEventListener("click", () => {
leftArrow();
});
Here is the leftArrow function:
leftArrow: () => {
if (document.querySelector(DOMStrings.characterImg).src = characters[0]) {
document.querySelector(DOMStrings.characterImg).classList.add("boris");
document.querySelector(DOMStrings.characterImg).src = characters[1];
const el = document.querySelector(DOMStrings.characterImg);
console.log(el);
} else if (document.querySelector(DOMStrings.characterImg).src = characters[1]) {
document.querySelector(DOMStrings.characterImg).classList.remove("boris");
document.querySelector(DOMStrings.characterImg).src = characters[0];
const el = document.querySelector(DOMStrings.characterImg);
console.log(el);
}
Here is where the images are stored:
const characters = ["Resources/Images/trump.png", "Resources/Images/boris.png"];
Here is where the DOM strings are stored:
const DOMstrings = {
characterImg: ".character-img"
}
Lastly, here is the relevant html:
<div class="character-select">
<ion-icon class="left" name="arrow-dropleft-circle"></ion-icon>
<ion-icon class="right" name="arrow-dropright-circle"></ion-icon>
<img class="character-img" src="Resources/Images/trump.png">
</div>
function myFunction() {
document.getElementById("myImg").src = "https://www.w3schools.com/jsref/hackanm.gif";
}
function myFunctionbygeneric(){
document.querySelector(".test").src = "https://www.w3schools.com/jsref/hackanm.gif";
}
function myFunctionbygenericid(){
document.querySelector("#myImg").src = "https://www.w3schools.com/jsref/compman.gif";
}
<img id="myImg" class="test" src="https://www.w3schools.com/jsref/compman.gif" width="107" height="98">
<button onclick="myFunction()">click here</button>
<button onclick="myFunctionbygenericid()">Query selector by id</button>
<button onclick="myFunctionbygeneric()">Query selector</button>
Use can use like this
let myImage = document.querySelector('img');
myImage.onclick = function() {
let mySrc = myImage.getAttribute('src');
if(mySrc === 'https://www.w3schools.com/jsref/compman.gif') {
myImage.setAttribute ('src','https://www.w3schools.com/jsref/hackanm.gif');
} else {
myImage.setAttribute ('src','https://www.w3schools.com/jsref/compman.gif');
}
}
<img src="https://www.w3schools.com/jsref/hackanm.gif" />
Related
Why does the input element not get updated?
function route() {
let textfield = {
inputEl: document.querySelector('#textfield'),
setValue: function(str) {
this.inputEl.value = str;
}
};
textfield.inputEl.addEventListener('click', function(event) {
document.body.innerHTML += '<button id="select">Select</button>';
owner(textfield);
});
}
function owner(controller) {
document.querySelector('#select').addEventListener('click', function(event) {
controller.setValue("Hello Universe!");
});
}
route();
I know how to go around this problem but i prefer to use controller.setValue() to update the input.
UPDATED
I have updated the code below - hopefully this is closer to what you are trying to achieve.
I needed to add a container where to place the button (instead of adding it to the body) - so added a wrapper container like this:
<div id="container">
<input type="text" id="textfield" />
</div>
Then, we can append the button to it as a child, like this:
document.getElementById('container').appendChild(btn);
See updated code below
function route() {
let textfield = {
inputEl: document.querySelector('#textfield'),
setValue: function(str) {
this.inputEl.value = str;
}
};
textfield.inputEl.addEventListener('click', function(event) {
// add the button if it's not already in there
if(document.getElementById('select')){
return;
}
let btn = document.createElement('button');
btn.id = 'select';
btn.innerHTML = 'Select';
document.getElementById('container').appendChild(btn);
owner(textfield);
});
}
function owner(controller) {
document.getElementById('select').addEventListener('click', function(event) {
controller.setValue("Hello Universe!");
});
}
route();
<div id="container">
<input type="text" id="textfield" />
</div>
I am using a forEach method to add an event listener to each button, everything is working the first time, the function is calling the filterElements function as wanted BUT when i try to click a second time the code doesen't respond, could it be because of my HTML collection that I am transforming to an Array using Array.from or what could it be ?
function filterPhotograpsIndividualTages(dataJson) {
const individualTags = Array.from(document.getElementsByClassName('individual-tags'));
individualTags.forEach(btn => btn.addEventListener('click', () => { //this is the forEach method
/*onClick clear the old HTML of photographersDiv and call
the function filterElements to execute his block code!*/
document.getElementById('container').innerHTML = "";
filterElements(dataJson, btn);// function is invoked here
}))
};
// this function is being called inside of the filterPhotograpsIndividualTages function
function filterElements(dataJson, btn){
dataJson.photographers.forEach(photographe => {
if(photographe.tags.indexOf(btn.id) != -1) {
const photographersDiv = document.getElementById('container');
const div = document.createElement("div");
div.innerHTML = `
<div class="photographerContainer">
<a href="photographers.html?id=${photographe.id}">
<div class="portraitBox">
<img src="${photographe.portrait}" alt="photo">
</div>
<h1 class="name">${photographe.name}</h1>
</a>
<p class="city">${photographe.city}, ${photographe.country}</p>
<p class="tagline">${photographe.tagline}</p>
<p class="price">${photographe.price}€/jour</p>
<p class="tags">${photographe.tags.map(tag => `<button id=${tag} class="tag individual-tags">#${tag}</button>`).join(" ")}</p>
</div>
`
photographersDiv.appendChild(div);
}})
};
When you add event like this, it only binding to DOM you have selected with getElementsByClassName not with the one re-add after delete
Instead you should bind whole document and check event's target
document.addEventListener('click', function(event) {
if (event.target.classList.contains('your_class')) {
Function();
}
});
function whatami(img){
console.log(img.key);
}
let animals = ["frog","frog","sheep","sheep","snail","snail","mouse","mouse","bat","bat","walrus",
"walrus","giraffe","giraffe","zebra","zebra","dog","dog","octopus","octopus","hippo",
"hippo","camel","camel","pig","pig","rhino","rhino","rooster","rooster","panda","panda",
"turtle","turtle","raccoon","raccoon","polar bear","polar bear","lion","lion","bison",
"bison","orca","orca","snake","snake","shark","shark","toucan","toucan","butterfly",
"butterfly","anteater","anteater","seal","seal","armadillo","armadillo","rooster","rooster"]
var array = shuffle(animals);
let images = array.map(image => {
return <img onClick = {whatami(image)} key={image} src={"/animalgameback.jpg"} alt="" className="img-responsive"/>
});
return (
<div>
<div>
{images}
</div>
</div>
)
}
}
I have this list of images and I need a way to find which one is clicked when I press one of them. How do I do this?
The click must receive a callback function. Try writing the onClick with a arrow function like this
onClick = { () => { whatami(image)} }
I would write ()=>{whatami(image)} instead of whatami(image). LEt me know if it works.
Short version: I need a button to carry out three seperate actions when clicked three times.
Long version: I have one page of my site where there is a little readable introduction with illustrations. I have a button that changes the first image to a second one when clicked once. When the user has finished reading the second image, clicking the same button then navigates to a different html location, using a multiclick function.
However, I need to add a third image to the introduction. I therefore need the button to change image1 to image2 on the first click, change image2 to image3 on the second click, then navigate to the next html location on the third click.
Is this possible? All of the multiclick solutions I've seen so far only cover two events. Or they use 'onclick', which I've been advised is bad practice. Can I modify the code I already have to add a third click action (maybe changing the value of calledonetime)? Or am I going in completely the wrong direction?
Working JS code for two actions:
<script>
jQuery(document).ready(function () {
$('#multiclick').click(function () {
multiclick();
});
});
var calledonetime = false;
function multiclick() {
if(calledonetime=== false) {
calledonetime = true;
var image = document.getElementById("infoscreentext");
image.src="infoscreentext2.png"; } /* action on first click */
else {
window.location.href = "castleview.html"; /* action on second click */
}
}
</script>
The HTML:
<body>
<div id="wrapper" div class="toshow">
<img src="infoscreenarrows.jpg" alt="Title" />
<img src="infoscreentext.png" id="infoscreentext" alt="" />
</div>
<div id="enterbutton">
<input type=image id=multiclick img src="silvercogarrow.png" alt="Enter" >
</div>
</body>
You can use a switch:
var clickCount = 0;
function clickHandler () {
clickCount += 1;
switch (clickCount) {
case 1:
// do action #1
break;
case 2:
// do action #2
break;
case 3:
// do action #3
break;
}
}
Or you can use an Array:
var clickCount = -1;
var actions = [];
function action1 (e) { /* prevent default, switch to image 1 */ }
function action2 (e) { /* prevent default, switch to image 2 */ }
function action3 () { /* follow hyperlink */ }
actions.push(action1);
actions.push(action2);
actions.push(action3);
function clickHandler (event) {
clickCount += 1;
actions[clickCount](event);
}
I would say do it with three different clicks as below with css html and js
<script>
jQuery(document).ready(function () {
$('#multiclick').click(function () {
multiclick();
});
});
var image1 = document.getElementById("infoscreentext");
var image2 = document.getElementById("infoscreentext2");
var image3 = document.getElementById("infoscreentext3");
image1 && image1.addEventListener('click', () => {
image1.classList.add('hide');
image2.classList.remove('hide');
});
image2 && image2.addEventListener('click', () => {
image2.classList.add('hide');
image3.classList.remove('hide');
});
image3 && image3.addEventListener('click', () => {
window.location.href = "castleview.html";
});
</script>
.hide {
display: none;
}
<body>
<div id="wrapper" div class="toshow">
<img src="infoscreenarrows.jpg" alt="Title" />
<img src="infoscreentext.png" class="" id="infoscreentext" alt="" />
<img src="infoscreentext2.png" class="hide" id="infoscreentext2" alt="" />
<img src="infoscreentext3.png" class="hide" id="infoscreentext3" alt="" />
</div>
<div id="enterbutton">
<input type=image id=multiclick img src="silvercogarrow.png" alt="Enter" >
</div>
</body>
Yes this is possible and so easy but why do you use a boolean for that? I suggest using an Integer for that, so let's start:-
<script>
jQuery(document).ready(function () {
$('#multiclick').click(function () {
multiclick();
});
});
var clickedCount = 0;
function multiclick() {
clickedCount++;
if(clickedCount == 1) {
var image = document.getElementById("infoscreentext");
image.src="infoscreentext2.png"; /* change image on first click */
var calledonetime[1];
} /* add 1 count to calledonetime */
else if(clickedCount == 2) {
var image = document.getElementById("inforscreentext2");
image.src="infoscreentext3.png"; } /* change image on second click */
else {
window.location.href = "castleview.html"; /* action on third click */
}
}
</script>
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>