音频播放 <audio src =" 路径 " controls> </audio> controls 不可设置宽高 为播放控件
视频播放 <video src=" 路径 " width="400" controls> </video> 可设置宽高
video / audio 通过附加属性可以更好的控制视频的播放 autoplay 自动播放 controls 是否显示默认播放控件 loop 循环播放 preload 预加载,同时设置了autoplay,此属性将失效
- currentTime 音频 / 视频当前播放的进度
- duration 音频 / 视频 总时间
- paused 音频 / 视频是否处于暂停
- load( ) 重新加载音频 / 视频 video / audio.load( )
- play( ) 播放 video / audio.play( )
- pause( ) 暂停 video / audio.pause( )
- oncanplay: 在开始播放时触发
- ontimeupdate: 时时监控当前进度
- onended: 播放完时触发
var ad = document.querySelector("audio");
var sp = document.querySelector("span"); //变化的盒子
var lin = document.querySelector(".line"); //父类盒子
//播放时触发的事件
ad.ontimeupdate = function(){ //比例关系
sp.style.width = lin.offsetWidth * ad.currentTime / ad.duration + "px";
}
// 自定义进度条在鼠标按下移动时 视频/音频播放进度跟着改变
lin.onmousedown = function(){
// 鼠标移动
lin.onmousemove = function(){
sp.style.width = event.pageX - lin.offsetLeft + "px";
ad.currentTime = ad.duration * sp.offsetWidth / lin.offsetWidth;
}
}
//鼠标松开
lin.onmouseup = function(){
lin.onmousemove = null;
}
localStorage 不手动删除 数据一直存在 可以多窗口( 同源)共享
sessionStorage 关闭页面 数据就会删除 只能在同一页面共享
存储数据 :
localStorage/sessionStorage.setItem("name" ,input.value ) 第一个参数为数据名称第二个参数为数据内容
获取数据:
localStorage/sessionStorage.getItem("name" ) 获取存储数据名称为 name 的数据内容
删除数据:
localStorage/sessionStorage.removeItem("name" ) 删除存储数据名称为 name 的数据内容
清空数据:
localStorage/sessionStorage.clear( ) 清空所有数据
全屏状态下 宽高位置等数值属性无法修改 但其内部子类元素所有属性均可修改
box.onclick = function () {
// box.requestFullscreen();
if (ifFullscreen()) { //判断是否全屏
if (document.exitFullscreen) { //兼容写法
document.exitFullscreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
}
} else {
if (box.requestFullscreen) {
box.requestFullscreen();
} else if (box.webkitRequestFullscreen) {
box.webkitRequestFullscreen();
} else if (box.mozRequestFullscreen) {
box.mozRequestFullscreen();
} else {
alert("sorry,无法全屏");
}
}
}
.box:-webkit-full-screen{
/* 宽度 高度 等大小属性无法改变 */
width: 200px;
height: 500px;
background-color: orange;
}
.box:-webkit-full-screen .hw{
/* 子类需写在fullsceen 后面 子类所有属性都可改变*/
font-size: 50px;
font-weight: bold;
color: pink;
}
contenteditable 给单独标签设置时 其内容可被编辑 直接在行内书写 contenteditable = "true"
designMode JS中使用 可时全局内的元素都可被编辑 designMode = "on" ;
window.onload = function() {
document.designMode = "on";
}
<div class="box" contenteditable = true draggable = true></div> //行内样式中书写
<button draggable = true>我是按钮</button>
**draggable ** 拖拽属性 元素可被拖拽 可在行内设置 draggable = "true";
拖拽元素
box.ondrag = function( ){ } 持续拖拽
box.ondragstart = function( ){ } 开始拖拽
box.ondragleave = function( ){ } 鼠标离开拖拽元素
box.ondragend = function( ){ } 停止拖拽
目标元素
box.ondragenter = function( ){ } 鼠标进入目标元素
box.ondragover = function( ){
event.preventDefault; 阻止默认事件 让元素可以堆叠
} 鼠标在目标元素上停留
box.ondrop = function( ){ } 鼠标在目标元素上松开
box.ondragleave = function( ){ } 鼠标离开目标元素
var box = document.querySelector(".box");
box.ondragstart = function(){
// startX = event.offsetX;
// startY = event.offsetY; event.offsetX /offsetY 在元素拖拽后会发生变化
startX = event.pageX - box.offsetLeft;
startY = event.pageY - box.offsetTop;
}
box.ondragend = function(){
box.style.left = event.pageX - startX + "px";
box.style.top = event.pageY - startY + "px";
}
没有数据交互:
ipt.onkeydown = function () {
if (event.keyCode == 13) {
doing.innerHTML += `<li>
<input type="checkbox" onchange = "change()"><P contenteditable = true onkeydown="stopEnter()">${ipt.value}</P><span onclick="remove()">-</span>
</li>`;
todoCount.innerText = ++todoCount.innerText;
ipt.value = "";
}
}
//内容修改时阻止换行
function stopEnter(){
if(event.keyCode ==13){ //触发事件的编码
event.preventDefault(); //阻止默认行为
event.target.blur(); //目标元素失去焦点
}
}
//内容里选择框选中时
function change(){
if(event.target.checked){
todoCount.innerText = --todoCount.innerText;//= ~~todoCount.innerText - 1
doneCount.innerText = ++doneCount.innerText;
doneok.appendChild(event.target.parentNode);
//appendChild添加元素时会删除之前所在父类中的元素
}else{
todoCount.innerText = ++todoCount.innerText;
doneCount.innerText = --doneCount.innerText;
doing.appendChild(event.target.parentNode);
}
}
//删除
function remove(){
event.target.parentNode.remove(); //删除li
if(event.target.parentNode.firstElementChild.checked){
doneCount.innerText = --doneCount.innerText;
}else{
todoCount.innerText = --todoCount.innerText;
}
}
有数据交互:
var arr = JSON.parse(localStorage.getItem("todos")) || [];
// console.log(arr)
var dragEl = null;
refresh(); //进入页面先将数据库中的数据渲染到页面
//刷新页面
function refresh() {
doneok.innerHTML = "";
doing.innerHTML = "";
var todoNum = 0,
doneNum = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i].checked) {
doneok.insertAdjacentHTML("beforeEnd", `<li draggable = "true" data- index = "${i}">
<input data-index = "${i}" type="checkbox" onchange = "change()" checked = "true">
<P data-index = "${i}" onclick = "startEdit()" onkeydown="stopEnter()" onblur = "edit()">${arr[i].content}</P>
<span data-index = "${i}" onclick="remove()">-</span>
</li>`); //动态获取添加的内容 及当前元素的下标
doneNum++;
} else {
doing.insertAdjacentHTML("beforeEnd", `<li draggable = "true" data- index = "${i}">
<input data-index = "${i}" type="checkbox" onchange = "change()">
<P data-index = "${i}" onclick = "startEdit()" onkeydown="stopEnter()" onblur = "edit()">${arr[i].content}</P>
<span data-index = "${i}" onclick="remove()">-</span>
</li>`)
todoNum++;
}
}
todoCount.innerText = todoNum;
doneCount.innerText = doneNum;
//获取所有的li
var liEl = document.querySelectorAll("li");
//遍历 拖拽时交换位置
liEl.forEach(function(item,index,array){
item.ondragstart = function(){
dragEl = this; //保存开始拖拽的元素
}
item.ondragover = function(){
event.preventDefault(); //拖拽元素悬浮时 阻止默认事件 允许元素堆叠
}
item.ondrop = function(){
var nowi = this.dataset.index; //停止拖拽时的目标元素索引
var befi = dragEl.dataset.index;
if(nowi != befi && arr[nowi].checked == arr[befi].checked){ //确保是在 未完成部分调换位置
var temp = arr[befi]; //首先交换从数据库中获得数据的数组中元素 再将交换后 的数据添加到数据库 然后渲染页面
arr[befi] = arr[nowi];
arr[nowi] = temp;
localStorage.setItem("todos",JSON.stringify(arr));
refresh();
}
}
})
}
// JSON.stringify() 将值转换为相应的JSON格式 字符串
// 布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值。
// undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)
// 或者被转换成 null(出现在数组中时)。函数、undefined 被单独转换时,
// 会返回 undefined,如JSON.stringify(function(){}) or JSON.stringify(undefined).
// JSON.stringify({}); // '{}'
// JSON.stringify(true); // 'true'
// JSON.stringify("foo"); // '"foo"'
// JSON.stringify([1, "false", false]); // '[1,"false",false]'
// JSON.stringify({ x: 5 }); // '{"x":5}'
// JSON.stringify({ x: 5, y: 6 }); // "{"x":5,"y":6}"
// JSON.stringify([undefined, Object, Symbol("")]); // '[null,null,null]'
// JSON.parse() 方法用来解析JSON字符串,构造由字符串描述的JavaScript值或对象。
// 提供可选的 reviver 函数用以在返回之前对所得到的对象执行变换(操作)。
// JSON.parse('{}'); // {}
// JSON.parse('true'); // true
// JSON.parse('"foo"'); // "foo"
// JSON.parse('[1, 5, "false"]'); // [1, 5, "false"]
// JSON.parse('null'); // null
// JSON.parse() 不允许用逗号作为结尾
// JSON.parse("[1, 2, 3, 4, ]"); 错误的
// JSON.parse('{"foo" : 1, }'); 错误的
//输入框输入内容失去焦点时 自动添加内容
ipt.onblur = function () {
if (ipt.value.trim() == "") {
return;
}
arr.push({
checked: false,
content: ipt.value
})
localStorage.setItem("todos", JSON.stringify(arr));
refresh();
ipt.value = "";
}
//增加内容 同时向数据库中增加
ipt.onkeydown = function () {
// string.trim() 去掉字符串前后的空格
if (ipt.value.trim() === "") {
return;
}
if (event.keyCode == 13) {
arr.push({
checked: false,
content: ipt.value
})
localStorage.setItem("todos", JSON.stringify(arr));
refresh();
ipt.value = "";
}
}
//开始修改内容时 延迟执行
function startEdit() {
event.target.setAttribute("contenteditable", true);
// setAttribute()设置元素的属性值 getAttribute()获取元素的属性值 //removeAttribute() 删除元素的属性值
var et = event.target; //event.target 在延迟函数中无法使用 需用变量提前接收
setTimeout(function () { //当从上一个文本框点击到下一个文本框时 需要再次点击确认(实现 双机效果) 如果在行内直接绑定 contenteditable 没有此效果
et.focus();
}, 50)
}
//内容修改时阻止换行
function stopEnter() {
if (event.keyCode == 13) { //触发事件的编码
event.preventDefault(); //阻止默认行为
event.target.blur(); //目标元素失去焦点
}
}
//编辑文本
function edit() {
//先将修改的内容添加到从数据库中获取到的数量数组
再将该数组转换添加到数据库 后将数据库中的数据渲染到页面
arr[event.target.dataset.index].content = event.target.innerText;
localStorage.setItem("todos", JSON.stringify(arr));
refresh();
}
//内容里选择框选中时
function change() {
arr[event.target.dataset.index].checked = event.target.checked;
localStorage.setItem("todos", JSON.stringify(arr)); //将值转换为相应的JSON格式的 字符串 ==> " xx " 给原来内容加上单引号/双引号
refresh();
}
//删除
function remove() {
//从当前触发删除事件的元素开始 删除一个(就是自己)
arr.splice(event.target.dataset.index, 1);
localStorage.setItem("todos", JSON.stringify(arr));
refresh();
}
todoCount.innerText = --todoCount.innerText; 也可使用 = ~~todoCount.innerText -1
if(event.keyCode ==13){ //触发事件的编码(回车)
event.preventDefault(); //阻止默认行为
event.target.blur(); //目标元素失去焦点
}
doing.innerHTML += `<li> //li中有input p span 标签
<input type="checkbox" onchange = "change()"><P contenteditable = true onkeydown="stopEnter()">${ipt.value}</P><span onclick="remove()">-</span>
</li>`;