无法以编程方式调整我相对元素之间的边距

时间:2019-06-13 03:17:22

标签: javascript css

这是我目前要达到的目标: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>

任何提示都会很棒, 谢谢

0 个答案:

没有答案