How to run just one Function inside UseEffect? - javascript

Does anybody know how to solve this code. I have a carousel, and there is previous and next icon. When clicked, I have to run a specific function inside useEffect().
I want to run the plusSlides() function, which simply calculates the new main carousel picture.
The code is:
function Carousel({ children }) {
useEffect(() => {
var slideIndex = 1;
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slideIndex-1].style.display = "block";
}
});
return (
<CarouselStyled visible={visible}>
<div className="slideshow-container">
<div className="container">
<Link href={`/${router.locale == "bs" ? "" : "en"}`}>
<a className="mylogo">
<img src="/logo.svg" alt="Doxat" />
</a>
</Link>
</div>
<div className="mySlides fade">
<img src="/images/doxat-2.jpg" />
</div>
<div className="mySlides fade">
<img src="/images/doxat-1.jpg" />
</div>
<div className="mySlides fade">
<img src="/images/doxat-3.jpg" />
</div>
<a className="prev" onClick={() => plusSlides(-1)}>
/* When clicked here, the plusSlides function has to be run*/
<MdChevronLeft />
</a>
<a className="next">
<MdChevronRight />
</a>
</div>
</CarouselStyled>
);
}

your function need definition on useEffect() outside,then because you use function component,just call plusSlides can work
function Carousel({ children }) {
const plusSlides = ()=>{
// do somthing
}
useEffect(()=>{
},[])
return(
<div>
<a className="prev" onClick={() => plusSlides(-1)}></a>
</div>
)
}

Related

image lightbox with reactjs using jsx

i am trying to use this image lightbox in reactjs https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_slideshow_gallery . But it seems to be not working for me in reactjs.I am having problem with onclick function declarations.Here is my code so far:
render() {
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
var captionText = document.getElementById("caption");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " active";
captionText.innerHTML = dots[slideIndex-1].alt;
}
return (
<div>
<div className="container">
<div className="mySlides">
<div className="numbertext">1 / 6</div>
<img src="img_woods_wide.jpg" style="width:100%"/>
</div>
<div className="mySlides">
<div className="numbertext">2 / 6</div>
<img src="img_5terre_wide.jpg" style="width:100%"/>
</div>
<a className="prev" onClick="plusSlides(-1)">❮</a>
<a className="next" onClick="plusSlides(1)">❯</a>
<div className="caption-container">
<p id="caption"></p>
</div>
<div className="row">
<div className="column">
<img className="demo cursor" src="img_woods.jpg" style="width:100%"
onClick="currentSlide(1)" alt="The Woods"/>
</div>
<div className="column">
<img className="demo cursor" src="img_5terre.jpg" style="width:100%"
onClick="currentSlide(2)" alt="Cinque Terre"/>
</div>
</div>
</div>
</div>
);
}
I have also tried declaring the script into the componentDidMount.But it seems to be not working.How can i fix this?
You should not access DOM in React.
But you should create model of your component in state and map it to view in render() function
UPD:
The code could looks like this
const useSlider = (items) => {
const [pointer, setPointer] = useState(0)
useEffect(() => {
setPointer(0) // reset pointer if items list changes
}, [items])
// Move pointer forvard
const next = () => setPointer((pointer) =>
pointer < items.length - 1 ? pointer + 1 : 0
);
// Move Pointer back
const prev = () => setPointer((pointer) =>
pointer > 0 ? pointer - 1 : items.length - 1
);
// Focused item
const item = useState (() => items[pointer], [items, pointer])
return {
pointer,
next,
prev,
setPointer,
item,
}
}
const Slider = ({ items }) => {
const { next, prev, pointer, setPointer, item } = useSlider(items);
return (
<div>
<div className="container">
<div className="mySlides">
<div className="numbertext">{`${pointer + 1} / ${items.length}`}</div>
<img src={item.src} style="width:100%" />
</div>
<a className="prev" onClick={prev}>❮</a>
<a className="next" onClick={next}>❯</a>
<div className="caption-container">
<p id="caption">{item.caption}</p>
</div>
<div className="row">
{
items.map((item, pointer) => (
<div key={pointer} className="column">
<img
className="demo cursor"
src={item.src}
style="width:100%"
onClick={() => setPointer(pointer)}
alt={item.caption}
/>
</div>
))
}
</div>
</div>
</div>
);
}
const items = [{
src: 'img_woods.jpg',
caption: 'The Woods'
}, {
src: 'img_5terre.jpg',
caption: 'Cinque Terre'
}];
// <Slider items={items}/>

