GlideJS - 将幻灯片与 React Components 一起使用时的奇怪行为
GlideJS - Weird behavior when using slide with React Components
我在 React 项目中使用 GlideJS,但它返回了一个奇怪的行为。这些组件没有在每个视图中显示一个,并且它们的宽度已更改。
组件:
import React, { Component } from "react";
import Glide from "@glidejs/glide";
export default class SliderGlide extends Component {
state = { id: null };
componentDidMount = () => {
// Generated random id
this.setState(
{ id: `glide-${Math.ceil(Math.random() * 100)}` },
this.initializeGlider
);
};
initializeGlider = () => {
this.slider = new Glide(`#${this.state.id}`, this.props.options);
this.slider.mount();
};
componentWillReceiveProps = newProps => {
if (this.props.options.startAt !== newProps.options.startAt) {
this.slider.go(`=${newProps.options.startAt}`);
}
};
render = () => (
<div
id={this.state.id}
className="mt-10"
style={{ overflowX: "hidden", userSelect: "none", maxWidth: "100vw" }}
>
<div className="glide__arrows" data-glide-el="controls">
<button
className="glide__arrow glide__arrow--left rounded-full"
data-glide-dir="<"
title="Veja mais ofertas!"
>
<span className="hidden">Anterior</span>
</button>
<button
className="glide__arrow glide__arrow--right rounded-full"
data-glide-dir=">"
title="Veja mais ofertas!"
>
<span className="hidden">Próximo</span>
</button>
</div>
<div className="glide__track" data-glide-el="track">
<div className="glide__slides" style={{ display: "flex" }}>
{this.props.children.map((slide, index) => {
return React.cloneElement(slide, {
key: index,
className: `${slide.props.className} glide__slide`
});
})}
</div>
</div>
<div className="glide__bullets" data-glide-el="controls[nav]">
{this.props.children.map((slide, index) => {
return <button key={index} className="glide__bullet rounded-full" data-glide-dir={"=" + index} />;
})}
</div>
</div>
);
}
SliderGlide.defaultProps = {
options: {}
};
所以在 Carousel 组件内部,我传递了 childrens 和 glide 选项,它们是组件。
const Plans = ({ plans, handleOffer }) => {
const carouselOptions = { type: 'slide',
perView: 1,
startAt: 0,
}
return (
<div className="section__slider relative mt-10 flex justify-center items-center">
<Carousel options={carouselOptions}>
{ plans.map((plan, i) => {
return (
<OfferProduct key={i} i={i} plan={plan} handleOffer={handleOffer}/>
)
})
}
</Carousel>
</div>
)
}
export default Plans;
我想知道这个问题是否与我的代码有关,我是否遗漏了一些我需要导入的样式表,或者传递给 glide 的操作是否有误。
我刚刚使用 glidejs
和 React
为您设置了完整的工作演示。检查一下,让我知道它是否适合你。 code sandbox
index.js
class Plans extends Component {
state = {
myPlans: [
{ id: 0, text: "plan 0", price: 0 },
{ id: 1, text: "plan 1", price: 1 },
{ id: 2, text: "plan 2", price: 2 },
{ id: 3, text: "plan 3", price: 3 }
]
};
handleOffer = id => {
console.log("handleOffer clicked, id: ", id);
};
render() {
const carouselOptions = { type: "slide", perView: 1, startAt: 0 };
return (
<div className="home-section test">
<SliderGlide options={carouselOptions}>
{this.state.myPlans.map(plan => (
<OfferProduct
key={plan.id}
plan={plan}
handleOffer={this.handleOffer}
/>
))}
</SliderGlide>
</div>
);
}
}
export default Plans;
OfferProduct.js
const OfferProduct = ({ plan, handleOffer }) => {
return (
<>
<div onClick={() => handleOffer(plan.id)} className="card">
<p>
<h3> Card no: {plan.id} </h3>
<span>price: {plan.price}</span>
</p>
</div>
</>
);
};
export default OfferProduct;
SliderGlide.js
export default class SliderGlide extends Component {
state = { id: null };
componentDidMount = () => {
// Generated random id
this.setState(
{ id: `glide-${Math.ceil(Math.random() * 100)}` },
this.initializeGlider
);
};
initializeGlider = () => {
this.slider = new Glide(`#${this.state.id}`, this.props.options);
this.slider.mount();
};
componentWillReceiveProps = newProps => {
if (this.props.options.startAt !== newProps.options.startAt) {
this.slider.go(`=${newProps.options.startAt}`);
}
};
render = () => (
// controls
<div id={this.state.id} className="slider">
<div className="two-controls-btns" data-glide-el="controls">
<button className="arrow-left" data-glide-dir="<" title="start">
<span className="hidden">Start</span>
</button>
<button className="arrow-right" data-glide-dir=">" title="end">
<span className="hidden">End</span>
</button>
</div>
{/* track */}
<div className="glide__track" data-glide-el="track">
<div className="glide__slides" style={{ display: "flex" }}>
{this.props.children.map((slide, index) => {
return React.cloneElement(slide, {
key: index,
className: `${slide.props.className} glide__slide`
});
})}
</div>
</div>
{/* bottom bullets */}
<div className="bottom_bullets" data-glide-el="controls[nav]">
{this.props.children.map((slide, index) => {
return (
<button
key={index}
className="single-bullet"
data-glide-dir={"=" + index}
title=".g"
/>
);
})}
</div>
</div>
);
}
SliderGlide.defaultProps = {
options: {}
};
styles.css
.App {
font-family: sans-serif;
text-align: center;
}
.home-section {
width: 500px;
margin: auto;
display: flex;
justify-content: center;
align-items: center;
background-color: lightblue;
}
.card {
width: 50px;
height: 75px;
background-color: violet;
padding: 10px;
}
.slider {
width: 300px;
height: 200px;
overflow-x: hidden;
user-select: none;
padding: 20px;
}
.arrow-left,
.arrow-right {
background-color: #4caf50;
border: none;
color: white;
padding: 10px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 12px;
margin: 4px 2px;
border-radius: 50%;
}
.two-controls-btns {
width: 100%;
margin: auto;
padding: 0;
display: flex;
flex-flow: row;
justify-content: space-around;
align-items: center;
}
.single-bullet {
background-color: #080f47;
border: none;
padding: 8px;
display: inline-block;
margin: 5px;
border-radius: 50%;
}
.bottom_bullets {
width: 200px;
margin: auto;
padding: 0;
display: flex;
flex-flow: row;
justify-content: center;
align-items: center;
}
.test {
border: 1px solid red;
}
我在 React 项目中使用 GlideJS,但它返回了一个奇怪的行为。这些组件没有在每个视图中显示一个,并且它们的宽度已更改。
组件:
import React, { Component } from "react";
import Glide from "@glidejs/glide";
export default class SliderGlide extends Component {
state = { id: null };
componentDidMount = () => {
// Generated random id
this.setState(
{ id: `glide-${Math.ceil(Math.random() * 100)}` },
this.initializeGlider
);
};
initializeGlider = () => {
this.slider = new Glide(`#${this.state.id}`, this.props.options);
this.slider.mount();
};
componentWillReceiveProps = newProps => {
if (this.props.options.startAt !== newProps.options.startAt) {
this.slider.go(`=${newProps.options.startAt}`);
}
};
render = () => (
<div
id={this.state.id}
className="mt-10"
style={{ overflowX: "hidden", userSelect: "none", maxWidth: "100vw" }}
>
<div className="glide__arrows" data-glide-el="controls">
<button
className="glide__arrow glide__arrow--left rounded-full"
data-glide-dir="<"
title="Veja mais ofertas!"
>
<span className="hidden">Anterior</span>
</button>
<button
className="glide__arrow glide__arrow--right rounded-full"
data-glide-dir=">"
title="Veja mais ofertas!"
>
<span className="hidden">Próximo</span>
</button>
</div>
<div className="glide__track" data-glide-el="track">
<div className="glide__slides" style={{ display: "flex" }}>
{this.props.children.map((slide, index) => {
return React.cloneElement(slide, {
key: index,
className: `${slide.props.className} glide__slide`
});
})}
</div>
</div>
<div className="glide__bullets" data-glide-el="controls[nav]">
{this.props.children.map((slide, index) => {
return <button key={index} className="glide__bullet rounded-full" data-glide-dir={"=" + index} />;
})}
</div>
</div>
);
}
SliderGlide.defaultProps = {
options: {}
};
所以在 Carousel 组件内部,我传递了 childrens 和 glide 选项,它们是组件。
const Plans = ({ plans, handleOffer }) => {
const carouselOptions = { type: 'slide',
perView: 1,
startAt: 0,
}
return (
<div className="section__slider relative mt-10 flex justify-center items-center">
<Carousel options={carouselOptions}>
{ plans.map((plan, i) => {
return (
<OfferProduct key={i} i={i} plan={plan} handleOffer={handleOffer}/>
)
})
}
</Carousel>
</div>
)
}
export default Plans;
我想知道这个问题是否与我的代码有关,我是否遗漏了一些我需要导入的样式表,或者传递给 glide 的操作是否有误。
我刚刚使用 glidejs
和 React
为您设置了完整的工作演示。检查一下,让我知道它是否适合你。 code sandbox
index.js
class Plans extends Component {
state = {
myPlans: [
{ id: 0, text: "plan 0", price: 0 },
{ id: 1, text: "plan 1", price: 1 },
{ id: 2, text: "plan 2", price: 2 },
{ id: 3, text: "plan 3", price: 3 }
]
};
handleOffer = id => {
console.log("handleOffer clicked, id: ", id);
};
render() {
const carouselOptions = { type: "slide", perView: 1, startAt: 0 };
return (
<div className="home-section test">
<SliderGlide options={carouselOptions}>
{this.state.myPlans.map(plan => (
<OfferProduct
key={plan.id}
plan={plan}
handleOffer={this.handleOffer}
/>
))}
</SliderGlide>
</div>
);
}
}
export default Plans;
OfferProduct.js
const OfferProduct = ({ plan, handleOffer }) => {
return (
<>
<div onClick={() => handleOffer(plan.id)} className="card">
<p>
<h3> Card no: {plan.id} </h3>
<span>price: {plan.price}</span>
</p>
</div>
</>
);
};
export default OfferProduct;
SliderGlide.js
export default class SliderGlide extends Component {
state = { id: null };
componentDidMount = () => {
// Generated random id
this.setState(
{ id: `glide-${Math.ceil(Math.random() * 100)}` },
this.initializeGlider
);
};
initializeGlider = () => {
this.slider = new Glide(`#${this.state.id}`, this.props.options);
this.slider.mount();
};
componentWillReceiveProps = newProps => {
if (this.props.options.startAt !== newProps.options.startAt) {
this.slider.go(`=${newProps.options.startAt}`);
}
};
render = () => (
// controls
<div id={this.state.id} className="slider">
<div className="two-controls-btns" data-glide-el="controls">
<button className="arrow-left" data-glide-dir="<" title="start">
<span className="hidden">Start</span>
</button>
<button className="arrow-right" data-glide-dir=">" title="end">
<span className="hidden">End</span>
</button>
</div>
{/* track */}
<div className="glide__track" data-glide-el="track">
<div className="glide__slides" style={{ display: "flex" }}>
{this.props.children.map((slide, index) => {
return React.cloneElement(slide, {
key: index,
className: `${slide.props.className} glide__slide`
});
})}
</div>
</div>
{/* bottom bullets */}
<div className="bottom_bullets" data-glide-el="controls[nav]">
{this.props.children.map((slide, index) => {
return (
<button
key={index}
className="single-bullet"
data-glide-dir={"=" + index}
title=".g"
/>
);
})}
</div>
</div>
);
}
SliderGlide.defaultProps = {
options: {}
};
styles.css
.App {
font-family: sans-serif;
text-align: center;
}
.home-section {
width: 500px;
margin: auto;
display: flex;
justify-content: center;
align-items: center;
background-color: lightblue;
}
.card {
width: 50px;
height: 75px;
background-color: violet;
padding: 10px;
}
.slider {
width: 300px;
height: 200px;
overflow-x: hidden;
user-select: none;
padding: 20px;
}
.arrow-left,
.arrow-right {
background-color: #4caf50;
border: none;
color: white;
padding: 10px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 12px;
margin: 4px 2px;
border-radius: 50%;
}
.two-controls-btns {
width: 100%;
margin: auto;
padding: 0;
display: flex;
flex-flow: row;
justify-content: space-around;
align-items: center;
}
.single-bullet {
background-color: #080f47;
border: none;
padding: 8px;
display: inline-block;
margin: 5px;
border-radius: 50%;
}
.bottom_bullets {
width: 200px;
margin: auto;
padding: 0;
display: flex;
flex-flow: row;
justify-content: center;
align-items: center;
}
.test {
border: 1px solid red;
}