xixijiang的主页


  • Home

  • Archives

  • Tags

css定位属性

Posted on 2017-07-18

说到定位属性,首先想到的是relative,absolute等等,但今天一查,原来面试官口中说的定位属性原来不仅仅是这些~~~~

属性 版本 继承性 简介
position css2 无 用来设置文档对象的定位方式
z-index css2 无 用来设置文档对象的层叠顺序,必须定位position属性为absolute、relative、或fixed,此取值方可生效
top css2 无 用来设置文档对象与其最近一个定位的父对象顶部相关的位置,仅当定义position属性值为absolute、relative、fixed,此取值方可生效
right css2 无 检索或这是对象与其最近一个定位的父对象右边相关的位置
bottom css2 无 检索或设置与其最近一个定位的父对象底边相关的位置
left css2 无 检索或设置与其最近一个定位的父对象左边相关的位置

position对应的值

  • 绝对定位(position: absolute)

绝对定位的作用是将元素从文档流中拖出来,然后使用left,right,top,bottom属性相对于其最近的一个具有定位属性的父包含块(containing block)进行绝对定位,而且是相对于其边框内边缘的,而不是其padding内边缘。如果不存在这样的包含块,则相对于body元素定位。

原来的空间会被其他元素挤占。

元素在最终位置时也不会挤占其他元素的空间,而是浮动到其他元素的上方。

  • 相对定位(postition: relative)

通过left,right,top,bottom属性确定元素在正常文档流中的偏移位置,相对定位完成的过程是首先按static(float)方式生成一个元素(并且元素像层一样浮动起来),然后相对于以前的位置移动,移动方向和幅度由left,right,top,bottom属性确定,偏移前的位置保留不动,没有脱离文档流。

原来的空间不会被其他元素挤占。

元素在最终位置时也不会挤占其他元素的空间,它浮动到其他元素的上方。

  • 固定定位(positition: fixed)

与absolute定位类型类似,但它相对移动的坐标是视图(屏幕内的网页窗口)本身,由于视图本身是固定的,它不会随浏览器窗口的滚动条滚动而变化,不会受文档流动影响。

  • position: static

是默认值。就是按正常的布局流从上到下从左到右布局,没有指定position,默认是static。

  • position: inherit

继续父元素的position值

javascript组件化开发方式

Posted on 2017-07-18

看到要求后,第一反应就是我们最普通的写法(小白写法):

<!DOCTYPE html>
<html>
<head>
  <title></title>
  <script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
  <input type="text" name="" id="inputBox"><span id="res">0</span>个字
  <script type="text/javascript">
    $(function () {
      var input = $('#inputBox');
      input.on('keyup', function () {
        var num = input.val();
        if(num.length !== 0) {
          $('#res').html(num.length);
        }else{
          $('#res').html('0');
        }
      })

    })
  </script>
</body>
</html>

待更新~~

html5 localstorage/sessionstorage/cookie (local storage篇)

Posted on 2017-07-18

local storage与session storage用法相同,这里以local storage为例。

检测浏览器是否支持localStorage

if(window.localStorage){
    alert('support localStorage');
}else {
    alert('does not support localStorage');
}

存储数据的方法

直接给window.localStorage添加一个属性,例如:window.localStorage.a或者window.localStorage['a']。它的读取、写、删除操作方法非常简单,是以键值对的方式存在的,如下:

localStorage.a = 1; 
localStorage['a'] = 'abc'; // 会覆盖上面的值
localStorage.setItem('b', "isaac");
var a1 = localStorage["a"];//获取a的值
var a2 = localStorage.a;//获取a的值
var b = localStorage.getItem("b");//获取b的值
localStorage.removeItem("a"); //清除a的值

这里推荐使用的当然是setItem和getItem,removeItem。

如果希望一次性清除所有的键值,可以使用clear()。

另外,html5还提供了一个key方法,可以在不知道有哪些键值的时候使用,如下:

var storage = window.localStorage;
function showStorage(){
    for(var i=0;i<storage.length;i++){
          // key(i)获得相应的键,再用getItem()方法获得对应的值
          document.write(storage.key(i)+ " : " +             storage.getItem(storage.key(i)) + "<br>");
    }
}
下面是一个简单的例子,实现计数器:
<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
  <input type="button">
  <script type="text/javascript">
    function showStorage(){
      document.getElementsByTagName('input')[0].value = storage.pageLoadCount;
    }
    var storage = window.localStorage;
    if(!storage.getItem("pageLoadCount")){
      storage.setItem("pageLoadCount", 0);
    } 
    storage.pageLoadCount = parseInt(storage.getItem("pageLoadCount")) +1;
    showStorage();
  </script>
