sumerui - jQuery仿抖音视频网页源码【纯前端HTML5 + JS + CSS】
演示实例
部分代码片段:
HTML部分:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title></title>
<script src="js/mui.min.js"></script>
<script src="https://www.jq22.com/jquery/jquery-1.10.2.js"></script>
<script src="js/swiper.min.js"></script>
<!-- 先注释 -->
<script src="js/iphone-inline-video.min.js"></script>
<link href="css/mui.min.css" rel="stylesheet" />
<link href="css/swiper.min.css" rel="stylesheet" />
<link href="css/index.css" rel="stylesheet" />
<script type="text/javascript" charset="utf-8">
mui.init();
</script>
</head>
<body>
<div id="wrap">
<!-- 顶部的三个页面入口植发,美发,养发 -->
<div class="topWrap">
<div class="faWrap">
<div class="zhifa">植发</div>
<div class="meifa">美发</div>
<div class="yangfa">养发</div>
<div class="shipin">视频</div>
</div>
</div>
<div class="swiper-container">
<div class="swiper-wrapper">
<!--
<div class="swiper-slide">
<video class="video" id="video1" preload="auto" data-id="1"
src="http://baobab.kaiyanapp.com/api/v1/playUrl?vid=164016&resourceType=video&editionType=default&source=aliyun&playUrlType=url_oss"
x5-playsinline playsinline webkit-playsinline page-gesture="true" show-fullscreen-btn="false"
show-center-play-btn="true" show-play-btn="false" enable-play-gesture="true"
loop="true">你的浏览器不支持HTML5播放此视频
</video>
<div class="play">
<img src="./imgs/bigplayBtn.png" alt="">
</div>
<div class="desc">
<div class="desc_name">@吃货世界</div>
<div class="desc_title">欢迎来到美丽的大山世界太刺激了下次有时间还想来</div>
</div>
<div class="function">
<div class="guanzhu">
<img src="./imgs/touxiang.png" alt="">
<div class="guanzhu_btn">关注</div>
<div class="guanzhuBtn_active">已关注</div>
<div class="guanzhu_number">666w</div>
</div>
<div class="dianzan">
<img class="xin" src="./imgs/dianzan.png" alt="">
<img class="xin_active" src="./imgs/dianzan1.png" alt="">
<div class="dianzan_number">666w</div>
</div>
<div class="xiaoxi">
<img src="./imgs/xiaoxi.png" alt="">
<div class="xiaoxi_number">666w</div>
</div>
<div class="zhuanfa">
<img src="./imgs/zhuanfa.png" alt="">
</div>
</div>
</div>
-->
</div>
</div>
<!-- pc浏览器做了限制只有加了muted=true才能知道播放
<video controls="controls" id="video" autoplay="true" preload="auto" muted=true>
你的浏览器不支持HTML5播放此视频
<source src="http://www.w3school.com.cn/example/html5/mov_bbb.mp4" type="video/mp4" />
</video> -->
<!-- 底部tabbar -->
<div class="botWrap">
<div class="tabbar">
<div class="tabbarIndex">
<img src="./imgs/active_home.png" alt="">
<span>主页</span>
</div>
<div class="tabbarCity">
<img src="./imgs/tongcheng.png" alt="">
<span>同城</span>
</div>
<div class="tabbarXiangji">
<img src="./imgs/xiangji.png" alt="">
</div>
<div class="tabbarSearch">
<img src="./imgs/faxian.png" alt="">
<span>发现</span>
</div>
<div class="tabbarMine">
<img src="./imgs/mine.png" alt="">
<span>我的</span>
</div>
</div>
</div>
<!-- 底部一级留言弹框 -->
<div class="remarkWrap">
<div class="remark">
<div class="remark_top">
<div class="remarkTop_title">
精彩评论
</div>
<div class="remarkTop_close">
X
</div>
</div>
<div class="remark_mid">
<div class="remark_sigle">
<div class="remarkMid_info">
<div class="info_left">
<img src="./imgs/touxiang.png" alt="">
</div>
<div class="info_mid">
<div class="info_name">山村一枝花</div>
<div class="info_date">10月31日 9:20:23</div>
</div>
<div class="info_right">
<div>8882</div>
<img src="./imgs/muzhi.png" alt="">
</div>
</div>
<div class="remarkMid_content">
欢迎来到美丽的大山世界太刺激了下次有时间还想再来欢迎来到美丽的大山世界太刺激了下次有时间还想再来欢迎来到美丽的大山世界太刺激了
下次有时间还想再来欢迎来到美丽的大山世界太刺激了下次有时间还想再来
</div>
<div class="remarkMid_btn">
<span>496</span>条回复>
</div>
</div>
</div>
<div class="remark_bottom">
<input class="remarkBottom_input" type="text" placeholder="来说两句">
<div class="remarkBottom_send">发送</div>
<img src="./imgs/huifu.png" alt="">
</div>
</div>
</div>
<!-- 底部二级回复弹框 -->
<div class="twoRemarkWrap">
<div class="twoRemark">
<div class="twoRemark_top">
<div class="twoRemarkTop_title">
评论详情
</div>
<div class="twoRemarkop_close">
∨
</div>
</div>
<!-- 上面的楼主部分 -->
<div class="twoRemark_mid">
<div class="twoRemark_sigle">
<div class="twoRemarkMid_info">
<div class="info_left">
<img src="./imgs/touxiang.png" alt="">
</div>
<div class="info_mid">
<div class="info_name">山村二枝花 <span>楼主</span></div>
<div class="info_date">10月31日 9:20:23</div>
</div>
<div class="info_right">
<div>8882</div>
<img src="./imgs/muzhi.png" alt="">
</div>
</div>
<div class="twoRemarkMid_content">
欢迎来到美丽的大山世界太刺激了下次有时间还想再来欢迎来到美丽的大山世界太刺激了下次有时间还想再来欢迎来到美丽的大山世界太刺激了
下次有时间还想再来欢迎来到美丽的大山世界太刺激了下次有时间还想再来
</div>
</div>
</div>
<!-- 下面的二级回复部分 -->
<div class="twoRemark_wrap">
<div class="twoRemarkWrap_item">
<div class="twoRemarkWrap_info">
<div class="infoItem_left">
<img src="./imgs/touxiang.png" alt="">
</div>
<div class="infoItem_mid">
<div class="infoItem_name">山村二枝花 <span>回复 </span> @风吹枫又落</div>
<div class="infoItem_date">10月31日 9:20:23</div>
</div>
<div class="infoItem_right">
<div>8882</div>
<img src="./imgs/muzhi.png" alt="">
</div>
</div>
<div class="twoRemarkWrap_content">
欢迎来到美丽的大山世界太刺激了下次有时间还想再来欢迎来到美丽的大山世界太刺激了
</div>
</div>
</div>
<div class="twoRemark_bottom_wrap">
<div class="twoRemark_bottom">
<input class="twoRemarkBottom_input" type="text" placeholder="回复">
<div class="twoRemarkBottom_send">发送</div>
<img src="./imgs/huifu.png" alt="">
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
window.onload = function () {
$.ajax({
type: "GET",
url: "#",
contentType: 'application/json',
data: {
page: 1,
type: 1
},
dataType: "jsonp",
success: function (res) {
console.log(res.data)
},
error: function (xhr) {
console.log(xhr);
}
});
var arr = [{
title: "温州威客网络科技有限公司",
msg: true,
state: 'pause',
src: 'https://blz-videos.nosdn.127.net/1/OverWatch/AnimatedShots/Overwatch_TheatricalTeaser_WeAreOverwatch_zhCN.mp4',
videoImg: ''
},
];
// console.log(arr);
//循环后台的数据拼接上去
$.each(arr, function (i, item) {
console.log(item.src);
var lihtml = $(
`<div class="swiper-slide">
<video class="video" id="video${i+1}" preload="auto" src="${item.src}" data-id="${i+1}" page-gesture="true" x5-playsinline="" playsinline="" webkit-playsinline=""
show-fullscreen-btn="false" show-center-play-btn="true" show-play-btn="false" enable-play-gesture="true" loop="true">你的浏览器不支持HTML5播放此视频</video>
<div class="play"><img src="./imgs/bigplayBtn.png" alt=""></div><div class="desc"><div class="desc_name">@吃货世界</div>
<div class="desc_title">欢迎来到美丽的大山世界太刺激了下次有时间还想来</div>
</div>
<div class="function" id="${item.state}">
<div class="guanzhu">
<img src="./imgs/touxiang.png" alt="">
<div class="guanzhu_btn">关注</div>
<div class="guanzhuBtn_active">已关注</div>
<div class="guanzhu_number">666w</div>
</div>
<div class="dianzan">
<div id="hongxin" class="${item.msg?"xin":"xin_active"}"></div>
<div class="dianzan_number">666</div>
</div>
<div class="xiaoxi">
<img src="./imgs/xiaoxi.png" alt="">
<div class="xiaoxi_number">888</div>
</div>
<div class="zhuanfa">
<img src="./imgs/zhuanfa.png" alt="">
</div>
</div>
</div>`
)
$(".swiper-wrapper").append(lihtml);
})
var mySwiper = new Swiper('.swiper-container', {
direction: 'vertical', // 垂直切换选项
on: {
slideChangeTransitionEnd: function () {
$(".remarkWrap").slideUp(100);
$(".twoRemarkWrap").slideUp(100);
console.log(this.activeIndex) //切换结束时,告诉我现在是第几个slide
var videoLength = $(".swiper-container .swiper-slide").length;
console.log(videoLength);
//先显示 (这一部分是不能实现进去就播放因为没有进行过交互动作所以先在加载的时候全部先暂停并时间重置为0,用户点击的时候再播放)
// for (var i = 1; i < (videoLength + 1); i++) {
// var select = "video" + i;
// console.log(select)
// var video = document.getElementById(select);
// video.currentTime = 0;
// video.pause();
// $(".swiper-container .swiper-slide .play img").show();
// }
//先注释
//循环这些视频,如果是刚滑动的这个视频就播放并时间重置为0,其它取消播放
for (var i = 1; i < (videoLength + 1); i++) {
if (i != this.activeIndex + 1) {
var select = "video" + i;
console.log(select)
var video = document.getElementById(select);
video.pause();
$(".swiper-container .swiper-slide .play img").show();
}
}
var activeIndex = this.activeIndex + 1
var select = "video" + activeIndex;
console.log(select)
var video = document.getElementById(select);
video.currentTime = 0;
video.play();
console.log($(".swiper-container .swiper-slide").eq(this.activeIndex))
$(".swiper-container .swiper-slide").eq(this.activeIndex).find(
".play img").hide();
},
},
})
//ios会使用自带的视频播放器全屏播放
$('.swiper-wrapper video').each(function () {
console.log(1)
enableInlineVideo(this);
});
//先注释 与用户进行了一次交互动作,取消播放的图片,并播放视频
mui.alert('欢迎使用龙秀app', function () {
var video = document.getElementById("video1");
$("#video1").next().children("img").hide();
video.play()
});
//关注敬请期待
$("#wrap").on("click", ".swiper-slide .function .guanzhu", function (e) {
mui.alert("敬请期待")
})
//转发敬请期待
$("#wrap").on("click", ".swiper-slide .function .zhuanfa", function (e) {
mui.alert("敬请期待")
})
//点赞变红心 还是考虑用一个div的背景图片来做 用2个img太难考虑了
$("#wrap").on("click", ".swiper-slide .function .dianzan #hongxin", function (e) {
//先获取视频id
// var id = $(this).data("id");
if ($(this).hasClass("xin")) { //点击实心
// 发送ajax成功之后
$(this).addClass("xin_active").removeClass("xin");
var number = Number($(this).next().text()) + 1;
$(this).next().text(number)
mui.alert("点赞成功")
} else if ($(this).hasClass("xin_active")) { //点击红心
// 发送ajax成功之后
$(this).addClass("xin").removeClass("xin_active");
var number = Number($(this).next().text()) - 1;
console.log(number)
if (number < 0) {
number = 0
}
$(this).next().text(number)
mui.alert("取消点赞")
}
})
//一级留言点赞变红拇指 还是考虑用一个div的背景图片来做 用2个img太难考虑了
$("#wrap").on("click", ".remark_mid .remarkMid_info .info_right .plinfo_img",
function (e) {
//先获取评论id
// var id = $(this).data("id");
console.log(1);
if ($(this).hasClass("plmuzhi")) { //点击实心
// 发送ajax成功之后
$(this).addClass("plmuzhi_active").removeClass("plmuzhi");
var number = Number($(this).prev().text()) + 1;
console.log(number)
$(this).prev().text(number)
} else if ($(this).hasClass("plmuzhi_active")) { //点击红心
// 发送ajax成功之后
$(this).addClass("plmuzhi").removeClass("plmuzhi_active");
var number = Number($(this).prev().text()) - 1;
console.log(number)
$(this).prev().text(number)
}
})
//一级评论点赞变红拇指 还是考虑用一个div的背景图片来做 用2个img太难考虑了
$("#wrap").on("click", ".twoRemarkWrap .twoRemark .twoRemark_mid .twoRemarkMid_info .info_right .info_img",
function (e) {
//先获取评论id
// var id = $(this).data("id");
console.log(1);
if ($(this).hasClass("muzhi")) { //点击实心
// 发送ajax成功之后
$(this).addClass("muzhi_active").removeClass("muzhi");
var number = Number($(this).prev().text()) + 1;
console.log(number)
$(this).prev().text(number)
} else if ($(this).hasClass("muzhi_active")) { //点击红心
// 发送ajax成功之后
jascript部分
/*! npm.im/iphone-inline-video 2.2.2 */
var enableInlineVideo = function () {
"use strict"; /*! npm.im/intervalometer */
function e(e, i, n, r) {
function t(n) {
d = i(t, r), e(n - (a || n)), a = n
}
var d, a;
return {
start: function () {
d || t(0)
},
stop: function () {
n(d), d = null, a = 0
}
}
}
function i(i) {
return e(i, requestAnimationFrame, cancelAnimationFrame)
}
function n(e, i, n) {
function r(r) {
n && !n(e, i) || r.stopImmediatePropagation()
}
return e.addEventListener(i, r), r
}
function r(e, i, n, r) {
function t() {
return n[i]
}
function d(e) {
n[i] = e
}
r && d(e[i]), Object.defineProperty(e, i, {
get: t,
set: d
})
}
function t(e, i, n) {
n.addEventListener(i, function () {
return e.dispatchEvent(new Event(i))
})
}
function d(e, i) {
Promise.resolve().then(function () {
e.dispatchEvent(new Event(i))
})
}
function a(e) {
var i = new Audio;
return t(e, "play", i), t(e, "playing", i), t(e, "pause", i), i.crossOrigin = e.crossOrigin, i.src = e.src || e.currentSrc || "data:", i
}
function u(e, i, n) {
(m || 0) + 200 < Date.now() && (e[h] = !0, m = Date.now()), n || (e.currentTime = i), k[++T % 3] = 100 * i | 0
}
function o(e) {
return e.driver.currentTime >= e.video.duration
}
function s(e) {
var i = this;
i.video.readyState >= i.video.HAVE_FUTURE_DATA ? (i.hasAudio || (i.driver.currentTime = i.video.currentTime + e * i.video.playbackRate / 1e3, i.video.loop && o(i) && (i.driver.currentTime = 0)), u(i.video, i.driver.currentTime)) : i.video.networkState === i.video.NETWORK_IDLE && 0 === i.video.buffered.length && i.video.load(), i.video.ended && (delete i.video[h], i.video.pause(!0))
}
function c() {
var e = this,
i = e[g];
if (e.webkitDisplayingFullscreen) return void e[E]();
"data:" !== i.driver.src && i.driver.src !== e.src && (u(e, 0, !0), i.driver.src = e.src), e.paused && (i.paused = !1, 0 === e.buffered.length && e.load(), i.driver.play(), i.updater.start(), i.hasAudio || (d(e, "play"), i.video.readyState >= i.video.HAVE_ENOUGH_DATA && d(e, "playing")))
}
function v(e) {
var i = this,
n = i[g];
n.driver.pause(), n.updater.stop(), i.webkitDisplayingFullscreen && i[w](), n.paused && !e || (n.paused = !0, n.hasAudio || d(i, "pause"), i.ended && !i.webkitDisplayingFullscreen && (i[h] = !0, d(i, "ended")))
}
function p(e, n) {
var r = {};
e[g] = r, r.paused = !0, r.hasAudio = n, r.video = e, r.updater = i(s.bind(r)), n ? r.driver = a(e) : (e.addEventListener("canplay", function () {
e.paused || d(e, "playing")
}), r.driver = {
src: e.src || e.currentSrc || "data:",
muted: !0,
paused: !0,
pause: function () {
r.driver.paused = !0
},
play: function () {
r.driver.paused = !1, o(r) && u(e, 0)
},
get ended() {
return o(r)
}
}), e.addEventListener("emptied", function () {
var i = !r.driver.src || "data:" === r.driver.src;
r.driver.src && r.driver.src !== e.src && (u(e, 0, !0), r.driver.src = e.src, i || !n && e.autoplay ? r.driver.play() : r.updater.stop())
}, !1), e.addEventListener("webkitbeginfullscreen", function () {
e.paused ? n && 0 === r.driver.buffered.length && r.driver.load() : (e.pause(), e[E]())
}), n && (e.addEventListener("webkitendfullscreen", function () {
r.driver.currentTime = e.currentTime
}), e.addEventListener("seeking", function () {
k.indexOf(100 * e.currentTime | 0) < 0 && (r.driver.currentTime = e.currentTime)
}))
}
function l(e) {
var i = e[h];
return delete e[h], !e.webkitDisplayingFullscreen && !i
}
function f(e) {
var i = e[g];
e[E] = e.play, e[w] = e.pause, e.play = c, e.pause = v, r(e, "paused", i.driver), r(e, "muted", i.driver, !0), r(e, "playbackRate", i.driver, !0), r(e, "ended", i.driver), r(e, "loop", i.driver, !0), n(e, "seeking", function (e) {
return !e.webkitDisplayingFullscreen
}), n(e, "seeked", function (e) {
return !e.webkitDisplayingFullscreen
}), n(e, "timeupdate", l), n(e, "ended", l)
}
function y(e, i) {
if (void 0 === i && (i = {}), !e[g]) {
if (!i.everywhere) {
if (!b) return;
if (!(i.iPad || i.ipad ? /iPhone|iPod|iPad/ : /iPhone|iPod/).test(navigator.userAgent)) return
}
e.pause();
var n = e.autoplay;
e.autoplay = !1, p(e, !e.muted), f(e), e.classList.add("IIV"), e.muted && n && (e.play(), e.addEventListener("playing", function i() {
e.autoplay = !0, e.removeEventListener("playing", i)
})), /iPhone|iPod|iPad/.test(navigator.platform) || console.warn("iphone-inline-video is not guaranteed to work in emulated environments")
}
}
var m, b = "object" == typeof document && "object-fit" in document.head.style && !matchMedia("(-webkit-video-playable-inline)").matches,
g = "fregante:iphone-inline-video",
h = "fregante:iphone-inline-video:event",
E = "fregante:iphone-inline-video:nativeplay",
w = "fregante:iphone-inline-video:nativepause",
k = [],
T = 0;
return y
}();
源码地址:点击下载
*****SUMER UI3.0****