Javascript click on specific element always uses wrong/other element id - javascript

I have several html pages and each one has a varying number of buttons that appear based on the page's content.
In just Javascript (since I don't use jquery), I am trying to have the same few lines of code apply to the respective button that was clicked, with the exception that the id tag has to be 'concatenated' into a variable based on the respective button that was clicked.
I saw other solutions on here that cycled through the elements of the class (in this case the "zoom_buttonClass"). However, when I attempt this, regardless of number of buttons on the page or which button was clicked, it is always the LAST button in the list that seems to be the one seen as clicked.
I need to always check if buttons are clicked, but how do I apply the actions based on the ACTUAL button that was clicked?
My HTML and JS code snippets are below:
Thanks in advance.
HTML code:
<div class="modalClass" id="myModalID">
<span class="closeModalClass" aria-label="Close Photo Enlargement Modal Box">×</span>
<img class="modal_contentClass" id="modalEnlargementID">
</div>
<div id="captionID"></div>
JS code:
for (var i = 0;i < document.getElementsByClassName("zoom_buttonClass").length;i++){
document.getElementsByClassName("zoom_buttonClass")[i].addEventListener('click', myFunction
(var attribute = this.getAttribute("id");
var photoIDstring = "photo"+counterX+"ID";
document.getElementById('myModalID').style.display = "block";
document.getElementById('captionID').style.display = "block";
document.getElementById("modalEnlargementID").src = document.getElementById(photoIDstring).src;
captionText.innerText = document.getElementById(photoIDstring).alt;
), false);
};

Well, I started again and I think I may have hit upon a solution. It seems to work.
var captionText = document.getElementById("captionID");
var howManyButtons = document.getElementsByClassName("zoom_buttonClass").length;
var buttonCollection = document.getElementsByClassName("zoom_buttonClass");
for (let i=0; i < howManyButtons; i++) {
buttonCollection[i].onclick = function() {
let photoIDstring = "photo"+(i+1)+"ID";
document.getElementById('myModalID').style.display = "block";
document.getElementById('captionID').style.display = "block";
document.getElementById("modalEnlargementID").src = document.getElementById(photoIDstring).src;
captionText.innerText = document.getElementById(photoIDstring).alt;
}
}

Related

jQuery().detach().appendTo Duplicating all detached elements

I'm trying to add some extra divs to the build-in blogs "read more" links. I've managed to add all the necessary div but I'm struggling to move the text from where it is into another div. I've managed to move it using:
'''jQuery(".readmore").detach().appendTo('.js-add-btn-assets');'''
But instead of moving the one .readmore element to the .js-add-btn-assets. Its making copies of all of the Read More Links on the page and putting them all under the .js-add-btn-assets so I essentially have 4 .readmore elements for every Read More link.
enter image description here
How do I change this so the .readmore class is only moving to the .js-add-btn-assets within its respected parent class instead of all classes on the page?
Like this:
enter image description here
Here all the code I'm currently using
<span class="more-link">
<a href="#" class="readmore">Continue reading
<span class="screen-reader-text">Blog Template</span>
</a>
</span>
var AddButtonWrap = document.querySelectorAll(".more-link");
for (i = 0; i < AddButtonWrap.length; i++) {
AddButtonWrap[i].classList.add("dbtb-button-wrap add-dbtb-button-div");
}
var SelectButtonDiv = document.querySelectorAll(".add-dbtb-button-div"); {
for (i = 0; i < SelectButtonDiv.length; i++) {
var dbtbBtnDiv = document.createElement('div');
dbtbBtnDiv.className = 'dbtb-button js-add-btn-assets';
SelectButtonDiv[i].appendChild(dbtbBtnDiv);
}
}
jQuery(".readmore").detach().appendTo('.js-add-btn-assets');
Do the moves in a third loop.
Something like below should work (untested)
First detach, then Append.
for (i = 0; i < AddButtonWrap.length; i++)
{
var readMore = jQuery(AddButtonWrap[i]).find(".readmore").detach();
readMore.appendTo(jQuery(AddButtonWrap[i]).find(".js-add-btn-assets"));
}

Adding Next & Previous Buttons to modal with JavaScript

I have made a clean modal to use on a website to open images, everything works fine and is pretty nice.
Now I want to make a next image and previous image button for a better user experience.
I have a plan, so I find the index of the current image that is in the modal and I increment it by one on the next button, and decrement it by one on the previous button, HM ok seems easy enough. So how do I go about doing this?
this is my Modal code
window.onload = function() {
var imgArr = document.getElementsByClassName("myImg");
var modalWindow = document.getElementById("myModal");
var modalImg = document.getElementById("img01");
var caption = document.getElementById("caption");
var span = document.getElementById("close");
var modalBlock = document.getElementById("modalBlock");
for (i = 0; i < imgArr.length; i++) {
var picture = imgArr[i];
var list = Array.from(imgArr);
picture.onclick = function() {
openImg(this);
var index = list.indexOf(this);
console.log(index);
};
}
function openImg(pic) {
modalWindow.style.display = "block";
modalBlock.style.transform = "translateY(0%)";
modalImg.src = pic.src;
modalImg.alt = pic.alt;
caption.innerHTML = modalImg.alt;
imgIndex = picture[i];
bodyScrollLock.disableBodyScroll(myModal);
}
};
Now I have the open image that I've clicked on and its index, and I'm stuck on what to do next. I've found the w3 lightbox tutorial, but it's so different from my code I need to swap everything. Does anyone have an idea how I can do this with my own code?
A jsFiddle how it looks at the moment
https://jsfiddle.net/superVoja/eoyda1vh/15/
If you insist on building this from scratch then you will need to start thinking about what you should control with HTML and CSS and leave the rest to do with JavaScript.
I would use Modal window set with Html and hide it with CSS, then when image link and trigger fires I would bring modal to front. Using fadein fadeout, opacity and z-index to make sure that is on the front. Set background to black in order to get the Modal effect.
The faster way is to use library like Lightbox js
Then overwrite using CSS and maybe some js if need to in order to adjust to your liking.
Well, here is the answer I got myself if anyone reads this give yourself some time, you'll find the answer yourself!
I followed my code and did exactly the thing I was trying to do, I found the index of the image that is clicked, and then I just incremented it by one like this.
var next = this.document.getElementById("next");
var slideIndex = "";
for (i = 0; i < imgArr.length; i++) {
var picture = imgArr[i];
var list = Array.from(imgArr);
picture.onclick = function() {
var index = list.indexOf(this);
slideIndex = index;
openImg(imgArr[index]);
console.log(index);
};
}
next.addEventListener("click", function(event) {
openImg(imgArr[(slideIndex += 1)]);
});
It may not look pretty, but it's mine and I am proud of it!
And here is a link How it looks!

.onclick() only fires on the first button

When I clicked the "show comments" button, the result always only shown on the first button even though I clicked on the other button (2nd, 3rd, 4th, ... button). The content I wanted is shown correctly, but it doesn't displayed on the corresponding button.
I already tried to search the solutions over the internet, but I don't think I found the one, especially the other solutions answered with the use of jQuery. (No jQuery solutions, please)
HTML:
<div id="card-container" class="posts-card-container">
<p><strong><em>Press button "Show Posts" above (any user)</em></strong></p>
</div>
some of the script.js:
function showPosts(data) {
let cardContainer = document.getElementById('card-container').querySelector('p');
cardContainer.innerHTML = '';
for (let i = 0; i < data.length; i++) {
let cardTitle = '<h3>TITLE: '+data[i].title+'</h3>';
let cardBody = '<p><em>'+data[i].body+'</em><p>'
let btnShowComments = '<td><button id="button-show-comment" class="button-comments" postId='+data[i].id
+' onclick="loadComments('+data[i].id+')">Show Comments</button></td>';
let cardShowComments = '<div id="show-comments"><p></p></div>';
let newCard = '<div id="card-container" class="child-card-container">'+cardTitle
+cardBody+btnShowComments+cardShowComments+'</div>';
cardContainer.innerHTML += newCard;
}
}
function showComments(data) {
let commentContainer = document.getElementById("show-comments");
commentContainer.innerHTML = '<h2>Comments</h2>';
for (let i = 0; i < data.length; i++) {
let commentPoster = data[i].name+' '+'('+data[i].email+')';
let commentBody = data[i].body;
let newComment = '<p><strong>'+commentPoster+'</strong><em> commented:
"'+commentBody+'</em></p>';
commentContainer.innerHTML += newComment;
}
}
I expect the newComment is displayed on the corresponding button (e.g: if onclick() happened on the third button, newComment must be displayed under the third button), but in my code the newComment always displayed on the first button only.
By definition document.getElementById only returns one DOM element, the first one found, even if multiple with the same id are present. You should find a different way of selecting the button and you should also avoid having multiple elements with the same id as it's intended to be unique.
Edit: I realized after the fact that that's not exactly what you're asking, but you should still avoid using the same id multiple times, it causes all kinds of problems.
The problem here is that querySelector() in showPosts() will only ever give the first element in the set of elements you are looking through that fits the selector.
Which isn't what you want, so instead, we can hook up this function to an event, where we put an onclick event surrounding the div containing all buttons, and use event.target to select the button that you are using. So, something like:
document.getElementById("card-container").onclick=function showPosts(event)
{
let data=getData();//put in something like this
//no needed element checking since only buttons have onclick events
let cardContainer = event.target;
...
}
However, you will have to get data another way in order to use it in the function. Not to mention, you shouldn't be using the same ID in two differing elements. IDs are for directing the browser towards a single element.

Create multiple buttons in JavaScript

I have checked for syntax errors and it does seems like everything is okay, it just does not do anything when loading the body of the page. I know I have linked the script correctly to the html file, because I've already implemented a JS Clock which displays itself in the page as you can see in the pen. Is there anything wrong with my code? Why aren't my 10 buttons displaying? I fear Bootstrap may be preventing me from getting my buttons show up.
My purpose is to create 10 buttons, so that I don't have to write the same code 10 times.
The Codepen is just to check out my code, I work on Atom usually. This is my Codepen!
<div class="container-fluid" id="buttons">
</div>
function createButtons() {
for(i = 0; i < 11; i++) {
var button = document.createElement("<button type=\"button\" class=\"btn btn-outline-success\">Chapter[i]</button>");
var buttonDiv = document.getElementById("buttons");
buttonDiv.appendChild(button);
}
}
document.body.addEventListener("load", createButtons(), false);
The function createElement accept a tag name as argument.
var Chapter = [0,1,2,3,4,5,6,7,8,9,10];
for(i = 0; i < 11; i++) {
var button = document.createElement("button");
button.innerHTML = Chapter[i];
button.className = "btn btn-outline-success";
var buttonDiv = document.getElementById("buttons");
buttonDiv.appendChild(button);
}

JavaScript - Toggle function

Im trying to hide/show a JS function I have defined in a chrome extension.
What I have so far:
The span classes I am trying to hide are label:
dspan.className = "cExtension";
//Create toggle button:
function createToggleButton(){
var toggleButton = document.createElement("button");
toggleButton.innerHTML = "Toggle Overlay";
toggleButton.id = "Toggle"
var header = document.getElementById("header");
header.appendChild(toggleButton);
toggleExtension();
}
// find all spans and toggle display:
function toggleExtension(){
var spans = document.getElementsByTagName('span');
var toggle = function() {
for (var i = 0, l = spans.length; i < l; i++) {
if (spans[i].getAttribute('class') == 'cExtension')
if (spans[i].style.display == 'none') spans[i].style.display = '';
else spans[i].style.display = 'none';
}
}
document.getElementById('Toggle').onclick = toggle;
}
The button shows on the header, however it is unclickable. If I change document.getElementById('Toggle').onclick = toggle; to document.getElementById('Toggle').onclick = alert{"Hello"); the alert is triggered on page load on not onclick. I am trying to get this done in pure JS. Where am I going wrong?
First of all, document.getElementById("Toggle").onclick = alert("Hello"); will set the onclick event to whatever the alert function returns, not the alert function itself. So the alert function happens at page load so it can figure out what to return. So you could do this: document.getElementById("Toggle").onclick = function(){alert("Hello");}; and that might work.
Edit: Scratch everything that was here: I missed that toggle variable set to a function in toggleExtension.
I haven't tested all this so I can't guarantee that it'll all work in your specific case.
if visible is set remove it, otherwise add it
div.classList.toggle("visible");
add/remove visible, depending on test conditional, i less than 10
div.classList.toggle("visible", i < 10 );
Make sure browser support: http://caniuse.com/#feat=classlist
Why not use jQuery?
It will do all hard job for you.
http://api.jquery.com/toggle/
Cheers!

Categories