Authored by 邱骏

update

... ... @@ -114,10 +114,6 @@ export default {
},
max() {
return this.clientWidth / 375 * this.loadDistance;
},
nowPage() {
this.nextPage
return this.page;
}
},
watch: {
... ... @@ -125,51 +121,53 @@ export default {
this.$nextTick(()=>{
setTimeout(()=>{
this.init();
},300);
}, 300);
});
},
data(newVal,oldVal) {
this.$nextTick(() => {
clearTimeout(this.timer);
this.timer = setTimeout(() => {
if(this.isresizing) {
if (this.isresizing) {
return;
}
if (newVal.length<this.loadedIndex) {
if (newVal.length < this.loadedIndex) {
this.loadedIndex = 0
}
if (newVal.length>oldVal.length || newVal.length>this.loadedIndex) {
if (newVal.length>oldVal.length || newVal.length > this.loadedIndex) {
if (newVal.length === oldVal.length) {
this.resize(this.loadedIndex>0?this.loadedIndex:null)
this.resize(this.loadedIndex > 0 ? this.loadedIndex : null);
return;
}
this.resize(oldVal.length>0?oldVal.length:null)
this.resize(oldVal.length > 0 ? oldVal.length : null)
}
},300);
}, 300);
});
},
page(newVal, oldVal) {
console.log('page=', newVal, oldVal);
}
},
methods: {
init() { // initialize
init() { // initialize
this.root = this.$refs.vueWaterfall;
this.clearColumn();
var col = parseInt(this.col, 10);
for(var i = 0; i < col; i++) {
for (var i = 0; i < col; i++) {
let odiv = document.createElement('div');
odiv.className = 'vue-waterfall-column';
if (this.width) {
odiv.style.width = this.width + 'px'
odiv.style.width = this.width + 'px';
if (i !== 0) {
odiv.style.marginLeft = this.gutterWidth + 'px';
}
this.columnWidth = this.width
}
else {
this.columnWidth = this.width;
} else {
odiv.style.width = 100 / parseInt(col, 10) + '%';
this.columnWidth = 100 / parseInt(col, 10) / 100 * document.documentElement.clientWidth;
}
if(!this.root) {
if (!this.root) {
this.root = this.$refs.vueWaterfall;
}
this.root && this.root.appendChild(odiv);
... ... @@ -181,184 +179,153 @@ export default {
if (!dom.getElementByTagName) {
return;
}
var imgs = dom.getElementByTagName('img');
for(var i=0;i<imgs.length;i++)
{
var lazySrc = imgs[i].getAttribute('lazy-src');
if(!imgs[i].getAttribute('src') && lazySrc)
{
var newImg = new Image();
newImg.src = lazySrc;
if (newImg.complete)
{
var trueWidth = imgs[i].offsetWidth || this.columnWidth
var imgColumnHeight = newImg.height*trueWidth/newImg.width
if(imgs[i].offsetWidth)
{
imgs[i].style.height = imgColumnHeight+'px'
}
}
else{
await new Promise((resolve,reject)=>{
newImg.onload = function(){
var trueWidth = imgs[i].offsetWidth || this.columnWidth;
var imgColumnHeight = newImg.height * trueWidth / newImg.width;
if(imgs[i].offsetWidth)
{
imgs[i].style.height = imgColumnHeight+'px'
}
resolve()
}
newImg.onerror= function(){
resolve()
}
})
}
}
}
},
async append(dom){ //append dom element
var self = this
if(this.columns.length>0)
{
let min = this.columns[0]
for(var i = 1; i < this.columns.length; i++) {
if(await self.getHeight(min) > await self.getHeight(self.columns[i]) + 50){
min = self.columns[i];
}
}
min && min.appendChild(dom)
await this.setDomImageHeight(dom)
}
},
checkImg(dom){ //check has image
if(!dom)
{
return false
}
if(dom.getElementsByTagName&&dom.getElementsByTagName("img").length)
{
return true
}
else{
return false
}
},
async resize(index,elements){ //resize and render
this.isresizing = true
var self = this
if(!this.$slots.default){
this.isresizing = false
return
}
if(!index&&index!=0&&!elements)
{
elements = this.$slots.default
this.loadedIndex = 0
this.clear()
}
else if(!elements){
this.loadedIndex = index
elements = this.$slots.default.splice(index)
}
var imgs = dom.getElementByTagName('img');
for (var i = 0; i < imgs.length; i++) {
var lazySrc = imgs[i].getAttribute('lazy-src');
if (!imgs[i].getAttribute('src') && lazySrc) {
var newImg = new Image();
newImg.src = lazySrc;
if (newImg.complete) {
var trueWidth = imgs[i].offsetWidth || this.columnWidth
var imgColumnHeight = newImg.height*trueWidth/newImg.width
for(var j=0;j<elements.length;j++){
if(elements[j].elm&&self.checkImg(elements[j].elm))
{
var imgs = elements[j].elm.getElementsByTagName('img')
var newImg = new Image()
newImg.src = imgs[0].src
if(newImg.complete)
{
await self.append(elements[j].elm)
self.lazyLoad(imgs)
}
else{
await new Promise( (resolve,reject)=>{
newImg.onload = async function(){
await self.append(elements[j].elm)
self.lazyLoad(imgs)
resolve()
}
newImg.onerror= async function(){
await self.append(elements[j].elm)
self.lazyLoad(imgs)
resolve()
}
})
}
}
else{
await self.append(elements[j].elm)
}
self.loadedIndex++
}
this.isresizing = false
self.$emit('finish')
},
computedPx(img,imgApi){
if(imgs[i].offsetWidth) {
imgs[i].style.height = imgColumnHeight+'px'
}
} else{
await new Promise((resolve, reject) => {
newImg.onload = function() {
var trueWidth = imgs[i].offsetWidth || this.columnWidth;
var imgColumnHeight = newImg.height * trueWidth / newImg.width;
img.style.width = imgApi.width/this.columnWidth
},
lazyLoad(imgs){
if(!imgs)
{
if(!this.root)
{
this.root = this.$refs.vueWaterfall
}
imgs = this.root&&this.root.getElementsByTagName('img')
}
if(imgs[i].offsetWidth) {
imgs[i].style.height = imgColumnHeight+'px'
}
resolve();
};
newImg.onerror= function() {
resolve();
};
});
}
}
}
},
async append(dom) { // append dom element
var self = this;
if (this.columns.length > 0) {
let min = this.columns[0];
for (var i = 1; i < this.columns.length; i++) {
if (await self.getHeight(min) > await self.getHeight(self.columns[i]) + 50){
min = self.columns[i];
}
}
min && min.appendChild(dom)
await this.setDomImageHeight(dom)
}
},
checkImg(dom){ // check has image
if (!dom) {
return false;
}
if (dom.getElementsByTagName && dom.getElementsByTagName('img').length) {
return true;
} else {
return false;
}
},
async resize(index, elements) { // resize and render
this.isresizing = true;
var self = this;
if (!this.$slots.default) {
this.isresizing = false;
return;
}
if (!index && index != 0 && !elements) {
elements = this.$slots.default;
this.loadedIndex = 0;
this.clear();
} else if (!elements) {
this.loadedIndex = index;
elements = this.$slots.default.splice(index);
}
if(!imgs || imgs.length<0)
{
return
}
for(var index=0;index<imgs.length; index++)
{
if(imgs[index].className.match('animation')&&imgs[index].getAttribute('src'))
{
continue
}
else if(imgs[index].className.match('animation')&&!imgs[index].getAttribute('src'))
{
imgs[index].src = imgs[index].getAttribute('lazy-src')
imgs[index].removeAttribute('lazy-src')
}
else if(imgs[index].getAttribute('src')&&!imgs[index].className.match('animation')){
imgs[index].className = imgs[index].className + ' animation'
}
else if(!imgs[index].getAttribute('src')&&imgs[index].getBoundingClientRect().top<this.clientHeight+this.trueLazyDistance)
{
imgs[index].src = imgs[index].getAttribute('lazy-src')
imgs[index].className = imgs[index].className + ' animation'
imgs[index].removeAttribute('lazy-src')
}
}
},
clearColumn(){
this.columns.forEach((item)=>{
item.remove()
})
this.columns=[]
},
clear(){
this.columns.forEach((item)=>{
item.innerHTML = ''
})
},
mix(){
var elements = this.$slots.default
elements.sort(()=>{return Math.random()-0.5})
this.resize(0,elements)
},
for (var j = 0; j < elements.length; j++) {
if (elements[j].elm && self.checkImg(elements[j].elm)) {
var imgs = elements[j].elm.getElementsByTagName('img');
var newImg = new Image();
newImg.src = imgs[0].src;
if (newImg.complete) {
await self.append(elements[j].elm);
self.lazyLoad(imgs);
} else {
await new Promise((resolve, reject) => {
newImg.onload = async function() {
await self.append(elements[j].elm);
self.lazyLoad(imgs);
resolve();
};
newImg.onerror = async function() {
await self.append(elements[j].elm);
self.lazyLoad(imgs);
resolve();
};
});
}
} else {
await self.append(elements[j].elm)
}
self.loadedIndex++;
}
this.isresizing = false;
self.$emit('finish');
},
computedPx(img, imgApi) {
img.style.width = imgApi.width/this.columnWidth
},
lazyLoad(imgs) {
if (!imgs) {
if (!this.root) {
this.root = this.$refs.vueWaterfall
}
imgs = this.root&&this.root.getElementsByTagName('img')
}
if (!imgs || imgs.length < 0) {
return;
}
for (var index = 0; index < imgs.length; index++) {
if (imgs[index].className.match('animation') && imgs[index].getAttribute('src')) {
continue;
} else if (imgs[index].className.match('animation') && !imgs[index].getAttribute('src')) {
imgs[index].src = imgs[index].getAttribute('lazy-src')
imgs[index].removeAttribute('lazy-src')
} else if (imgs[index].getAttribute('src') && !imgs[index].className.match('animation')) {
imgs[index].className = imgs[index].className + ' animation'
} else if (!imgs[index].getAttribute('src') && imgs[index].getBoundingClientRect().top < this.clientHeight + this.trueLazyDistance) {
imgs[index].src = imgs[index].getAttribute('lazy-src')
imgs[index].className = imgs[index].className + ' animation'
imgs[index].removeAttribute('lazy-src')
}
}
},
clearColumn() {
this.columns.forEach((item) => {
item.remove();
});
this.columns = [];
},
clear() {
this.columns.forEach((item) => {
item.innerHTML = '';
})
},
mix() {
var elements = this.$slots.default;
elements.sort(() => {return Math.random() - 0.5});
this.resize(0, elements);
},
async getHeight(dom) {
return dom.offsetHeight;
},
... ... @@ -371,7 +338,7 @@ export default {
const scrollHeight = this.height ? this.root.scrollHeight : this.root.scrollHeight; //document.documentElement.offsetHeight
var diff = scrollHeight - scrollTop - self.clientHeight;
console.log('scrollTop=', scrollTop, 'scrollHeight=', scrollHeight, 'diff=', diff, 'max=', self.max);
// console.log('scrollTop=', scrollTop, 'scrollHeight=', scrollHeight, 'diff=', diff, 'max=', self.max);
self.$emit('scroll', {scrollHeight: scrollHeight, scrollTop: scrollTop, clientHeight: self.clientHeight, diff: diff, time: Date.now()})
if (diff < self.max && self.loadmore && scrollHeight > self.clientHeight) {
... ...
... ... @@ -15,7 +15,7 @@
<script>
import LayoutApp from '../../components/layout/layout-app';
import {createNamespacedHelpers} from 'vuex';
import {mapState as mapYohoState, createNamespacedHelpers} from 'vuex';
import waterFallList from './components/waterfall';
const {mapActions, mapState} = createNamespacedHelpers('article/articleList');
... ... @@ -39,6 +39,7 @@ export default {
},
computed: {
...mapYohoState(['yoho']),
...mapState(['articleList', 'articleListInfo']),
listInfo() { // 列表基础信息
if (this.articleListInfo) {
... ... @@ -49,9 +50,13 @@ export default {
pageSize: this.articleListInfo.pageSize || 20,
totalCount: this.articleListInfo.totalCount || 0,
totalPage: this.articleListInfo.totalPage || 1
}
};
}
}
},
watch: {
'yoho.context.isLogin': function(val) {
this.isLogin = val;
}
},
asyncData({store}) {
... ...
... ... @@ -10,13 +10,23 @@
:page="listInfo.pageNo"
@loadmore="loadMore">
<template>
<div class="cell-item" v-for="(item, index) in articleList">
<div class="cell-item" v-for="(item, index) in articleList" v-if="item.dataType === 1">
<div class="item-image">
<img :src="item.coverImage" v-if="item.dataType === 1">
<img :src="item.coverImage">
<!-- <img :src="item.resourceSrc" v-else-if="item.dataType === 2">-->
</div>
<div class="item-info">
<p v-if="item.content" class="item-title">{{item.content}}</p>
<div class="user-info">
<div class="user-head">
<img :src="item.authorHeadIco">
</div>
<p class="user-name">{{item.authorName}}</p>
<div class="zan-container">
<i :class="[item.hasPraised === 'Y' ? 'iconzan-fill' : 'iconzan_n', 'iconfont', 'btn-zan']"></i>
<p class="zan-count">{{item.praiseCount ? item.praiseCount : '赞'}}</p>
</div>
</div>
</div>
</div>
</template>
... ... @@ -98,25 +108,94 @@ export default {
overflow-x: hidden;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
z-index: 1;
img {
width: 100%;
float: left;
}
.item-image {
width: 100%;
border-radius: 16px 16px 0 0;
overflow: hidden;
img {
width: 100%;
float: left;
}
}
.cell-item {
margin-bottom: 16px;
.item-info {
height: 168px;
background-color: #fff;
border-radius: 0 0 16px 16px;
.item-title {
padding: 8px 20px 0 20px;
max-height: 80px;
line-height: 40px;
font-weight: 600;
font-size: 28px;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
word-break: break-all;
overflow: hidden;
}
.user-info {
position: relative;
padding: 0 20px;
height: 70px;
display: flex;
align-items: center;
.user-head {
width: 40px;
height: 40px;
border-radius: 50%;
overflow: hidden;
}
.user-head img {
height: 100%;
}
.user-name {
display: inline-block;
max-width: 150px;
white-space: nowrap;
overflow: hidden;
font-size: 24px;
font-weight: 300;
padding-left: 8px;
text-overflow: ellipsis;
}
.zan-container {
position: absolute;
display: flex;
right: 0;
width: 120px;
height: 34px;
align-items: center;
}
.btn-zan {
font-size: 34px;
}
.btn-zan.iconzan-fill {
color: #c30016;
}
.zan-count {
display: inline-block;
font-size: 26px;
margin-left: 12px;
max-width: 60px;
white-space: nowrap;
overflow: hidden;
}
}
}
}
}
... ...
... ... @@ -12,6 +12,7 @@ export default {
let result = await this.$api.get('/api/grass/article/list', {
page,
limit,
columnType: 1001,
lastedTime
});
... ... @@ -27,9 +28,9 @@ export default {
if (item.dataType === 1) {
item.authorHeadIco = item.authorHeadIco.replace(/{mode}/, 2).replace(/{width}/, 40).replace(/{height}/, 40);
item.coverImage = item.coverImage.replace(/{mode}/, 2).replace(/{width}/, imageWidth).replace(/{height}/, imageHeight);
item.coverImage = item.coverImage.replace(/{mode}/, 2).replace(/{width}/, imageWidth).replace(/{height}/, imageHeight).replace(/\/format\/webp/, '');
} else if (item.dataType === 2) {
item.resourceSrc = item.resourceSrc.replace(/{mode}/, 2).replace(/{width}/, imageWidth).replace(/{height}/, imageHeight);
item.resourceSrc = item.resourceSrc.replace(/{mode}/, 2).replace(/{width}/, imageWidth).replace(/{height}/, imageHeight).replace(/\/format\/webp/, '');
}
item.imageNewWidth = imageWidth;
... ...
... ... @@ -3,7 +3,7 @@ module.exports = {
'/api/grass/article/list': {
ufo: false,
auth: false,
api: 'app.grass.xyRecArticleList',
api: 'app.grass.columnArticleList',
params: {
page: {type: Number},
limit: {type: Number}
... ...