Multiple line image slider with buttons

I am working on a website that should have image sliders with clickable buttons that flip to the next image.
I was able to make a single slider / page, but as I have no experience in coding yet, I ran into difficulties when I was trying make multiple sliders following each other directly. The buttons of a certain slider started to mix up, and target other sliders too, or only the first one, but not the way I wanted..
So I started copying and repeating the same lines of code and applying them to groups of images separately.
I also want some text to flip together with the images, so I grouped the text and images together with the buttons, and finally I ended up having a lot of repetition, and way too long codes. :-)
Right now it works, but I assume that there is a much easier, solution, that would make my code a lot shorter.
Can someone help me with:
Having one good java script, that doesn't mix up the targets, when having multiple sliders?
Having only one "buttons"/slider instead of copying them to all the "containergrid"s groups, but still flipping the text together with the image?
Thanks, and sorry for the long code. :)
<div class="content">
<!---THE FIRST SLIDER--->
<div class="slider_1">
<div class="slides_1">
<div class="containergrid">
<div class="description">
<p class="maindescription">Description</p>
<p class="year">2017</p>
</div>
<div class="imgbutton">
<img class="img_1_1">
<div class="button">
<button class="prev"
onclick="plusDivs1(-1)"></button>
<button class="next"
onclick="plusDivs1(1)"></button>
</div>
</div>
</div>
</div>
<div class="slides_1">
<div class="containergrid">
<div class="description">
<p class="maindescription">Description</p>
<p class="year">2017</p>
</div>
<div class="imgbutton">
<img class="img_1_2">
<div class="button">
<button class="prev"
onclick="plusDivs1(-1)"></button>
<button class="next"
onclick="plusDivs1(1)"></button>
</div>
</div>
</div>
</div>
</div>
<!---THE SECOND SLIDER--->
<div class="slider_2">
<div class="slides_2">
<div class="containergrid">
<div class="description">
<p class="maindescription">Description</p>
<p class="year">2017</p>
</div>
<div class="imgbutton">
<img class="img_2_1">
<div class="button">
<button class="prev"
onclick="plusDivs1(-1)"></button>
<button class="next"
onclick="plusDivs1(1)"></button>
</div>
</div>
</div>
</div>
<div class="slides_2">
<div class="containergrid">
<div class="description">
<p class="maindescription">Description</p>
<p class="year">2017</p>
</div>
<div class="imgbutton">
<img class="img_2_2">
<div class="button">
<button class="prev"
onclick="plusDivs1(-1)"></button>
<button class="next"
onclick="plusDivs1(1)"></button>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
var slideIndex = 1;
showDivs1(slideIndex);
function plusDivs1(n) {
showDivs1(slideIndex += n);
}
function showDivs1(n) {
var i;
var x = document.getElementsByClassName("slides_1");
if (n > x.length) { slideIndex = 1 }
if (n < 1) { slideIndex = x.length }
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex - 1].style.display = "flex";
}
</script>
<script>
var slideIndex = 1;
showDivs2(slideIndex);
function plusDivs2(n) {
showDivs2(slideIndex += n);
}
function showDivs2(n) {
var i;
var x = document.getElementsByClassName("slides_2");
if (n > x.length) { slideIndex = 1 }
if (n < 1) { slideIndex = x.length }
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex - 1].style.display = "flex";
}
</script>
So you would just have to pass a reference to your slides into the showDivs function, so you can keep the clicks independent of one another. You'd still have to initialize each slider separately.
function plusDivs(slider, n) {
showDivs(slider, slideIndex += n);
}
function showDivs(slider, index) {
var i;
var x = document.getElementsByClassName(slider);
if (index > x.length) {
slideIndex = 1
}
if (index < 1) {
slideIndex = x.length
}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex - 1].style.display = "flex";
}
// Initialize the sliders
var slideIndex = 1;
showDivs('slides_1', slideIndex);
showDivs('slides_2', slideIndex);
In your HTML you just need to pass the reference to the plusDivs function:
onclick="plusDivs('slides_1', 1)"
Here is a fiddle showing a working example

