2017-07-29 104 views
4

下面的代碼有兩個容器div之間的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中的位置?如果是這樣的話:有沒有一種方法可視化其從一個地方到另一個地方的過渡(通過此路徑上的幻燈片)?

+3

我怕回答你的問題是沒有。你可以淡出和淡入,但是如果你想要一個運動轉換,你需要改變一個元素的位置屬性,而不是重新設置它。 –

+0

這應該如何?它可以像這個[小提琴](https://jsfiddle.net/awolf2904/9t2btpvs/)嗎?如果這就是你想要的,我可以添加一個答案,並給出一些細節,我已經創建了它。但正如羅伊所提到的,創建一個元素並改變點擊位置可能更容易。就像在這[小提琴](https://jsfiddle.net/awolf2904/741wk6d0/)。我認爲這看起來更好,因爲顏色變化也是動畫。或者,內容不同的兩個元素是? – AWolf

+0

@AWolf:非常感謝小提琴 - 他們會做出很好的回答。第二個符合我的法案(明天我會仔細看看)。我想要做的是讓兩組標籤過濾文章列表(一組「顯示帶這些標籤的文章」,另一組「不顯示......」)。過濾和標籤切換工作,(我的代碼示例是我實際編碼的簡化)。我只是覺得,當點擊一個標籤時,其他組的幻影太突然了,我寧願讓它從一個組滑到另一個組 - 第二個小提琴似乎實現了。 – WoJ

回答

0

一個簡單腳本,動畫一個div從原點移動到目的地:

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"; 
 
    } 
 
}
#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; 
 
}
<div id="origin"> 
 
    <div id="element"> 
 
    </div> 
 
</div> 
 
<div id="destination"> 
 
</div>

1

好,感謝更好的解釋我你的用例。現在它更清楚你需要什麼。

請看看下面修改的演示或在fiddle

在演示中我添加了兩個滑塊和過濾器,因爲我已經理解它應該如何工作。一個「自編碼」滑塊,一個使用Vue-js-toggle-button依賴項。

我認爲兩者都適合你,但我可能會使用庫,因爲它會減少你的代碼和樣式。

那麼它是如何工作的?

我使用的是transition: all 0.5s ease;和兩個類叫animation一個過渡動畫:

  • 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: { 
 
    \t toggleButton: window['vue-js-toggle-button'] 
 
    },*/ 
 
    data: { 
 
    include: true, 
 
    filterTags: 'even odd', 
 
    articles: [{ 
 
    \t id: 0, 
 
    \t title: 'Test0', 
 
     tags: ['even'] 
 
    }, 
 
    { 
 
    \t id: 1, 
 
    \t title: 'Test1', 
 
     tags: ['odd'] 
 
    }, 
 
    { 
 
    \t id: 2, 
 
    \t title: 'Test2', 
 
     tags: ['even'] 
 
    }, 
 
    { 
 
    \t id: 3, 
 
    \t title: 'Test3', 
 
     tags: ['odd'] 
 
    }, 
 
    { 
 
    \t id: 4, // just to test even & odd exluding 
 
    \t title: 'Test4', 
 
     tags: ['no number'] 
 
    } 
 
    
 
    ] 
 
    }, 
 
    computed: { 
 
    \t filtered() { 
 
    \t return this.articles.filter((article) => 
 
     \t article.tags.some((tag) => 
 
     { 
 
      let result = this.filterTags && this.filterTags.indexOf(tag) !== -1 
 
      return this.include ? result: !result; 
 
     \t }) 
 
    ) 
 
    } 
 
    }, 
 
    methods: { 
 
    \t updateFilterInclude ({value}) { 
 
    \t 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>

+0

謝謝 - 我在描述中不清楚。屏幕截圖在這裏:i.imgur.com/WKzR76z.png。箭頭是我提到的「路徑」(當前點擊「你好」,立即將它移動到「不顯示...」框 - 我想添加一個幻燈片的概念,以便用戶更清楚這一事實它移動了(他可能不會注意到,特別是有更多的標籤))。 – WoJ

+0

好的,我明白了。這似乎有點複雜,因爲你必須爲每個你點擊的標籤添加一個轉換。我今天晚些時候會檢查一下。但現在我已經創建了一個基本的小提琴,只有動畫缺失。這是[小提琴](https://jsfiddle.net/awolf2904/cf0jknu9/)。這是我第一次嘗試不用修改庫,但我認爲需要更改'vue-input-tag'代碼才能獲得預期的結果。 – AWolf