"https://wmprod.oss-cn-shanghai.aliyuncs.com/community/FrMUWxHT5PONNOz5eEiYhRP618eW.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/community/FrMUWxHT5PONNOz5eEiYhRP618eW.png)
怎么区分点击事件是用户的真实操作还是代码触发的呢? 目前在使用NodePlayer播放器时遇到一个问题,使用它的自动播放时,一开始视频是没有声音的,得点击一下才有声音,官方API给出的解释以及解决方法如下: "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20250110/3b71bcaeed80d3da4c7dfb01f8d96b05.png) 官方API说当点击播放器的时候,声音可以恢复。 但如果我们想实现无感知操作,不想让用户再多一步点击操作,通过在代码里自己调用click去触发点击事件,声音恢复无效。 但无论是使用.click和创建一个点击事件其实都能触发监听点击事件的方法,说明代码触发的点击是生效了的,但为什么声音恢复无效呢?NodePlayer官方API上说“需要由一个真实的用户交互操作来恢复,不能使用代码”,但两者都是能触发监听点击事件的方法,NodePlayer是怎么区分到底是真实的用户操作还是代码触发的呢? var btn = document.getElementById('btn'); //自动点击方法一 var event = new MouseEvent('click', { 'view': window, 'bubbles': true, 'cancelable': true }); btn.dispatchEvent(event); //自动点击方法二 btn.click() //监听点击事件 btn.addEventListener('click', function() { console.log('被点击了') }); NodePlayer相关文档地址:"https://www.nodemedia.cn/doc/web/#/1/3" (https://link.segmentfault.com/?enc=9yMKIXWJBmICxFXpAIh15A%3D%3D.wlubGtGakTd%2B3A2SUiOmWN2TOxCkOUPifWibn8JQPjK90H1OmDkfLmrLF8HDJ%2B0i)
vue3可以访问后端https接口吗,可以的话是怎么配置呢
抓包魅族社区"https://www.meizu.cn/" (https://link.segmentfault.com/?enc=It8MvyQ0DAaNXEBcZW5Ezg%3D%3D.b75VlS1FPlBlkWOT5AMT97f%2BHiM6gcup%2BduDFmvXn9Q%3D) , 里面有一字段数据是json,需要按规则将key,value转html才能正常显示。求各位指点一下如何实现这种json转html。 这是大概的json数据: [ { "c": [ { "x": "8 月即将过去,9 月即将到来。距离魅族 20 系列发布已经过去了 5 个月时间,在这 5个月的时间里,魅族 20 系列陪你度过了哪些有趣且快乐的时光呢?" } ], "t": "p" }, { "c": [ { "x": "作为魅族最新的全能旗舰,各位在用上它之后,玩原神、打吃鸡、上王者,是否打出过惊为天人的操作?又是否在跑分平台上跑出过其他手机都没有出现过高分成绩呢?" } ], "t": "p" }, { "c": [ { "x": "\n从即日起至8月31日23:59,评论区晒出你的安兔兔跑分成绩,活动结束后,参与晒图跑分活动的魅友将获得 99 煤球奖励,跑分最高者更有机会赢取 999 煤球大奖。" } ], "t": "p" }, { "cv": 0, "s": "https://ssm.res.meizu.com/content/2023/08/28/4018386/140424375354139.jpg", "y": { "h": "1421px", "w": "1080px" }, "c": [ { "x": "" } ], "t": "z" }, ....... ] 规则是这样的: const tr = { t: "type", x: "text", b: "bold", th: "through", y: "style", w: "width", h: "height", s: "src", n: "name", u: "uid", c: "children", l: "italic", r: "url", p: "paragraph", h1: "header1", h2: "header2", h3: "header3", d: "divider", q: "blockquote", v: "video", k: "link", i: "image", m: "mention", tc: "topic", z: "img", cv: "cover", sc: "shopCard" };
浏览器打印,可以自定义页眉页脚吗? "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20241221/760e01ede6e15bfa7865ecc034a0755b.png)
九、如何验证 HTML 是否正确 ?验证 HTML 的最好方法使用 W3C 创立并维护的标记验证服务,网址如下:https://validator.w3.org/提交一个线上 URL,HTML 文件或者代码,网页会返回相应的错误报告十、什么是 HTML5,HTML5 有哪些新特性 ?(1)什么是 HTML5?HTML5 是定义 HTML 标准的组新版本,具有两个不同的概念:HTML5 是一个新版本的 HTML 语言,具有新的元素,属性和行为HTML5 有更大的技术集,允许构建多样化和更强大的网站和应用程序(2)HTML5 有哪些新特性 ?根据功能,HTML5 新特性可以分为:语义:能够更恰当地描述内容是什么新的区块和段落元素举例: <section> 表示一个包含在 HTML 文档的独立部分 <article> 表示文档、页面、应用或网站中的独立结构 <nav> 表示页面的一部分,其目的是在当前文档或其他文档提供导航链接 <header> 用于展示介绍性内容辅助导航。包含标题,Logo,搜索框和作者名称 <footer> 表示最近一个章节或根节点元素的页脚,包含作者,版权,相关链接 <aside> 表示一个和其余页面内容几乎无关的部分,通常是侧边栏或标注框 <hgroup>代表文档章节所属的多级别目录嵌入和允许操作新的多媒体内容举例: <audio> 用于在文档中嵌入音频内容 <video> 用于再文档嵌入媒体播放器,支持视频及音频播放表单的改进强制性校验 API举例: required 必填属性pattern 声明正则校验规则属性 minlength 和 maxlength 限制输入的长度 constraint validation API 检测和自定义表单元素的状态新 <input> 元素的 type 属性值举例: color 取色器 date 日期控件 detetime-local 不包括时区的日期控件 month 输入年和月的控件,没有时区 range 输入不需要精确地数字空间 search 搜索字符串的单行文字区域 tel 输入电话号码的控件 time 输入时间的控件 url 输入并校验 URL 的控件其它新的语义元素举例: <mark> 为表示引用或符号目的而标记或突出显示的文本 <figure> 常与 <figcaption> 配合使用,表示独立的说明内容 <data> 将一个指定内容和机器可读的翻译联系在一起 <time> 表示机器可读的 24 小时制的时间或者公历日期 <progress> 显示一项任务的完成进度<meter> 用来显示已知范围的标量值或者分数值 <main> 呈现了文档的 <body> 或应用的主体部分 output 表示计算或用户操作的结果<iframe> 的改进精确控制 <iframe> 元素的安全级别和期望的渲染举例:sandbox 对呈现在 iframe 框架中的内容启用一些额外的限制条件srcdoc 支持的浏览器优先使用 srcdoc 代替 srcMathML用于描述数学公式、符号的一种标记语言,允许直接嵌入数学公式连通性:能够通过创新的新技术方法进行通信Web Sockets允许在页面和服务器之间建立持久连接,并通过这种方法来交换非 HTML 数据Server-sent events允许服务器向客户端推送事件WebRTC支持在浏览器客户端之间语音 / 视频交流和数据分享的技术浏览器原生支持点对点的分享应用数据和进行电话会议离线 & 存储:能够让网页再客户端本地存储数据并且更高效地离线运行离线资源:应用程序缓存缓存 .manifest 上的资源,离线或资源没有更新时,浏览器会加载缓存的离线资源在线和离线事件navigator.onLine 返回在线 true 或离线 falseonline 和 offline 事件window document document.body 使用 addEventListenerdocument document.body 的 .ononline 或 .onoffline 属性设为一个 JavaScript Function 对象<body> 标签上指定 ononline="..." 或 onoffline="..." 属性WHATWG 客户端会话和持久化存储(又名 DOM 存储)StorageDOM 存储被设计为用户提供一个更大存储量,更安全,更便捷的存储方法代替掉将一些不需要让服务器知道的信息存储到 cookies 里的这种传统方法构造函数 Storage 及其实例seesionStorage 全局对象,维护着页面会话期间有效的存储空间,重新载入或从崩溃中恢复不会丢失localStorage 全局对象,本次持久化存储,隐身模式下关闭浏览器会丢弃IndexedDB用于在客户端存储大量的结构化数据,包括文件 / 二进制大型对象(blobs)使用索引实现对数据的高性能搜索在 Web 应用程序中使用文件File API:可以访问 FileList,包含表示用户所选择的 File 对象name 文件名称,只读字符串,只包含文件名,不包含任何路径信息size 以字节数为单位的文件大小,只读的 64 位整数type 文件的 MIME 类型,只读字符串,当类型不能确定为 ""通过 change 事件访问被选择的文件this.files通过 drogenter dragover drag 的 dataTransfer 的 files 中获取文件列表对象 URL window.URL.createObjectURL() 和 window.URL.revokeObjectURL()多媒体:加快普及 video 和 audio 应用,丰富 web 表现力HTML5 音视频<video> 和 <audio> 标签以及 JavaScript 和 APIs 用于对其进行控制WebRTC支持在浏览器客户端之间语音 / 视频交流和数据分享的技术浏览器原生支持点对点的分享应用数据和进行电话会议Camera API使用手机的摄像头拍照,然后把拍到的照片发送给当前网页Track 和 WebVTT<track> 元素怒被当作媒体元素 <audio> 和 <video> 的子元素WebVTT(Web 视频文本跟踪格式)使用 <track> 元素现实定时文本轨道(如字幕或标题)的格式化,支持 VTTCue 和 VTTRegion 接口2D/3D 绘图 & 效果:提供定制图形、动画界面的新选择Canvas<canvas> 元素被用来通过 JavaScript (Canvas API 或 WebGL API)绘制图形及图形动画HTML5 文本 API 由 <canvas> 支持fillText(text, x, y, [, maxWidth]) 在指定的 (x, y) 位置填充指定的文本strokeText(text, x, y, [, maxWidth] 在指定的 (x, y) 位置绘制文本边框WebGLWebGL (Web 图形库) 是一个 JavaScript API,可在任何兼容的 Web 浏览器中渲染高性能的交互式 3D 和 2D 图形,无需使用插件WebGL 引入 OpenGL ES 2.0,通过 canvas.getContext('webgl') 使用WebGL 2 引入 OpenGL ES 3.0,通过 canvas.getContext('webgl2') 使用SVGSVG (可缩放矢量图形)是一种描述二维的矢量图形,基于 XML 的标记语言优雅而简洁地渲染不同大小的图形,并和 CSS,DOM,JavaScript 和 SMIL 等其他网络标准无缝衔接可以搜索、索引、编写脚本和压缩,也可以使用任何文本编辑器和绘图软件来创建和编辑 SVG性能 & 集成:提供作用显著的性能优化方案,更有效地使用设备硬件Web Workers为 Web 内容在后台线程中运行脚本提供一种简单方法线程可以执行任务而不干扰用户界面专用 workernew Worker() 构建通过 postMessage() 和 onmessage 事件函数发送和接收消息共享 workernew SharedWorker() 构建通过 po``r``t``.``postMessage() 和 po``r``t.onmessage 事件函数发送和接收消息worker 中需先使用 onconnect 获取 portXMLHttpRequest Level 2 可以设置 HTTP 请求的时限 可以使用 FormData 对象管理表单数据 可以上传文件 可以请求不同域名下的数据(跨域请求) 可以获取服务器端的二进制数据 可以获得数据传输的进度信息即时编译的 JavaScript 引擎 新一代的 JavaScript 引擎更强大,性能更杰出History APIHistory 接口允许操作浏览器的曾经在标签页或者框架里访问的会话历史记录属性History.length 返回一个整数,该整数表示会话历史中元素的数目,包括当前加载的页History.scrollRestoration 允许 Web 应用程序在历史导航上显式地设置默认滚动恢复行为。此属性可以是自动的(auto)或者手动的(manual)History.state 返回一个表示历史堆栈顶部的状态的值。这是一种可以不必等待 popstate 事件而查看状态的方式方法History.back() 在浏览器历史记录里前往上一页,用户可以点击浏览器左上角的返回按钮模拟此方法,等价于 history.go(-1)History.forward() 在浏览器历史记录中前往下一页,用户可以点击浏览器左上角的前进按钮模拟此方法,等价于 history.go(1)History.go() 通过当前页面的相对位置从浏览器历史记录(会话记录)加载页面History.pushState() 按指定的名称和 URL(如果提供该参数)将数据 push 进会话历史栈,数据被 DOM 进行不透明处理,你可以指定任何可以被序列化的 JavaScript 对象History.replaceState() 按指定的数据,名称和 URL(如果提供该参数)更新历史栈上最新的入口。这个数据被 DOM 进行了不透明处理。您可以指定任何可以被序列化的 JavaScript 对象Content EditableHTML 中任何元素都可以被编辑,设置 contenteditable 属性为 true 即可HTML5 将此属性标准化HTML 拖放 APIHTML 拖放(Drag and Drop)接口使应用程序能够在浏览器中私用拖放功能引入拖放功能的基本步骤确定可拖拽元素给元素添加 draggable 属性,添加全局事件处理函数 ondragstart定义拖拽数据通过 drag event 的 dataTransfer 属性访问事件数据通过 dataTransfer 的 setData() 方法为拖拽数据添加一个项通过 dataTransfer 的 setDrageImage 方法定义拖拽图像通过 dataTransfer 的 dropEffect 属性定义拖拽效果copy 表明拖拽的数据将从它原本的位置拷贝到目标的位置move 表明被拖拽的数据将被移动link 表明拖拽源位置和目标之间将会创建一些关系表格或是连接确定放置区域给元素添加 ondragover 和 ondrop 事件处理程序属性定义放置效果通过 dataTransfer 的 dropEffect 属性定义拖拽效果拖拽结束拖拽操作结束时,在源元素(开始拖拽时的目标元素)上触发 dragend 事件不管拖拽是完成还是取消,这个事件都会被触发HTML 焦点管理DOM 属性 activeElement 与方法 hasFocus() 为程序按提供了更好的控制页面交互的能力,特别是丢与用户行为引发的交互activeElement 只读属性,用来返回当前在 DOM 或者 shadow DOM 树中处于聚焦状态的 ElementDo``cumen``t.hasFocus() 方法返回一个 Boolean,表明当前文档或者文档内的节点是否获得了焦点。该方法可以用来判断当前文档中的活动元素是否获得了焦点两者关系获得焦点的元素一定是当前文档的活动元素一个文档中的活动元素不一定获得了焦点基于 Web 的协议处理程序使用 navigator.registerProtoolHandler(sch``em``e,``ur``l``, tit``le) 方法把 web 应用程序注册成一个协议处理程序requestAnimationFrame传入一个回调函数,该回调函数会在浏览器下一次重绘之前执行全屏 API全屏 API 为使用用户的整个屏幕展现网络内容提供了一种简单的方式,不需要时退出全屏模式方法Document.exitFullscreen() 用于请求从全屏模式切换到窗口模式,会返回一个 Promise,会在全屏模式完全关闭的时候,被重置为 resolved 状态Element.requestFullscreen() 请求浏览器将特定元素置为全屏模式,隐去屏幕上的浏览器所有 UI 元素,以及其它应用属性DocumentOrShadowRoot.fullscreenElement fullscreenElement 属性提供了当前在 DOM(或者 shadow DOM)里被展示为全屏模式的 Element,如果这个值为 null,文档不处于全屏模式Document.fullscreenEnabled fullscreenEnabled 属性提供了启用全屏模式的可能性。当它的值是 false 的时候,表示全屏模式不可用事件处理程序Document 事件处理程序 onfullscreenchange 和 onfullscreenerrorElement 事件处理程序 onfullscreenchange 和 onfullscreenerror指针锁定 API 光标移到浏览器或者屏幕区域之外,指针锁定也能够让你访问鼠标事件 指针锁定是持久性的。指针锁定不释放鼠标,直到作出一个显式的 API 调用或者用户使用一个专门的释放手势 指针锁定不局限于浏览器或者屏幕边界 指针锁定持续发送事件,而不管鼠标按钮状态如何 指针锁定隐藏光标 指针锁定目前需要先进入全屏模式 requestFullscreen() 然后执行 requestPointerLock() 方法在线和离线事件 navigator.onLine 返回在线 true 或离线 false online 和 offline 事件 window document document.body 使用 addEventListener document document.body 的 .ononline 或 .onoffline 属性设为一个 JavaScript Function 对象 <body> 标签上指定 ononline="..." 或 onoffline="..." 属性设备访问 :能够处理各种输入和输出设备Camera API 使用手机的摄像头拍照,然后把拍到的照片发送给当前网页触摸事件触摸事件提供了在触摸屏或触控板商解释手指(或触控笔)活动的能力触摸事件接口可为程序提供多点触控交互的支持,分为开始、移动、结束三个阶段接口TouchEvent 接口将当前所有活动的触摸点封装起来Touch 接口表示单独一个触摸点,其中包括浏览器视角的相对坐标TouchList 表示一组 Touch,用于多点触控的情况使用地理位置定位地理位置 API 允许用户向 Web 应用程序提供他们的位置出于隐私考虑,报告地理位置和前会先请求用户许可方法,通过 navigator.geolocation 提供getCurrentPosition(success[, error[, options]]) 用来获取设备当前位置watchPosition(success[, error, options]]) 用于注册监听器,在设备的地理位置发生改变的时候自动被调用,返回一个 idclearWatch(id) 清除注册的位置及错误监听器检测设备方向DeviceOrientationEvent 它会在加速度传感器检测到设备在方向上产生变化时触发DeviceMotionEvent 它会在加速度发生改变时触发指针锁定 API 光标移到浏览器或者屏幕区域之外,指针锁定也能够让你访问鼠标事件 指针锁定是持久性的。指针锁定不释放鼠标,直到作出一个显式的 API 调用或者用户使用一个专门的释放手势 指针锁定不局限于浏览器或者屏幕边界 指针锁定持续发送事件,而不管鼠标按钮状态如何 指针锁定隐藏光标 指针锁定目前需要先进入全屏模式 requestFullscreen() 然后执行 requestPointerLock() 方法 样式设计:支持创作更复杂的主题十一、什么是 MIME types,常见的 MIME types 有哪些 ?MIMEtype(现在称为“媒体类型(media type)”,但有时也是“内容类型”(content type))是指示文件类型的字符串,与文件一起发送(例如,一个声音文件可能被标记为 audio/ogg 一个图像文件可能是 image/png )。它与传统 Windows 上的文件扩展名有相同目的NavigatorPlugins.mimeTypes 返回一个 MimeTypeArray 对象,其中包含可被当前浏览器识别的 MimeType 对象列表两种主要的 MIME 类型text/plain 表示文本文件的默认值,一个文本文件应当是人类可读的,并且不包含二进制数据application/octet-stream 表示所有其他情况的默认值。一种未知的文件类型应当使用此类型。浏览器在处理这些文件时会特别小心,试图防止、避免用户的危险行为Web 常见的 MIME 类型十二、什么是 ARIA?ARIA(Accessible Rich Internet Applications)是能够让残障人士更加便利地访问 Web 内容和使用 Web 应用的一套机制,来自 W3C 的网络无障碍计划(Web Accessibility Initiative)ARIA 是对超文本标记语言(HTML)的补充,以便在没有其他机制的情况下,使得应用程序中常用的交互和小部件可以传递给辅助交互技术ARIA 是一组特殊的易用性属性,可以添加到任意标签上,尤其适用于 HTML。role 属性定义了对象的通用类型(例如文章、警告、或幻灯片)。额外的 ARIA 属性提供了其他有用的特性,例如表单的描述或进度条的当前值ARIA 在大多数流行的浏览器和屏幕阅读器中得到了实现开发人员应该更倾向使用对应的语义化 HTML 元素,而不是使用 ARIA
我花了几天的时间用vue写了一个五子棋,与机器人对战 但是我感觉里面代码很多重复的部分,想要简化写法,希望大家帮我看看 五子棋 机器人小福正持黑棋与您作战 人机对战 {{ tip }} 重新开始 import { ref } from 'vue' import dialogVue from '../comm/dialog.vue' export default { components: { dialogVue }, setup() { //机器人玩五子棋的思路是 //当用户有三个连在一起时,挡住一边,有四个时,阻挡用户,其他情况机器人自己企图完成五个连线 const isMachine = ref(false)//是否是机器人对战 const score = ref(0) const row = ref(20) const col = ref(20) const visible = ref(false) const tip = ref('') const boxs = ref([[{ place: 0, x: 0, y: 0 }]]) const curUser = ref(1)//只可以是1或者2 1表示白 2表示黑 let airPlace = []//记录机器人下棋子的地方 let previousBox = { place: 0, x: 0, y: 0 } let fourDetial = {}//机器人是否有四个连在一起 function init() { curUser.value = 1 visible.value = false airPlace = [] boxs.value = [] previousBox = { place: 0, x: 0, y: 0 } fourDetial = {} for (let i = 0; i fourDetial.x - fourDetial.times + 1; i--) { if (boxs.value[i][fourDetial.y].place === 0) { boxs.value[i][fourDetial.y].place = 2 fourDetial = determineEquare3(4, 2, { x: i, y: fourDetial.y, place: 2 }) airPlace.push((i) * row.value + fourDetial.y) curUser.value = 1 return } } } else if (boxs.value[fourDetial.x + 1]?.[fourDetial.y]?.place === 0) { boxs.value[fourDetial.x + 1][fourDetial.y].place = 2 fourDetial = determineEquare3(4, 2, { x: fourDetial.x + 1, y: fourDetial.y, place: 2 }) airPlace.push((fourDetial.x + 1) * row.value + fourDetial.y) curUser.value = 1 return } else if (boxs.value[fourDetial.x - fourDetial.times]?.[fourDetial.y]?.place === 0) { boxs.value[fourDetial.x - fourDetial.times][fourDetial.y].place = 2 fourDetial = determineEquare3(4, 2, { x: fourDetial.x - fourDetial.times, y: fourDetial.y, place: 2 }) airPlace.push((fourDetial.x - fourDetial.times) * row.value + fourDetial.y) curUser.value = 1 return } } else if (fourDetial.type === 2) { if (fourDetial.geyi) { for (let j = fourDetial.y; j > fourDetial.y - fourDetial.times + 1; j--) { if (boxs.value[fourDetial.x][j].place === 0) { boxs.value[fourDetial.x][j].place = 2 fourDetial = determineEquare3(4, 2, { x: fourDetial.x, y: j, place: 2 }) airPlace.push((fourDetial.x) * row.value + j) curUser.value = 1 return } } } else if (boxs.value[fourDetial.x]?.[fourDetial.y + 1]?.place === 0) { boxs.value[fourDetial.x][fourDetial.y + 1].place = 2 fourDetial = determineEquare3(4, 2, { x: fourDetial.x, y: fourDetial.y + 1, place: 2 }) airPlace.push((fourDetial.x) * row.value + fourDetial.y + 1) curUser.value = 1 return } else if (boxs.value[fourDetial.x]?.[fourDetial.y - fourDetial.times]?.place === 0) { boxs.value[fourDetial.x][fourDetial.y - fourDetial.times].place = 2 fourDetial = determineEquare3(4, 2, { x: fourDetial.x, y: fourDetial.y - fourDetial.times, place: 2 }) airPlace.push((fourDetial.x) * row.value + fourDetial.y - fourDetial.times) curUser.value = 1 return } } else if (fourDetial.type === 3) { if (fourDetial.geyi) { let i for (let j = fourDetial.y - 1; j > fourDetial.y - fourDetial.times + 1; j--) { i = fourDetial.x - (fourDetial.y - j) if (boxs.value[i]?.[j]?.place === 0) { boxs.value[i][j].place = 2 fourDetial = determineEquare3(4, 2, { x: i, y: j, place: 2 }) airPlace.push((i) * row.value + j) curUser.value = 1 return } } } else if (boxs.value[fourDetial.x + 1]?.[fourDetial.y + 1]?.place === 0) { boxs.value[fourDetial.x + 1][fourDetial.y + 1].place = 2 fourDetial = determineEquare3(4, 2, { x: fourDetial.x + 1, y: fourDetial.y + 1, place: 2 }) airPlace.push((fourDetial.x + 1) * row.value + fourDetial.y + 1) curUser.value = 1 return } else if (boxs.value[fourDetial.x - fourDetial.times]?.[fourDetial.y - fourDetial.times]?.place === 0) { boxs.value[fourDetial.x - fourDetial.times][fourDetial.y - fourDetial.times].place = 2 fourDetial = determineEquare3(4, 2, { x: fourDetial.x - fourDetial.times, y: fourDetial.y - fourDetial.times, place: 2 }) airPlace.push((fourDetial.x - fourDetial.times) * row.value + fourDetial.y - fourDetial.times) curUser.value = 1 return } } else if (fourDetial.type === 4) { if (fourDetial.geyi) { let i for (let j = fourDetial.y; j temp.x - temp.times + 1; i--) { if (boxs.value[i][temp.y].place === 0) { boxs.value[i][temp.y].place = 2 fourDetial = determineEquare3(4, 2, { x: i, y: temp.y, place: 2 }) airPlace.push((i) * row.value + temp.y) } } } else if (boxs.value[temp.x + 1]?.[temp.y]?.place === 0) { boxs.value[temp.x + 1][temp.y].place = 2 fourDetial = determineEquare3(4, 2, { x: temp.x + 1, y: temp.y, place: 2 }) airPlace.push((temp.x + 1) * row.value + temp.y) } else if (boxs.value[temp.x - temp.times]?.[temp.y]?.place === 0) { boxs.value[temp.x - temp.times][temp.y].place = 2 fourDetial = determineEquare3(4, 2, { x: temp.x - temp.times, y: temp.y, place: 2 }) airPlace.push((temp.x - temp.times) * row.value + temp.y) } } else if (temp.type === 2) { if (temp.geyi) { for (let j = temp.y; j > temp.y - temp.times + 1; j--) { if (boxs.value[temp.x][j].place === 0) { boxs.value[temp.x][j].place = 2 fourDetial = determineEquare3(4, 2, { x: temp.x, y: j, place: 2 }) airPlace.push((temp.x) * row.value + j) } } } else if (boxs.value[temp.x]?.[temp.y + 1]?.place === 0) { boxs.value[temp.x][temp.y + 1].place = 2 fourDetial = determineEquare3(4, 2, { x: temp.x, y: temp.y + 1, place: 2 }) airPlace.push((temp.x) * row.value + temp.y + 1) } else if (boxs.value[temp.x]?.[temp.y - temp.times]?.place === 0) { boxs.value[temp.x][temp.y - temp.times].place = 2 fourDetial = determineEquare3(4, 2, { x: temp.x, y: temp.y - temp.times, place: 2 }) airPlace.push((temp.x) * row.value + temp.y - temp.times) } } else if (temp.type === 3) { if (temp.geyi) { let i for (let j = temp.y - 1; j > temp.y - temp.times + 1; j--) { i = temp.x - (temp.y - j) if (boxs.value[i]?.[j]?.place === 0) { boxs.value[i][j].place = 2 fourDetial = determineEquare3(4, 2, { x: i, y: j, place: 2 }) airPlace.push((i) * row.value + j) } } } else if (boxs.value[temp.x + 1]?.[temp.y + 1]?.place === 0) { boxs.value[temp.x + 1][temp.y + 1].place = 2 fourDetial = determineEquare3(4, 2, { x: temp.x + 1, y: temp.y + 1, place: 2 }) airPlace.push((temp.x + 1) * row.value + temp.y + 1) } else if (boxs.value[temp.x - temp.times]?.[temp.y - temp.times]?.place === 0) { boxs.value[temp.x - temp.times][temp.y - temp.times].place = 2 fourDetial = determineEquare3(4, 2, { x: temp.x - temp.times, y: temp.y - temp.times, place: 2 }) airPlace.push((temp.x - temp.times) * row.value + temp.y - temp.times) } } else if (temp.type === 4) { if (temp.geyi) { let i for (let j = temp.y; j 0) { boxs.value[previousBox.x - 1][previousBox.y].place = 2 airPlace.push((previousBox.x - 1) * row.value + previousBox.y) } else { boxs.value[previousBox.x + 1][previousBox.y].place = 2 airPlace.push((previousBox.x + 1) * row.value + previousBox.y) } } else { let time = [{ time: 0, pre: -1, geyi: false }, { time: 0, pre: -1, geyi: false }, { time: 0, pre: -1, geyi: false }, { time: 0, pre: -1, geyi: false }] airPlace.some((item, index, arr) => { let itemi = Math.floor(item / row.value) let itemj = item % row.value if (time[0].time = 4) { if ((boxs.value[itemi][itemj + 1]?.place === 0 && boxs.value[itemi][itemj + 1]) || (boxs.value[itemi][itemj - time[0].times]?.place === 0 && boxs.value[itemi][itemj - time[0].time])) return true else { //虽然有四个横着,但是这四个横着两边都被挡住了,所以重新再来 time[0] = { time: 0, pre: -1, geyi: false } } } } } if (time[1].pre === -1 || arr[time[1].pre] === item - 1 || (arr[time[1].pre] === item - 2 && !time[1].geyi)) { if (arr[time[1].pre] === item - 2) { if (boxs.value[Math.floor((item - 1) / row.value)][(item - 1) % row.value].place === 0) { time[0].geyi = true } else { return false } } if ((arr[time[1].pre] === item - 1 || arr[time[1].pre] === item - 2) && time[1].time === 0) { time[1].time = 0 time[1].geyi = false } else time[1].time++ if (time[1].time > 3) { time[1].time = 0 } time[1].pre = index } if (time[2].pre === -1 || arr[time[2].pre] === item - 1 || (arr[time[2].pre] === item - 2 && !time[2].geyi)) { if (arr[time[2].pre] === item - 2) { if (boxs.value[Math.floor((item - 1) / row.value)][(item - 1) % row.value].place === 0) { time[0].geyi = true } else { return false } } if ((arr[time[2].pre] === item - 1 || arr[time[2].pre] === item - 1) && time[2].time === 0) { time[2].time = 0 time[2].geyi = false } else time[2].time++ if (time[2].time > 2) { time[2].time = 0 } time[2].pre = index } if (time[3].pre === -1 || arr[time[3].pre] === item - 1 || (arr[time[3].pre] === item - 2 && !time[3].geyi)) { if (arr[time[3].pre] === item - 2) { if (boxs.value[Math.floor((item - 1) / row.value)][(item - 1) % row.value].place === 0) { time[0].geyi = true } else { return false } } if ((arr[time[3].pre] === item - 1 || arr[time[3].pre] === item - 1) && time[3].time === 0) { time[3].time = 0 time[3].geyi = false } else time[3].time++ if (time[3].time > 1) { time[3].time = 0 } time[3].pre = index } }) time = time.sort((a, b) => b.time - a.time) let placeHas = time.some(item => { if (item.time > 0 && item.pre > -1) { const i = Math.floor(airPlace[item.pre] / row.value) const j = Math.floor(airPlace[item.pre] % row.value) if (boxs.value[i][j + 1]?.place === 0) { boxs.value[i][j + 1].place = 2 airPlace.push(i * row.value + j + 1) fourDetial = determineEquare3(4, 2, { x: i, y: j + 1, place: 2 }) return true } if (boxs.value[i][j - item.time]?.place === 0) { boxs.value[i][j - item.time].place = 2 airPlace.push(i * row.value + j - item.time) fourDetial = determineEquare3(4, 2, { x: i, y: j - item.time, place: 2 }) return true } } }) if (placeHas) { airPlace = airPlace.sort((a, b) => a - b) return } time = [{ time: 0, pre: -1, index: -1 }, { time: 0, pre: -1, index: -1 }, { time: 0, pre: -1, index: -1 }, { time: 0, pre: -1, index: -1 }] airPlace.some((item, index) => { let itemi = Math.floor(item / row.value) let itemj = item % row.value if (time[0].time = 4) { if ((boxs.value[itemi + 1][itemj]?.place === 0 && boxs.value[itemi + 1][itemj]) || (boxs.value[itemi - time[0].time][itemj]?.place === 0 && boxs.value[itemi - time[0].time][itemj])) return true else { //虽然有四个竖着,但是这四个竖着两边都被挡住了,所以重新再来 time[0] = { time: 0, pre: -1 } } } } } if (time[1].pre === -1 || time[1].pre === item - row.value) { if (time[1].pre === item - row.value && time[1].time === 0) { time[1].time = 0 } else time[1].time++ if (time[1].time > 3) { time[1].time = 0 } time[1].pre = item time[1].index = index } if (time[2].pre === -1 || time[2].pre === item - row.value) { if (time[2].pre === item - row.value && time[2].time === 0) { time[2].time = 0 } else time[2].time++ if (time[2].time > 2) { time[2].time = 0 } time[2].pre = item time[2].index = index } if (time[3].pre === -1 || time[3].pre === item - row.value) { if (time[3].pre === item - row.value && time[3].time === 0) { time[3].time = 0 } else time[3].time++ if (time[3].time > 1) { time[3].time = 0 } time[3].pre = item time[3].index = index } }) time = time.sort((a, b) => b.time - a.time) placeHas = time.some(item => { if (item.time > 0 && item.pre > -1) { const i = Math.floor(item.pre / row.value) const j = Math.floor(item.pre % row.value) if (boxs.value[i + 1]?.[j]?.place === 0) { boxs.value[i + 1][j].place = 2 airPlace.push((i + 1) * row.value + j) fourDetial = determineEquare3(4, 2, { x: i + 1, y: j, place: 2 }) return true } if (boxs.value[i - item.time]?.[j]?.place === 0) { boxs.value[i - item.time][j].place = 2 airPlace.push((i - item.time) * row.value + j) fourDetial = determineEquare3(4, 2, { x: i - item.time, y: j, place: 2 }) return true } } }) if (placeHas) { airPlace = airPlace.sort((a, b) => a - b) return } } } //判断用户是否有横竖斜大于等于3个棋子的情况,只需要查看用户上一个棋子落下后是否造成这样的情况就行 function determineEquare3(maxTime = 3, userPlace = 1, box = previousBox) { let times = 0 let preP = -1 let geyi = false let tempArr = [] //竖 for (let i = (box.x - 5 >= 0 ? box.x - 5 : 0); i = maxTime) { if (times === 3 && geyi) { continue } if (boxs.value[i + 1]?.[box.y].place !== 0 && boxs.value[i + 1]?.[box.y].place !== userPlace && boxs.value[i - times]?.[box.y].place !== 0) { break } else { tempArr[0] = tempArr[0]?.times > times ? tempArr[0] : { x: i, y: box.y, type: 1, times, geyi } if (boxs.value[i + 1]?.[box.y].place !== 0 || boxs.value[i - times]?.[box.y].place !== 0) { tempArr[0].priority = 2 } else { tempArr[0].priority = 1 } } } } } times = 0 preP = -1 geyi = false //横 for (let j = (box.y - 5 >= 0 ? box.y - 5 : 0); j = maxTime) { if (times === 3 && geyi) { continue } if (boxs.value[box.x]?.[j + 1]?.place !== 0 && boxs.value[box.x]?.[j + 1].place !== userPlace && boxs.value[box.x]?.[j - times]?.place !== 0) { break } else { tempArr[1] = tempArr[1]?.times > times ? tempArr[1] : { x: box.x, y: j, type: 2, times, geyi } if (boxs.value[box.x]?.[j + 1]?.place !== 0 || boxs.value[box.x]?.[j - times]?.place !== 0) { tempArr[1].priority = 2 } else { tempArr[1].priority = 1 } } } } } times = 0 preP = -1 geyi = false //左斜 let i let j if (box.x - 5 >= 0 && box.y - 5 >= 0) { i = box.x - 5 j = box.y - 5 } else if (box.x - 5 >= 0 && box.y - 5 = 0) { i = 0 j = box.y - (box.x - i) } else { if (box.x > box.y) { j = 0 i = box.x - (box.y - j) } else { i = 0 j = box.y - (box.x - i) } } for (j; j = maxTime) { if (times === 3 && geyi) { i++ continue } if (boxs.value[i + 1]?.[j + 1]?.place !== 0 && boxs.value[i + 1]?.[j + 1].place !== userPlace && boxs.value[i - times]?.[j - times]?.place !== 0) { break } else { tempArr[2] = tempArr[2]?.times > times ? tempArr[2] : { x: i, y: j, type: 3, times, geyi } if (boxs.value[i + 1]?.[j + 1]?.place !== 0 || boxs.value[i - times]?.[j - times]?.place !== 0) { tempArr[2].priority = 2 } else { tempArr[2].priority = 1 } } } } i++ } //右斜 if (box.x - 5 >= 0 && box.y + 5 = 0 && box.y + 5 >= row.value) { j = row.value - 1 i = box.x - (row.value - 1 - box.y) } else if (box.x - 5 row.value - 1 - box.y) { j = row.value - 1 i = box.x - (row.value - 1 - box.y) } else { i = 0 j = box.y + (box.x - i) } } preP = -1 times = 0 geyi = false for (j; j > (box.y - 5 >= 0 ? box.y - 5 : 0); j--) { console.log(times, preP, geyi, tempArr[0], i, j, box, 'times,preP,geyi,tempArr[0],i,j,box,右斜') if (boxs.value[i]?.[j]?.place === userPlace) { if (preP === -1 || preP === j + 1 || (preP === j + 2 && !geyi)) { if (preP === j + 2) { if (boxs.value[i - 1][j + 1]?.place === 0) { geyi = true times++ } else { continue } } times++ } else { times = 1 geyi = false } preP = j if (times >= maxTime) { if (times === 3 && geyi) { i++ continue } if (boxs.value[i + 1]?.[j - 1]?.place !== 0 && boxs.value[box.x]?.[j - 1].place !== userPlace && boxs.value[i - times]?.[j + times]?.place !== 0) { break } else { tempArr[3] = tempArr[3]?.times > times ? tempArr[3] : { x: i, y: j, type: 4, times, geyi } if (boxs.value[i + 1]?.[j - 1]?.place !== 0 || boxs.value[i - times]?.[j + times]?.place !== 0) { tempArr[3].priority = 2 } else { tempArr[3].priority = 1 } } } } i++ } console.log(tempArr, 'temp') tempArr = tempArr.sort((a, b) => b.times - a.times) if (tempArr[0]?.times >= 3) { if (tempArr[0].priority === 2) { let temp = null tempArr.map((item, index, arr) => { if (item?.times >= arr[0].times) { if (item.priority === 1) { temp = item } } }) if (temp) { return temp } //挡住一边的三个没有必要去阻挡 if (tempArr[0]?.times === 3) { return false } } return tempArr[0] } return false } //验证是否赢了 function validateWin() { if(visible.value) return for (let i = 0; i .mineDlearance { display: flex; justify-content: center; width: 100%; height: 100%; // align-items: center; .game { // background: #ccc; padding: 10px; height: 850px; .top { display: flex; justify-content: space-between; } .game-main { margin-top: 10px; .item-one { width: 40px; height: 40px; border: 1px solid #000; box-sizing: border-box; background: goldenrod; cursor: pointer; .circle { width: 100%; height: 100%; border-radius: 100%; } } } } }
"image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20250108/67b17e94dbc4844548d6ef884ca2ea67.png) 这是一个水塔的svg,需求: 水面跟随进度上升下降 进度低于20时变红色,其余进度变绿色 整体尺寸不是固定的,跟随父布局大小 思路1:目前我的思路是根据进度,切10张水塔图,根据进度动态显示。但这增加包体积,感觉也有点粗暴。 思路2:用两张图上下放置,上面的水塔用clip-path根据进度切,但好像只能且固定大小,因为svg的path好像是固定的 目前没有更好的解决思路,各位大佬怎么看?
网页f12调试如何查看鼠标悬浮时才出现的dom元素
"debounce-version1" (https://link.segmentfault.com/?enc=5M4djQn6RXb97dn5%2FIuSsg%3D%3D.M4IlNX7pUgrfVff4Fyn6tiHAcLHsW1lunvGhImsFK0hElPT8VqDDHU8lYs8DbmtFG8coFyIt9FDu%2BPtPWyqctw%3D%3D) "debounce-version2" (https://link.segmentfault.com/?enc=H7bAur3zI9mr1Gy3yNsiaA%3D%3D.56UgzDeQ8o19EOVC95PM8kK68vn3zxLJZinmVNEXBWtkm2TQkd1DSp04CJ5ZeBZ52w0mTGJF44Y%2B%2FkLmrmlsog%3D%3D) version1 跟 version2的区别是移动了" if (notCalled && immediate) result = func.apply(context, args);" 的位置 我的预期是这两个代码应该执行结果是一致的,都返回1 但是version1 没有防抖成功 function debounce(func, wait, immediate) { var timeout var debounced = function () { var context = this; var args = arguments; var notCalled = !timeout; if (timeout) clearTimeout(timeout); if (notCalled && immediate) result = func.apply(context, args); timeout = setTimeout(function () { if (!immediate) func.apply(context, args); timeout = null; }, wait); }; return debounced; } var counter = 0; var debouncedIncr = debounce( function () { counter++; if (counter < 10) debouncedIncr(); }, 32, true, ); debouncedIncr(); console.log(counter, 1, "incr was called immediately"); setTimeout(function () { console.log(counter, 1, "incr was debounced"); }, 96);