how to improve the div switcher ReactJs - javascript

How to improve this code?
There are 3 buttons on the page and each button is responsible for its own component (there is just text for now) If you click on the "1" button, one component appears, click on 2, the first one disappears and another component appears, etc.
I did this using conditions, but I think that this is not good, especially when there are millions of buttons and you have to write a condition every time. I know that in Js this can be done in several lines, no matter how many elements there are
let [current, setcurrnet] = useState(1)
function se(props){
setcurrnet(props)
}
function Modl(props){
if(props.el == 1){
return("Hi")
}
else if(props.el == 2){
return("By")
}
else{
return("Hello By")
}
}
<button onClick={()=>se(1)}>1</button>
<button onClick={()=>se(2)}> 2</button>
<button onClick={()=>se(3)}>3</button>
<Modl el={current} />

Related

How can I use getElementById or querySelectorAll for an infinite number of IDs? (creating toggle buttons to show/hide divs)

Javascript noob here, as you can probably tell, and was wondering if anyone could help me clean this up. Trying to avoid Jquery, please.
It’s pretty basic: There’s a toggle button, a section of content, and a close button within that section of content. The content is hidden by default, but when the toggle button is clicked, the content becomes visible and the user gets auto-scrolled to it. When the close button is clicked, the section of content disappears and the user is auto-scrolled back up to the main section with all the toggle buttons.
This should be repeated for individual sections of content, with each unique content section associated with its corresponding toggle button.
JSFiddle: https://jsfiddle.net/bythrees/mw5nh1cd/51/
This works as intended but is there a way to clean up the Javascript so that if more than 2 sections of content are desired, it will happen automatically, without having to add another section — Toggle 3, Toggle 4, Toggle 5, and so on — to the JS? I was looking into querySelectorAll (I don't HAVE to be using IDs, can easily use classes) and map but don’t know how to make it work.
Here's the code I'm using. It just seems dumb if I have to repeat all of that for each Toggle, changing the numbers for each one.
document.addEventListener('DOMContentLoaded', function() {
const toggle1 = document.getElementById('toggle-1');
const toggleContent1 = document.getElementById('toggle-content-1');
const closeContent1 = document.getElementById('close-toggle-1');
const toggle2 = document.getElementById('toggle-2');
const toggleContent2 = document.getElementById('toggle-content-2');
const closeContent2 = document.getElementById('close-toggle-2');
// Toggle 1
if (toggle1) {
toggle1.addEventListener('click', () => {
toggleContent1.classList.toggle('show');
});
closeContent1.addEventListener('click', () => {
toggleContent1.classList.remove('show');
});
}
// Toggle 2
if (toggle2) {
toggle2.addEventListener('click', () => {
toggleContent2.classList.toggle('show');
});
closeContent2.addEventListener('click', () => {
toggleContent2.classList.remove('show');
});
}
});
Thanks in advance!

Displaying elements from an array into the site doesn't work

I am learning some JS now and I am having some trouble with a new functionality I am trying to add to a website.
I have designed a div with a preview image and a navigation bar below with 4 thumbnails of the images you can navigate through, I have two buttons so you can navigate through the images quicker. My goal is to change from one image to another with JS trying to avoid CSS so I can practice. The code I wrote changes to the immediate next image but not the following, no matter how many times I click the "next" button.
I copied the entire project CSS to the pen and I can't delete it. I don't think you'll need to check the CSS but if so, the part of the code that has to do with this question starts in line 410, ignore the rest.
For the time being, I just want it to navigate forwards. I'm working with an array but if anyone has a different approach let me know!
Sorry for my English, hope I made myself clear. Anyways, here is my pen so you can see what I am talking about: https://codepen.io/Nulaxz/pen/poroKJg.
Here is the actual function I am using but seems not to work. The last two "console.log" are just for testing purposes.
nextBtn.addEventListener('click', () => {
const result = arr => {
count++;
if (count >= 4) {
count = 0;
};
return `<div class="img-div">
<img src="http://127.0.0.1:5500/img/icon-previous.svg" alt="prev-btn" class="prev-btn">
<img src=${arr[count]} alt="" id="image-1-preview">
<img src="http://127.0.0.1:5500/img/icon-next.svg" alt="next-btn" class="next-btn">
</div>`;
};
imgPreview.innerHTML = result(imgArr);
console.log(count);
console.log(result(imgArr));
});
This project is a challenge from FrontEndMentor, just in case anyone did it in the past and could tell me how he solved it.
The problem is, you're recreating the next button as well. It causes the button element to be removed from the DOM (along with its click event listener) and recreated again. This is why the button doesn't work anymore.
What you could do is, just updating the image src property. like so:
nextBtn.addEventListener('click', () => {
count++;
if (count >= 4) {
count = 0;
};
document.getElementById('image-1-preview').src = arr[count];
});

Toggle one of two classes with JavaScript

So I am creating this button that expands when clicked and hides data when clicked again. I have made it work, but it was working only one time before refresh, then I figured I need to take a different approach, by toggling class on the button itself, not the div where data appears. And my problem is, that to do so I need to toggle only one of two classes the button has with javascript. How do I do that?
const expandMovies = document.querySelector("#btnMovies");
expandMovies.addEventListener("click", toggleMovies)
function toggleMovies() {
if (expandMovies.classList.contains("inactive")) {
getMovies();
expandMovies.classList.toggle("active");
} else {
parentMovies.style.display="none";
expandMovies.classList.toggle("inactive");
}
};
You can use second property of toggle method which forces to remove or add class forcibly. Following is the code snippet which can helpful for you.
const expandMovies = document.querySelector("#btnMovies");
expandMovies.addEventListener("click", toggleMovies)
function toggleMovies() {
if (expandMovies.classList.contains("inactive")) {
getMovies();
expandMovies.classList.toggle("inactive",false);
expandMovies.classList.toggle("active",true);
} else {
parentMovies.style.display="none";
expandMovies.classList.toggle("active",false);
expandMovies.classList.toggle("inactive",true);
}
};

How to store JS slideToggle in localStorage only for clicked button

I have several buttons including divs which they have the same name. unfortunately I can not change the names, they are generated by cms.
So for example when I click only on first button, only the first div is hidden or displayed, and that's fine.
But after refresh page it opens or closes all divs depending is the first div closed or opened, and that I do not want it.
here is the code:
<button class="a">Button</button>
<div class="target"></div>
<button class="a">Button</button>
<div class="target"></div>
$('.a').click(function() {
$(this).next(".target").slideToggle(function() {
localStorage.setItem('visible', $(this).is(":visible"));
});
});
$('.target').toggle(localStorage.getItem('visible') === 'true');
here you can see jsfiddle example: https://jsfiddle.net/pj3gs0z9/3/
So my question is, is it possible to store only clicked button information, and after page refresh display or hide div from only clicked button ?
Thank you
It is possible, but probably not in your case. If you tell us you can't change your button properties, and they are exactly the same, then you won't be able to store different data in your localStorage.
Isn't there any way where you can add some additional information to your button ? It could be a class, an id, a name, or even a data-XXX attribute.
By the way, how are your buttons generated ? are they hard coded, or fetched from a database, or ... ?
EDIT
Here is a way of adding different classes to all of your buttons (althoguh I recommend adding data attributes, but whatever floats your boat) :
let buttons = document.getElementsByTagName('button'); // Array of your buttons
let index = 0;
for (let button of buttons) {
button.className += 'myCustomClass-' + ++index; // Add a custom class to your buttons
}
// Now in your local storage, you can store the class of the button !
EDIT 2 I would store it like this :
// On click, in VanillaJS (sorry, haven't used JQuery in a while)
button.onclick = () => {
let visibleButtons = localStorage.getItem('visible-buttons') || [];
visibleButtons.push(button.className.match(/(myCustomClass-[0-9]*)/)[0]);
}
This is one quick solution, but because of a slideToggle you gonna have a small flash of milliseconds of a visible div unless you first have them hidden and then based on localStorage display them.
$('.a').click(function() {
$(this).next(".target").slideToggle(function() {
localStorage.setItem('visible-' + $(this).index(), $(this).is(":visible"));
});
});
$.each($('.target'), function(k, trg) {
$(trg).toggle(localStorage.getItem('visible-' + $(trg).index()) === 'true');
});

Both if and elseif statements triggering

I'm building a button that moves away from the mouse and "wraps" around the window. Relatively new to jQuery/JavaScript, I'm building this as a learning exercise (I was inspired by #4 on this page: http://panjiva.com/jobs/challenges).
Background: this is actually my second attempt, and probably not the most elegant solution to the problem. Basically, in this second version, there are hidden "temp" buttons that move in tandem with the button and appear when the button begins to leave the screen. (My first attempted had only two buttons but I ran into issues there.)
Below is an nested if/else statement that detects when a portion of the button is moving out of the window and, if it is, reveals a temp button in the correct location to the give the "wrap" effect. It also checks to see if the entire button has moved off screen and, if so, moves the button to the new coordinates (where the temp button had been exposed).
I thought this entire if/else statment should only allow the button to wrap to one side, even when the button left at a corner. However, it is sometimes wrapping to 2 or 3 corners when leaving to a corner. Why is this happening?
I've created a JSFiddle with the complete code: http://jsfiddle.net/aaronmacy/AVwpU/
All help/advice would be much appreciated!
// Is any part of the button about to move off the page?
// To the top?
if (edgeTop < 0) {
// Always wrap to the bottom
bottom.show();
// Is the button disappearing?
if (edgeBottom < 0) {
// Move the button
buttonNextY += parseInt(viewportHeight);
moveAll();
// Hide everything else
hideTemps();
}
else {
moveAll();
}
}
// To the right?
else if (edgeRight > parseInt(viewportWidth)) {
// Wrap to the left
left.show();
// Is the button disappearing?
if (edgeLeft > parseInt(viewportWidth)) {
buttonNextX -= parseInt(viewportWidth);
moveAll();
hideTemps();
}
else {
moveAll();
}
}
// To the bottom?
else if (edgeBottom > parseInt(viewportHeight)) {
// Wrap to the top
top.show();
// Is the button disappearing?
if (edgeTop > parseInt(viewportHeight)) {
buttonNextY -= parseInt(viewportHeight);
moveAll();
hideTemps();
}
else {
moveAll();
}
}
// To the left?
else if (edgeLeft < 0) {
// Wrap to the right
right.show();
// Is the button disappearing?
if (edgeRight < 0) {
buttonNextX += parseInt(viewportWidth);
moveAll();
hideTemps();
}
else {
moveAll();
}
}
// If the button is completely inside the window
else {
moveAll();
}
I think their requirement is unclear "other side of screen".... I would say your script works fine. they didn't really think about bonus requirements, they just added it to see which candidate will give more effort.... Anyway, make more distance between your buttons, add at least button width on x and height of button on y axis... and don't hide any of copies. It will wrap naturally, believe me ;)

Categories

Resources