Uncaught ReferenceError: toggleFunction is not defined at HTMLButtonElement.onclick

I try to fix this code soo the click funktion for toggle works but I get the error
Uncaught ReferenceError: toggleFunction is not defined
at HTMLButtonElement.onclick
Its sure very easy to fix but I cant find the problem.
I have tried to change the document.getElementsByClassName to
document.getElementsById but it didnt work.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://unpkg.com/react#16.4.1/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom#16.4.1/umd/react-dom.production.min.js"></script>
</head>
<body>
<div class="c-section">
<div class="c-header">
<div class="c-header__menu">
<ul class="c-navigation">
<li>Stories</li>
<li>Events</li>
<li>Places</li>
<li>Boards</li>
</ul>
</div>
<div class="c-rotate">
<div class="c-rotate__text">
<h1 class="c-rotate__title">Beautiful Escape</h1>
<p class="c-rotate__text-inspiring">One of the greatest things about the sport of surfing is that you
need only three things: your body a surfboard, and a wave.
</p>
</div>
<div class="c-rotate__image">
<img src="img/vawe.jpg" alt="">
</div>
</div>
</div>
<div class="c-citate">
<p class="c-citate__text">Surfing is the most blissful experience you can have on this planet,<br>
a taste of heaven.<br>
John McCarthy</p>
</div>
<div class="c-image__video">
<div class="c-image__video-section">
<img src="img/surfer.jpg" alt="" class="surferonBeach">
<p class="c-text-inspiring__surfer">By better understanding the various aspects<br>
of surfing, you will improve faster and have more<br>
fun in the water.</p>
<p class="c-text__read-more" id="expandable-section-1" tabindex="-1">Read More</p>
</div>
<img src="img/surferonwave.jpg" alt="" class="surferonWave">
</div>
<div class="c-shop">
<div class="c-shop__text">
<p>Shop</p>
<h2 class="c-title__shop">Surfboards</h2>
</div>
<div class="c-product">
<div class="c-product__slide">
<ul class="c-product__list fade">
<li class="c-product__background"><img src="img/surfboard2.png" alt=""></li>
<li class="c-product__background"><img src="img/surfboard3.png" alt=""></li>
<li class="c-product__background"><img src="img/surfboard1.png" alt=""></li>
</ul>
</div>
<div class="c-product__slide">
<ul class="c-product__list fade">
<li class="c-product__background"><img src="img/surfboard4.png" alt=""></li>
<li class="c-product__background"><img src="img/surfboard5.png" alt=""></li>
<li class="c-product__background"><img src="img/surfboard6.png" alt=""></li>
</ul>
<div id="c-product__toggle">
test
</div>
</div>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
<!-- Toggle funktion -->
<button class="content-button__toggle" onclick="toggleFunction()">Show</button>
</div>
</div>
<div class="c-surf-training">
<div class="c-text__surf-training">
<h2 class="c-title__surf-training">Surf Training</h2>
<p class="c-text-inspiring__surf-training">By better understanding the varius aspects of surfing,<br>
you will improve faster and have more fun in the water.</p>
<p class="c-read-more" id="expandable-section-1" tabindex="-1">Read More</p>
</div>
<div class="c-surf-training--image">
<img src="img/surferonwave2.jpg" alt="">
</div>
</div>
<div class="c-point-break">
<div class="c-point-break--image">
<img src="img/sunset.jpg" alt="">
</div>
<div class="c-point-break__flex">
<h2 class="c-point-break__title-">Point Break</h2>
<div class="c-point-break__expand">
<p class="c-text-inspiring__point-break">By better understanding the varius aspects of surfing,<br>
you will improve faster and have more fun in the water</p>
<p class="c-read-more" id="expandable-section-1" tabindex="-1">Read More</p>
</div>
</div>
</div>
<div class="c-form">
<h2 class="c-join__title">Join the club</h2>
<p class="c-text-inspiring">Text</p>
<form action="index.html" method="GET" class="c-form__input">
<input id="join-input" class="join-block__input" name="e-mail" type="text" placeholder="Your E-mail">
<button class="o-join__button">
<span class="visually-hidden">Join our newsletter</span>
</button>
</form>
</div>
<div class="c-camp">
<img src="img/campfire.jpg" alt="">
<div class="c-camp-flex">
<p>Our camp</p>
<h2 class="c__">CA 91932, USA Imperial Beach 560 Silver Strand Blvd</h2>
Get in touch
</div>
</div>
<div class="c-footer__menu">
<ul class="c-navigation">
<li>Stories</li>
<li>Events</li>
<li>Places</li>
<li>Boards</li>
</ul>
</div>
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
</div>
<script type="text/javascript">
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function showSlides(n){
var i;
var slides = document.getElementsByClassName("c-product__slide");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slideIndex-1].style.display = "block";
// toggle funktion för hide show surfbrädor
function toggleFunction(){
var x = document.getElementsByClassName("c-product__toggle");
if (x.style.display === "block") {
x.style.display = "none";
}else{
x.style.display = "block";
}
}
}</script>
</body>
</html>
``````````````````````
I want to be able to show the text test and toggle hide show that.
But I get error:
Uncaught ReferenceError: toggleFunction is not defined
at HTMLButtonElement.onclick
You messed up the curly braces when you wrote the toggleFunction function, you placed it inside the showSlides function.
change
<script type="text/javascript">
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function showSlides(n){
var i;
var slides = document.getElementsByClassName("c-product__slide");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slideIndex-1].style.display = "block";
// toggle funktion för hide show surfbrädor
function toggleFunction(){
var x = document.getElementsByClassName("c-product__toggle");
if (x.style.display === "block") {
x.style.display = "none";
}else{
x.style.display = "block";
}
} // There's an extra curly brace here
}</script>
to
<script type="text/javascript">
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function showSlides(n){
var i;
var slides = document.getElementsByClassName("c-product__slide");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slides[slideIndex-1].style.display = "block";
} // This curly was missing
// toggle funktion för hide show surfbrädor
function toggleFunction(){
var x = document.getElementsByClassName("c-product__toggle");
if (x.style.display === "block") {
x.style.display = "none";
}else{
x.style.display = "block";
}
}
</script>

