Blob下载文件 & 模拟滚动条实现
1.vue切换路由视图时,事件钩子顺序是 当前模块create-->上一个模块beforeDestroy-->当前模块mounted
因此注册全局事件(比如给window注册事件)应放在mounted里,不然有可能被上一个模块的beforeDestroy移去
2.Ajax请求 后端直接返回二进制流数据(可能是excel、word文件等) 在前端让用户下载
用到Blob() 和 window.URL的api
var blob = new Blob([res.data], {type: "application/vnd.ms-excel"});
var a = document.createElement('a');
a.download = 'pickcenter_log.xlsx';
a.href = window.URL.createObjectURL(blob);
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(a.href);
document.body.removeChild(a);
3. 模拟一个滚动条,可以让滚动条出现在任意位置、相对窗口固定
视口设置为overflow:hidden; 内容盒子设置为position:relative,通过定位来实现滚动效果
如果原生设置了overflow:scroll ,有滚动条时滚动了一定长度,再把overflow设为hidden,虽然滚动条消失了,但是scrollLeft(scrollTop)的影响还存在,会看到之前滚动到的区域,scrollTop置零之后可以归位
mousedown和mousemove事件里preventDefault可以防止拖拽时选中了文字
具名函数表达式(注意:非函数声明)只能在该回调函数内部被访问到,如fnmove,在slideStart里访问会报错未定义
参考:
FunctionDeclaration :
function Identifier ( FormalParameterList opt ){ FunctionBody } FunctionExpression :
function Identifier opt ( FormalParameterList opt ){ FunctionBody }opt表示可有可无,所以函数表达式分为匿名函数和具名函数,所谓的"具名函数表达式"(Named function expressions,NFE),这个函数的识别名,它的作用域是只能在函数的主体(FunctionBody)内部。
原因当然它只是个原本就可有可无的"代理"函数名,真正的这函数识别名称是被赋值的那个变量识别名。
<template>
<div class="scroll-bar" :name="name" v-show="show">
<div class="scroll-track" @click.self="moveThumb">
<div class="scroll-thumb" @mousedown.prevent="slideStart"></div>
</div>
</div>
</template> <script>
export default {
// visibleWidth可视区域宽 scrollWidth内容总宽度 barWidth滚动条轨道长度 elementId视口容器 scrollElementId内容盒子
props:['name','visibleWidth','scrollWidth','barWidth','elementId', 'scrollElementId', 'show'],
data () {
return {
scrollLeft:0,
pos:null
}
},
mounted(){
var $scrollBar = $('.scroll-bar[name="'+ this.name +'"]');
var $track = $scrollBar.find('.scroll-track');
$track.width(this.barWidth || this.visibleWidth);
},
watch:{
show(val){
val && ($('#' + this.elementId).get(0).scrollLeft = 0);
},
// 内容宽度变化
scrollWidth(val){
this.reComputeAll({resetLeft:true});
},
//可视区域宽度会随窗口缩小放大而变化
visibleWidth(val){
this.reComputeAll({resetLeft:false});
}
},
methods:{
reComputeAll(params){
var $scrollBar = $('.scroll-bar[name="'+ this.name +'"]');
var $track = $scrollBar.find('.scroll-track');
var $thumb = $scrollBar.find('.scroll-thumb');
var barWidth = this.barWidth || this.visibleWidth;
var thumbWidth = parseInt(this.visibleWidth * barWidth / this.scrollWidth);
var thumbLeft = parseInt(this.scrollLeft * barWidth / this.scrollWidth);
if (params.resetLeft) {
thumbLeft = 0;
this.scrollLeft = 0;
$('#' + this.scrollElementId).css('left', '0px');
}
!this.barWidth && $track.width(barWidth);
$thumb.width(thumbWidth);
$thumb.css('left', thumbLeft + 'px');
},
reComputeRelative(thumbLeft){
var $scrollBar = $('.scroll-bar[name="'+ this.name +'"]');
var $thumb = $scrollBar.find('.scroll-thumb');
var $element = $('#' + this.scrollElementId);
var barWidth = this.barWidth || this.visibleWidth;
var thumbWidth = parseInt(this.visibleWidth * barWidth / this.scrollWidth);
(thumbLeft < 0) && (thumbLeft = 0);
(thumbLeft > barWidth - thumbWidth) && (thumbLeft = barWidth - thumbWidth);
$thumb.css('left', thumbLeft + 'px');
this.scrollLeft = parseInt(thumbLeft * this.scrollWidth / barWidth);
$element.css('left', -this.scrollLeft + 'px');
},
slideStart(event){
var self = this;
var $scrollBar = $('.scroll-bar[name="'+ this.name +'"]');
var $thumb = $scrollBar.find('.scroll-thumb');
var disX = event.clientX;
!this.pos && (this.pos = event.clientX);
var othumbLeft = parseInt($thumb.css('left'));
function fnmove (e){
var thumbScroll = e.clientX - disX;
var thumbLeft = othumbLeft + thumbScroll;
self.reComputeRelative(thumbLeft);
}
$(document).on('mousemove', fnmove);
$(document).on('mouseup', function fnup(e){
$(document).off('mousemove', fnmove);
$(document).off('mouseup', fnup);
});
},
moveThumb(e){
if (this.pos === null) return;
var thumbLeft = e.clientX - this.pos;
this.reComputeRelative(thumbLeft);
}
}
}
</script> <style lang='less'>
@import '../../assets/css/config.less';
.scroll-bar{
position:fixed;
bottom:0px;
left:220px;
.scroll-track{
position:relative;
height:20px;
background-color: #f5f5f5;
border-radius:10px;
}
.scroll-thumb{
position:absolute;
height: 20px;
border-radius: 10px;
box-shadow: 0 0 6px rgba(0,0,0,.4);
background-color: #e7e7e7;
}
}
</style>
4.字符串中含有<script></script>标签时,</script>要对/转译,或者分开"</scri" + "pt>" 因为编译时会优先读取</script>然后当做脚本已结束
5.getBoundingClientRect() 获取可是区域的位置和几何属性
6.vue在子组件添加ref属性,通过父组件的$ref可以收集子组件的引用
7.html5中,想让html页面被缓存需要加入manifest属性,没有该属性的html页面不参与缓存协商,不受cache-control控制,会请求最新值
Blob下载文件 & 模拟滚动条实现的更多相关文章
- springmvc和servlet在上传和下载文件(保持文件夹和存储数据库Blob两种方式)
参与该项目的文件上传和下载.一旦struts2下完成,今天springmvc再来一遍.发现springmvc特别好包,基本上不具备的几行代码即可完成,下面的代码贴: FileUpAndDown.jsp ...
- python paramiko模拟ssh登录,实现sftp上传或者下载文件
Python Paramiko模块的安装与使用详解 paramiko是短链接,不是持续链接,只能执行你设定的shell命令,可以加分号执行两次命令. http://www.111cn.net/phpe ...
- 利用 Blob 处理 node 层返回的二进制文件流字符串并下载文件
博客地址:https://ainyi.com/65 解释 | 背景 看到标题有点懵逼,哈哈,实际上是后端将文件处理成二进制流,返回到前端,前端处理这个二进制字符串,输出文件或下载 最近公司有个需求是用 ...
- 由于想要实现下载的文件可以进行选择,而不是通过<a>标签写死下载文件的参数,所以一直想要使用JFinal结合ajax实现文件下载,但是ajax实现的文件下载并不能触发浏览器的下载文件弹出框,这里通过模拟表单提交实现同样的效果。
由于想要实现下载的文件可以进行选择,而不是通过<a>标签写死下载文件的参数,所以一直想要使用JFinal结合ajax实现文件下载(这样的话ajax可以传递不同的参数),但是ajax实现的文 ...
- JS模拟滚动条(有demo和源码下载,支持拖动 滚轮 点击事件)
由于游览器自带的滚动条在美观方面并不是很好看,所以很多设计师希望通过自己设计出来的滚动条来做这样的效果,JS模拟滚动条其实很早看到jQuery有这样的插件或者KISSY有这样的组件,一直想着自己什么时 ...
- firefox下载文件弹出框之终极解决方案-vbs模拟键盘操作
由于近期一直被firefox的保存文件弹出框困扰,摸索尝试过几种方法,已有的方法可以跑通但是对对效果不太满意,因此一直在寻找合适的解决办法. 最近发现了也可以通过VBS来处理弹出框,速度也不错,其原理 ...
- vue通过Blob实现下载文件
需求是这样的...... 具体实现,前端拿到后端返回回来的数据,然后通过Blob实现下载,文件内容样式啥的都是后端写的 script代码: 这里的data就是后端返回回来的数据,此方法兼容IE dow ...
- 前端/H5/JS:通过URL下载文件并转存到其他服务器(微信),Blob文件转File文件
现在有一个图片URL,在自己服务器上,一个微信提供的媒体文件上传URL,我在前端通过JS实现转存微信服务器 1. http://file.xxx.com/asd.jpg 自己的 2.https://a ...
- 数据库blob图片文件,多图片打包下载
数据库存储blob图片文件,前端打包下载 数据库图片文件实体类 package com.cmrh.mspserver.pos.dto; import java.io.Serializable; imp ...
随机推荐
- Centos7快速安装haproxy
HAProxy是一个使用C语言编写的自由及开放源代码软件[1],其提供高可用性.负载均衡,以及基于TCP和HTTP的应用程序代理. HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要 ...
- Tomcat三种项目部署方式
第一种:直接将项目放在webapps目录下 材料:项目文件名hello,文件hello.html如图: 访问地址: 注释:hello 项目文件名 hello.html 访问的文件名字 第二种:修改c ...
- immutable-styles 新的css style 开发模式
immutable-styles 是一个开源的library,可以方便我们开发强壮以及可预测的web 界面,不用担心其他css 的影响 特性 编译时错误提示 防止css 覆盖 分离破坏点 严格继承 重 ...
- go-elasticsearch 来自官方的 golang es client
elasticsearch 终于有了官方的golang sdk 了,地址 https://github.com/elastic/go-elasticsearch 当前还不稳定,同时主要是对于es7 的 ...
- 为什么 PCB 生产时推荐出 Gerber 给工厂?
为什么 PCB 生产时推荐出 Gerber 给工厂? 事情是这样的,有一天电工王工,画了一块 PCB,发给 PCB 板厂. 过了几天 PCB 回来了,一看不对呀,这里的丝印怎么少了,那里怎么多了几条线 ...
- mongodb之 非正常关闭启动报错处理
Mongodb如果非正常关闭,直接启动会报错.查看日志文件. 处理: 需要做的是删除mongod.lock和WiredTiger.lock这两个lock文件,然后执行--repair,这里的mongo ...
- TypeScript 之 JSX
https://m.runoob.com/manual/gitbook/TypeScript/_book/doc/handbook/JSX.html JSX中,类型断言必须使用as操作符. 类型检查 ...
- C# 泛型类和泛型方法
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- ASP.NET AJAX入门系列(9):在母版页中使用UpdatePanel
本文简单介绍一下在母版页中使用UpdatePanel控件,翻译自官方文档. 主要内容 1.添加UpdatePanel控件到Content Page 2.通过Master Page刷新UpdatePan ...
- 红外协议之NEC协议
NEC协议载波:38khz 其逻辑1与逻辑0的表示如图所示: 逻辑1为2.25ms,脉冲时间560us:逻辑0为1.12ms,脉冲时间560us.所以我们根据脉冲时间长短来解码.推荐载波占空比为1/3 ...