.main ul {
height: 100px;
width: 200px;
background: gray;
overflow:hidden
}
.main a {
margin: 10px 0;
}
<div class="main">
<a href="#">Up </a>
<ul>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
</ul>
<a href="#">Down </a>
</div>
Now i want if i click up button then list item should be slide up and if i click down button the list item should going down. How can i do this by vue js please anyone help me.
CodePudding user response:
Is this the effect that you were hoping to achieve? Liberal use of querySelector
, querySelectorAll
and various sibling selectors make this a relatively straight forward task.
// assign event handler to each hyperlink which themselves have a dataset attribute to aid identification
document.querySelectorAll('a[data-dir]').forEach( a=>a.addEventListener('click',function(e){
// the css class that will be assigned to indicate selected item
const cn='active';
let ul=this.parentNode.querySelector('ul');
let col=Array.from( ul.querySelectorAll('li') );
// prevent highlist disappearing
if( ( ul.querySelector('li.active')==ul.lastElementChild && this.dataset.dir=='down' ) || ( ul.querySelector('li.active')==ul.firstElementChild && this.dataset.dir=='up' ) )return false;
// If no active element is found, make the first LI active.
if( !ul.querySelector('li.active') )ul.firstElementChild.classList.add( cn );
else{
// otherwise process all LI elements until we find the active element
col.some( li=>{
if( li.classList.contains(cn) ){
// clear an other instances of the active class
col.forEach(n=>n.classList.remove(cn));
// highlight appropriate previous/next LI element
switch( this.dataset.dir ){
case 'up':
if( li.previousElementSibling!=null && li.previousElementSibling.tagName=='LI' )li.previousElementSibling.classList.add(cn)
break;
case 'down':
if( li.nextElementSibling!=null && li.nextElementSibling.tagName=='LI' )li.nextElementSibling.classList.add(cn);
break;
}
return true;
}
});
}
}));
.main ul {
min-height: 100px;
width: 200px;
background: gray;
overflow:hidden;
list-style:none inside;
}
.main a {
margin: 10px 0;
}
li{
padding:0.25rem;background:whitesmoke;
}
.active{
background:pink;
}
<div class="main">
<a href="#" data-dir='up'>Up</a>
<ul>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
</ul>
<a href="#" data-dir='down'>Down</a>
</div>
CodePudding user response:
@Professor Abronsius has a good solution using pure Javascript but if you want to do this in Vue you'll need to have your times in your data
object and a scoped variable to keep track of which item is selected.
To expand on this you'd probably want to dynamically update your times array as the user cycled through them.
new Vue({
el: "#app",
data: {
selected:2,
times: [
"11:00am",
"10:00am",
"9:00am",
"8:00am",
"7:00am",
"6:00am"
]
},
methods: {
up: function(){
this.selected--;
},
down: function(){
this.selected ;
}
}
})
ul {
width:100px;
}
li.active {
background-color:lightgrey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Times:</h2>
<span v-on:click="up">Up</span>
<ul>
<li v-for="(time, index) in times" :class="{ active : selected == index}">
{{time}} {{index}}
</li>
</ul>
<span v-on:click="down">Down</span>
</div>