蒙层禁止下方页面滚动防抖动完美方案
学习链接
js如何禁止滚动条滚动,但不消失! - 这个是完美解决方案(在线demo示例)
解决窗口滚动条消失而导致的页面内容抖动的问题
完美解决js 禁止滚动条滚动,并且滚动条不消失,页面大小不闪动
蒙层禁止页面滚动的方案
蒙层禁止页面滚动-自己的上篇
最终的效果
前言
在页面中,经常会需要打开一些弹窗,弹窗下面会有一个蒙层,蒙层下面是页面。蒙层需要覆盖整个视口。但是一般会遇到3个问题不那么好解决
- 打开弹窗后,当鼠标滚动时,底下的页面也会跟随滚动。
- 浏览器右侧的滚动条在一些方案中会隐藏,而导致打开弹窗和关闭弹窗时,由于滚动条的显示和隐藏而导致页面抖动闪烁。
- 浏览器右侧的滚动条在一些方案中,打开弹窗时候,可能会丢失当前的滚动位置,而直接回到了顶部。
如果有上面这3个问题,直接找上面提到的完美方案即可解决
蒙层禁止页面滚动的方案
直接拷贝的蒙层禁止页面滚动的方案 - 来自WindrunnerMax,以作记录。
弹窗是一种常见的交互方式,而蒙层是弹窗必不可少的元素,用于隔断页面与弹窗区块,暂时阻断页面的交互。但是在蒙层出现的时候滚动页面,如果不加处理,蒙层底部的页面会开始滚动,实际上我们是不希望他进行滚动的,因此需要阻止这种行为。当弹出蒙层时禁止蒙层下的页面滚动,也可以称为滚动穿透的问题,文中介绍了一些常用的解决方案。
实现
首先需要实现一个蒙层下滚动的效果示例,当我们点击弹窗按钮显示蒙层之后,再滚动鼠标的话能够看到蒙层下的页面依旧是能够滚动的。如果在蒙层的内部进行滚动,当蒙层内滚动条滚动到底部的时候再继续滚动的话,蒙层下的页面也是能够滚动的,这样的交互就比较混乱,文中内容的测试环境是Chrome 96.0.4664.110。
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>蒙层禁止页面滚动的方案</title><style type="text/css">#mask{position: fixed;height: 100vh;width: 100vw;background: rgba(0, 0, 0, 0.6);top: 0;left: 0;display: flex;align-items: center;justify-content: center;}.hide{display: none !important;}.long-content > div{height: 300px;}.mask-content{width: 300px;height: 100px;overflow-x: auto;background: #fff;}.mask-content > div{height: 300px;}</style>
</head>
<body><button id="btn">弹窗</button><div class="long-content"><div>long content</div><div>long content</div><div>long content</div><div>long content</div><div>long content</div><div>long content</div><div>long content</div></div><div id="mask" class="hide"><div class="mask-content"><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div></div></div>
</body><script type="text/javascript">(() => {const btn = document.getElementById("btn");const mask = document.getElementById("mask");btn.addEventListener("click", e => {mask.classList.remove("hide");})mask.addEventListener("click", e => {mask.classList.add("hide");})})();</script>
</html>
body hidden
此方案是一种比较常用的方案,即打开蒙层时给body添加overflow: hidden;,在关闭蒙层时就移除这个样式,例如思否的登录弹窗、antd的Modal对话框就是这样的方式。 这种方案的优点是简单方便,只需添加css样式,没有复杂的逻辑。缺点是在移动端的适配性差一些,部分安卓机型以及safari中,无法阻止底部页面滚动,另外有些机型可能需要给根节点添加overflow: hidden;样式才有效果,此外由于实际上是将页面的内容给裁剪了,所以在设置这个样式的时候滚动条会消失,而移除样式的时候滚动条又会出现,所以在视觉上是会有一定的闪烁现象的,当然也可以定制滚动条的样式,但滚动条样式就是另一个兼容性的问题了,还有同样是因为裁剪。
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>蒙层禁止页面滚动的方案</title><style type="text/css">#mask{position: fixed;height: 100vh;width: 100vw;background: rgba(0, 0, 0, 0.6);top: 0;left: 0;display: flex;align-items: center;justify-content: center;}.hide{display: none !important;}.long-content > div{height: 300px;}.body-overflow-hidden{overflow: hidden;}.mask-content{width: 300px;height: 100px;overflow-x: auto;background: #fff;}.mask-content > div{height: 300px;}</style>
</head>
<body><button id="btn">弹窗</button><div class="long-content"><div>long content</div><div>long content</div><div>long content</div><div>long content</div><div>long content</div><div>long content</div><div>long content</div></div><div id="mask" class="hide"><div class="mask-content"><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div></div></div>
</body><script type="text/javascript">(() => {const btn = document.getElementById("btn");const mask = document.getElementById("mask");const body = document.body;btn.addEventListener("click", e => {mask.classList.remove("hide");body.classList.add("body-overflow-hidden");})mask.addEventListener("click", e => {mask.classList.add("hide");body.classList.remove("body-overflow-hidden");})})();</script>
</html>
touch preventDefault
上边的方案对于移动端的效果不是很理想,如果需要在移动端进行处理的话,可以利用移动端的touch事件,来阻止默认行为,当然这是适用于移动端的方式,另外要是把手机通过蓝牙也好转接线也好接上鼠标的话,那就是另一回事了。假如蒙层内容不会有滚动条,那么上述方法是没有问题的,但是假如蒙层内容有滚动条的话,那么它再也无法动弹了。所以如果在蒙层内部有元素需要滚动的话,需要用Js控制其逻辑,但是逻辑控制起来又是比较复杂的,我们可以判断事件的event.target元素,如果touch的目标是弹窗不可滚动区域即背景蒙层就禁掉默认事件,反之就不做控制,之后又出现了问题,需要判断滚动到顶部和滚动到底部的时候禁止滚动,否则触碰到上下两端,弹窗可滚动区域的滚动条到了顶部或者底部,依旧穿透到body,使得body跟随弹窗滚动,这样的话逻辑的复杂程度就比较高了。
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>蒙层禁止页面滚动的方案</title><style type="text/css">#mask{position: fixed;height: 100vh;width: 100vw;background: rgba(0, 0, 0, 0.6);top: 0;left: 0;display: flex;align-items: center;justify-content: center;}.hide{display: none !important;}.long-content > div{height: 300px;}.mask-content{width: 300px;height: 100px;overflow-x: auto;background: #fff;}.mask-content > div{height: 300px;}</style>
</head>
<body><button id="btn">弹窗</button><div class="long-content"><div>long content</div><div>long content</div><div>long content</div><div>long content</div><div>long content</div><div>long content</div><div>long content</div></div><div id="mask" class="hide"><div class="mask-content"><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div></div></div>
</body><script type="text/javascript">(() => {const btn = document.getElementById("btn");const mask = document.getElementById("mask");const body = document.body;const scrollerContainer = document.querySelector(".mask-content");let targetY = 0; // 记录下第一次按下时的`clientY`scrollerContainer.addEventListener("touchstart", e => {targetY = Math.floor(e.targetTouches[0].clientY);});const touchMoveEventHandler = e => {if(!scrollerContainer.contains(e.target)) {e.preventDefault();}let newTargetY = Math.floor(e.targetTouches[0].clientY); //本次移动时鼠标的位置,用于计算let scrollTop = scrollerContainer.scrollTop; // 当前滚动的距离let scrollHeight = scrollerContainer.scrollHeight; // 可滚动区域的高度let containerHeight = scrollerContainer.clientHeight; //可视区域的高度if (scrollTop <= 0 && newTargetY - targetY > 0) { // 到顶console.log("到顶");if(e.cancelable) e.preventDefault(); // 必须判断`cancelable` 否则容易出现滚动正在进行无法取消的`error`} else if (scrollTop >= scrollHeight - containerHeight && newTargetY - targetY < 0 ) { // 到底console.log("到底");if(e.cancelable) e.preventDefault(); // 必须判断`cancelable` 否则容易出现滚动正在进行无法取消的`error`}}btn.addEventListener("click", e => {mask.classList.remove("hide");body.addEventListener("touchmove", touchMoveEventHandler, { passive: false });})mask.addEventListener("click", e => {mask.classList.add("hide");body.removeEventListener("touchmove", touchMoveEventHandler);})})();</script>
</html>
body fixed
目前常用的方案就是该方案了,要阻止页面滚动,可以将其固定在视图中即position: fixed,这样它就无法滚动了,当蒙层关闭时再释放,当然还有一些细节要考虑,将页面固定视图后内容会回头最顶端,这里我们需要记录一下用来同步top值,这样就可以得到一个兼容移动端与PC端的较为完善的方案了,当然对于浏览器的api兼容性是使用document.documentElement.scrollTop控制还是window.pageYOffset + window.scrollTo控制就需要另行适配了。在示例中为了演示弹窗时不会导致视图重置到最顶端,将弹窗按钮移动到了下方。
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>蒙层禁止页面滚动的方案</title><style type="text/css">#mask{position: fixed;height: 100vh;width: 100vw;background: rgba(0, 0, 0, 0.6);top: 0;left: 0;display: flex;align-items: center;justify-content: center;}.hide{display: none !important;}.long-content > div{height: 300px;}.mask-content{width: 300px;height: 100px;overflow-x: auto;background: #fff;}.mask-content > div{height: 300px;}</style>
</head>
<body><div class="long-content"><div>long content</div><div>long content</div><div>long content</div><button id="btn">弹窗</button><div>long content</div><div>long content</div><div>long content</div><div>long content</div></div><div id="mask" class="hide"><div class="mask-content"><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div><div>mask-content</div></div></div>
</body><script type="text/javascript">(() => {const btn = document.getElementById("btn");const mask = document.getElementById("mask");const body = document.body;let documentTop = 0; // 记录按下按钮时的 `top`btn.addEventListener("click", e => {mask.classList.remove("hide");documentTop = document.scrollingElement.scrollTop;body.style.position = "fixed"body.style.top = -documentTop + "px";})mask.addEventListener("click", e => {mask.classList.add("hide");body.style.position = "static";body.style.top = "auto";document.scrollingElement.scrollTop = documentTop;})})();</script>
</html>
解决js 禁止滚动条滚动,并且滚动条不消失,页面大小不闪动
下面就是:
- 关闭页面滚动的时候,记录页面的滚动位置。然后监听滚轮滚动事件,它一滚动就恢复原来的位置
- 恢复页面滚动的时候,把记录的位置都清空,然后该怎么滚就怎么滚
- 在scrollTo方法中,最好加上behavior:'instant’属性。
- 例:window.scrollTo({top:winY,behavior:‘instant’});
但是,我自己在测试的时候,还是会有下方页面滚动的现象,但是最终还是回到原来的位置,就想弹簧一样。
var winX = null;
var winY = null;window.addEventListener('scroll', function () {if (winX !== null && winY !== null) {window.scrollTo(winX, winY);}
});function disableWindowScroll() {winX = window.scrollX;winY = window.scrollY;
}function enableWindowScroll() {winX = null;winY = null;
}
解决窗口滚动条消失而导致的页面内容抖动的问题
今天在项目中遇到了这样一个问题,点击按钮出现遮罩层和弹窗,不过弹窗出现后还是可以滚动底部的页面,于是写了一段js使弹窗出来后使底部页面增添overflow: hidden的样式解决了这个问题,但是还有一个细节问题就是页面的滚动条也占据宽度,滚动条消失后会有一个抖动的效果,给人体验很不好
尝试了几个办法,以下是个人认为比较好的解决办法:
首先获取窗口文档显示区的宽度和DOM文档的根节点html元素对象的宽度,前者减去后者计算出滚动条的宽度
// 滚动条宽度
let scrollWidth = window.innerWidth - document.documentElement.offsetWidth;
弹窗打开时,滚动条消失先给body元素设置overflow:hidden防止底部页面滚动,然后再给底部页面右侧的padding 设置scrollWidth的值来模拟滚动条存在时底部页面内容的位置
document.body.style.overflow = 'hidden';
this.$refs.index.style.paddingRight = scrollWidth + 'px';
弹窗关闭时,body元素设置overflow:auto,因为弹窗关闭时弹窗又恢复了,重新获取 scrollWidth 的值设置padding为0,这样底部页面的内容就不会在抖动啦,以下为完整代码(不是一个组件的方法,主要逻辑就是上面的代码)
show() {this.isShow = !this.isShow;// 滚动条宽度let scrollWidth = window.innerWidth - document.documentElement.offsetWidth;document.body.style.overflow = 'hidden';this.$refs.index.style.paddingRight = scrollWidth + 'px';
}
close() {this.isShow = false;this.$parent.show();document.body.style.overflow = 'auto';
}
完美解决方案
<script>document.getElementById("enable").onclick = function () {enableScroll();document.getElementById("status").innerHTML = "enabled";document.getElementById("status").className = "enabled";};document.getElementById("disable").onclick = function () {disableScroll();document.getElementById("status").innerHTML = "disabled";document.getElementById("status").className = "disabled";};// left: 37, up: 38, right: 39, down: 40const keys = { 37: 1, 38: 1, 39: 1, 40: 1 };function preventDefault(e) {e.preventDefault();}function preventDefaultForScrollKeys(e) {if (keys[e.keyCode]) {preventDefault(e);return false;}}let supportsPassive = false;try {window.addEventListener("test", null, Object.defineProperty({}, "passive", {get: function () {supportsPassive = true;},}));} catch (e) {}const wheelOpt = supportsPassive ? { passive: false } : false;const wheelEvent = "onwheel" in document.createElement("div") ? "wheel" : "mousewheel";// call this to Disablefunction disableScroll() {window.addEventListener("DOMMouseScroll", preventDefault, false); // older FFwindow.addEventListener(wheelEvent, preventDefault, wheelOpt); // modern desktopwindow.addEventListener("touchmove", preventDefault, wheelOpt); // mobilewindow.addEventListener("keydown", preventDefaultForScrollKeys, false);}// call this to Enablefunction enableScroll() {window.removeEventListener("DOMMouseScroll", preventDefault, false);window.removeEventListener(wheelEvent, preventDefault, wheelOpt);window.removeEventListener("touchmove", preventDefault, wheelOpt);window.removeEventListener("keydown", preventDefaultForScrollKeys, false);}
</script>
- preventDefaultForScrollKeys事件主要阻止键盘↑↓←→键的默认行为;
- e.preventDefault()该方法将通知 Web 浏览器不要执行与事件关联的默认动作(如果存在这样的动作)。相关文档
- { passive: false }的作用:passive的作用
- window.addEventListener(“test”, null…这段代码来源于:addEventListener
- …“onwheel” in document.createElement(“div”)…滚轮事件的不同浏览器兼容
示例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>* {margin: 0;}body {width: 100%;}.box1 {height: 1000px;width: 100%;background-color: #bfa;}</style><script>// left: 37, up: 38, right: 39, down: 40const keys = { 37: 1, 38: 1, 39: 1, 40: 1 };function preventDefault(e) {e.preventDefault();}function preventDefaultForScrollKeys(e) {if (keys[e.keyCode]) {preventDefault(e);return false;}}let supportsPassive = false;try {window.addEventListener("test", null, Object.defineProperty({}, "passive", {get: function () {supportsPassive = true;},}));} catch (e) { }const wheelOpt = supportsPassive ? { passive: false } : false;const wheelEvent = "onwheel" in document.createElement("div") ? "wheel" : "mousewheel";// call this to Disablefunction disableScroll() {window.addEventListener("DOMMouseScroll", preventDefault, false); // older FFwindow.addEventListener(wheelEvent, preventDefault, wheelOpt); // modern desktopwindow.addEventListener("touchmove", preventDefault, wheelOpt); // mobilewindow.addEventListener("keydown", preventDefaultForScrollKeys, false);}// call this to Enablefunction enableScroll() {window.removeEventListener("DOMMouseScroll", preventDefault, false);window.removeEventListener(wheelEvent, preventDefault, wheelOpt);window.removeEventListener("touchmove", preventDefault, wheelOpt);window.removeEventListener("keydown", preventDefaultForScrollKeys, false);}window.onload = () => {let btn1 = document.querySelector('#btn1')let btn2 = document.querySelector('#btn2')btn1.onclick = () => {disableScroll()}btn2.onclick = () => {enableScroll()}}</script>
</head><body><div class="box1">一段很长的文字...[使用lorem1000]</div><button id="btn1">disableWindowScroll</button><button id="btn2">enableWindowScroll</button>
</body></html>
vue中使用
把这两个函数暴露出去就行了,然后打开弹窗的时候,调用disableScroll方法,在关闭弹窗的时候,调用enableScroll的方法
scrollCtrl.js
// 控制页面的滚动条是否可以跟随鼠标滚动而滚动// left: 37, up: 38, right: 39, down: 40
const keys = { 37: 1, 38: 1, 39: 1, 40: 1 };function preventDefault(e) {e.preventDefault();
}function preventDefaultForScrollKeys(e) {if (keys[e.keyCode]) {preventDefault(e);return false;}
}let supportsPassive = false;
try {window.addEventListener("test", null, Object.defineProperty({}, "passive", {get: function () {supportsPassive = true;},}));
} catch (e) { }const wheelOpt = supportsPassive ? { passive: false } : false;
const wheelEvent = "onwheel" in document.createElement("div") ? "wheel" : "mousewheel";// call this to Disable
function disableScroll() {window.addEventListener("DOMMouseScroll", preventDefault, false); // older FFwindow.addEventListener(wheelEvent, preventDefault, wheelOpt); // modern desktopwindow.addEventListener("touchmove", preventDefault, wheelOpt); // mobilewindow.addEventListener("keydown", preventDefaultForScrollKeys, false);
}// call this to Enable
function enableScroll() {window.removeEventListener("DOMMouseScroll", preventDefault, false);window.removeEventListener(wheelEvent, preventDefault, wheelOpt);window.removeEventListener("touchmove", preventDefault, wheelOpt);window.removeEventListener("keydown", preventDefaultForScrollKeys, false);
}
export {enableScroll,disableScroll
}
PrevImg.vue
组件中使用scrollCtrl.js
<template><transition name="slidedown"><div class="prev-container" v-show="isShow"><div class="mask"></div><div class="indicator"><i @click="operate('zoomIn')" class="iconfont icon-jiahao1"></i><i @click="operate('zoomOut')" class="iconfont icon-jian"></i><i @click="operate('rotate')" class="iconfont icon-reset"></i><i @click="close" class="iconfont icon-close"></i></div><div :class="['prev-next', 'left', { 'pointer-allowd': isPrev }]" @click="operate('left')"><i class="iconfont icon-houtuishangyige"></i></div><div :class="['prev-next', 'right', { 'pointer-allowd': isNext }]" @click="operate('right')"><i class="iconfont icon-qianjinxiayige"></i></div><div ref="imgWrapperRef" class="img-wrapper"><img :src="imgPaths[imgIdx]" :style="imgStyle" alt=""></div></div></transition>
</template><script>import {enableScroll,disableScroll} from '@/utils/scrollCtrl.js'export default {name: 'PrevImg',components: {},data() {return {isShow: false,imgIdx: 0,imgPaths: [],transform: {rotate: 0,scale: 1},enterAniClass: '',winY: null,}},computed: {imgStyle() {let { rotate, scale } = this.transformreturn {transform: `scale(${scale}) rotate(${rotate}deg)`}},isNext() {return this.imgIdx != this.imgPaths.length - 1},isPrev() {return this.imgIdx != 0},},mounted() {this.$refs['imgWrapperRef'].onclick = e => {console.log(e.target, 2323);if (e.target == this.$refs['imgWrapperRef']) {this.close()}}console.log(enableScroll,disableScroll,'11');},methods: {open({ imgIdx, imgPaths }) {this.isShow = truethis.imgIdx = imgIdxthis.imgPaths = imgPathsdisableScroll() // 关闭滚动},close() {console.log('object');this.isShow = falsethis.transform = {rotate: 0,scale: 1}enableScroll() // 打开滚动},operate(command) {if (command == 'zoomIn') {this.transform.scale += 0.04} else if (command == 'zoomOut') {this.transform.scale -= 0.04} else if (command == 'rotate') {this.transform.rotate += 90} else {this.transform = {rotate: 0,scale: 1}if (command == 'left') {if (this.imgIdx == 0) {return}this.imgIdx = this.imgIdx - 1} else if (command == 'right') {if (this.imgIdx == this.imgPaths.length - 1) {return}this.imgIdx = this.imgIdx + 1}}}}
}
</script><style lang="scss">
.slidedown-enter-active,
.slidedown-leave-active {transition: all 0.5s;
}.slidedown-enter,
.slidedown-leave-to {opacity: 0;transform: translateY(-20px);
}.slidedown-enter-to,
.slidedown-leave {opacity: 1;transform: translateY(0)
}.prev-container {position: fixed;top: 0;left: 0;width: 100%;height: 100%;z-index: 99999999999;.mask {position: absolute;background-color: rgba(0, 0, 0, .3);width: 100%;height: 100%;z-index: -1;}.pointer-allowd {cursor: pointer !important;}.prev-next {width: 36px;height: 36px;border-radius: 50%;background-color: rgba(255, 255, 255, .3);text-align: center;line-height: 36px;cursor: not-allowed;position: absolute;top: 0;bottom: 0;margin: auto;z-index: 2000;}.left {left: 30px;}.right {right: 30px;}.indicator {display: flex;justify-content: flex-end;padding: 20px;z-index: 100;i {padding: 10px;background-color: rgba(255, 255, 255, .3);border-radius: 50%;margin: 0 5px;cursor: pointer;}}.img-wrapper {position: absolute;top: 0;width: 100%;height: 100%;z-index: -1;display: flex;align-items: center;justify-content: center;img {max-height: 100%;max-width: 80%;transition: all 0.5s;}}
}</style>
相关文章:

蒙层禁止下方页面滚动防抖动完美方案
学习链接 js如何禁止滚动条滚动,但不消失! - 这个是完美解决方案(在线demo示例) 解决窗口滚动条消失而导致的页面内容抖动的问题 完美解决js 禁止滚动条滚动,并且滚动条不消失,页面大小不闪动 蒙层禁止…...
微积分python基础
微积分基础(python) 文章目录 微积分基础(python)1 函数与极限2 求导与微分3 不定积分4 定积分 1 函数与极限 # 导入sympy库 from sympy import * # 将x符号化 x Symbol("x") xx \displaystyle x x # 利用sympy中solve函数求解方程 X solve(x**2-10*x21,x) X pri…...
Redis缓存数据库(一)
目录 一、概述 1、Redis 2、Redis的安装 Redis Windows环境设置 3、String: 字符串 3.1、字符串 3.2、数值 3.3、bitmap 4、Hash: 散列 5、List: 列表 6、Set: 集合 7、Sorted Set: 有序集合 一、概述 常识: 磁盘:1.寻址:ms&…...

物联网|uart串口相关寄存器|波特率设置及计算|发送处理代码|串口接收中断处理函数|物联网之蓝牙4.0 BLE基础-学习笔记(7)
文章目录 13 uart串口基础开发基本电路图:实验相关寄存器波特率设置及计算计算过程:设置中断发送处理代码串口接收中断处理函数main.c 13 uart串口基础开发 基本电路图: 实验相关寄存器 相关寄存器UxCSR、UxCSR、UxGCR、UxBUF、UxBAUD、CLK…...

有数·智享未来 | 新华三重磅发布绿洲平台3.0
5月10日,紫光股份旗下新华三集团以“有数智享未来”为主题,成功举办绿洲平台3.0新品发布会。全新一代绿洲平台实现内核进阶,以五大技术能力升级、五大行业方案沉淀、六类服务能力保障,三位一体构筑更领先的用数底座、更落地的用数…...

在Apex中获取Site URL
Foreword 目前SF暂未提供直接有效的方法在Apex获取SiteURL,我们可以在Idea (Access URL for a Site or Community from Apex)页面投票,除了下面提供的一种hack思路,当然也可以通过Custom Label手动维护。 Format of Site URL Sandbox site …...

【电子学会】2023年03月图形化三级 -- 比大小.md
文章目录 比大小1. 准备工作2. 功能实现3. 设计思路与实现(1)角色分析(2)背景分析(3)所用积木块介绍a. 运动类b. 外观类c. 事件类d. 控制类e. 运算类f. 变量类 (4)角色、舞台背景设置…...

Kali-linux使用Nessus
Nessus号称是世界上最流行的漏洞扫描程序,全世界有超过75000个组织在使用它。该工具提供完整的电脑漏洞扫描服务,并随时更新其漏洞数据库。Nessus不同于传统的漏洞扫描软件,Nessus可同时在本机或远端上遥控,进行系统的漏洞分析扫描…...

青训营 x 训练营结营测试题目(前端方向)
文章目录 📋前言🎯选择题(含多选)📝最后 📋前言 这篇文章的内容是23年6月青训营 x 训练营结营题目,题目一共有25题,题目类型为选择题,包括了单选题和多选题,…...

虚拟化技术介绍-VMware和Docker的区别
都说今天是一个云时代,其实云的本质就是由基础架构提供商提供基础架构,应用开发商不再关心基础架构。我们可以类比人类刚刚发明电的时候,工厂需要自己建电站,而现在只需要电线和插座就可以使用电。云时代让我们可以在分钟、甚至秒…...

TinyHttpd 运行过程出现的问题
最近拉了个 TinyHttpd 的工程下来,不过好像各个都有些改动,最后挑了篇阅读量最多的。工程也是从这里面给的链接下载的。 参考自:https://blog.csdn.net/jcjc918/article/details/42129311 拿下来在编译运行前,按这里说的&#x…...

【Linux】shell编程—数组
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、shell数组1,数组的概念2.数组的定义 二、Shell数组操作1. 获取数组的所有元素的列表2. 获取数组的所有元素下标3.取数组的元素个数4. 获取数组的某个元素的值5.…...
Maven仓库与Maven插件
目录 Maven 仓库 本地仓库 中央仓库 远程仓库 Maven 依赖搜索顺序 Maven 阿里云(Aliyun)仓库 gradle 配置指南 Maven 插件 插件类型 实例 Maven 仓库 在 Maven 的术语中,仓库是一个位置(place)。 Maven 仓库是项目中依赖的第三方库…...

【溯源反制】CDN域前置云函数-流量分析|溯源
文章目录 CDN隐藏C2地址环境搭建上传至威胁感知平台直接分析使用DNSQuerySniffer和Process Monitor定位进程网络流量分析文件属性(IDAPro Ollydbg) 域前置隐藏环境搭建威胁感知流量分析 云服务API网关/云函数云函数使用HTTPcs的流量可以简单的分为三个阶段 云函数使用HTTPS 总结…...

【Vue】学习笔记-全局事件总线
全局事件总线(GlobalEventBus) 一种可以在任意组件通信的方式,本质上就是一个对象,它必须满足以下条件 所有的组件对象都必须能看见他这个对象必须能够使用$ on $ emit $ off方法取绑定、触发和解绑事件 使用步骤 定义全局事件总线 //创建VUE new V…...

MATLAB数值运算(六)
目录 实验目的 实验内容 原创代码,仅供参考,不要直接CV呀 ~_~ 实验目的 1)掌握定义符号对象和创建符号表达式的方法; 2)掌握符号运算基本命令和规则; 3)掌握符号表达式的运算法则以及符号矩阵…...

某医院Pad网络故障分析
分析背景 某医院为了加强信息安全管理,防止病人隐私信息泄露,采用部署“零信任”安全架构设计理念的企业移动安全支撑平台方案。 但在部署前期测试时,遇到了严重的性能问题。 在本次测试环境中,通过PAD访问患者转运业务&#x…...

git 撤销中间某次提交,保留其他提交的方法
今天上班脑抽了,吧test直接合到了uat,因为项目近期就我一个人开发,自己拉个三个分支再改不同的东西,最后都是发到test分支发测试,发生产的时候一个个和嫌麻烦,直接吧test分支怼到了uat,结果生产就出问题了&…...

空中下载技术(OTA)电控信息安全
随着汽车电子控制系统功能复杂度和数据颗粒度呈阶梯式增加,其发展速度逐渐超越网络安全防护方法、技术和标准的发展,现阶段汽车电子正面临巨大的网络信息安全风险,对功能安全的潜在影响也仍在探索和解决中,信息安全问题已经成为影…...

数据库sql语句(count(*)和count(字段))
例题: 创建如下两张表 分别命名为books和persons (1)按照书名,姓名的顺序列出字里包含‘德’字的人物的姓名,书名和字。 select name 姓名,bookname 书名,style 字 from books,persons where style like %德% and bo…...

C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...

现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...

Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...