day 4 input type=file 提交文件的过程

本文探讨了HTML中文件输入(input type=file)的onchange与oninput事件的应用,分享了两种文件上传框的CSS美化方案,包括利用定位技巧和label元素隐藏input。同时,文章深入介绍了如何使用FormData对象进行文件上传,并借助fetch API实现异步请求,配合node.js的formidable模块处理文件上传。此外,还提供了基于express和mock.js搭建前后端分离Mock服务器的指南。

简单的总结

input type=file 类型 有onchange事件 还有oninput事件

上传文件的框的css美化  有两种方法
1.用一个div包起来利用定位来做  主要的知识点就是让input框透明度设置为0 然后定位的z-index值要设置的比span的大
 .avatar {
      width: 100px;
      height: 50px;
      position: relative;
      overflow: hidden;
      background: brown;
      border-radius: 3px;
      transition: all 1s;
    }

    .avatar:hover {
      background: blueviolet;
    }

    .avatar-file {
      width: 100%;
      height: 100%;
      position: absolute;
      z-index: 50;
      opacity: 0;
    }

    .avatar-span {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      text-align: center;
      line-height: 50px;
      color: white;
      font-size: 20px;
    }
2.用lable包起来  然后让input框隐藏就可以了 设置span的样式就可以了 lable不设置宽和高  自适应就可以了
      .upload-fields {
        cursor: pointer;
      }
      .upload-fields .btn {
        display: inline-block;
        padding: 5px 8px;
        background-color: #09f;
        color: #FFF;
      }
      .upload-fields:hover .btn {
        background-color: #06c;
      }
      .upload-fields input[type="file"] {
        display: none;
      }
<input type="file" class="avatar-file" onchange="handleFileInput(this)">
    //意思就是在这个事件中传个参数  把自己传了进去
     const handleFileInput=function(e){
      console.log(e.files[0].name)
      console.log(e.files[0])   
      document.querySelector('.fileName').innerHTML=e.files[0].name
    }
 //e.files[0]得到的结果就是下面的类型

1555586444267

FormData对象用以将数据编译成键值对,以便用XMLHttpRequest来发送数据。

FormData是一个对象 你可以new一个实例来调用它的方法

 const data = new FormData()
 const avatar = document.querySelector('.avatar-file').files[0]
 data.append('avatar', avatar)
 data.append('name', 'huang')
// 使用ajax上传,这里使用了fetch,也可以使用jQuery,也可以使用其它任何的ajax库,比如后期咱们工作天天用的axios
      fetch('/sign/upload', {
          method: 'post',
          body: data
        })
        .then(resp => resp.json())
        .then(json => {
          if (json.code === 200) {
            console.log(json.data.url)
            uploadImg.setAttribute('src', json.data.url)
          }
        })
//append就是把数据通过键值对的方式传给后台
//后台在接收到数据的时候有一个解析前端发过来数据的方法
//node.js有一个包叫做formidable  Node.js模块,用于解析表单数据,尤其是文件上载。

//特征
//快速(~500mb / sec),非缓冲的多部分解析器
//自动将文件上载写入磁盘
//内存占用少
//优雅的错误处理
//非常高的测试覆盖率

//首先安装一下
//npm i formidable -S
//然后引用
const formidable=require("formidable");

// 先实例化一个formidable.IncomingForm
const form = new formidable.IncomingForm()
// 设置上传的目录,这里咱们设置到express的静态资源目录
form.uploadDir = path.join(process.cwd(), 'public/uploads')
// 保留扩展名
form.keepExtensions = true
//解析请求的数据
form.parse(req,function(err,fields,files){
    // console.log(fields)
    // fields  就是你在请求的时候定义的 data.append('name', 'huang')
    // files  就是你在请求的时候定义的 data.append('avatar', avatar)
    if (files) {
      res.json({
        code: 200,
        data: {
          errMsg: '上传成功',
          url: '/uploads/' + path.basename(files.avatar.path)
            //path.basename解析路径中文件的名字的
            //path.dirname解析路径中的前面的部分的
        }
      })
    }
  })


