uniapp中videojs、renderjs的使用
在uniapp中使用了某些前端库或iframe,需要操作这些库中的dom的时候, 而uni上又没有document等基础对象。也就无法操作这些dom去实现一些交互逻辑,那么,涉及到这些的前端类库就无法使用,例如html2、canvas、image、video。而要用这些怎么办,这是用就出现了renderjs这种视图层工具来进行渲染。大幅降低逻辑层和视图层的通讯损耗,提供高性能视图交互能力
使用方法:
- 在原有script下方再添加script,其中lang="renderjs"固定, module=“demo”,module的名字任意起
- 可以通过 this.$ownerInstance 获取当前组件的 ComponentDescriptor 实例。类似于vm
- 视图层绑定事件通过 module名称 . 逻辑层定义方法,有两个参数,1.事件对象event,2. 当前组件实例ComponentDescriptor
- 两个script间的通信需要通过:this.$ownerInstance 全局组件实例 或者 事件参数ComponentDescriptor 身上的callMethod方法,去抛出方法、传值,类似于vue组件间emit
- 可以使用 vue 组件的生命周期不可以使用 App、Page 的生命周期
使用参考:https://blog.csdn.net/dabaooooq/article/details/129272111
代码
uniapp在APP端video层级最高,不能被其它覆盖,引入videojs实现,使用renderjs实现原生的DOM操作。
<template><div class="full_screen_video" v-show="visible" :class="{ 'normal': !fullScreen }"><!-- 遮盖video 添加点击事件 --><div class="video_mask" @click="foldShortVideo" ></div><p v-if="fullScreen" class="back" @click="closeDialogHandle"><image src="@i/common/back_white.svg" alt=""></image><span>{{ title}}</span></p><view :info="videoItem" :change:info="videos.updateVideo" :options="videoOptions" :change:options="videos.optionsChange"class="video_box"ref="videoEle" id="videoEle"></view><view class="video_control_box" v-if="fullScreen" ><!-- 开始结束时间 --><view class="video_time"><span>{{ formatTime(videoCurrentTime) }} </span> <span>{{ formatTime(videoTotalTime) }}</span></view><!-- 视频播放器 --><div class="video_control"><p class="disp_ac"><image v-if="!isStart" src="@i/video/icon_video_start.svg" mode="widthFix" @tap="startAndStop('start')" alt=""></image><image v-else src="@i/video/icon_video_stop.svg" mode="widthFix" @tap="startAndStop('stop')" alt=""></image><image src="@i/video/icon_video_next.svg" mode="widthFix" @tap="playNext" alt="" v-if="videoList.length > 0"></image></p><p><view :class="{'normal_mode':normalMode}" class="formation_select_box mr60" @click="showOption = !showOption"><span class="select_text">{{ speedValue +'x'}}</span><view class="select_menu" :class="{ ani: showOption }" v-show="showOption"><view class="select_menu_item" v-for="item in speedOptions" :key="item.value"><span :class="{'active': speedValue === item.value}" @click="changeSpeed(item.value)">{{ item.label +'x'}}</span></view></view></view><image v-if="normalMode" src="@i/video/full_screen.svg" mode="widthFix" @tap="fullScreenVideo" alt=""></image></p></div></view><view v-else class="video_control_box video_control_box_small" ><div class="time_bar_box"><div class="time_btn"><image v-if="!isStart" src="@i/video/icon_video_start.svg" mode="widthFix" @tap="startAndStop('start')" alt=""></image><image v-else src="@i/video/icon_video_stop.svg" mode="widthFix" @tap="startAndStop('stop')" alt=""></image><image src="@i/video/icon_video_next.svg" mode="widthFix" @tap="playNext" alt="" v-if="videoList.length > 0"></image></div><div class="time_bar"><span>{{ formatTime(videoCurrentTime) }} </span> <span>{{ formatTime(videoTotalTime) }}</span></div></div><div class="video_btn"><view class="formation_select_box mr50" @click="showOption = !showOption"><span class="select_text">{{ speedValue +'x'}}</span><view class="select_menu" :class="{ ani: showOption }" v-show="showOption"><view class="select_menu_item" v-for="item in speedOptions" :key="item.value"><span :class="{'active': speedValue === item.value}" @click="changeSpeed(item.value)">{{ item.label +'x'}}</span></view></view></view> <image src="@i/video/download.svg" mode="widthFix" @tap="downloadVideo" alt=""></image><image v-if="normalMode" src="@i/video/full_screen.png" mode="widthFix" @tap="fullScreenVideo" alt=""></image></div></view><!-- 视频列表 --><div class="video_list" v-if="showVideoList && videoList.length" ><scroll-view scroll-x="true" ><div class="video_list_item"><div v-for="(item, index) in videoList" :key="index" class="video_item" :class="{'active': index === currentVideoIndex}" @click="playVideo(item, index)"><div class="video_img"><image class="snapshot" :src="item.snapshot && !item.imgError ? item.snapshot : defaultSnapshot" @error="item.imgError = true" alt="snapshot" ></image><span class="total_time" v-if="item.end && item.start">{{formatTime(item.end - item.start)}}</span></div><div class="clip_info"><div class="text_over">{{item.name || item.label || ''}}</div><div class="video_list_time">{{ formatDate(item.createTime).split('-').slice(0,3).join('/').split(' ').slice(0,1).join() }}</div></div></div></div></scroll-view></div></div>
</template><script>
export default {name: 'pad-video-play', // 在主视频内播放的组件,短片会跳转到主视频对应的时间props: {// 控制显示隐藏visible: {type: Boolean,default: false},// 主视频下的短视频播放列表videoList: {type: Array,default:() => []},// 主视频播放源videoMain: {type: Object,default: () => { }},// 视频类型, 默认为全屏播放videoType: {type: String,default: 'full_screen'},},data() {return {videoCurrentTime: 0, // 视频当前时间videoTotalTime: 0, // 视频总时长isStart: false, // 是否开始volumeValue: 1, // 音量初始值(0-1)showVideoList: true, // 是否显示视频列表currentVideoIndex: -1, // 当前播放的视频下标defaultSnapshot: require("static/images/video/default_snapshot.svg"), // 默认缩略图videoOptions: {closeDialog: false}, // 视频操作选项fullScreen: this.videoType === 'full_screen', // 是否是全屏speedValue: '1.0', // 初始播放速度showOption:false, // 控制倍速弹窗speedOptions: [ // 阵型选项{ label: '2.0', labelEn: '2.0', value: '2.0' },{ label: '1.5', labelEn: '1.5', value: '1.5' },{ label: '1.25', labelEn: '1.25', value: '1.25' },{ label: '1.0', labelEn: '1.0', value: '1.0' },{ label: '0.5', labelEn: '0.5', value: '0.5' },],videoItem: {},title:''};},computed: {// 是否是正常模式下的视频播放normalMode() {let boolean = this.videoType === 'normal';return boolean;}},watch: {currentVideoIndex(newVal) {this.$emit('change-video-index', newVal);},videoMain: {handler (newVal) { this.videoItem = {url: newVal.url}this.title = newVal.name },immediate: true,deep:true},visible(newVal) {if (newVal) { this.videoOptions = {closeDialog: false,volumeChangeOption: { volume: 1 } }this.volumeValue = 1;}}},methods: {foldShortVideo(){this.showVideoList = !this.showVideoList},// 关闭弹框closeDialogHandle () {this.videoOptions = {closeDialog: true}if (this.videoType === 'full_screen') {// setTimeout(() => { this.$emit('cancelVideo', false);// },100)} else {this.fullScreen = false;}this.showVideoList = false;this.$emit('update:visible',false)},// 开始视频onPlayerPlay() {this.speedValue = '1.0'this.isStart = true;},// 实时更新onTimeUpdate(currentTime){this.videoCurrentTime = currentTime;},// 暂停视频onPlayerPause() {this.isStart = false;},// 加载视频源数据onLoadedmetadata(totalTime) {this.videoTotalTime = totalTime;},// 开始或暂停视频startAndStop(type) {this.videoOptions = {startAndStopOption: { type }}},// 改变视频音量volumeChange(volume) {this.volumeValue = volume;this.videoOptions = {volumeChangeOption: { volume } }},// 播放视频playVideo(item, index) {this.speedValue = '1.0'// // 在正常模式播放下, 不可重复点击当前视频if (this.normalMode && item && this.currentVideoIndex === index) {return;}this.$set(this.videoItem, 'startTime', item.start);this.currentVideoIndex = index;this.videoList.forEach(item => {item.forceUpdate = false})item.forceUpdate = true},// 改变视频的速度changeSpeed(speed) {this.speedValue = speed || '1.0';this.videoOptions = {playbackRate: { speed }}},// 播放下一个playNext(){this.speedValue = '1.0'this.videoList.forEach(item => {item.forceUpdate = false})let index = this.currentVideoIndex;if(this.currentVideoIndex+1<this.videoList.length){ this.currentVideoIndex = index+1;this.$set(this.videoList[index+1],'forceUpdate',true)this.$set(this.videoList, index + 1, this.videoList[index + 1]);this.$set(this.videoItem, 'startTime', this.videoList[index+1].start);}else{ this.currentVideoIndex = 0;this.$set(this.videoList[0],'forceUpdate',true)this.$set(this.videoList, 0, this.videoList[0]);this.$set(this.videoItem, 'startTime', this.videoList[0].start);}},// 进入/退出 全屏视频fullScreenVideo() {this.fullScreen = !this.fullScreen;},// 格式化时间formatTime(result) {let h = Math.floor(result / 3600) < 10 ? "0" + Math.floor(result / 3600) : Math.floor(result / 3600);let m = Math.floor((result / 60) % 60) < 10 ? "0" + Math.floor((result / 60) % 60) : Math.floor((result / 60) % 60);let s = Math.floor(result % 60) < 10 ? "0" + Math.floor(result % 60) : Math.floor(result % 60);return Math.floor(result / 3600) == 0 ? m + ":" + s : h + ":" + m + ":" + s;},// 格式化日期formatDate(createTime){let date = new Date(createTime);let str = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;return str;}}
};
</script><script module="videos" lang="renderjs">import './video-offset.js'; // videojs 引入import Videojs from 'video.js';import 'video.js/dist/video-js.css';export default {data() {return {videoPlayer: null, // 当前视频播放器}},mounted() {},methods: {// 初始化视频initVideoJS(item) {if(this.videoPlayer){this.videoPlayer.dispose();this.videoPlayer = null;}let that = this;let videoEle = document.createElement('video');videoEle.style = 'width:100%; height:100%';videoEle.setAttribute("class", "video-js vjs-big-play-centered");let videos = document.getElementById('videoEle');console.log(videos);videos.appendChild(videoEle)let option = {controls: true, // 是否显示控制条preload: 'auto', // 是否预加载视频数据muted: false, // 是否静音language: 'zh-CN', // 设置语言autoplay: true, // 自动播放, 正常模式下不进行自动播放sources: [ // 视频源{type: "video/mp4",src: item.url}, {type: "video/webm",// webm格式src: item.url}, {type: "video/mov", // mov格式src: item.url},],controlBar: { // 设置控制条组件children: [{ name: 'progressControl' }, // 播放进度条// // { name: 'fullscreenToggle' } // 全屏按钮]}};// video.js初始化实例化的对象this.videoPlayer = Videojs(videoEle, option, function onPlayerReady() {// 开始视频this.on('play', function() {that.$ownerInstance.callMethod('onPlayerPlay');})// 暂停视频this.on('pause', function() {that.$ownerInstance.callMethod('onPlayerPause');})// 实时更新this.on('timeupdate', function() {let currentTime = that.videoPlayer ? that.videoPlayer.currentTime() : 0;that.$ownerInstance.callMethod('onTimeUpdate', currentTime);})// 加载视频源数据this.on('loadedmetadata', function() {let totalTime = parseInt(that.videoPlayer.duration()) || 0;that.$ownerInstance.callMethod('onLoadedmetadata', totalTime);})});},// 监听 videoData 数据变更updateVideo(newValue) {if(!newValue || !newValue.url) return;if(this.videoPlayer && newValue.startTime){this.videoPlayer.currentTime(newValue.startTime)return}this.initVideoJS(newValue);},// 监听改变视频操作选项optionsChange(newValue) {if (newValue && newValue.startAndStopOption) {// 开始或暂停视频let { type } = newValue.startAndStopOption;type === 'start' ? this.videoPlayer.play() : this.videoPlayer.pause();} else if (newValue && newValue.volumeChangeOption) {// 改变视频音量let { volume } = newValue.volumeChangeOption;this.videoPlayer && this.videoPlayer.volume(volume);} else if (newValue && newValue.closeDialog) {console.log('销毁了')// 销毁videoJs实例this.videoPlayer && this.videoPlayer.dispose();this.videoPlayer = null} else if (newValue && newValue.continuePlay) {// 继续播放视频let { url } = newValue.continuePlay;this.initVideoJS(url);} else if(newValue && newValue.playbackRate){let { speed } = newValue.playbackRate;// 改变视频的播放速度this.videoPlayer && this.videoPlayer.playbackRate(speed);}}}}
</script><style lang='less' scoped>
.video_mask {position: absolute;width: 100%;height: calc(100% - 62.81rpx);top: 0;left: 0;background-color: transparent;z-index: 1;
}
::v-deep {// 视频style.video_box{width: 100%;height: 100%;video{object-fit:fill;}}.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{opacity: 1;}.video-js{position: relative;.vjs-control-bar {width:663.32rpx;left: 43.34rpx;bottom: 47.9rpx;background-color: transparent;z-index: 105;opacity: 1;}.vjs-play-progress{background: #38CB89;&::before{color: #38CB89;}}.vjs-slider{background-color: rgba(255, 255, 255, 0.36);}}
}
.disp_ac{display: flex;align-items: center;
}
/* 文字超出部分设置为... */
.text_over {max-width: 85%;word-break: break-all;text-overflow: ellipsis;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 2; /* 这里是超出几行省略 */overflow: hidden;
}
.full_screen_video{width: 100%;height: 100%;position: fixed;z-index: 102;left: 0;top: 0;box-sizing: border-box;color: #fff;font-family: 'SysFontR';// 默认视频样式&.normal{width: 100%;height: 100%;position: relative;.video_list,.video_shrink{display: none;}.video_control_box{width: 100%;height: 37.69rpx;position: absolute;left: 0;bottom: 4.71rpx;z-index: 5;display: flex;flex-direction: column;align-items: center;padding: 0 10.05rpx;box-sizing: border-box;&.video_control_box_small{.formation_select_box{bottom: 7rpx;.select_text{font-size: 10.05rpx;}.select_menu{bottom:0;transform:scale(.8) }}}.time_bar_box{width: 100%;height: 12.25rpx;display: flex;align-items: center;.time_btn{image{width: 11.93rpx;height: 9.42rpx;margin-right: 10.05rpx;}}.time_bar{flex: 1;display: flex;justify-content:space-between;font-size: 9.74rpx;color: #f3f3f3;}}.video_btn{width: 100%;display: flex;justify-content: flex-end;text-align: right;margin-top: 6.28rpx;image{width: 10.99rpx;height: 10.05rpx;margin-right: 15.7rpx;}}}.video_control{height: 47.11rpx;bottom: 4.71rpx;image{width: 10.05rpx !important;height: 10.05rpx !important;margin-right: 15.7rpx;}}::v-deep {.vjs-control-bar{width: calc(100% - 74.75rpx - 37.69rpx);left: 76.75rpx;bottom: 27.84rpx;}}}.back{position: absolute;z-index: 200;top: 0;left: 0;width: 100%;height: 58.59rpx;padding-left: 14.64rpx;font-size: 13.82rpx;display: flex;align-items: center;cursor: pointer;background: linear-gradient(180deg, #000000 0%, rgba(0, 0, 0, 0) 100%);image{width: 6.44rpx;height: 12.3rpx;margin-right: 20.1rpx;}}.formation_select_box{position: relative;border-radius: 3.77rpx;display: flex;align-items: center;justify-content: center;&.normal_mode{right: 118rpx;}.select_text{font-family: 'AkrobatMedium';font-size: 11.31rpx;color: #fff;position: relative;}.select_menu {width: 43.66rpx;position: absolute;bottom: 18.04rpx;left: -13rpx;z-index: 999;padding: 13.82rpx 0 0;text-align: center;box-sizing: border-box;border-radius: 3.77rpx;background: #000000;color: #F3F3F3;.select_menu_item {position: relative;z-index: 2;margin-bottom: 12.56rpx;>span {display: inline-block;width: 100%;height: 100%;box-sizing: border-box;font-size: 10.05rpx;font-family: AkrobatRegular;&.active{color: #38CB89;}}}}.ani {animation: ani 0.2s;}@keyframes ani {0% {transform: scaleY(0);}100% {transform: scaleY(1);}}.mask_box {width: 70vw;height: 100vh;position: fixed;left: 0;top: 60rpx;z-index: 99;background: transparent;}}.video_time{position: absolute;bottom: 49.94rpx;width: 100%;box-sizing: border-box;padding:0 15.7rpx;line-height: 14.13rpx;display: flex;justify-content:space-between;z-index: 104;}.video_control{position: absolute;left: 0;z-index: 5;bottom: 5.85rpx;width: 161.13rpx;height: 35.15rpx;display: flex;align-items: center;justify-content: space-between;padding: 0 19.04rpx;box-sizing: border-box;width: 100%;p{display:flex;align-items: center;image{width: 17.59rpx;height: 17.59rpx;margin-right: 15.23rpx;// opacity: .6;}.video_volume{position: relative;.video_volume_slider{display: none;position: absolute;right: 30px;top: -85px;padding-top: 5px;background-color: rgba(0, 0, 0, 0.36);&.hover{display: inline-block;}}}}}.video_list{position: absolute;width: 100%;top: 0;right: 0;z-index: 201;background: rgba(29, 29, 29, 0.8);backdrop-filter: blur(50px);color: #fff;padding-top: 25.13rpx;padding-bottom: 6.28rpx;box-sizing: border-box;display: flex;// transition: all 200ms;.close_img{position: absolute;top: 50%;transform: translateY(-50%);right: 236.81rpx;width: 20.5rpx;height: 75rpx;}.video_item{width: 83.54rpx;flex-shrink: 0;display: flex;flex-direction: column;margin-left: 12.56rpx;box-sizing: border-box;display: flex;&.active{.text_over{font-family: SysFontM;color: #38CB89;}}.video_img{width: 100%;height: 47.11rpx;box-sizing: border-box;position: relative;image.snapshot{border-radius: 3.77rpx;width: 100%;height: 100%;}.total_time{font-family: SysFontR;height: 12.89rpx;position: absolute;left: 2.92rpx;bottom: 2.92rpx;padding: 0 5.85rpx;font-size: 8.2rpx;line-height: 12.89rpx;color: rgb(255, 255, 255);background: rgba(30, 30, 30, .6);}}.clip_info{width: 100%;box-sizing: border-box;font-size: 8.2rpx;color: rgba(255, 255, 255, .8);position: relative;padding: 4.71rpx 0;// .clip_label{// font-size: 10.68rpx;// color: rgba(255, 255, 255,1);// line-height: 14.06rpx;// margin-bottom: 7.54rpx;// display: flex;// align-items: center;// }}}}.video_list_item {display: flex;width: 100%;overflow-x: auto;}.video_shrink{position: fixed;top: 50%;transform: translateY(-50%);right: 0;width: 20.5rpx;height: 75rpx;}.video_list_time {font-family: AkrobatRegular;margin-top: 3px;}
}
</style>;相关文章:
uniapp中videojs、renderjs的使用
在uniapp中使用了某些前端库或iframe,需要操作这些库中的dom的时候, 而uni上又没有document等基础对象。也就无法操作这些dom去实现一些交互逻辑,那么,涉及到这些的前端类库就无法使用,例如html2、canvas、image、vide…...
AIGC AI绘画 Midjourney 参数大全详细列表
AIGC ChatGPT 职场案例 AI 绘画 与 短视频制作, Power BI 商业智能 68集, 数据库Mysql8.0 54集 数据库Oracle21C 142集, Office 2021实战, Python 数据分析, ETL Informatica 案例实战 Excel 2021实操,函数大全,图表大全,大屏可视化制作 加技巧500集 数据分析可视化T…...
安装hadoop,并配置hue
0、说明 对于大数据学习的初始阶段,我也曾尝试搭建相应的集群环境。通过搭建环境了解组件的一些功能、配置、原理。 在实际学习过程中,我更多的还是使用docker来快速搭建环境。 这里记录一下我搭建hadoop的过程。 1、下载hadoop 下载地址:…...
23种经典设计模式:单例模式篇(C++)
前言: 博主将从此篇单例模式开始逐一分享23种经典设计模式,并结合C为大家展示实际应用。内容将持续更新,希望大家持续关注与支持。 什么是单例模式? 单例模式是设计模式的一种(属于创建型模式 (Creational Pa…...
ros中对move_base的调用
move_base包中自带costmap2d, global planner 等功能 也可以直接调用其中make_plan进行路径规划 #include "geometry_msgs/PoseStamped.h" #includde "nav_msgs/GetPlan.h"void fillPathRequest(nav_msgs::GetPlan::Request &request, float start_x…...
Git从本地库撤销已经添加的文件或目录
场景 在提交时, 误将一个目录添加到了暂存区, 而且commit 了本地库,同批次commit 的还有其他需要提交的文件。 commit 之后发现这个目录下所有的文件都不需要提交, 现在需要撤销这个提交, 使这个目录不被push到远端库。 这里以远端服务器github 为例,在Git GUI下看到的…...
百度SEO优化的特点(方式及排名诀窍详解)
百度SEO优化的特点介绍: 百度SEO优化是指对网站进行优化,使其在百度搜索引擎中获得更好的排名,进而获取更多的流量和用户。百度SEO优化的特点是综合性强、效果持久、成本低廉、投资回报高。百度的搜索算法不断更新,所以长期稳定的…...
Gin 文件上传操作(单/多文件操作)
参考地址: 单文件 | Gin Web Framework (gin-gonic.com)https://gin-gonic.com/zh-cn/docs/examples/upload-file/single-file/ 单文件 官方案例: func main() {router := gin.Default()// 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)router.MaxMultipartMem…...
分类预测 | MATLAB实现KOA-CNN-LSTM开普勒算法优化卷积长短期记忆神经网络数据分类预测
分类预测 | MATLAB实现KOA-CNN-LSTM开普勒算法优化卷积长短期记忆神经网络数据分类预测 目录 分类预测 | MATLAB实现KOA-CNN-LSTM开普勒算法优化卷积长短期记忆神经网络数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.MATLAB实现KOA-CNN-LSTM开普勒算法优化…...
Qt应用开发(基础篇)——列表视图 QListView
一、前言 QListView类继承于QAbstractItemView类,提供了一个列表或者图标视图的模型。 视图基类 QAbstractItemView QListView效果相当于Windows文件夹右键->查看->图标和列表,使用setViewMode()设置视图模式,并且提供setIconSize()函数…...
vue-6
一、声明式导航-导航链接 1.需求 实现导航高亮效果 如果使用a标签进行跳转的话,需要给当前跳转的导航加样式,同时要移除上一个a标签的样式,太麻烦!!! 2.解决方案 vue-router 提供了一个全局组件 router…...
温度在线检测技术在电力电缆线路的应用
在电力电缆的日常运行检测中,针对电缆温度的状况,所采用的电力温度在线检测技术也得到了大范围的普及。电网系统中,其单位时间内可输送的电力能源受到其温度的变化影响。因此,采用更有效的方式实时检测电缆系统运行温度࿰…...
2023年中国自动化微生物样本处理系统竞争现状及行业市场规模分析[图]
微生物检测能够对感染性疾病的病原体或者代谢物进行检测分析,是IVD的细分领域之一。2022年中国体外诊断市场规模1424亿元。 2015-2022年中国体外诊断市场规模 资料来源:共研产业咨询(共研网) 微生物检测由于样本类型多样…...
硬链接和软连接的区别
软链接(也称为软连接或符号链接)是一种特殊的文件,其内容是另一个文件的路径。当你使用软链接时,实际上是在操作另一个文件。软链接的优点是它可以跨文件系统使用,因此可以跨分区或磁盘链接文件。此外,软链…...
保护隐私与增强网络安全之网络代理技术
目录 前言 一、网络代理技术原理 二、网络代理技术类型 1. HTTP代理 2. SOCKS代理 3. DNS代理 4. 加密代理 5. 反向代理 三、网络代理技术应用 1. 加速网络访问速度 2. 绕过网络限制 3. 保护个人隐私 4. 节省带宽 5. 改善网络安全 四、网络代理技术优缺点 网络…...
【每日一题】CF1680C. Binary String | 双指针 | 简单
题目内容 原题链接 给定一个长度为 n n n 的 01 01 01 字符串,对于一个子串 s u b sub sub ,子串内部的 0 0 0 的数量为 x x x ,子串以外的 1 1 1 的数量为 y y y ,子串的代价为 m a x ( x , y ) max(x, y) max(x,y) &…...
10.selenium进阶
文章目录 1、嵌套网页1、1 什么是嵌套页面1、2 selenium获取嵌套页面的数据 2、执行JavaScript代码3、鼠标动作链4、selenium键盘事件5、其他方法5、1 选择下拉框5、2 弹窗的处理 6、selenium设置无头模式7、selenium应对检测小结 1、嵌套网页 在前端开发中如果有这么一个需…...
【安全】 Java 过滤器 解决存储型xss攻击问题
文章目录 XSS简介什么是XSS?分类反射型存储型 XSS(cross site script)跨站脚本攻击攻击场景解决方案 XSS简介 跨站脚本( cross site script )为了避免与样式css(Cascading Style Sheets层叠样式表)混淆,所以简称为XSS。 XSS是一种经常出现在web应用中的计算机安全…...
一、Excel VBA 是个啥?
Excel VBA 从入门到出门一、Excel VBA 是个啥?二、Excel VBA 简单使用 👋Excel VBA 是个啥? ⚽️1. Excel 中的 VBA 是什么?⚽️2. 为什么 VBA 很重要?⚽️3. 是否有无代码方法可以在 Excel 中实现工作流程自动化&…...
Spring Boot读取配置文件
Spring Boot 是一种用于快速构建基于Spring的应用程序的框架,它提供了很多便利的功能和约定,使开发者可以快速搭建、配置和部署应用程序。在Spring Boot中,读取配置文件是一个非常常见的任务,本文将介绍如何在Spring Boot应用程序…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
