相对于列表大小的模态位置

时间:2017-05-10 20:32:35

标签: javascript html css vuejs2

我在v-for(或ng-repeat,如你所愿)中有一个待办事项列表,并且在每一个中我想要一个删除模式。我用js和css手工做这个模态。问题是,我希望模态的位置相对于列表。 例如,如果我在列表的第一个元素,我希望模态出现在顶部(在第一个元素的前面)。 但如果是列表的第10个元素,我希望模态出现在第10个元素的前面,而不是在第一个元素前面的顶部。

喜欢这个小提琴:https://jsfiddle.net/cvrnogueira/0twuem2s/7/

有没有人知道我该怎么做?

html:

<div id="vue-instance">
  <ul>
    <li v-for="(index, item) in inventory">
      {{ item.name }} - ${{ item.price }}
      <button @click="deleteLeader(index, item)"> delete</button>
    </li>
  </ul>
</div>

JS:

 var vm = new Vue({
  el: '#vue-instance',
  data: {
    inventory: [
      {name: 'MacBook Air', price: 1000},
      {name: 'MacBook Pro', price: 1800},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Acer Aspire One', price: 300}
    ]
  },
   methods: { 
           deleteLeader: function(index,item){
                    this.inventory.splice(index,1);
            }
           }

});

2 个答案:

答案 0 :(得分:1)

您可以将$event作为参数传递给deleteLeader函数,从那里您可以获取被引用的html元素并获取其位置并将其分配给模态

类似这样的事情

var vm = new Vue({
  el: '#vue-instance',
  data: {
    inventory: [
      {name: 'MacBook Air', price: 1000},
      {name: 'MacBook Pro', price: 1800},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Acer Aspire One', price: 300}
    ]
  },
   methods: { 
           deleteLeader: function(index,item,event){              
              var m = document.getElementById("modal");
              
              m.style.display = "block";
              m.style.top = event.target.offsetTop + "px";
              m.style.left = event.target.offsetLeft + "px";
              //this.inventory.splice(index,1);
            }
           }
           
});
#modal{
  position: absolute;
  top:0;
  left: 0;
  background-color: red;
  padding: 20px;
  box-shadow: 0 4px 5px 0 rgba(0,0,0,0.14), 0 1px 10px 0 rgba(0,0,0,0.12), 0 2px 4px -1px rgba(0,0,0,0.3);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.16/vue.js"></script>

<div id="vue-instance">
  <ul>
    <li v-for="(index, item) in inventory">
      {{ item.name }} - ${{ item.price }}
      <button @click="deleteLeader(index, item,$event)"> delete</button>
    </li>
  </ul>
</div>

<div id="modal" style="display: none;">
  <h4>Are you sure?</h4>
  <button>Yes</button>
  <button>Maybe</button>
</div>

答案 1 :(得分:1)

解决方案:具有动态CSS属性的绝对定位模态

您可以将vue的$event作为参数传递,从中获取点击位置,然后更改您的绝对定位元素的topleft CSS属性(在您的情况下为模态)。

enter image description here

代码

HTML:

<div id="vue-instance">
  <ul>
    <li v-for="(index, item) in inventory">
      {{ item.name }} - ${{ item.price }}
      <button @click="deleteLeader(index, item, $event)"> delete</button>
    </li>
  </ul>
  <div id="modal" class="hidden">
    Hello, I'm a modal!
  </div>
</div>

JS:

var vm = new Vue({
  el: '#vue-instance',
  data: {
    inventory: [
      {name: 'MacBook Air', price: 1000},
      {name: 'MacBook Pro', price: 1800},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Lenovo W530', price: 1400},
      {name: 'Acer Aspire One', price: 300}
    ]
  },
   methods: { 
           deleteLeader: function(index,item,event){
                    // maybe at this point you'd want to rename this method's name
                    this.inventory.splice(index,1);

                    var modal = document.getElementById("modal");
                    modal.style.top = event.clientY + "px";
                    modal.style.left = event.clientX + "px";
                    modal.classList.remove("hidden");
            }
           }

});

CSS:

#modal {
  padding: 5px;
  position: absolute;
  background: red;
  border-radius: 10px;
  color: #fff;
}

.hidden {
  display: none;
}

工作示例:

https://jsfiddle.net/t88Lom9a/2/