adding images to a span - javascript

i am creating a black jack game, and im trying to have the suit appear next to the card that is drawn. However the suit is only showing on the last card drawn, but i want it to be shown after every card thats drawn.
const drawCard = () => {
getCardValue() //returns value from ace-k
getCardSuit() //return heart, spade etc. and sets the corresponding src to img
let cardSpan = document.createElement('span');
cardSpan.innerHTML = ` ${cardNumber} ${cardSuit} `
cardSpan.appendChild(img)
playerHand.append(cardSpan)
}
(im using helper functions to get the card number and card suit). The above code is creating a new span for every card, but like i said only the last card is appending the image. when i console.log it in dev tools i get this
<span>3 clubs</span>
<span>
5 Hearts
<img src... etc>
</span>
any body know how i can get it to appear next to every card? thank you.

Sounds like you only have one image, which is already appended somewhere else, so it moves to the other span. How about:
const image = document.createElement('image')
image.src = ???
cardSpan.appendChild(image)

Related

back and forth between nodes in vanilla javascript

I'm expanding a site (menright.com) that displays about fifty years of photos. This link goes to the first photo page: (https://menright.com/pages/photoPages/photos-1967.php). Each photo is followed by a caption, and there is a button that allows the viewer to see a longer description that replaces the caption. The button isn't working here but allows you to see what I'm talking about.
To implement this I have an img (the button) inside of a p tag (the caption). Clicking the button substitutes the longer description drawn from the alt and the title in a second img (the picture) immediately above the caption.
I can't use IDs since there are many captions and pictures on each page.
Here is the HTML skeleton of the significant parts of the problem:
<img alt='long description' title='location image taken' />
<p class='the caption'> <img class='get long description button' /> </p>
I'm thinking I have to find the node of the target (the button), track its parent (the caption), and then get the alt and title from something like a previousSibling (the picture) and use the innerHTML of the parent (the caption) to display the long description.
Am I correct in this assumption, or is there another way to do this? And if this is the technique I need to use, how do I do it? I'm totally new to using nodes in my vanilla Javascript, and I don't want to add JSquery or other libraries to my pages.
This is my first post here, though I've used the site for years. Thanks for any help you might provide!
I'm thinking I have to find the node of the target (the button), track its parent (the caption), and then get the alt and title from something like a previousSibling (the picture) and use the innerHTML of the parent (the caption) to display the long description.
Am I correct in this assumption, or is there another way to do this?
If you stick to that structure, yes, that's what you'd do (probably previousElementSibling so you don't have to worry about intervening Text nodes), and setting textContent rather than innerHTML unless you want < and & in the text to be interpreted as HTML. You'd probably do it via event delegation on whatever container has all of these in it (body, if there's nothing nearer):
theContainer.addEventListener("click", event => {
const btn = event.target.closest(".get.long.description.button");
if (btn && theContainer.contains(btn)) {
const p = btn.parentElement;
const alt = p.previousElementSibling?.alt;
if (alt) {
p.textContent = alt; // `textContent` assuming you don't have tags
}
}
});
But if you can wrap all of that in an element:
<div class="wrapper">
<img alt='long description' title='location image taken' />
<p class='the caption'>
<img class='get long description button' />
</p>
</div>
...you can make it more robust:
theContainer.addEventListener("click", event => {
const wrapper = event.target.closest(".container");
if (wrapper && theContainer.contains(wrapper)) {
const p = wrapper.querySelector(".the.caption");
const alt = wrapper.querySelector(".location.image.taken")?.alt;
if (alt) {
p.textContent = alt; // `textContent` assuming you don't have tags
}
}
});
That doesn't rely on the exact relationship between the elements, just that they're all in the same container, so you can move them around as the page design evolves without changing your code.

trying to grab image url within div's children

I'm making an extension that grabs an image URL within the "uCW" div on an HTML page.
Currently, I have:
var uCW = jNode.closest("div._q7o");
var image = uCW[0].children[1].getElementsByTagName("img")[0].src;
console.log(image);
That finds the image by going into the div/children and pulling the image. Unfortunately, this method is problematic, since it stops working if the children change, which they regularly do.
Instead, I want to select the image by searching the div and all its children (there are a lot of them) for the first image/string that starts with "https://external" (all the images I want start this way, and that doesn't seem to change.)
This is what I tried:
var uCW = jNode.closest("div._q7o");
var image = $(uCW).find([name^="https://external"]).src;
console.log(image);
This doesn't work. The console just prints "undefined."
You could do it like this, if ucw is a classname (if it's an id, you would write $("#ucw") instead):
var image = $(".ucw").find('[src^="https://external"]').attr("src");
console.log(image);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="ucw">
<img src="https://external/1.jpg"/>
</div>
If your images have a name attribute with the source of the image as value, you can also adjust your attempt to fetch the images via their name attribute like you did:
var image = $(".ucw").find('[name^="https://external"]').attr("src");

How can the same button play different videos every time it's clicked?

I'm trying to hack together a video player to play local files in a cool interface, it's literally only ever going to be used by my family so the code doesn't have to be beautiful or anything. I've basically got a table full of DVD covers, and when clicked each one of them is supposed to open a modal with a video player for Chrome.
I've managed to do all of this, except I'm struggling to get it so the same button/image can be pressed and a different video file gets shown. Basically this is what I've got inside every table cell:
<th>
<div class="imageBox">
<div class="imageInn">
<img id="standardDVD" src="images/dvdCover1.jpg" alt="Snow">
<div class="hoverImg">
<img id="buttonPlay" src="images/play.png" alt="play">
</div>
</div>
</div>
</th>
I've then got the following JavaScript code to show the modal when that's clicked (I basically took it from here and modified it to show a video instead):
var playButton = document.getElementById('buttonPlay');
playButton.onclick = function(){
modal.style.display = "block";
document.getElementById("videoModal").src = videoToPlay;
}
var dvdCover = document.getElementById('standardDVD');
dvdCover.onclick = function(){
modal.style.display = "block";
document.getElementById("videoModal").src = videoToPlay;
}
(I've got two basically identical ones so it works if either the DVD cover or the button is clicked)
My thinking was to try and somehow get the src of the image (which should be doable if it's the image that's clicked, but I'm not too sure about how to get the dvd cover src if the button is the one getting clicked. From there I was thinking of having a simple (but long) JavaScript if function to convert each DVD cover to the src of the right video file, and simply change the videoToPlay variable used in the modal:
var videoToPlay = "movies/a Movie.mp4";
Edit since I don't think I was clear: I have a table with 55 different DVD covers, each in one cell and each with the identical HTML code except with a different dvdCover1.jpg image. What I'm trying to do is get it so each one plays the correct video, without having to make a new function for each.
I realize this is definitely not best practice, and any suggestions to improve the overall setup are appreciated - although I'm trying to get this together for Christmas and my knowledge of HTML and CSS is basically zero which is why I'm currently going for simplicity: only 5 people will ever see this anyway so best practice isn't necessarily important!
One option is to create an array with all your movies paths:
var videosToPlay = [
"movies/a Movie.mp4",
"movies/movie a.mp4",
"movies/a new Movie.mp4"
];
Then you need to get all handlers like this:
var dvdsCover = document.getElementsByClassName('standard-dvd-class-in-all-table');
Then just define the click event to all of them using the matching index. Your array must match the full table order of DVDs:
[...dvdsCover].forEach((dvdCover, index) => {
dvdCover.onclick = () => {
modal.style.display = "block";
document.getElementById("videoModal").src = videosToPlay[index];
};
});
Hope it helps.

onmouseover & onmouseleave functions not working properly

I'm new to this site and relatively new to web development. I was trying to incorporate javascript to this webpage I made with just HTML & CSS. This webpage is basically an online store for certain products and what I was trying to do was that when someone has their mouse over one of the products, it would provide some details such as the name of the product and the price and when they move the mouse out, it would go back to just an image of the product. For some reason, with my code, it will change the elements so that it shows the details but it won't change back to the original image after the mouse moves away.
I've tried everything I could think of and the goal of this project was to make sure I had an understanding of javascript so I was trying to do this without any jquery. Any advice would be greatly appreciated.
Here is the code:
//Holds all div elements with class attribute "productlink" which hold the product images
var products = document.getElementsByClassName("productlink");
//When this function is called, the product image is changed to show an image of the product, the name and price
//classNum - specifc class element being called
//priceAmount - price of product
//describe - Description/Name of the product
function hoverDetails(classNum, priceAmount, describe) {
//Div container for details, image of product, price of product and description
var divContainer = document.createElement("div");
var image = document.createElement("img");
var price = document.createElement("p");
var description = document.createElement("p");
var priceTextNode = document.createTextNode(priceAmount);
var descriptionTextNode = document.createTextNode(describe);
description.appendChild(descriptionTextNode);
price.appendChild(priceTextNode);
image.src = picArray[classNum];
divContainer.setAttribute("class", "newdiv");
image.setAttribute("class", "newimg");
price.setAttribute("class", "itemprice")
description.setAttribute("class", "itemdescription");
products[classNum].parentNode.style.textDecoration = "none";
divContainer.appendChild(image);
divContainer.appendChild(description);
divContainer.appendChild(price);
//This should replace the current image with the details specified eariler
//childNode is set to 1 due to a #text node in the div
products[classNum].replaceChild(divContainer, products[classNum].childNodes[1]);
}
//This function, when called, replaces the detailed product with just an image of the product
function originalImage(classNum) {
var image = document.createElement("img");
image.setAttribute("class", "display_image");
image.src = picArray[classNum];
products[classNum].replaceChild(image, products[classNum].childNodes[1]);
}
Here is the element that is referencing these functions:
<a href="#">
<div class="productlink" onmouseover="hoverDetails(0,'$85.95','Printer') "onmouseout="originalImage(0)">
<img class="display_image" src="images/printer1.jpg" />
</div>
Don't the mind the variable names and I'm sorry if my code seems too much. Any help would be appreciated.
EDIT: Just to let people know, both functions work. The onmouseleave event works when the onmouseover event is not attached. Additionally, the code works when the onmouseover event is replaced with onclick. When I replace onmouseover with onmouseenter, the code works once but never again. This is very strange.
There is actually another mouse event called onmouseout. Add another attribute called onmouseout="removeHoverDetails()" and then inside of removeHoverDetails() select everything and say .visibility = "hidden"; Or whatever way you want to use to get rid of the elements in the popup. Also check out w3schools tutorial on onmouseover and onmouseout: http://www.w3schools.com/jsref/event_onmouseover.asp
Okay I found the solution to my problem. I put the onmouseover event on the image element of the "productlink" div an left the onmouseout event on the div and looks to be working fine.

Javascript - changing image won't work unless i alert()

I'm building a JavaScript based poker game that get some updates from a server via Ajax.
when player are in "show down" each one of them supposed to show what card he holds,
I'm changing the pictures of each showdown hand (from blank card to an actual card i.e King of spades img)
I have the weirdest problem: when i change the images (as shown in the code below),
the images wont change from blanks to actual cards, they remain "blank.png".
whats weird is if i remove the "//" from line9 (and get an alert message) the cards are shown with their actual image i.e "Ace of spades.png"..
what's with that?!
function executeShowDown(){
(...)
var playerCard1Id = "#player"+(playerNum)+"card1"; //the specific image id for hole card #1
var playerCard2Id = "#player"+(playerNum)+"card2"; //the specific image id for hole card #2
var card1 = "res/images/cards/"+handArr[0]+".png";
var card2 = "res/images/cards/"+handArr[1]+".png";
$(playerCard1Id).attr("src", card1);
$(playerCard2Id).attr("src", card2);
$(playerCard1Id).css('visibility','visible');
$(playerCard2Id).css('visibility','visible');
//alert("endShowDown"); ##### LINE 9 #####
return;
}
This might be happening too fast. Maybe add something to make it wait for 1 second or so, or you could use a callback function, I see you use return there so maybe the other function where you call this from does not wait for it to end.
Good luck!

Categories