How to display Image caption with Image in slider

I want to display image caption under each images in image slider.
But right now my problem is all the image captions are displaying for each image like this
View :
<div class="grid-11 left">
#if (Model.Photos.Count > 0)
{
<div style="padding:10px">
<div class="slide-content" style="max-width:800px">
#foreach (var photos in Model.Photos)
{
<div>
<img class="mySlides" src="#Url.Content(photos.photo_url)"/>
</div>
<span>#photos.photo_caption</span>
}
<div class="w3-center">
<div class="w3-section">
<button class="w3-button w3-light-grey" onclick="plusDivs(-1)">❮ </button>
<button class="w3-button w3-light-grey" onclick="plusDivs(1)"> ❯</button>
</div>
</div>
</div>
</div>
}
</div>
Script :
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function currentDiv(n) {
showDivs(slideIndex = n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
if (n > x.length) {
slideIndex = 1
}
if (n < 1) {
slideIndex = x.length
}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex - 1].style.display = "block";
}
How do is display caption for each image by passing image_id?
The problem is you're targeting the image only for display block/none via class="mySlides". You need to wrap the image and caption in some sort of container and target that instead.
#foreach (var photos in Model.Photos)
{
<div class="mySlides">
<div>
<img src="#Url.Content(photos.photo_url)"/>
</div>
<span>#photos.photo_caption</span>
</div>
}