node.js 中自带一个模块path模块
Node.js path 模块提供了一些用于处理文件路径的小工具
var path = require("path")
//path.basename解析路径中文件的名字的
//path.dirname解析路径中的前面的部分的
//path.join(process.cwd(), 'public/uploads')
//process.cwd()根目录下的意思
//path.resolve(__dirname, 'views')
//__dirname当前执行文件的目录下

基于expressmock.js搭建自己的前后端分离Mock服务器

  1. 运行$ npx express-generator api-server创建一个express项目

  2. $ cd api-server进入项目目录

  3. $ npm install安装项目所需要的依赖

  4. $ npm install nodemon -D安装nodemon

  5. $ npm install mockjs -S安装mockjs

  6. 打开项目目录下的package.json, 更改scripts:

    - "start": "node ./bin/www"
    + "start": "nodemon ./bin/www"
    
  7. 根据需要配置路由

  8. 比如,有一个叫users的路由挂载在 /users下,就可以这么来写这个mock数据

// 引入Mock对象
const Mock = require('mockjs')


// 定义生成数据列表的方法
const generateData = () => {
  // 使用Mock.mock方法来生成mock数据
  return Mock.mock({
    "code": 200,
    "data|12": [
      {
        "id": "@id",
        "title": "@ctitle(15, 25)",
        "author": "@cname",
        "volume": "@int(100, 300)",
        "createAt": "@int(10000000000000, 1554363040517)"
      }
    ]
  })
}

// 定义另外一个方法,用于生成单个数据
const generateDataById = (id) => {
  return Mock.mock({
    "code": 200,
    data: {
      id,
      "title": "@ctitle(15, 25)",
      "author": "@cname",
      "volume": "@int(100, 300)",
      "createAt": "@int(10000000000000, 1554363040517)"
    }
  })
}
/* 获取用户列表 */
router.get('/', function(req, res, next) {
  res.json(generateData())
});
/* 获取单个用户,根据用户的id, 这里有一个express通配符路由(动态路由) */
router.get('/:id', function(req, res, next) {
  const  {
    id
  } = req.params
  res.json(generateDataById(id))
});

module.exports = router;

这样我们就可以使用 http://localhost:port/users获取用户列表,

使用 http://localhost:port/users/任意的id参数获取用户信息

例如:http://localhost:port/users/:123 返回的数据就是id=123的数据

当你想把请求的数据做分页的时候 你可以在请求的时候添加两个参数

limite每页显示数据的条数

offset从第几条开始的

//定义一个这样的方法
const generateData=(limite=10,offset=0)=>{
  return Mock.mock({
   code:200,
   data:{
      nowPage:(offset/limite)+1,
      isLastPage:false,
      total:30,
      [`list|${limite}`]:[{
        "id": "@id",
        "title": "@ctitle(15, 25)",
        "author": "@cname",
        "volume": "@int(100, 300)",
        "createAt": "@int(10000000000000, 1554363040517)"
      }]
    }
  })
}

//如果你想用一个表达式作为一个对象的属性的时候要用[]包起来[`list|${limite}`]
router.get('/', function(req, res, next) {
  const {limite=10,offset=0}=req.query;
  res.json(generateData(limite,offset))
});

//在GET请求的时候请求的参数被绑定在URL上?后面的  后端接收的时候就是在req.query里面 是个对象
//在POST请求的时候请求的参数后端在接收的时候是放在req.body里面的  是个对象
//在用通配符去请求数据的时候要用:隔开例如:id=10  后端在接收的时候 在req.params里面可以得到  是个对象
//一个函数在定义的时候可以给形参定义一个初始值  当在调用这个函数的时候如果没有传参数的时候会用初始值执行这个函数

//如果你想用一个表达式作为一个对象的属性的时候要用[]包起来[`list|${limite}`]

解构赋值

var obj={x:1,y:2,z:3};
var {x,y}=obj;
//相当于定义了两个变量 x=1 y=2 
var {b}=obj
//这样是不行的 这个时候b输出的是undefined
var {x=10}=obj
//这个时候输出的X还是1
var {x,...test}=obj
//这个时候输出的是x=1  test是剩下的全部