</body>
</html>

不断刷新页面就能看到数字每次加一。

需要注意的是:html5本地存储只能存字符串,任何格式存储的时候都会被自动转成字符串,所以读取的时候,需要自己进行类型转换,这就是上面例子中使用parseInt的原因之一

另外,在iPhone/iPad上有时设置setItem()时会出现诡异的QUOTA_EXCEEDED_ERR错误,这时一般在setItem之前,先removeItem()就ok了。(暂时还没做过移动端)

storage事件

html5的本地存储,还提供了一个storage事件,可以对键值对的改变进行监听,使用方法如下:

if(window.addEventListener){
  window.addEventListener('storage', handle_storage, false);
}else if(window.attachEvent){
  window.attachEvent("onstorage", handle_storage);
}

function handle_storage(e){
  if(!e){
    e=window.event;
  }
}

对于事件变量e,是一个StorageEvent对象,提供了一些实用的属性,可以很好的观察键值对的变化:

属性 类型 描述
key string 添加、删除、或者修改的名
oldValue Any 修改前的值,如果是新加的键,该属性的值为null
newValue Any 修改后的值,如果是新机的键,该属性的值为null
url/uri String 触发storage键值对改变对应的方法所在页面的url/uri
那怎么使用storage事件呢?

当同源页面的某个页面修改了localStorage,其余的同源页面只要注册了storage事件,就会触发。

所以,这个例子需要以下条件:

(1)同一个浏览器打开了两个同源页面

(2)其中一个网页修改了localStorage

(3)另一个网页注册了storage事件

很容易犯的错误,在同一个网页修改本地存储,又在同一个网页监听,这样是没有效果的

例子:
在网页A:监听了storage事件:

<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
  <script type="text/javascript">
    window.addEventListener('storage', function(e){
    alert(e.newValue);
  })
  </script>
</body>
</html>

在网页B:修改了localStorage

<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
  <script type="text/javascript">
    localStorage.clear();
    localStorage.setItem('foo', 'bar');
  </script>
</body>
</html>

运行:将上面两个网页保存,放到同一个服务器上,然后,先打开A.html, 再打开B.html,就会看到A.html会弹出提示,注意两个网页要同源。(同源页面:一个大网站的所有小页面)

对于没有服务器的童鞋,可以这样:
比如先打开一个www.baidu.com,在控制台里输入:

