当前位置: 首页 > news >正文

蒙层禁止下方页面滚动防抖动完美方案

学习链接

js如何禁止滚动条滚动,但不消失! - 这个是完美解决方案(在线demo示例)

解决窗口滚动条消失而导致的页面内容抖动的问题

完美解决js 禁止滚动条滚动,并且滚动条不消失,页面大小不闪动

蒙层禁止页面滚动的方案

蒙层禁止页面滚动-自己的上篇

最终的效果

在这里插入图片描述

前言

在页面中,经常会需要打开一些弹窗,弹窗下面会有一个蒙层,蒙层下面是页面。蒙层需要覆盖整个视口。但是一般会遇到3个问题不那么好解决

  1. 打开弹窗后,当鼠标滚动时,底下的页面也会跟随滚动。
  2. 浏览器右侧的滚动条在一些方案中会隐藏,而导致打开弹窗和关闭弹窗时,由于滚动条的显示和隐藏而导致页面抖动闪烁。
  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如何禁止滚动条滚动&#xff0c;但不消失&#xff01; - 这个是完美解决方案&#xff08;在线demo示例&#xff09; 解决窗口滚动条消失而导致的页面内容抖动的问题 完美解决js 禁止滚动条滚动&#xff0c;并且滚动条不消失&#xff0c;页面大小不闪动 蒙层禁止…...

微积分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: 有序集合 一、概述 常识&#xff1a; 磁盘&#xff1a;1.寻址&#xff1a;ms&…...

物联网|uart串口相关寄存器|波特率设置及计算|发送处理代码|串口接收中断处理函数|物联网之蓝牙4.0 BLE基础-学习笔记(7)

文章目录 13 uart串口基础开发基本电路图&#xff1a;实验相关寄存器波特率设置及计算计算过程&#xff1a;设置中断发送处理代码串口接收中断处理函数main.c 13 uart串口基础开发 基本电路图&#xff1a; 实验相关寄存器 相关寄存器UxCSR、UxCSR、UxGCR、UxBUF、UxBAUD、CLK…...

有数·智享未来 | 新华三重磅发布绿洲平台3.0

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

在Apex中获取Site URL

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

【电子学会】2023年03月图形化三级 -- 比大小.md

文章目录 比大小1. 准备工作2. 功能实现3. 设计思路与实现&#xff08;1&#xff09;角色分析&#xff08;2&#xff09;背景分析&#xff08;3&#xff09;所用积木块介绍a. 运动类b. 外观类c. 事件类d. 控制类e. 运算类f. 变量类 &#xff08;4&#xff09;角色、舞台背景设置…...

Kali-linux使用Nessus

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

青训营 x 训练营结营测试题目(前端方向)

文章目录 &#x1f4cb;前言&#x1f3af;选择题&#xff08;含多选&#xff09;&#x1f4dd;最后 &#x1f4cb;前言 这篇文章的内容是23年6月青训营 x 训练营结营题目&#xff0c;题目一共有25题&#xff0c;题目类型为选择题&#xff0c;包括了单选题和多选题&#xff0c;…...

虚拟化技术介绍-VMware和Docker的区别

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

TinyHttpd 运行过程出现的问题

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

【Linux】shell编程—数组

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、shell数组1,数组的概念2.数组的定义 二、Shell数组操作1. 获取数组的所有元素的列表2. 获取数组的所有元素下标3.取数组的元素个数4. 获取数组的某个元素的值5.…...

Maven仓库与Maven插件

目录 Maven 仓库 本地仓库 中央仓库 远程仓库 Maven 依赖搜索顺序 Maven 阿里云(Aliyun)仓库 gradle 配置指南 Maven 插件 插件类型 实例 Maven 仓库 在 Maven 的术语中&#xff0c;仓库是一个位置&#xff08;place&#xff09;。 Maven 仓库是项目中依赖的第三方库…...

【溯源反制】CDN域前置云函数-流量分析|溯源

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

【Vue】学习笔记-全局事件总线

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

MATLAB数值运算(六)

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

某医院Pad网络故障分析

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

git 撤销中间某次提交,保留其他提交的方法

今天上班脑抽了&#xff0c;吧test直接合到了uat,因为项目近期就我一个人开发&#xff0c;自己拉个三个分支再改不同的东西&#xff0c;最后都是发到test分支发测试&#xff0c;发生产的时候一个个和嫌麻烦&#xff0c;直接吧test分支怼到了uat&#xff0c;结果生产就出问题了&…...

