Three.js頂點射線碰撞檢測具體實現(xiàn)步驟詳解
一、基本思路
核心算法流程:
第1步:遍歷幾何體所有頂點,分別創(chuàng)建與幾何體中心坐標構(gòu)成的射線
對于 每個幾何體A 的 每個頂點V:
頂點位置 = V 的世界坐標位置
中心位置 = 幾何體A 的世界坐標中心點
方向向量 = 中心位置 - 頂點位置
創(chuàng)建射線Raycaster:
起點 = 頂點位置
方向 = 方向向量(歸一化)
實現(xiàn)細節(jié):
- 獲取幾何體的頂點坐標數(shù)組(Float32Array,每3個值表示一個頂點的x,y,z坐標)
- 將頂點從局部坐標系轉(zhuǎn)換到世界坐標系
- 計算幾何體的世界中心點(通常是物體位置)
- 對每個頂點創(chuàng)建從頂點指向中心的射線
第2步:射線交叉計算
對于 幾何體A 的 每條射線R:
使用Raycaster的intersectObject()方法:
檢測射線R 是否與 幾何體B 相交
如果相交:
獲取交點信息(交點坐標、距離、面信息等)
關(guān)鍵點:
- Raycaster.intersectObject(幾何體B) 返回交點數(shù)組
- 交點數(shù)組按距離從近到遠排序
- 如果射線與幾何體B有交點,說明這條射線可能穿過了幾何體B
第3步:通過距離判斷兩個網(wǎng)格模型是否碰撞
對于 幾何體A 的 每條射線R 的 每個交點I:
計算:起點到交點的距離 = 距離1
計算:起點到幾何體A中心的距離 = 距離2
如果 距離1 < 距離2:
說明射線在到達自己中心之前就擊中了對方
判斷為"這條射線穿過了對方幾何體"
如果 至少有一條射線穿過對方幾何體:
判斷為"兩個幾何體發(fā)生碰撞"
邏輯解釋:
- 射線是從自己頂點指向自己中心的
- 如果射線在到達自己中心之前就擊中了對方,說明對方在自己"內(nèi)部"或"前方"
- 如果射線先到達自己中心,說明對方在自己"后方"或"外部"
二、具體實現(xiàn)步驟詳解
Step 1: 獲取幾何體所有頂點(世界坐標)
// 1.1 獲取幾何體的頂點位置數(shù)據(jù)
const geometry = mesh.geometry
const positionAttribute = geometry.attributes.position
const positions = positionAttribute.array // [x1, y1, z1, x2, y2, z2, ...]
// 1.2 獲取世界變換矩陣
const matrixWorld = mesh.matrixWorld
// 1.3 遍歷所有頂點,轉(zhuǎn)換為世界坐標
const worldVertices = []
for (let i = 0; i < positions.length; i += 3) {
// 創(chuàng)建局部坐標頂點
const localVertex = new THREE.Vector3(
positions[i], // x
positions[i + 1], // y
positions[i + 2] // z
)
// 轉(zhuǎn)換為世界坐標
const worldVertex = localVertex.clone()
worldVertex.applyMatrix4(matrixWorld)
worldVertices.push(worldVertex)
}
Step 2: 計算幾何體中心點(世界坐標)
// 方法1:直接使用mesh的世界位置(對于對稱幾何體)
const center = new THREE.Vector3()
mesh.getWorldPosition(center)
// 方法2:計算所有頂點的平均值(更精確)
let sum = new THREE.Vector3(0, 0, 0)
for (const vertex of worldVertices) {
sum.add(vertex)
}
const center = sum.divideScalar(worldVertices.length)
Step 3: 創(chuàng)建頂點到中心的射線
// 3.1 創(chuàng)建Raycaster實例
const raycaster = new THREE.Raycaster()
// 3.2 對于每個頂點,創(chuàng)建從頂點指向中心的射線
for (const vertex of worldVertices) {
// 計算方向向量(從頂點指向中心)
const direction = center.clone().sub(vertex).normalize()
// 設(shè)置射線
raycaster.set(vertex, direction)
// 現(xiàn)在raycaster就代表了一條從頂點指向中心的射線
// 我們可以用它來檢測與其他幾何體的交點
}
Step 4: 射線交叉計算
// 4.1 檢測射線是否與另一個幾何體相交
const otherMesh = ... // 另一個幾何體
const intersects = raycaster.intersectObject(otherMesh)
// 4.2 分析交點信息
if (intersects.length > 0) {
const firstIntersect = intersects[0] // 最近的交點
// 交點信息包含:
// - point: 交點坐標(Vector3)
// - distance: 從射線起點到交點的距離
// - object: 被擊中的物體
// - face: 被擊中的面
// - faceIndex: 面的索引
}
Step 5: 通過距離判斷是否碰撞
// 5.1 計算關(guān)鍵距離
const distanceToIntersect = vertex.distanceTo(firstIntersect.point) // 頂點到交點的距離
const distanceToCenter = vertex.distanceTo(center) // 頂點到中心的距離
// 5.2 判斷邏輯
if (distanceToIntersect < distanceToCenter) {
// 情況:射線在到達自己中心之前就擊中了對方
// 說明對方幾何體在自己"前方"或"內(nèi)部"
// 這很可能表示兩個幾何體相交或碰撞
console.log('這條射線穿過了對方幾何體!')
// 記錄碰撞信息
collisions.push({
vertex: vertex,
intersectPoint: firstIntersect.point,
rayDirection: direction
})
} else {
// 情況:射線先到達自己中心,然后才可能擊中對方
// 說明對方幾何體在自己"后方"或"外部"
// 這很可能表示兩個幾何體沒有碰撞
}
Step 6: 綜合判斷碰撞
// 6.1 統(tǒng)計所有穿過的射線
let collisionCount = 0
for (所有頂點射線) {
if (射線穿過了對方幾何體) {
collisionCount++
}
}
// 6.2 判斷是否發(fā)生碰撞
if (collisionCount > 0) {
console.log(`發(fā)生碰撞!共有 ${collisionCount} 條射線穿過對方幾何體`)
return true // 發(fā)生碰撞
} else {
console.log('沒有碰撞')
return false // 沒有碰撞
}
三、數(shù)學原理圖解
情況1:發(fā)生碰撞(射線穿過對方)
頂點
│
│ 距離1(到交點)
│
▼ 交點(在對方幾何體上)
│
│ 距離2(從交點到中心)
│
▼ 中心
距離1 < 距離1+距離2(即距離1 < 頂點到中心的距離)
∴ 射線在到達中心之前擊中了對方 → 碰撞!情況2:沒有碰撞(射線先到中心)
頂點
│
│ 距離1(到中心)
│
▼ 中心
│
│ 距離2(從中心到交點)
│
▼ 交點(在對方幾何體上)
距離1 < 距離1+距離2(但射線要先經(jīng)過中心)
∴ 射線先到達中心,然后才可能擊中對方 → 沒有碰撞!
四、性能優(yōu)化考慮
1. 頂點采樣優(yōu)化
// 不檢測所有頂點,只采樣一部分
const sampleRate = 0.3 // 采樣率30%
for (let i = 0; i < worldVertices.length; i += Math.floor(1/sampleRate)) {
// 只檢測部分頂點
}
2. 分層次檢測
// 第一步:快速檢測(包圍盒)
const box1 = new THREE.Box3().setFromObject(mesh1)
const box2 = new THREE.Box3().setFromObject(mesh2)
if (!box1.intersectsBox(box2)) {
return false // 包圍盒不相交,肯定不碰撞,快速返回
}
// 第二步:精確檢測(頂點射線)
// 只有包圍盒相交時,才進行更耗時的頂點檢測
3. 空間分割優(yōu)化
// 使用八叉樹或BVH(包圍盒層次結(jié)構(gòu))加速 // 只檢測可能相交的幾何體
4. 距離閾值優(yōu)化
// 添加容差閾值
const threshold = 0.01 // 1厘米容差
if (distanceToIntersect < distanceToCenter + threshold) {
// 考慮為碰撞(避免浮點數(shù)精度問題)
}
五、適用場景與限制
適用場景:
- 需要精確碰撞檢測(如物理模擬、游戲碰撞)
- 不規(guī)則幾何體碰撞(非AABB/球體等簡單形狀)
- 需要知道碰撞位置(不僅僅是是否碰撞)
限制:
- 計算量大:頂點越多越慢
- 凹形幾何體問題:射線可能從凹處"穿過"而不碰撞
- 薄物體問題:對于非常薄的幾何體可能漏檢
六、偽代碼總結(jié)
function 頂點射線碰撞檢測(幾何體A, 幾何體B):
// Step 1: 獲取頂點
頂點數(shù)組A = 獲取世界坐標頂點(幾何體A)
頂點數(shù)組B = 獲取世界坐標頂點(幾何體B)
// Step 2: 計算中心
中心A = 計算世界中心(幾何體A)
中心B = 計算世界中心(幾何體B)
// Step 3-4: 檢測A的頂點射線
for 每個頂點V in 頂點數(shù)組A:
方向 = 歸一化(中心A - 頂點V)
射線 = 創(chuàng)建射線(頂點V, 方向)
交點 = 射線.檢測相交(幾何體B)
if 交點存在:
if 距離(頂點V, 交點) < 距離(頂點V, 中心A):
碰撞計數(shù)器++
// Step 3-4: 檢測B的頂點射線
for 每個頂點V in 頂點數(shù)組B:
方向 = 歸一化(中心B - 頂點V)
射線 = 創(chuàng)建射線(頂點V, 方向)
交點 = 射線.檢測相交(幾何體A)
if 交點存在:
if 距離(頂點V, 交點) < 距離(頂點V, 中心B):
碰撞計數(shù)器++
// Step 5: 判斷結(jié)果
if 碰撞計數(shù)器 > 0:
return true // 發(fā)生碰撞
else:
return false // 沒有碰撞
—# Three.js 頂點射線碰撞檢測實現(xiàn)步驟詳解
一、基本思路
核心算法流程:
第1步:遍歷幾何體所有頂點,分別創(chuàng)建與幾何體中心坐標構(gòu)成的射線
對于 每個幾何體A 的 每個頂點V:
頂點位置 = V 的世界坐標位置
中心位置 = 幾何體A 的世界坐標中心點
方向向量 = 中心位置 - 頂點位置
創(chuàng)建射線Raycaster:
起點 = 頂點位置
方向 = 方向向量(歸一化)
實現(xiàn)細節(jié):
- 獲取幾何體的頂點坐標數(shù)組(Float32Array,每3個值表示一個頂點的x,y,z坐標)
- 將頂點從局部坐標系轉(zhuǎn)換到世界坐標系
- 計算幾何體的世界中心點(通常是物體位置)
- 對每個頂點創(chuàng)建從頂點指向中心的射線
第2步:射線交叉計算
對于 幾何體A 的 每條射線R:
使用Raycaster的intersectObject()方法:
檢測射線R 是否與 幾何體B 相交
如果相交:
獲取交點信息(交點坐標、距離、面信息等)
關(guān)鍵點:
- Raycaster.intersectObject(幾何體B) 返回交點數(shù)組
- 交點數(shù)組按距離從近到遠排序
- 如果射線與幾何體B有交點,說明這條射線可能穿過了幾何體B
第3步:通過距離判斷兩個網(wǎng)格模型是否碰撞
對于 幾何體A 的 每條射線R 的 每個交點I:
計算:起點到交點的距離 = 距離1
計算:起點到幾何體A中心的距離 = 距離2
如果 距離1 < 距離2:
說明射線在到達自己中心之前就擊中了對方
判斷為"這條射線穿過了對方幾何體"
如果 至少有一條射線穿過對方幾何體:
判斷為"兩個幾何體發(fā)生碰撞"
邏輯解釋:
- 射線是從自己頂點指向自己中心的
- 如果射線在到達自己中心之前就擊中了對方,說明對方在自己"內(nèi)部"或"前方"
- 如果射線先到達自己中心,說明對方在自己"后方"或"外部"
二、具體實現(xiàn)步驟詳解
Step 1: 獲取幾何體所有頂點(世界坐標)
// 1.1 獲取幾何體的頂點位置數(shù)據(jù)
const geometry = mesh.geometry
const positionAttribute = geometry.attributes.position
const positions = positionAttribute.array // [x1, y1, z1, x2, y2, z2, ...]
// 1.2 獲取世界變換矩陣
const matrixWorld = mesh.matrixWorld
// 1.3 遍歷所有頂點,轉(zhuǎn)換為世界坐標
const worldVertices = []
for (let i = 0; i < positions.length; i += 3) {
// 創(chuàng)建局部坐標頂點
const localVertex = new THREE.Vector3(
positions[i], // x
positions[i + 1], // y
positions[i + 2] // z
)
// 轉(zhuǎn)換為世界坐標
const worldVertex = localVertex.clone()
worldVertex.applyMatrix4(matrixWorld)
worldVertices.push(worldVertex)
}
Step 2: 計算幾何體中心點(世界坐標)
// 方法1:直接使用mesh的世界位置(對于對稱幾何體)
const center = new THREE.Vector3()
mesh.getWorldPosition(center)
// 方法2:計算所有頂點的平均值(更精確)
let sum = new THREE.Vector3(0, 0, 0)
for (const vertex of worldVertices) {
sum.add(vertex)
}
const center = sum.divideScalar(worldVertices.length)
Step 3: 創(chuàng)建頂點到中心的射線
// 3.1 創(chuàng)建Raycaster實例
const raycaster = new THREE.Raycaster()
// 3.2 對于每個頂點,創(chuàng)建從頂點指向中心的射線
for (const vertex of worldVertices) {
// 計算方向向量(從頂點指向中心)
const direction = center.clone().sub(vertex).normalize()
// 設(shè)置射線
raycaster.set(vertex, direction)
// 現(xiàn)在raycaster就代表了一條從頂點指向中心的射線
// 我們可以用它來檢測與其他幾何體的交點
}
Step 4: 射線交叉計算
// 4.1 檢測射線是否與另一個幾何體相交
const otherMesh = ... // 另一個幾何體
const intersects = raycaster.intersectObject(otherMesh)
// 4.2 分析交點信息
if (intersects.length > 0) {
const firstIntersect = intersects[0] // 最近的交點
// 交點信息包含:
// - point: 交點坐標(Vector3)
// - distance: 從射線起點到交點的距離
// - object: 被擊中的物體
// - face: 被擊中的面
// - faceIndex: 面的索引
}
Step 5: 通過距離判斷是否碰撞
// 5.1 計算關(guān)鍵距離
const distanceToIntersect = vertex.distanceTo(firstIntersect.point) // 頂點到交點的距離
const distanceToCenter = vertex.distanceTo(center) // 頂點到中心的距離
// 5.2 判斷邏輯
if (distanceToIntersect < distanceToCenter) {
// 情況:射線在到達自己中心之前就擊中了對方
// 說明對方幾何體在自己"前方"或"內(nèi)部"
// 這很可能表示兩個幾何體相交或碰撞
console.log('這條射線穿過了對方幾何體!')
// 記錄碰撞信息
collisions.push({
vertex: vertex,
intersectPoint: firstIntersect.point,
rayDirection: direction
})
} else {
// 情況:射線先到達自己中心,然后才可能擊中對方
// 說明對方幾何體在自己"后方"或"外部"
// 這很可能表示兩個幾何體沒有碰撞
}
Step 6: 綜合判斷碰撞
// 6.1 統(tǒng)計所有穿過的射線
let collisionCount = 0
for (所有頂點射線) {
if (射線穿過了對方幾何體) {
collisionCount++
}
}
// 6.2 判斷是否發(fā)生碰撞
if (collisionCount > 0) {
console.log(`發(fā)生碰撞!共有 ${collisionCount} 條射線穿過對方幾何體`)
return true // 發(fā)生碰撞
} else {
console.log('沒有碰撞')
return false // 沒有碰撞
}
三、數(shù)學原理圖解
情況1:發(fā)生碰撞(射線穿過對方)
頂點
│
│ 距離1(到交點)
│
▼ 交點(在對方幾何體上)
│
│ 距離2(從交點到中心)
│
▼ 中心
距離1 < 距離1+距離2(即距離1 < 頂點到中心的距離)
∴ 射線在到達中心之前擊中了對方 → 碰撞!情況2:沒有碰撞(射線先到中心)
頂點
│
│ 距離1(到中心)
│
▼ 中心
│
│ 距離2(從中心到交點)
│
▼ 交點(在對方幾何體上)
距離1 < 距離1+距離2(但射線要先經(jīng)過中心)
∴ 射線先到達中心,然后才可能擊中對方 → 沒有碰撞!
四、性能優(yōu)化考慮
1. 頂點采樣優(yōu)化
// 不檢測所有頂點,只采樣一部分
const sampleRate = 0.3 // 采樣率30%
for (let i = 0; i < worldVertices.length; i += Math.floor(1/sampleRate)) {
// 只檢測部分頂點
}
2. 分層次檢測
// 第一步:快速檢測(包圍盒)
const box1 = new THREE.Box3().setFromObject(mesh1)
const box2 = new THREE.Box3().setFromObject(mesh2)
if (!box1.intersectsBox(box2)) {
return false // 包圍盒不相交,肯定不碰撞,快速返回
}
// 第二步:精確檢測(頂點射線)
// 只有包圍盒相交時,才進行更耗時的頂點檢測
3. 空間分割優(yōu)化
// 使用八叉樹或BVH(包圍盒層次結(jié)構(gòu))加速 // 只檢測可能相交的幾何體
4. 距離閾值優(yōu)化
// 添加容差閾值
const threshold = 0.01 // 1厘米容差
if (distanceToIntersect < distanceToCenter + threshold) {
// 考慮為碰撞(避免浮點數(shù)精度問題)
}
五、適用場景與限制
適用場景:
- 需要精確碰撞檢測(如物理模擬、游戲碰撞)
- 不規(guī)則幾何體碰撞(非AABB/球體等簡單形狀)
- 需要知道碰撞位置(不僅僅是是否碰撞)
限制:
- 計算量大:頂點越多越慢
- 凹形幾何體問題:射線可能從凹處"穿過"而不碰撞
- 薄物體問題:對于非常薄的幾何體可能漏檢
六、偽代碼總結(jié)
function 頂點射線碰撞檢測(幾何體A, 幾何體B):
// Step 1: 獲取頂點
頂點數(shù)組A = 獲取世界坐標頂點(幾何體A)
頂點數(shù)組B = 獲取世界坐標頂點(幾何體B)
// Step 2: 計算中心
中心A = 計算世界中心(幾何體A)
中心B = 計算世界中心(幾何體B)
// Step 3-4: 檢測A的頂點射線
for 每個頂點V in 頂點數(shù)組A:
方向 = 歸一化(中心A - 頂點V)
射線 = 創(chuàng)建射線(頂點V, 方向)
交點 = 射線.檢測相交(幾何體B)
if 交點存在:
if 距離(頂點V, 交點) < 距離(頂點V, 中心A):
碰撞計數(shù)器++
// Step 3-4: 檢測B的頂點射線
for 每個頂點V in 頂點數(shù)組B:
方向 = 歸一化(中心B - 頂點V)
射線 = 創(chuàng)建射線(頂點V, 方向)
交點 = 射線.檢測相交(幾何體A)
if 交點存在:
if 距離(頂點V, 交點) < 距離(頂點V, 中心B):
碰撞計數(shù)器++
// Step 5: 判斷結(jié)果
if 碰撞計數(shù)器 > 0:
return true // 發(fā)生碰撞
else:
return false // 沒有碰撞
這個算法的主要思想是:如果一個幾何體的頂點發(fā)出的、指向自己中心的射線,在到達中心之前就擊中了另一個幾何體,那么這兩個幾何體很可能發(fā)生了碰撞或相交。
這個算法的主要思想是:如果一個幾何體的頂點發(fā)出的、指向自己中心的射線,在到達中心之前就擊中了另一個幾何體,那么這兩個幾何體很可能發(fā)生了碰撞或相交。
<template>
<div ref="containerRef"></div>
</template>
<script setup>
import { onMounted, ref } from 'vue'
import * as THREE from 'three'
const containerRef = ref(null)
let cube1, cube2
onMounted(() => {
const scene = new THREE.Scene()
scene.background = new THREE.Color(0x111111)
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.set(0, 5, 10)
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
containerRef.value.appendChild(renderer.domElement)
// 創(chuàng)建立方體1(可移動)
cube1 = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true })
)
cube1.position.set(-3, 0, 0)
scene.add(cube1)
// 創(chuàng)建立方體2(靜止)
cube2 = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshBasicMaterial({ color: 0x0000ff, wireframe: true })
)
cube2.position.set(0, 0, 0)
scene.add(cube2)
// 輔助線
scene.add(new THREE.AxesHelper(5))
// 核心算法:頂點射線碰撞檢測
const checkVertexRayCollision = () => {
console.log('=== 頂點射線碰撞檢測 ===')
// 1. 獲取頂點(世界坐標)
const getVertices = (mesh) => {
const geometry = mesh.geometry
const positions = geometry.attributes.position.array
const vertices = []
const matrixWorld = mesh.matrixWorld
for (let i = 0; i < positions.length; i += 3) {
const vertex = new THREE.Vector3(
positions[i],
positions[i + 1],
positions[i + 2]
)
vertex.applyMatrix4(matrixWorld)
vertices.push(vertex)
}
return vertices
}
const vertices1 = getVertices(cube1)
const vertices2 = getVertices(cube2)
// 2. 獲取中心點(世界坐標)
const center1 = new THREE.Vector3()
cube1.getWorldPosition(center1)
const center2 = new THREE.Vector3()
cube2.getWorldPosition(center2)
console.log('立方體1頂點數(shù):', vertices1.length)
console.log('立方體2頂點數(shù):', vertices2.length)
console.log('立方體1中心:', center1)
console.log('立方體2中心:', center2)
// 3. 檢測立方體1的頂點射線
let collisionCount = 0
for (let i = 0; i < vertices1.length; i++) {
const vertex = vertices1[i]
const direction = new THREE.Vector3().subVectors(center1, vertex).normalize()
const raycaster = new THREE.Raycaster()
raycaster.set(vertex, direction)
const intersects = raycaster.intersectObject(cube2)
if (intersects.length > 0) {
const intersect = intersects[0]
const distanceToHit = vertex.distanceTo(intersect.point)
const distanceToCenter = vertex.distanceTo(center1)
if (distanceToHit < distanceToCenter) {
collisionCount++
console.log(`立方體1頂點${i}: 射線穿過了立方體2`)
}
}
}
// 4. 檢測立方體2的頂點射線
for (let i = 0; i < vertices2.length; i++) {
const vertex = vertices2[i]
const direction = new THREE.Vector3().subVectors(center2, vertex).normalize()
const raycaster = new THREE.Raycaster()
raycaster.set(vertex, direction)
const intersects = raycaster.intersectObject(cube1)
if (intersects.length > 0) {
const intersect = intersects[0]
const distanceToHit = vertex.distanceTo(intersect.point)
const distanceToCenter = vertex.distanceTo(center2)
if (distanceToHit < distanceToCenter) {
collisionCount++
console.log(`立方體2頂點${i}: 射線穿過了立方體1`)
}
}
}
// 5. 判斷結(jié)果
if (collisionCount > 0) {
console.log(`?? 發(fā)生碰撞!共有 ${collisionCount} 條射線相交`)
cube1.material.color.set(0xff00ff)
cube2.material.color.set(0xff00ff)
return true
} else {
console.log('? 沒有碰撞')
cube1.material.color.set(0xff0000)
cube2.material.color.set(0x0000ff)
return false
}
}
// 自動移動并檢測
let direction = 1
const animate = () => {
requestAnimationFrame(animate)
// 移動立方體1
cube1.position.x += 0.01 * direction
// 邊界檢測
if (cube1.position.x > 2) direction = -1
if (cube1.position.x < -4) direction = 1
// 每10幀檢測一次
if (Math.floor(cube1.position.x * 10) % 10 === 0) {
checkVertexRayCollision()
}
renderer.render(scene, camera)
}
animate()
})
</script>
<style scoped>
div {
width: 100vw;
height: 100vh;
}
</style>
總結(jié)
到此這篇關(guān)于Three.js頂點射線碰撞檢測具體實現(xiàn)步驟的文章就介紹到這了,更多相關(guān)Three.js頂點射線碰撞檢測內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript?Object.defineProperty與proxy代理模式的使用詳細分析
這篇文章主要介紹了JavaScript?Object.defineProperty與proxy代理模式的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧2022-10-10
JS+DIV+CSS排版布局實現(xiàn)美觀的選項卡效果
這篇文章主要介紹了JS+DIV+CSS排版布局實現(xiàn)美觀的選項卡效果,通過簡單的div+css布局結(jié)合JavaScript切換頁面樣式實現(xiàn)美觀的選項卡效果,具有一定參考借鑒價值,需要的朋友可以參考下2015-10-10
談?wù)凧avaScript數(shù)組常用方法總結(jié)
本篇文章主要介紹了談?wù)凧avaScript數(shù)組常用方法總結(jié),在JavaScript中,我們需要時常對數(shù)組進行操作。一起跟隨小編過來看看吧2017-01-01
JavaScript中URL.createObjectURL和Blob實現(xiàn)保存文件
本文介紹了利用JavaScript中的Blob對象和URL.createObjectURL方法在瀏覽器端創(chuàng)建文件并實現(xiàn)下載功能,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧2025-07-07
Layui 設(shè)置select下拉框自動選中某項的方法
今天小編就為大家分享一篇Layui 設(shè)置select下拉框自動選中某項的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08
typescript中type和interface的區(qū)別有哪些
大家使用typescript總會使用到interface和type,所以下面這篇文章主要給大家介紹了關(guān)于typescript中type和interface區(qū)別的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-02-02