window.addEventListener('storage', function(e){
    alert(e.newValue);

再打开一个www.baidu.com,在控制台里输入:

localStorage.clear();
localStorage.setItem('foo', 'bar');

然后此时第一个页面就会弹出提示框了。

扩展

如果非得要在同一网页监听怎么办?可以重写localStorage的方法,抛出自定义事件。

<!DOCTYPE html>
<html>
<head lang="en">
    <title>A</title>
</head>
<body>
<script>
    var orignalSetItem = localStorage.setItem;
    localStorage.setItem = function(key,newValue){
        var setItemEvent = new Event("setItemEvent");
        setItemEvent.newValue = newValue;
        window.dispatchEvent(setItemEvent);
        orignalSetItem.apply(this,arguments);
    }
    window.addEventListener("setItemEvent", function (e) {
        alert(e.newValue);
    });
    localStorage.setItem("nm","1234");
</script>
</body>
<html>

格式转换

js使用json格式比较多,而localStorage存储的是字符串,如果希望把json格式的数据存储在本地,需要调用JSON.stringify()将其转为字符串。

如果从localStorage中读取数据,可以调用JSON.parse()将其转换为json对象。

参考自:http://blog.csdn.net/csethcrm/article/details/7409862
http://blog.csdn.net/ruangong1203/article/details/52841135

html5 localstorage/sessionstorage/cookie (cookie篇)

Posted on 2017-07-18

document对象的cookie属性

  • cookie是一小段文本信息,伴随在http请求里。
  • 它存储于访问者的计算机中,每当同一台计算机通过浏览器请求某个页面时,就会发送这个cookie。
  • 它是浏览器提供的一种机制,Javascript可以调用document对象的cookie属性,并创建和获取cookie的值,因此我们可以通过document.cookie访问它
  • cookie是存于用户硬盘的一个文件,这个文件通常对应于一个域名,也就是说,cookie可以跨越同一域名下的多个网页,但不能跨越多个域名调用。

cookie的根本用途

cookie将信息存储于用于硬盘,因此可以作为全局变量,这是它最大的一个优点。

它最根本的用途是能够帮助web站点保存有关访问者的信息。

cookie的几种小用途

  • 保存用户登录信息:这是最常用的,可以通过cookie保存用户的id
  • 创建购物车:把已选商品保存在cookie中,可以实现不同页面之间数据的同步(同一域名下可以共享cookie),同时在提交订单的时候又会把这些cookie传到后台。
  • 跟踪用户行为:通过cookie记录用户的偏好信息,然后向用户推荐个性化推广信息。这是可以禁用的,也是cookie的缺点之一。

cookie是如何工作的?

cookie是存在于用户硬盘中的,用户每次访问站点时,浏览器会根据URL在本地硬盘上查找与该URL有关的cookie,如果该cookie存在,就会将该cookie填充进request header里的cookie字段,与http请求一起发送到该站点。

cookie的格式和常见的属性


字符串规律:

  • 每个cookie都是键值对的形式
  • 名称和值都必须是URL编码的
  • 两对cookie之间用分号和空格隔开


name、value不必多说,自然是cookie的名和值。

domain,path,expires/max-age,size,http,secure等均是cookie的属性

我们先手动添加几个cookie,代码如下:

document.cookie = "test1=myCookie1;"
document.cookie = "test2=myCookie2; domain=.google.com.hk; path=/webhp"
document.cookie = "test3=myCookie3; domain=.google.com.hk; expires=Sat, 04 Nov 2017 16:00:00 GMT; secure"
document.cookie = "test4=myCookie4; domain=.google.com.hk; max-age=10800;"

domain和path

这两个共同决定了cookie能被哪些页面共享。

如果未设置domain和path,则默认为设置cookie的那个域,如test1所示;

domain可以包含子域,也可以不包含。domain选项中,可以是”.google.com.hk”(不包含子域,表示它对google.com.hk的所有子域都有效),也可以是”www.google.com.hk"(包含子域)。

path用于控制cookie发送的指定域的路径,默认为”/“,表示指定域下的所有路径都能访问,它是在域名的基础下,指定可以访问的路径。例如cookie设置为”domain=.google.com.hk; path=/webhp”,那么只有”.google.com.hk/webhp”及”/webhp”下的任一子目录如”/webhp/aaa”或”/webhp/bbb”会发送cookie信息,而”.google.com.hk”就不会发送,即使它们来自同一个域。

expries/max-age失效时间

expries 和 max-age 是用来决定cookie的生命周期的,也就是cookie何时会被删除。

expries 表示的是失效时间,准确讲是「时刻」,max-age表示的是生效的「时间段」,以「秒」为单位。

若 max-age 为正值,则表示 cookie 会在 max-age 秒后失效。如例四中设置”max-age=10800;”,也就是生效时间是3个小时,那么 cookie 将在三小时后失效。

若 max-age 为负值,则cookie将在浏览器会话结束后失效,即 session,max-age的默认值为-1。若 max-age 为0,则表示删除cookie。

secure

默认情况为空,不指定 secure 选项,即不论是 http 请求还是 https 请求,均会发送cookie。

是 cookie 的安全标志,是cookie中唯一的一个非键值对儿的部分。指定后,cookie只有在使用SSL连接(如HTTPS请求或其他安全协议请求的)时才会发送到服务器。

httponly(即http)

httponly属性是用来限制客户端脚本对cookie的访问。将 cookie 设置成 httponly 可以减轻xss(跨站脚本攻击 Cross Site Scripting)攻击的危害,

防止cookie被窃取,以增强cookie的安全性。(由于cookie中可能存放身份验证信息,放在cookie中容易泄露)

默认情况是不指定 httponly,即可以通过 js 去访问。

如何利用以上属性设置cookie?

  • 服务端设置
    服务器通过发送一个名为Set-cookie的HTTP头来创建一个cookie,作为Response Headers的一部分,每个Set-cookie表示一个cookie(如果想设置多个cookie,需要些多个Set-cookie),每个属性也是以键值对的形式(secure除外),属性间以分号加空格隔开。格式如下(只有cookie的名字和值是必须的):

    1
    Set-cookie: name=value[; expires=GMTDate][; domain=domain][; path=path][; secure]
  • 客户端设置
    客户端设置cookie的格式和Set-cookie头中使用的格式一样。如下:

    1
    document.cookie = "name=value[; expires=GMTDate][; domain=domain][; path=path][; secure]"

    若想要添加多个cookie,只能重复执行 document.cookie(如上)。这可能和平时写的 js 不太一样,一般重复赋值是会覆盖的,

    但对于cookie,重复执行 document.cookie 并「不覆盖」,而是「添加」(针对「不同名」的)。

cookie的缺点

  • 安全性: 由于cookie在http中是明文传递的,其中包含的数据都可以被他人访问,可能会被篡改、盗用
  • 大小限制:cookie的大小限制在4kb左右,不适合大量存储
  • 增加流量:cookie每次请求都会被自动添加到Request Header中,无形中增加了流量。cookie信息越大,对服务器请求的时间越长。

cookie存储在哪里

面试被问到,一脸懵….

cookie失效分为3种:
1、设置过期时间失效(只要设置了过期时间cookie就会存储在硬盘里面)
2、当会话结束时失效,即关闭浏览器窗口(如果没有设置expires,cookie就会存储在内存里面)
3、手动删除cookie失效

测试1:
打开浏览器,进入控制台,输入:

document.cookie="test=myCookie1;"

然后打开Application,找到cookie,此时就能看到我们设置的test1了,
这时候我们关闭这个网页(注意不是关闭浏览器),再重新打开刚才那个窗口,发现test1还在;
如果关闭浏览器,再重新打开刚才那个窗口,发现此时test1已经不见了。

测试2:
打开浏览器,进入控制台,输入:

document.cookie="test3=myCookie3; expires=Sat, 04 Nov 2017 16:00:00 GMT;"

关闭浏览器,再重新打开刚才那个窗口,发现此时test3还在。

转载自:http://www.cnblogs.com/cxying93/p/6107459.html

html5 localstorage/sessionstorage/cookie (一)

Posted on 2017-07-18

基本概念

cookie

cookie是小甜饼的意思,它确实非常小,大小在4kb左右。

cookie主要用途是保存登录信息,比如登录某个网站可以看到“记住密码”,通常是在cookie中存入一段辨别用户身份的数据来实现的。

localstorage

这是html5的新特性,用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。

sessionstorage

sessionstorage与localstorage的接口类似,但保存数据的生命周期不同。

它只是可以将一部分数据在当前会话中保存下来,刷新页面数据依旧存在,但当页面关闭后,sessionstorage中的数据就会被清空。

三者的异同

特性 cookie localstorage sessionstorage
数据的生命周期 可设置失效时间,默认是浏览器关闭后就失效 可以永久存储,除非手动清除 当关闭页面或者浏览器时,才会清除
存放数据大小 4kb 5M 5M
与服务端进行通信 携带在http头中,如果使用cookie保存过多数据,会带来性能问题 仅在客户端(浏览器)中,不参与和服务器的通信 仅在客户端(浏览器)中,不参与和服务器的通信
易用性 需要程序员自己封装,源生的cookie接口不友好 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持

应用场景

cookie: 用户是否登录

因为考虑到每个 HTTP 请求都会带着 Cookie 的信息,所以 Cookie 当然是能精简就精简啦,比较常用的一个应用场景就是判断用户是否登录。针对登录过的用户,服务器端会在他登录时往 Cookie 中插入一段加密过的唯一辨识单一用户的辨识码,下次只要读取这个值就可以判断当前用户是否登录啦。曾经还使用 Cookie 来保存用户在电商网站的购物车信息,如今有了 localStorage,似乎在这个方面也可以给 Cookie 放个假了~

localstorage: 购物车,html5游戏产生的一些本地数据
sessionstorage: 表单提交

如果遇到一些内容特别多的表单,为了优化用户体验,我们可能要把表单页面拆分成多个子页面,然后按步骤引导用户填写。这时候 sessionStorage 的作用就发挥出来了。

html5 video 标签横屏竖屏问题

Posted on 2017-07-17

在手机上录制的视频有些是横屏的,有些是竖屏的,发现使用video标签播放的时候横屏的视频有时候会变成竖屏播放,即使设置了宽高。所以这个播放方向是如何确定的?

先说一个场景
随便在微信打开一个带有视频的文章 你点击视频 视频播放 你把手机翻转变成横屏
你期望的结果是视频边横屏 并且 全屏 但实际当前视窗 已经横屏不知道哪里去了 视频还是在那个小窗口里播放。

video标签本身不具备响应横竖屏的事件

能捕获横竖屏方向的事件和方法

1、 window.orientation属性与onorientationchange事件

//判断手机横竖屏状态:
window.addEventListener("onorientationchange" in window ? "orientationchange" : "resize", function() {
    if (window.orientation === 180 || window.orientation === 0) {
        alert('竖屏状态!');
    }
    if (window.orientation === 90 || window.orientation === -90 ){
        alert('横屏状态!');
    } 
}, false);

//移动端的浏览器一般都支持window.orientation这个参数,通过这个参数可以判断出手机是处在横屏还是竖屏状态。

2、resize监听 通过计算来判断
3、css媒体查询

/* 竖屏 */
@media screen and (orientation:portrait) {

/* portrait-specific styles */

}

/* 横屏 */

@media screen and (orientation:landscape) {

/* landscape-specific styles */

}

屏幕方向对应的window.orientation值:

ipad,iphone: 90 或 -90 横屏

ipad,iphone: 0 或180 竖屏

Andriod:0 或180 横屏

Andriod: 90 或 -90 竖屏

转载自:https://segmentfault.com/q/1010000003913319/a-1020000003919464

http://www.cnblogs.com/AnotherLife/p/5764389.html

利用html5 video打造播放器(四)

Posted on 2017-07-17

(1)今天实现全屏、小屏切换
首先要获取到小屏、大屏情况下的视频的宽高

    pro.initInfo = function() {
    var that = this;
    // 在onload状态下,offsetHeight才会获取到正确的值
    window.onload = function() {
        that.miniInfo = { // mini状态时的样式
            zIndex: 1,
            width: that.video.offsetWidth + 'px',
            height: that.video.offsetHeight + 'px',
            position: that.vRoom.style.position,
            // transform: 'translate(0,0) rotate(0deg)'

        }
        var info = [
                document.documentElement.clientWidth || document.body.clientWidth,
                document.documentElement.clientHeight || document.body.clientHeight
            ],
            w = info[0],
            h = info[1],
            cha = Math.abs(h - w) / 2;
        that.maxInfo = { // max状态时的样式
            zIndex: 99,
            width: h + 'px',
            height: w + 'px',
            position: 'fixed',
            transform: 'translate(-' + cha + 'px,' + cha + 'px) rotate(90deg)'
        }

    }
}

(2)其次就是切换小屏、大屏
这里默认初始是小屏,所以应该在初始化时加上this.isMax = false;
如下:

var myVideo = function(dom) {
    var that = this;
    console.log('this',this);
    $.ready(function() {
        that.video = document.querySelector(dom || 'video');
        that.vRoom = that.video.parentNode;
        // 元素初始化
        that.initEm();
        // 事件初始化
        that.initEvent();
        // //  记录信息
        that.initInfo();
        // 当前播放模式false为mini播放
        that.isMax = false;
    });
}

当点击全屏按钮时,应该触发切换事件:

this.vControls.querySelector('.fill').addEventListener('tap', function() {
    that.switch();
})

切换事件函数如下:

pro.switch = function() {
    var vR = this.vRoom;
    var info = this.isMax ? this.miniInfo : this.maxInfo;
    for (var i in info) {
        vR.style[i] = info[i];
    }
    this.isMax = !this.isMax;
}

(3)接下来实现快进快退

// 快进快退
// 视频手势右滑动事件
this.video.addEventListener('swiperight', function(e) {
    console.log('right');
    this.currentTime += 5;
})
// 视频手势左滑动事件
this.video.addEventListener('swipeleft', function(e) {
    console.log('left');
    this.currentTime -= 5;
})

这样是可以实现小屏模式下的快进快退,但是大屏模式下就不行了,难道手机横放还要上下快进快退?

(4) 处理大屏模式下的快进快退

这时候我们先给video注册一个事件列表

var events = {};
// 增加或者删除事件
// 给video事件添加一个代理来删除添加事件,
// isF就是在新增这个事件是否删除之前的这个相同的事件,
// 因为添加事件用匿名函数的话,是不能删除的,这样设置一个代理就可以把动态添加的事件记录在events里面,便于操作
pro.eve = function(ename, callback, isF) {
    if (callback && typeof(callback) == 'function') {
        isF && arguments.callee(ename);
        events[ename] = callback;
        this.video.addEventListener(ename, events[ename]);
        console.log('删除事件:' + ename);
        return fun;
    }
    var fun = events[ename] || function() {};
    this.video.removeEventListener(ename, fun);
    console.log('删除事件:' + ename);
    return fun;
}

这时候补上修改当前播放进度和音量的功能:

//跳转视频进度 单位 秒
pro.setCurrentTime = function(t) {
    this.video.currentTime += t;
}
//设置音量大小 单位 百分比 如 0.1
pro.setVolume = function(v) {
    this.video.volume += v;
}

再通过代理给video事件添加左右上下滑动的事件((3)中那个就不需要了):

//视频手势右滑动事件
this.eve('swiperight',function(){
    if(that.isMax){
        return that.setVolume(0.2);
    }
    that.setCurrentTime(5);
});

//视频手势左滑动事件
this.eve('swipeleft', function() {
    if(that.isMax){
        return that.setVolume(-0.2);
    }
    that.setCurrentTime(-5);
});

//视频手势上滑动事件
this.eve('swipeup',function(){
    if(that.isMax){
        return that.setCurrentTime(-5);    
    }
    that.setVolume(0.2);
});

//视频手势下滑动事件
this.eve('swipedown', function() {
    if(that.isMax){
        return that.setCurrentTime(5);    
    }
    that.setVolume(-0.2);
});

github源码

参考:https://segmentfault.com/a/1190000006461476

感谢作者!!

利用html5 video打造播放器(三)

Posted on 2017-07-17

利用html5 video打造播放器(一)

利用html5 video打造播放器(二)

上一篇我们已经介绍了基本样式的实现,接下来我们实现相关的事件。


(1)首先,在js文件里,添加如下函数:

pro.initEvent = function() {
    var that = this;
}

(2)点击播放按钮,视频开始播放,那就给按钮添加一个tap事件吧,在pro.initEvent函数里加上:

// 给播放按钮图片添加事件
this.vimg.addEventListener('tap', function() {
    this.style.display = 'none';
    that.video.play();
})

这时候点击按钮,就可以播放了。并且,按钮也消失了。

(3)这时候光播放还不行,还得暂停啊,那就给视频加一个tap事件吧,在pro.initEvent函数里加上:

 // 视频点击暂停或播放事件
this.video.addEventListener('tap', function() {
    if (this.paused) {
        // 如果播放完毕,就从头开始播放
        if (this.ended) {
            this.currentTime = 0;
        }
        // 暂停时点击就播放
        this.play();
    } else {
        // 播放时点击就暂停
        this.pause();
    }
})

这时候我们再去点击视频所在区域,发现就可以停止了。

(3)接下来就是控制条了,我们想让它在播放时消失,暂停时显现,在pro.initEvent函数里加上:

 // 视频播放事件
this.video.addEventListener('play', function() {
    that.vimg.style.display = 'none';
    that.vControls.classList.add('vhidden');

    // 注意这里我们只是把控制条变成透明了,如果我们写了控制条的点击事件,那么变成透明后点击控制条位置还是会触发事件,所以我们可以写一段定时,让控制条3.5s后隐藏
    // 这里写成3.4s只是为了保险,如果没写animation-fill-mode:forwards样式,并且这里设置定时是3.5s,就会闪一下
    that.vCtrolTime = setTimeout(function() {
        that.vControls.style.visibility = 'hidden';
    }, 3400);
})

this.video.addEventListener('pause', function() {
    // 暂停时显示播放按钮
    that.vimg.style.display = 'block';
    that.vControls.classList.remove('vhidden');
    that.vControls.style.visibility = 'visible';
    that.vCtrolTime && clearTimeout(that.vCtrolTime);
})

同时呢,我们应该在css文件里写上动画:

@keyframes vhide {0% {opacity: 1;}100% {opacity: 0;}}
.vhidden{
      animation: vhide 3.5s ease-in;
      -webkit-animation: vhide 3.5s ease-in;
      // animation-fill-mode: forwards;
      // -webkit-animation-fill-mode: forwards;
}

这样,我们就实现了播放、暂停、控制条动画。

(4)好,现在开始显示视频总时间

首先我们得获取视频元信息,在pro.initEvent函数里加上:

// 获取视频元信息
this.video.addEventListener('loadedmetadata', function() {
    that.vDuration = this.duration;
    that.vControls.querySelector('.duration').innerHTML = stom(this.duration);
});

这里的stom函数是时间转换函数,如下:

// 时间格式化
function stom(t) {
    var h = Math.floor(t / 3600);
    h < 10 && (h = '0' + h);
    var m = Math.floor(t % 3600 / 60);
    if (m < 10) {
        m = '0' + m;
    }
    return h + ':' + m + ':' + (t % 3600 % 60 / 100).toFixed(2).slice(-2);
}

此时发现,已经有总时间啦~

(5)下面就开始获取当前播放了多少时间

this.video.addEventListener('timeupdate', function() {
    var currentPos = this.currentTime; // 获取当前播放的位置
    // 更新进度条
    var percentage = 100 * currentPos / that.vDuration;
    // 设置宽度
    that.vControls.querySelector('.timeBar').style.width = percentage + '%';
    that.vControls.querySelector('.current').innerHTML = stom(currentPos);
})

至此,我们实现了进度条时间的显示。

利用html5 video打造播放器(二)

Posted on 2017-07-17

有了video的基本知识(利用html5 video打造播放器(一)),接下来我们要量身定做播放器了。


那么我们的这个播放器要有什么功能呢?

1、自定义播放按钮

2、自定义的进度条,能够显示视频总时间,当前播放了多长时间

3、点击播放按钮,视频开始播放,按钮消失,进度条逐渐消失

4、点击视频,可以切换播放/暂停状态;如果切换为暂停,则播放按钮和进度条重新显示

5、全屏播放

6、手势拨动前进、快退

7、重力感应


下面开始:

(1)新建video-demo.html文件:

<div class="my-video">
    <!-- webkit-playsinline : 在ios中,加入此属性,可以关闭自动全屏播放 -->
    <!-- object-fit:fill : 视频充满video容器的大小 -->
    <video class="" style="" id="video1">
        <source src="2.mp4" type="video/mp4">
        <source src="2.ogg" type="video/ogg"> 设备不支持Video标签。
    </video>
</div>

(2)然后新建video-demo.css文件设置样式:

html, body{
      height: 100%;
}
.my-video{
      position: relative;
      background: black;
}

.my-video video {
      width: 100%;
      height: 100%;
      display: block;
      onject-fit: fill;
}

并在video-demo.html里引入该css文件:

<link rel="stylesheet" type="text/css" href="css/video-demo.css">

此时,应该能看到页面了。

(3)接下来我们要用到mui框架,所以需要在video-demo.html引入mui对应的js文件

<script type="text/javascript" src="js/mui.min.js"></script>

(4)下面我们新建video-demo.js文件,动态添加播放按钮和进度条,记得把该js文件引入到html里:

<script type="text/javascript" src="js/video-demo.js"></script>

(5)在video-demo.js里,我们先写上整体结构:

(function($) {
    var myVideo = function(dom) {
        var that = this;
        $.ready(function() {
            that.video = document.querySelector(dom || 'video');
            that.vRoom = that.video.parentNode;
            // 元素初始化
            that.initEm();
            // 事件初始化
            that.initEvent();
            //  记录信息
            that.initInfo();
        });
    }
    var nv = null;
    $.myVideo = function(dom) {
        return nv || (nv = new myVideo(dom));
    }
}(mui))

其中,

initEm是用于初始化元素,即动态添加播放按钮和控制条;

initEvent是用于放置我们需要的事件函数;

initInfo是用于处理相关信息,比如视频的元数据,小屏、全屏时对应的信息。

然后如果要使用myVideo对应的这些函数,就要在html里加入调用:

<script type="text/javascript">
  var v = mui.myVideo();
</script>

(6)接下来我们首先填充initEm()函数

var pro = myVideo.prototype;

pro.initEm = function() {
    // 动态添加播放按钮
    this.vimg = document.createElement("img");
    // 如果img的src设置为本地资源的话,那么以后使用会出现很多问题,比如,页面层级发生变化时,你要去修改video-demo.js,为避免夜长梦多,我们将图片转换为base64 
    // this.vimg.src = "img/play.png";
    // 以下就是base64编码,可以网上搜索在线转换工具,这里就没写上编码,太长了
    this.vimg.src = 'data:image/png;base64...';
    this.vimg.className = 'play-img';
    this.vRoom.appendChild(this.vimg);

    // 动态添加控制条
    this.vControls = document.createElement('div');
    this.vControls.classList.add('controls');
    this.vControls.innerHTML = '<div><div class="progressBar"><div class="timeBar"></div></div></div><div><span class="current">00:00</span>/<span class="duration">00:00</span></div><div><span class="fill">全屏</span></div>';
    this.vRoom.appendChild(this.vControls);
}

此时应该能看到播放按钮和控制条了,只是样式不对。

(7)接下来我们设置播放按钮的样式

.my-video .play-img{
  position: absolute;
  width: 15%;
  z-index: 99;
  left: 50%;
  top: 50%;
  transform: translateX(-50%) translateY(-50%)
}

(8)然后设置控制条的样式

.my-video .controls{
  width: 100%;
  height: 2rem;
  line-height: 2rem;
  font-size: 0.8rem;
  color: white;
  position: absolute;
  bottom:0;
  background: rgba(0, 0, 0, .55);
  display: flex;
}

.my-video .controls > * {
  flex: 1;
}

.my-video .controls > *:nth-child(1) {
  flex: 6;
}
.my-video .controls > *:nth-child(2) {
  flex: 2;
}

.my-video .controls .progressBar{
  margin: 0.75rem 5%;
  position: relative;
  width: 90%;
  height: 0.5rem;
  background: rgba(200, 200, 200, .55);
  border-radius: 10px;
}

.my-video .controls .timeBar {
    position: absolute;
    top: 0;
    left: 0;
    width: 0;
    height: 100%;
    background-color: rgba(99, 110, 225, .85);
    border-radius: 10px;
}

此时应该能看到这样了:
detail

至此,我们的基本样式已经搞定了,下面就是一些事件了。

利用html5 video打造播放器(一)

Posted on 2017-07-17

html5 video标签

1. video支持的视频格式

  • ogg: 带有theora视频编码和vorbis音频编码的ogg文件
  • mpeg 4: 带有H.264视频编码和AAC音频编码的MPEG 4文件
  • webM: 带有VP8视频编码和Vorbis音频编码的webM文件

2. 使用方法

// 方式1
<video src="movie.ogg" controls="controls" >
    您的浏览器不支持video标签
</video>

// 方式2
<video width="320" height="240" controls="controls">
    <source src="movie.mp4" type="video/mp4">
    <source src="movie.ogg" type="video/ogg">
    您的浏览器不支持video标签
</video>

说明:video元素可以包含多个source元素,每个source元素可以链接不同的视频文件,浏览器将使用第一个可识别的格式

3. video标签的属性

(1) width、height、src属性就不多说了

(2) 重点说一下controls属性:

语法:

<video controls="controls"/>

controls属性规定浏览器应该为视频提供播放控件。如果设置了该属性,则规定不存在作者设置的脚本控件。

浏览器控件应该包括:

  • 播放
  • 暂停
  • 定位
  • 音量
  • 全屏切换
  • 字幕(如果可用)
  • 音轨(如果可用)

(3) autoplay属性

语法:

<video autoplay="autoplay"/>

如果设置了该属性,视频将自动播放。

(4) loop属性
语法:

<video loop="loop"/>

如果设置了该属性,视频将循环播放。

(5) preload属性

该属性规定是否在页面加载后载入视频。(如果设置了autoplay属性,则忽略该属性)

语法:

<video preload="load"/>

属性值:

load: 规定是否预加载视频。可能的值:

  • auto-全部预加载
  • meta-部分预加载,只预加载视频的元数据(包括尺寸,第一帧,曲目列表,持续时间等)
  • none-不进行预加载。可以减少http请求。

(6) poster属性

语法:

<video preload="URL"/>

规定视频下载时显示的图像,或者在用户点击播放按钮前显示的图像。
如果未设置该属性,则使用视频的第一帧来代替。

(7) muted属性

语法:

<video muted/>

规定视频的音频输出应该被静音。

4. 常用方法

play(): 开始播放音频/视频
pause(): 暂停当前播放的音频/视频

5. 常用事件

oncanplay:当文件就绪就可以开始播放时运行的脚本(缓冲已足够开始时)
ontimeupdate: 当播放位置改变时运行的脚本(比如当用户快进到媒介中一个不同的位置时)
onended: 当媒介已到达结尾时运行的脚本(可发送类似“谢谢观看”之类的信息)

6. 常用API属性

duration:返回当前播放视频的总时间(单位是:秒)
paused:设置或返回视频是否暂停
currentTime: 设置或返回当前播放位置(单位是:秒)
ended: 返回视频的播放是否已经结束

1…678
xixijiang

xixijiang

切莫停下前进的脚步

74 posts
1 categories
12 tags
© 2019 xixijiang
Powered by Hexo
Theme - NexT.Muse