div改变位置时是否存在路径概念?

时间:2017-07-29 20:00:40

标签: javascript html css vue.js

下面的代码有一个div,点击后在两个容器div之间“移动”

new Vue({
  el: "#container",
  data: {
    left: true
  }
})
#container {
  width: 500px;
  display: flex;
  justify-content: space-between;
}

#left {
  width: 100px;
  background-color: red;
}

#right {
  width: 100px;
  background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script>
<div id="container">
  <div id="left">
    <div id="element" v-if="left" v-on:click="left=!left">element</div>
  </div>
  <div id="right">
    <div id="element" v-if="!left" v-on:click="left=!left">element</div>
  </div>
</div>

当这样的元素(具有相同的id)在渲染的DOM中更改其位置时,是否存在路径的概念?如果是这样的话:有没有办法可视化其从一个地方到另一个地方(通过这条路径上的幻灯片)?

2 个答案:

答案 0 :(得分:1)

好的,谢谢你更好地向我解释你的用例。现在你需要的东西更清楚了。

请查看下面的修改演示或fiddle

在演示中,我添加了两个滑块和过滤,因为我已经了解它应该如何工作。一个“自编码”滑块和一个使用Vue-js-toggle-button依赖项。

我认为两者都适合您,但我可能会使用该库,因为它会减少您的代码和样式。

那它是如何运作的?

我正在使用名为animation的过渡动画transition: all 0.5s ease;和两个类:

  • left-position类用于绿色背景颜色,margin-left: 0用于将元素放在容器的左侧
  • right-position类为红色背景,margin-left: calc(75% - 20px);为正确位置。 -20px是因为我添加的填充和75%,因为元素宽度为25%,有一个边距将元素推到右边缘。

通过切换include属性,动画被触发,边距更改将被设置为动画。

我在演示中检测到的问题

  • 两个滑块可能不同步 - 切换底部滑块切换两个滑块但切换另一个滑块不会切换库滑块。不确定,这里有什么不对,只是提到它,如果你只使用一个就不会有问题。
  • 列表转换有时候看起来有点奇怪 - 如果项目因过滤器更改而被删除,它们会出现并逐渐消失。

注意

演示中的标记输入是非常基本的,我会使用一个库,但因为这不是问题,我认为这对演示是可以的。

Vue.use(window['vue-js-toggle-button'].default)

new Vue({
  el: "#container",
/*  components: {
  	toggleButton: window['vue-js-toggle-button']
  },*/
  data: {
    include: true,
    filterTags: 'even odd',
    articles: [{
    	id: 0,
    	title: 'Test0',
      tags: ['even']
    },
    {
    	id: 1,
    	title: 'Test1',
      tags: ['odd']
    },
    {
    	id: 2,
    	title: 'Test2',
      tags: ['even']
    },
    {
    	id: 3,
    	title: 'Test3',
      tags: ['odd']
    },
    {
    	id: 4, // just to test even & odd exluding
    	title: 'Test4',
      tags: ['no number']
    }
    
   ]
  },
  computed: {
  	filtered () {
    	return this.articles.filter((article) => 
      	article.tags.some((tag) => 
        {
          let result = this.filterTags && this.filterTags.indexOf(tag) !== -1
          return this.include ? result: !result;
      	})
      )
    }
  },
  methods: {
  	updateFilterInclude ({value}) {
    	console.log(value)
      this.include = value
    }
  }
})
body {
  font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
}

.vue-js-switch#changed-font {
  font-size: 16px !important;
}

ul {
  list-style-type: none;
}

.flip-list-move {
  transition: transform 0.5s;
}

#container {
  width: 200px;
  /* border: 1px solid black; */
  position: absolute;
  left: 0;
  padding: 5px;
}

.animation {
  -webkit-transition: all 0.5s ease;
  -moz-transition: all 0.5s ease;
  -o-transition: all 0.5s ease;
  -ms-transition: all 0.5s ease;
  transition: all 0.5s ease;
}

.left-position {
  background-color: green;
  /*transform: translate(0, 0);*/
  margin-left: 0;
 }

.right-position {
  background: red;
  /*transform: translate(100%, 0);*/
  margin-left: calc(75% - 20px);
}

input {
  width: calc(100% - 14px);
  padding: 5px;
}

.slider {
  border: 1px solid gray;
  margin-top: 5px;
  padding: 5px;
  border-radius: 10px;
}
.element {
  width: 25%;
  cursor: pointer;
  padding: 10px;
  /* border: 1px solid black; */
  border-radius: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<script src="https://rawgit.com/euvl/vue-js-toggle-button/master/dist/index.js"></script>
<div id="container">
  Filter tags<input v-model="filterTags"/>
    <div class="slider">
      <div class="element animation" @click="include = !include" :class="{'left-position': include, 'right-position': !include}">
      {{include ? 'include' : 'exlude'}}
      </div>
    </div>
    <hr/>
    <toggle-button
      id="changed-font"
      :width="200"             
      :height="40"
      :color="{checked: 'green', unchecked: 'red'}"
      :labels="{checked: 'include', unchecked: 'exclude'}" :value="include" @change="updateFilterInclude"> {{include ? 'include' : 'exlude'}}</toggle-button>
    <transition-group name="flip-list" tag="ul">
      <li v-for="article in filtered" :key="article">
        {{article.tags.join(' ')}} - {{article.title}}
      </li>
    </transition-group>
</div>

答案 1 :(得分:0)

一个简单的脚本,可以激活从原点到目的地的div:

&#13;
&#13;
move( document.querySelector("#element"),  document.querySelector("#destination") ); 

function move( element, destination){

  var destinationElement= element.cloneNode(true);//https://developer.mozilla.org/fr/docs/Web/API/Node/cloneNode
  
  destinationElement.style.visibility= "hidden";
  destination.appendChild( destinationElement );
  
  animate( element, destinationElement );
  
  
}

//it could be better to use jquery animate: http://api.jquery.com/animate/
function animate( element, destination, step ){
  
  if( !step ) 
    step= 0;
    
  var steps= 100;
  var origin= element.getBoundingClientRect();
  element.style.position= "absolute";
  element.style.top= ( origin.top * ( (steps - step ) / steps ) + 
                     destination.getBoundingClientRect().top * (  step / steps ) ) + "px";
  element.style.left= ( origin.left * ( (steps - step ) / steps ) + 
                     destination.getBoundingClientRect().left * (  step / steps ) ) + "px";

  if( step < steps ){
    setTimeout( function(){
      animate(element, destination, ++step );
    },50);
  }else{
    element.parentNode.removeChild(element);
    destination.style.visibility= "visible";
  }
}
&#13;
#origin{
  width: 60px;
  height: 150px;
  border: solid 1px red;
}
#destination{
  width: 100px;
  height: 50px;
  position:relative;
  top: -50px;
  left:200px;
  border: solid 1px green;
}

#element{
  
  width: 10px;
  height: 20px;
  border: solid 1px blue;
  background-color: blue;
}
&#13;
<div id="origin">
  <div id="element">
  </div>
</div>
<div id="destination">
</div>
&#13;
&#13;
&#13;