My fiddles
Features: API fetching, infinite scroll, lazy loading.
by Simon Herteby
HTML
<script src="https://unpkg.com/[email protected]/dist/vue-mugen-scroll.min.js"></script>
<div id="vue">
<header>
<span class="user">{{user}} -</span> My fiddles
</header>
<div v-for="fiddle in fiddles" :class="{fiddle:true,fullscreen:fullscreen == fiddle}" ref="fiddle">
<h2>
<a :href="fiddle.url">{{fiddle.title}}</a>
<button @click="fullscreen ? fullscreen = false : fullscreen = fiddle">
{{fullscreen ? 'Disable Fullscreen' : 'Fullscreen'}}
</button>
</h2>
<p v-if="fiddle.description">{{fiddle.description}}</p>
<iframe v-if="fiddle.show" :src="fiddle.url + 'embedded/result,js,html,css'" frameborder="0"></iframe>
</div>
<mugen-scroll v-if="loadMore" :handler="load" :should-handle="loadMore && !loading">Loading...</mugen-scroll>
<div v-else class="mugen-scroll">You have reached the end.</div>
</div>
SCSS
body{
font-family:sans-serif;
margin:0;
background:#c8d1d5;
}
a{
text-decoration:inherit;
color:inherit;
&:hover{
color:#0af !important;
}
}
.mugen-scroll{
font-size:20px;
text-align:center;
margin:20px;
}
header{
background:#333;
font-size:30px;
padding:20px;
color:white;
.user{
color:lightgrey;
}
}
.fiddle{
background:white;
margin:20px;
box-shadow:0px 1px 4px rgba(0,0,0,0.4);
transition:0.2s;
display:flex;
flex-direction:column;
min-height:400px;
animation:appear 0.5s;
&.fullscreen{
position:fixed;
top:0;
bottom:0;
left:0;
right:0;
z-index:100;
margin:0;
}
h2{
text-decoration:none;
padding:10px;
margin:0px;
display:flex;
button{
margin-left:10px;
}
}
p{
margin:0 10px;
}
iframe{
flex-grow:1;
}
}
button{
background:linear-gradient(#0af,#08f);
color:white;
border:none;
border-radius:99px;
padding:5px 15px;
cursor:pointer;
box-shadow:0px 1px 1px rgba(0,0,0,0.4);
outline:none;
&:hover{
background:linear-gradient(#0bf,#09f);
}
&.big{
display:block;
margin:20px auto;
font-size:16px;
padding:10px 20px;
}
&[disabled]{
background:grey;
cursor:default;
}
}
@keyframes appear{
from{
opacity:0;
}
}
JavaScript
new Vue({
el: '#vue',
data: {
user:'Herteby',
fiddles: [],
fullscreen: false,
start:0,
loading:false,
loadMore:true,
},
methods:{
load(){
this.loading = true
fetch(location.origin + '/api/user/' + this.user + '/demo/list.json?start=' + this.start, {
mode: 'same-origin'
})
.then(res => res.json())
.then(res => {
this.loading = false
if(!res.length){
this.loadMore = false
} else {
res.forEach(fiddle => {
if(fiddle.title !== 'My fiddles'){ //Avoid infinite recursion!
this.fiddles.push(fiddle)
}
})
this.$nextTick(this.scroll)
}
})
this.start += 10
},
scroll(){
this.fiddles.forEach((fiddle, i) => {
if(!fiddle.show && this.$refs.fiddle[i].offsetTop < window.scrollY + window.innerHeight){
this.$set(fiddle, 'show', true)
}
})
}
},
mounted(){
window.addEventListener('scroll', this.scroll)
window.addEventListener('resize', this.scroll)
}
})