这是我目前要达到的目标:https://stackblitz.com/edit/react-3jxtgg?file=index.js,
我将以编程方式调整元素之间的边距。
当前,我已遵循此讨论中提出的解决方案:https://stackoverflow.com/a/12601490/9817602
但是看来我的余地不合适。下一个元素-这里的圆是三个-当它只应覆盖相对位置的空白时,仅与第二个圆重叠。
也许offsetWidth
是导致这种情况的值?
// in this code my objective will be to parse the relative position styl
// on first rendering using some function to set the following attributes:
// relative-style={this.setRelativeTemplate(elementRefName, deplacementDirection, deplacementValue)}
// relative-element={this.setRelativeElement(elementRefName)}
// then adjust the positionning of each element using again some function:
// adjustMargin()
// currently the circle following the relatived circle just overlap the relatived circle - see the result on the pageview of the IDE
class App extends React.Component{
constructor(prop){
super(prop);
this.child1=React.createRef();
this.child2=React.createRef();
}
state={
// prepare the property to receive the HTMLelement's candidate to a relative position
relativeStyle:{}
}
// parse the relativeStyle -see the setRelativeTemplate function-
// then call the function destinated to adjust the margin
componentDidMount(){
let relativeStyleUpdate= {...this.state.relativeStyle}
console.log("in componentDidMount: " , JSON.parse(this.child2.current.attributes["relative-style"].nodeValue));
for (var key in this) {
if(!key.includes("child")) continue
if(!this[key].current.attributes["relative-style"]) continue
console.log("key: ", key)
console.log("in for key: ", this[key].current.attributes["relative-style"].nodeValue)
relativeStyleUpdate[key]= JSON.parse(this[key].current.attributes["relative-style"].nodeValue)
}
console.log("relativeStyleUpdate: ", relativeStyleUpdate)
console.log("in componentDidMount this.state.relativeStyle: ", this.state.relativeStyle)
// after having parse the style and insert them in the currentState
// now I can leverage on them as reference in the adjustMargin function
// here we go, the style are here and the remaining is just the marginAdjustment
this.setState({
relativeStyle:relativeStyleUpdate
},()=> this.adjustMargin())
}
// create some style -width and height using paddingBottom- for my circle
generateStyle=(sizeReference)=>{
let unity="%"
return {
width:sizeReference+unity,
paddingBottom: sizeReference+unity
}
}
// precise that an element is candidate to be relative
// by entering a property corresponding to its name in the state
setRelativeElement=elementRefName=> {
if(this.state.relativeStyle[elementRefName]) return
this.setState( currentState =>({
relativeStyle: { ...currentState.relativeStyle, [elementRefName]: {}}
}), () => console.log("this.state.relativeStyle after setRelativeElement"
));
}
// set the JSON template that will be then parse to be transform in JSON Object
// I create here a JSON template string to allow me to pass it in the element attribute
// indeed, AFAIK object return [object object] when passed directly in an element attribute
setRelativeTemplate=(elementRefName, deplacementDirection, deplacementValue)=>{
return`{
"position":"relative",
"${deplacementDirection}":${deplacementValue},
"setting":{
"deplacementDirection": "${deplacementDirection}",
"deplacementValue": ${deplacementValue}
}
}`
}
// appreciate the deplacement of the element
// then set a relevant margin correction
// inspiration of the trick from here: https://stackoverflow.com/a/12601490/9817602
adjustMargin=()=>{
let relativeStyleUpdate= {...this.state.relativeStyle}
for (var elementRefName in this.state.relativeStyle) {
console.log("this.state elementRefName in adjustMargin: ", elementRefName)
let refElementStyle=this.state.relativeStyle[elementRefName];
let {deplacementDirection, deplacementValue}=refElementStyle.setting;
let elementRefCurrent= this[elementRefName].current;
console.log("refElementStyle: ", refElementStyle)
console.log("deplacementDirection: ", deplacementDirection)
let deplacementUnit="%";
let marginAdjustment
let elementOffsetWidth
let deplacementPixelValue
if(elementRefCurrent) elementOffsetWidth=elementRefCurrent.offsetWidth
deplacementPixelValue= window.innerWidth * (deplacementValue/100)
if( deplacementPixelValue > elementOffsetWidth) marginAdjustment = -elementOffsetWidth+"px"
else if( deplacementPixelValue < elementOffsetWidth) marginAdjustment = -deplacementValue+"%"
relativeStyleUpdate[elementRefName]["margin" + this.capitalizeFirstLetter(deplacementDirection)]=marginAdjustment
}
this.setState({
relativeStyle: relativeStyleUpdate
}, console.log("state after marginUpdate: ", this.state.relativeStyle))
}
// capitalize the first letter of marginDirection to create the marginAdjustment variable
capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
render(){
console.log("RENDER")
// in the render there is only image circle content _ container with their linked CSS style
return (
<div>
As you can see, the circle three overlaps the circle two
when it should just fill the blank gap
<div className="photo_slider">
<div
ref={this.child1}
className="circle_container pic1"
style={this.generateStyle(35)}
>
<img
src="https://i.pinimg.com/originals/33/9f/e1/339fe1507eb8a968484f2399d4bc873d.jpg"
alt="awesome_image"
className="circle__img"
/>
</div>
<div
ref={this.child2}
name="child2"
relative-style={this.setRelativeTemplate("child2", "right", 30)}
relative-element={this.setRelativeElement("child2")}
test={()=> "here i am"}
className="circle_container pic2"
style={Object.assign(this.generateStyle(35), this.state.relativeStyle["child2"])}
>
<img
src="http://www.wallpapers13.com/wp-content/uploads/2016/01/Beautiful-New-Year-Fireworks-915x515.jpg"
alt="awesome_image"
className="circle__img"
/>
</div>
<div
className="circle_container pic3"
style={this.generateStyle(50)}
>
<img
src="https://wallpapercave.com/wp/Nduz52P.jpg"
alt="awesome_image"
className="circle__img"
/>
</div>
<div
className="circle_container pic4"
style={this.generateStyle(15)}
>
<img
src="http://getwallpapers.com/wallpaper/full/0/5/d/1058601-fireworks-wallpaper-1920x1080-picture.jpg"
alt="awesome_image"
className="circle__img"
/>
</div>
<div
className="circle_container pic5"
style={this.generateStyle(10)}
>
<img
src="https://wallpapercave.com/wp/5MsoNXS.jpg"
alt="awesome_image"
className="circle__img"
/>
</div>
</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
.photo_slider{
width:100%;
height:100%;
display:flex;
justify-content: center;
align-items: center;
background: beige;
}
.circle_container{
height:30%;
width:30%;
border-radius: 50%;
overflow: hidden;
position: relative;
border: 3px dashed salmon;
margin:auto;
}
.circle__img {
position: absolute;
height: 100%;
width:100%;
object-fit: cover;
}
/*.pic1 img {
}*/
.pic2 {
position:relative;
/*right:130px;
margin-right:-130px;*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
<div id="root"></div>
任何提示都会很棒, 谢谢