如何基于新位置将选定的div水平居中?

时间:2019-02-12 16:13:50

标签: javascript vue.js

我的div拥有所有12个月的可用可点击按钮样式。

我要完成的工作是,我选择的每个月,无论我是在当前所选月份的前一个月还是之前单击一个月,都应将该月div移动到水平居中位置,并且父容器溢出- x设置为自动,因此父母应该将按钮滚动到视图中。

除了,我所知道的是,我需要获取月份(我刚刚选择的div)的偏移位置,并且我必须根据孩子来更改父div的滚动位置,这就是我要做的事情。

我为要解决的确切问题创建了jsFiddle

new Vue({
  el: "#app",
  data: {
    months: ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'],
    selected_month: 0,
  },
  methods: {
    select_month(event, key){
      this.selected_month = key;
      
      console.log(event);
      
      // parent - month-tracker__choice
			var parent = event.target.parentElement;
      
      // selected div
      var child = event.target;
      
      parent.scrollLeft = parent.scrollWidth - child.offsetWidth;
      //parent.scrollRight = parent.scrollWidth + child.offsetWidth;
    }
  }
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
  box-sizing: border-box;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 0 10px;
  transition: all 0.2s;
}

body {
  width: 400px;
}

.month-tracker__month-container {
  overflow: hidden;
  height: 62px;
}

.month-tracker__month-choice {
  overflow-y: hidden;
  display: flex;
  flex-wrap: nowrap;
  padding: 10px 0;
  overflow-x: auto;
  height: 74px;
}

.month-tracker__month-picker:first-child {
  margin-left: 0;
}

.month-tracker__month-picker:last-child {
  margin-right: 0;
}

.month-tracker__month-picker {
  padding: 10px 20px;
  border: 1px solid #ddd;
  border-radius: 20px;
  color: #858585;
  font-weight: 600;
  font-size: 14px;
  text-transform: capitalize;
  margin: 0 20px;
  min-width: 160px;
  text-align: center;
  cursor: pointer;
  width: 160px;
  height: 21px;
}

.month-tracker__month-selected {
  background-color: #3e76ff;
  color: #fff;
  transition: all .3s;
  box-shadow: 0 2px 14px 0 rgba(154, 154, 154, 0.19);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div class="month-tracker__month-container">
    <div class="month-tracker__month-choice">
      <div v-for="month, key in months" v-text="month" @click="select_month($event, key)" :class="{ 'month-tracker__month-selected': selected_month == key }" class="month-tracker__month-picker"></div>
    </div>
  </div>
</div>

2 个答案:

答案 0 :(得分:3)

您可以尝试以下方法:

parent.scrollLeft = child.offsetLeft - (child.offsetWidth / 2);

下面的工作演示:

new Vue({
  el: "#app",
  data: {
    months: ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'],
    selected_month: 0,
  },
  methods: {
    select_month(event, key){
      this.selected_month = key;
      
     // console.log(event);
      
      // parent - month-tracker__choice
			var parent = event.target.parentElement;
      
      // selected div
      var child = event.target;
      
      /**** this is what you need ****/
      parent.scrollLeft = child.offsetLeft - (child.offsetWidth/2);
      
    }
  }
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
  box-sizing: border-box;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 0 10px;
  transition: all 0.2s;
}

body {
  width: 400px;
}

.month-tracker__month-container {
  overflow: hidden;
  height: 62px;
}

.month-tracker__month-choice {
  overflow-y: hidden;
  display: flex;
  flex-wrap: nowrap;
  padding: 10px 0;
  overflow-x: auto;
  height: 74px;
}

.month-tracker__month-picker:first-child {
  margin-left: 0;
}

.month-tracker__month-picker:last-child {
  margin-right: 0;
}

.month-tracker__month-picker {
  padding: 10px 20px;
  border: 1px solid #ddd;
  border-radius: 20px;
  color: #858585;
  font-weight: 600;
  font-size: 14px;
  text-transform: capitalize;
  margin: 0 20px;
  min-width: 160px;
  text-align: center;
  cursor: pointer;
  width: 160px;
  height: 21px;
}

.month-tracker__month-selected {
  background-color: #3e76ff;
  color: #fff;
  transition: all .3s;
  box-shadow: 0 2px 14px 0 rgba(154, 154, 154, 0.19);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div class="month-tracker__month-container">
    <div class="month-tracker__month-choice">
      <div v-for="month, key in months" v-text="month" @click="select_month($event, key)" :class="{ 'month-tracker__month-selected': selected_month == key }" class="month-tracker__month-picker"></div>
    </div>
  </div>
</div>

答案 1 :(得分:2)

替换

parent.scrollLeft = parent.scrollWidth - child.offsetWidth;

使用

parent.scrollLeft = child.offsetWidth * key;

scrollLeft从左端开始。现有代码正在做的事情是从正确的位置进行设置。

更新:

parent.scrollLeft = (child.offsetWidth + 40) * key - 70;

对于提供的jsfiddle来说,这更准确。这里40是css提供的总保证金。 70是月份选择器宽度的一半减去总填充的一半