how to code for multiple modals where some of them are carousels with different number of slides

I have a page with several buttons, when each button is clicked a different modal pops up. Some of the modals are carousels, the code I have works but for only one of the carousels, when I have more than one I get extra empty slides on all the carousels. So I'm guessing my code is counting all the slides from all the carousels together. Im trying to have write something where it says if this modal is clicked then get the slides from the clicked modal only but Im struggling with that.
These are the bits of relevant code:
<script>
//Carousel
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function currentDiv(n) {
showDivs(slideIndex = n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
/*dots[i].className = dots[i].className.replace(" w3-white", "");*/
}
x[slideIndex-1].style.display = "block";
/*dots[slideIndex-1].className += " w3-white";*/
}
</script>
<script>
//Display corresponding modal of letter that is clicked
$(".button").on("click", function() {
var modal = $(this).data("modal");
$(modal).show();
document.body.classList.add("modal-open");
});
//Close modal when "x" is clicked or when area outside modal is clicked
$(".modal").on("click", function(e) {
var className = e.target.className;
if(className === "modal" || className === "close"){
$(this).closest(".modal").hide();
document.body.classList.remove("modal-open");
}
});
</script>
<button class="button" data-modal="#modalOne"><img id="myImg" src=""></button>
<button class="button" data-modal="#modalB"><img id="myImg" src=""></button>
<button class="button" data-modal="#modalC"><img id="myImg" src=""></button>
<!-- The Modal -->
<div id="modalA" class="modal">
<!-- Modal content -->
<div class="modal-content">
<span class="close">×</span>
<div class= "mySlides">
<img class="gif" src="" width="100" height="100" >
<h4>Title</h4>
<p> content </p>
</div>
<div class="mySlides">
<h4 Title</h4>
<p> content </p>
</div>
<div class="w3-left w3-hover-text-khaki" onclick="plusDivs(-1)">❮</div>
<div class="w3-right w3-hover-text-khaki" onclick="plusDivs(1)">❯</div>
</div>
</div>
<!-- The Modal B -->
<div id="modalB" class="modal">
<!-- Modal content -->
<div class="modal-content">
<span class="close">×</span>
<div class="mySlides">
<img class="gif" src="" width="100" height="100" >
<h4></h4>
<p></p>
</div>
</div>
</div>
<!-- The Modal C -->
<div id="modalC" class="modal">
<!-- Modal content -->
<div class="modal-content">
<span class="close">×</span>
<div class="mySlides">
<img class="gif" src="" width="100" height="100" >
<h4></h4>
<p></p>
<div class="mySlides">
<h4></h4>
<p></p>
</div>
<div class="w3-left w3-hover-text-khaki" onclick="plusDivs(-1)">❮</div>
<div class="w3-right w3-hover-text-khaki" onclick="plusDivs(1)">❯</div>
</div>
</div>
When you do this line
var x = document.getElementsByClassName("mySlides");
You count all the elements with class name of "mySlides", which is ALL of the slides in the HTML document.
Add code in your button click routine to count the number of slides in the corresponding modal:
Add this at the top of the javascript:
var modal = "modalA";
showDivs(slideIndex, modal);
Change the button click to:
$(".button").on("click", function() {
modal = $(this).data("modal").text();
$("#" + modal).show();
document.body.classList.add("modal-open");
});
Modify your showDivs function to include the new variable:
function showDivs(n, modal) {
var i;
var x = document.getElementById(modal).getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
/*dots[i].className = dots[i].className.replace(" w3-white", "");*/
}
x[slideIndex-1].style.display = "block";
/*dots[slideIndex-1].className += " w3-white";*/
}
Finally, change the data-modal attributes of your buttons to read:
<button class="button" data-modal="modalA">
<button class="button" data-modal="modalB">
<button class="button" data-modal="modalC">
You will also need to update the lines:
function plusDivs(n) {
showDivs(slideIndex += n, modal);
}
function currentDiv(n) {
showDivs(slideIndex = n, modal);
}

Categories