video属性练习,手写controls

news2024/12/24 11:56:52
 <video src="../xxx.mp4"></video>
    <div class="controls">
      <button id="btnPlay">播放/暂停</button>
    </div>
    <div class="controls" id="progress">
      进度:
      <input type="range" min="0" max="100" value="0" />
      <span>current</span>
      /
      <span>total</span>
    </div>
    <div class="controls" id="rate">
      播放速率:
      <button data-rate="0.5">0.5倍</button>
      <button data-rate="0.75">0.75倍</button>
      <button data-rate="1">1倍</button>
      <button data-rate="1.25">1.25倍</button>
      <button data-rate="1.5">1.5倍</button>
    </div>
    <div class="controls" id="volume">
      音量:
      <input type="range" min="0" max="100" value="50" />
      <span>50%</span>
    </div>
    <div class="controls">
      <button id="save">保存设置</button>
      <button id="load">加载设置</button>
    </div>

在这里插入图片描述

      video {
        width: 80%;
      }
      .active {
        background: #ffbd80;
      }
const controls = document.querySelectorAll(".controls")
const video = document.querySelector("video")
const progressSpans = document.querySelectorAll("#progress span")
const progressInp = document.querySelector("#progress input")
const btnPlay =document.querySelector("#btnPlay")
const rate = document.querySelector("#rate")
const volume = document.querySelector("#volume")
const inpV = volume.querySelector("input")
const spanV = volume.querySelector("span")

video.addEventListener("loadeddata", init)

//初始化
function init(){
    //显示进度
    showProgress();
    //默认倍速
    showSpeed();
   //初始化音量
    showVolume()
    //显示所有控件
    for (const item of Array.from(controls)) {
        item.style.display = "block"
    }
}
/**
 * 进度条显示
 */
function showProgress(){
    progressSpans[0].textContent = formatTime(video.currentTime)
    progressSpans[1].textContent = formatTime(video.duration)
    //进度条百分比
    progressInp.value = Math.floor(video.currentTime/video.duration *100)
}
//格式化
function formatTime(times){
    const hour = Math.floor(times/3600);
    const minute = Math.floor(times/60%60)
    const second = Math.floor(times%60);
    function format(num){
        return num>=10 ? num : '0'+num
    }
    return `${format(hour)}:${format(minute)}:${format(second)}`
}
//时间改变的时候,进度条也要改变
video.addEventListener("timeupdate",showProgress)
//点击进度条修改video的当前时间
progressInp.addEventListener("click",()=>{
    video.currentTime = Math.floor(progressInp.value/100 * video.duration)
})

/**
 * 初始化倍速
 */
function showSpeed(){
    const speed = Array.from( rate.querySelectorAll("button")).find(item=>{
        return +item.dataset.rate === video.playbackRate
   })
   document.querySelector("#rate button.active") && document.querySelector("#rate button.active").classList.remove("active")
   speed.classList.add("active")
}
//倍速播放
rate.addEventListener("click",(e)=>{
    if(e.target.tagName === 'BUTTON'){
        video.playbackRate = e.target.dataset.rate
        showSpeed()
    }
})
video.addEventListener("ratechange",showSpeed)


/**
 * 音量
 */
function showVolume(){
    if(video.muted){
        //静音的时候
        inpV.value = 0
        spanV.textContent = "0%"
        return;
    }
    inpV.value = Math.floor(video.volume *100)
    spanV.textContent = inpV.value +"%"
}
video.addEventListener("volumechange",showVolume)
//点击音量进度条,修改video音量
inpV.addEventListener("click",()=>{
    video.volume = inpV.value/100
})

/**
 * 播放、停止
 */
function playOrPause(){
    video.paused ? video.play() : video.pause();
}
btnPlay.addEventListener("click",playOrPause)


/**
 * 保存设置
 */
const save = document.querySelector("#save")
save.addEventListener("click",()=>{
    localStorage.setItem("vobj",JSON.stringify({
        currentTime: video.currentTime,
        duration: video.duration,
        progress: progressInp.value,
        rate: video.playbackRate,
        volume: inpV.value/100
    }))
})