空中下载技术(OTA)电控信息安全

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

数据库sql语句(count(*)和count(字段))

例题&#xff1a; 创建如下两张表 分别命名为books和persons &#xff08;1&#xff09;按照书名&#xff0c;姓名的顺序列出字里包含‘德’字的人物的姓名&#xff0c;书名和字。 select name 姓名,bookname 书名,style 字 from books,persons where style like %德% and bo…...

短视频矩阵源码系统

短视频矩阵源码系统开发要则&#xff1a; 1. 需求分析&#xff1a;对短视频平台的需求进行全面分析&#xff0c;确立系统开发目标和方向。 2. 技术选型&#xff1a;选用最适合的技术开发短视频矩阵系统&#xff0c;如前端框架、数据库、服务器等。 3. 系统设计&#xff1a;按…...

检测数据类型

//typeof() 对于基本数据类型没问题&#xff0c;遇到引用数据类型不管用 console.log(typeof 666) //number console.log(typeof [1,2,3]) //object //instanceof() 只能判断引用数据类型&#xff0c;不能判断基本数据类型 console.log( [] instanceof Array) //true …...

【2023春招】4399 web后台-Java后端开发

目录 一、JVM1.类加载过程2.static和final变量的初始化时机 二、依赖1.Spring Boot 自动装配2.使用依赖过程中遇到问题如何排查3.引入的某个依赖不符合预期&#xff0c;如何处理 三、数据库&#xff1a;1.InnoDB 和 MyISAM 索引的区别2.字符串类型字段&#xff0c;WHERE 数字&a…...

干货分享:PCB防静电设计的必要性

平时通过走路穿衣等日常活动带来的摩擦&#xff0c;会产生不同幅值的静电电压&#xff0c;但其能量很小不会对人体产生伤害&#xff0c;不过对于电子元器件来说&#xff0c;这种静电能量却是不能忽视的。 在干燥的环境下&#xff0c;人体静电&#xff08;ESD&#xff09;的电压…...

电脑压缩包文件不见了怎么办?2种办法轻松找回电脑丢失文件!

一般情况下&#xff0c;为了节省磁盘空间或者传送文件时能够更快点&#xff0c;我们都会选择把文件进行压缩&#xff0c;这样会更加方便。 但时间一长&#xff0c;由于各种各样的原因&#xff0c;比如&#xff1a; 清理积累下来的压缩包时不小心把需要的压缩文件删除了&#x…...

如何申请gpt4.0-如何接入ChatGPT4

如何接入ChatGPT4 ChatGPT-4是OpenAI公司推出的最新自然语言处理技术&#xff0c;采用深度学习算法&#xff0c;旨在提供更加高效、准确的人工智能语言处理能力。如果您想要接入ChatGPT-4&#xff0c;您可以按照以下步骤&#xff1a; 注册OpenAI账号并申请API密钥&#xff1a;…...

设计模式-备忘录模式

备忘录模式 文章目录 备忘录模式什么是备忘录模式为什么要用备忘录模式如何使用备忘录模式总结 什么是备忘录模式 在不违背封装原则的前提下&#xff0c;捕获一个对象的内部状态&#xff0c;并在该对象之外保存这个状态&#xff0c;以便之后恢复对象为先前的状态。   在我看来…...

阿里、京东等大厂年薪50w的测试都是什么水平?

各位做测试的朋友&#xff0c;但凡经历过几次面试&#xff0c;那么你一定曾被问到过以下问题&#xff1a; 1、在Linux环境下&#xff0c;怎么执行web自动化测试&#xff1f; 2、Shell如何&#xff0c;Docker熟悉吗&#xff1f; 3、全链路的压测实操过吗&#xff0c;如何推进与开…...

Java PECS(Producer Extends Consumer Super)原则

在看 Alibaba 开发手册时遇到 PECS 原则&#xff0c;刚开始阅读时感觉比较绕&#xff0c;也搜索了一些博文参考&#xff0c;个人觉得 Stackoverflow 的这篇文章比较实用 —— What is PECS (Producer Extends Consumer Super)? 后面结合 JDK 源码梳理了下 // java/util/List…...

Learn RabbitMQ with SpringBoot

文章目录 What is RabbitMQ?RabbitMQ Core conceptRabbitMQ ArchitectureInstall and setup RabbitMQ using DockerExplore RabbitMQ using management UICreate and setup Springboot3 project in intellijSpringboot and RabbitMQ Basic MessageConnection between Springbo…...