//数组的结构赋值用于两个数的交换很方便
let x=1,y=2;
[x,y]=[y,x]
//这样两个变量就交换了

怎么解决下面这种情况

1555655022735

for(let i=0;i<10;i++){
     setTimeout(function(){
       console.log(i)
     },1000)
}
 0
 1
 2
 3
 4
 5
 6
 7
 8
 9

for(var i=0;i<10;i++){
   (function(j){
     setTimeout(function(){
       console.log(j)
     },1000)
   })(i)
}
 0
 1
 2
 3
 4
 5
 6
 7
 8
 9

//用const命名的不能用=直接改变它的值
//但是可以用一些api去改变它的值
//如果是数组就可以用数组的api去改变 对象就用对象的改变

    <input type="text" name="username" oninput="handleInput(this)">
    <input type="email" name="email" oninput="handleInput(this)">
    <input type="password" name="password" oninput="handleInput(this)">
    <button onclick="handleSubmit()">signin</button>
    <script>
    const handleInput = (e) => {
      state[e.getAttribute('name')] = e.value
    }
    const state = {
      username: '',
      email: '',
      password: ''
    }
    const handleSubmit = () => {
      console.log(state)
    }
    </script>


//这个有点有用啊

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <style> form{ text-align:left; width:1000px; height:1000px; margin:auto; border:10px solid black; background-color: aquamarine; } </style> <form id="registratioForm" > <h1>注册表单</h1> 用户名:<input type = "text" name ="username" ><br> 密码:<input type = "password" name ="password"><br> 确认密码:<input type = "password" name ="password"><br> 注册日期:<input type = "date" name ="date"><br> 电话:<input type = "tel" name ="phone"><br> 邮箱:<input type = "email" name ="email"><br> 年龄:<input type = "text" name ="age"><br> 性别:<label><input type = "radio" name ="gender">男</label> <label><input type = "radio" name ="gender">女<br></label> 照片:<input type = "file" name ="photo"><br> 喜欢的食物:<input type = "checkbox" name ="food" value ="面条">面条 <input type = "checkbox" name ="food" value ="粥">粥 <input type = "checkbox" name ="food" value ="烧烤">烧烤<br> 学历:<select name="degree"> <option value ="1">初中</option> <option value ="2">高中</option> <option value ="3">本科</option> <option value ="4">研究生</option> <option value ="5">博士</option></select><br> <label>个人简介:</label><br> <textarea name ="information" cols="30" rows="10"></textarea><br> <input type = "submit" name ="submit"> <input type = "reset" name ="reset"><br> <input type="button" id="btt" value="点我"> <script src="jQuery.min.js"></script> <pre><p class="textchange" style="text-align:left size:200px" > 点一下文本内容即可改变文本颜色和文本大小 《《不要温和的走入那个良夜》》 Do not go gentle into that good night, Old age should burn and rave at close of day; Rage, rage against the dying of the light. Though wise men at their end know dark is right, Because their words had forked no lightning they Do not go gentle into that good night. Their frail deeds might have danced in a green bay, Wild men who caught and sang the sun in flight, And learn, too late, they grieved it on its way, Grave men, near death, who see with blinding sight And you, my father, there on the sad height, </p ></pre> <botton style ="border:4px double green" onclick = "showAlert()">信息填完点此处</botton> <script> let hasDoubleClicked = false; function showAlert(){ alert('撒花'); } $("#btt").click(function(){ alert("再点一次我就隐藏"); hasDoubleClicked=true; }).click(function(){ if(hasDoubleClicked){ $(this).hide(); } }); $(document).ready(function(){ $("#registratioForm").hide().fadeIn(4000); }); $("input").focus(function(){ $(this).animate({ width:'700%', backgroundColor:'#f0f0f0' },300); }).blur(function(){ $(this).animate({ width:'100%', backgroundColor:'#ffffff' },1000); }); $(".textchange").mousedown(function(){ $(this).animate({ " color":"red", "font-size":"20px" }); }); </script> </form> </body> </html>如何修改代码使文本内容在页面右边 表单在左边并且文本内容在点击后可以变为字体更大 字体颜色变红
最新发布
10-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值