/**
 * 加载设置
 */
const load = document.querySelector("#load")
load.addEventListener("click",()=>{
    let vobj = JSON.parse(localStorage.getItem("vobj"))
    video.currentTime = vobj.currentTime;
    video.playbackRate = vobj.rate;
    video.duration = vobj.duration;
    video.volume = vobj.volume
    showProgress();
    showSpeed();
    showVolume()
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1023061.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

编译chromium总结

文章目录 一、官方文档二、DEPOT_TOOLS_UPDATE三、少修改subprocess.py里的编码四、运行截图 之前在ubuntu18编译过&#xff0c;这次换win11试一试&#xff0c;成功后我又删了一次&#xff0c;再次编译发现了之前没注意到的点。下面是一些重点和我的实践。 一、官方文档 https…

【MT7628AN】IOT | MT7628AN OpenWRT开发与学习

IOT | MT7628AN OpenWRT开发与学习 时间:2023-06-21 文章目录 `IOT` | `MT7628AN` `OpenWRT`[开发与学习](https://blog.csdn.net/I_feige/article/details/132911634?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22132911634…

Python练习之选择与循环

目录 1、编写程序&#xff0c;运行后用户输入4位整数作为年份&#xff0c;判断其是否为闰年。提示&#xff1a;如果年份能被400整除&#xff0c;则为闰年&#xff1b;如果年份能被4整除但不能被100整除也为闰年。2、编写程序&#xff0c;用户从键盘输入小于 1000 的整数&#x…

链表oj题1(Leetcode)——移除链表元素,反转链表,链表的中间节点,

链表OJ 一&#xff0c;移除链表元素1.1分析1.2代码 二&#xff0c;找到链表的中间节点2.1分析2.2代码 三&#xff0c;反转链表3.1分析3.2代码 四&#xff0c;找到链表中倒数第k个节点4.1分析4.2代码 一&#xff0c;移除链表元素 移除链表元素 1.1分析 这里的删除要分成两种…

视频监控系统/视频汇聚平台EasyCVR平台页面展示优化

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

代码随想录算法训练营day55|392.判断子序列 |115.不同的子序列

392.判断子序列 力扣题目链接 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符而不改变剩余字符相对位置形成的新字符串。&#xff08;例如&#xff0c;"ace"是"…

基于Xml方式Bean的配置-Bean的依赖注入以及·自动装配

Bean的依赖注入配置 Bean的依赖注入方式 注入方式配置方式通过Bean的set方法注入 <property name"userDAO" ref"userDAO"/> <property name"userDAO" value"userDAO"/> 通过构造Bean的方法进行注入 <constructor-arg n…

AB试验(三)一次试验的规范流程

AB试验&#xff08;三&#xff09;一次试验的规范流程 一次完整且规范的A/B试验可参考下图&#xff1a; 确定目标和假设 核心&#xff1a;A/B测试是因果推断&#xff0c;所以我们首先要确定原因和结果。目标决定了结果&#xff0c;而假设又决定了原因。 如何确定 分析问题&am…

极盾故事|“二次授权”“脱敏复原”,某银行数据动态脱敏系统get新技能?

数据&#xff0c;既要可用&#xff0c;又要安全&#xff0c;还要合规&#xff01;企业“一难、两难、多难”的困境&#xff0c;如何破&#xff1f; 极盾科技助力某商业银行&#xff0c;基于极盾觅踪构建应用数据动态脱敏系统&#xff0c;实现30&#xff0b;核心应用系统以及用户…

科技云报道:青云科技打出“AI算力牌”,抢跑“云+AI”新增市场

科技云报道原创。 近三年&#xff0c;中国云计算市场在多个维度同时发生着剧烈变化——疫情极大加速了全社会对于数字化的认知和接受程度&#xff1b;一系列云原生技术依托着开源和蓬勃的市场而迅速发展演变&#xff0c;更多产品和技术名词同时涌向市场&#xff1b;国际关系复…

Jenkins+Gitee+Docker+Ruoyi项目前后端分离部署

前言 描述&#xff1a;本文主要是用来记录 如何用标题上的技术&#xff0c;部署到云服务器上通过ip正常访问。 一、总览 1.1、Docker做的事 拉取 mysql 镜像拉取 redis 镜像拉取 jdk 镜像拉取 nginx 镜像 解释说明&#xff1a;前端项目的打包文件放在 nginx容器运行。后端…

时间在情绪周期视角来看也是不存在的

在交易软件里我们会发现有交易周期&#xff0c;分钟级别&#xff0c;小时级别&#xff0c;天&#xff0c;周&#xff0c;月&#xff0c;年等。对于超短线而言这些周期没有任何意义&#xff0c;换言之时间这个东西不是一个维度&#xff0c;所以你去用时间选出来的股票那代表什么…

以“窖主节”之名,泸州老窖邀你赴一场“浓烈”的约会

“永远不要低估一颗浓烈的心。” 最近&#xff0c;在河北秦皇岛海边沙滩上&#xff0c;一座“双手碰杯”的艺术装置吸引了不少来自天南海北的游客打卡拍照。原来&#xff0c;这是泸州老窖“窖主节”秦皇岛站的活动主题打卡点。 9月15日—17日&#xff0c;为期三天的泸州老窖“…

【VisualStudio】NuGet包管理器下载缓存packages文件夹过大怎么清理

使用Visual Studio 开发工具时间长了&#xff0c;会发现整个项目的总大小越来越大&#xff0c;默认是存放在电脑系统盘里的&#xff0c;随着Windows11系统常常更新重启&#xff0c;导致系统盘闲置空间越来越小&#xff0c;该怎么办呢。 描述问题 整个解决方案项目会越变越大&…

MURD560-ASEMI超快恢复二极管MURD560

编辑&#xff1a;ll MURD560-ASEMI超快恢复二极管MURD560 型号&#xff1a;MURD560 品牌&#xff1a;ASEMI 封装&#xff1a;TO-252 正向电流&#xff1a;5A 反向电压&#xff1a;600V 引线数量&#xff1a;3 芯片个数&#xff1a;1 芯片尺寸&#xff1a;74MIL 漏电流…

Spring Cloud Alibaba Ribbon负载均衡器

文章目录 Ribbon 负载均衡器环境搭建1.依赖2.配置3.修改其默认的负载均衡策略3.1 验证 4.创建自定义的Rule4.1 MyRule&#xff08;&#xff09;4.2 在配置config类中配置 5.饥饿加载6.我只想访问不想被别的访问 Ribbon 负载均衡器 背景 Ribbon 是一个用于客户端负载均衡的开源…

云原生容器平台——新华资产数字化转型加速器

新华资产管理股份有限公司&#xff08;以下简称“新华资产”&#xff09;于2006年5月经中国保险监督管理委员会批准、7月3日正式挂牌成立&#xff0c;是国内首批专业保险资产管理机构。2020年上半年&#xff0c;公司管理的资产规模突破万亿元人民币&#xff0c;投资收益水平居行…

Gin学习记录4——Controller和中间件

一. Controller 用不同的Controller可以实现业务的分类&#xff0c;不同类型的请求可以共用同一套中间件 1.1 单文件Controller 几乎等同于函数封装&#xff0c;直接将ctrl的代码写入到一个文件里然后调用&#xff1a; package adminimport ("net/http""git…

天猫健康“小补点”掀起养生新趋势,燕窝、自在水搭着喝双倍补

长时间对着电脑、一坐就是一天、想运动却挤不出时间……这几乎是大部分职场人的常态。为了守护健康&#xff0c;许多职场人开始探索便捷、有效的养生方式。 顺应这一需求&#xff0c;天猫健康发起“带薪养生小补点”活动&#xff0c;携手新加坡健康品牌余仁生、元气森林旗下品…

爬虫 — Scrapy 框架(二)

目录 一、Scrapy 核心文件1、spider2、Request3、构造 post 请求4、response 二、案例三、Scrapy 下载中间件1、执行顺序2、使用方法3、Download Middlewares 默认方法4、代理 IP4.1、工作原理4.2、分类4.3、查看 IP 地址4.4、常用代理 四、Scrapy 爬虫中间件五、Scrapy 下载图…