💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、豆包、星火、月之暗面及文生图、文生视频 广告
# DOM操作模块 DOM操作模块提供浏览器环境下的DOM元素操作工具,包括透明度设置、图片处理等功能。 ## 引用方式 ### ES6 模块引用 ```javascript import sinma from 'sinmajs'; // 或者使用解构赋值 import { setOpacity, imageToBase64 } from 'sinmajs'; ``` ### CommonJS 引用 ```javascript const sinma = require('sinmajs'); ``` ### 浏览器直接引用 ```html <script src="https://unpkg.com/sinmajs@latest/dist/sinma.min.js"></script> <script> // 直接使用 sinma 对象 const element = document.getElementById('myDiv'); sinma.setOpacity(element, 0.5); </script> ``` ## API 列表 ### setOpacity(element, opacity) - 设置元素透明度 设置DOM元素的透明度,兼容IE浏览器和现代浏览器。 #### 参数 - `element` {HTMLElement} - DOM元素对象 - `opacity` {number} - 透明度值,范围 0-1(0完全透明,1完全不透明) #### 返回值 - {void} - 无返回值 #### 功能代码 ```javascript function setOpacity(element, opacity) { if (!element) return; element.style.opacity = opacity; element.style.filter = `alpha(opacity=${opacity * 100})`; } ``` #### 使用方法 ```javascript const element = document.getElementById('myDiv'); sinma.setOpacity(element, 0.5); // 设置为50%透明度 sinma.setOpacity(element, 0); // 完全透明 sinma.setOpacity(element, 1); // 完全不透明 sinma.setOpacity(element, 0.8); // 80%不透明度 ``` #### 使用范例 ```javascript // 渐变显示效果 function fadeIn(element, duration = 1000) { let opacity = 0; const increment = 1 / (duration / 16); // 约60fps sinma.setOpacity(element, 0); element.style.display = 'block'; const timer = setInterval(() => { opacity += increment; if (opacity >= 1) { opacity = 1; clearInterval(timer); } sinma.setOpacity(element, opacity); }, 16); } // 渐变隐藏效果 function fadeOut(element, duration = 1000) { let opacity = 1; const decrement = 1 / (duration / 16); const timer = setInterval(() => { opacity -= decrement; if (opacity <= 0) { opacity = 0; sinma.setOpacity(element, 0); element.style.display = 'none'; clearInterval(timer); } else { sinma.setOpacity(element, opacity); } }, 16); } // 鼠标悬停透明度变化 function setupHoverEffect(element) { element.addEventListener('mouseenter', () => { sinma.setOpacity(element, 0.7); }); element.addEventListener('mouseleave', () => { sinma.setOpacity(element, 1); }); } // 加载状态指示器 function showLoading(element) { sinma.setOpacity(element, 0.3); element.style.pointerEvents = 'none'; } function hideLoading(element) { sinma.setOpacity(element, 1); element.style.pointerEvents = 'auto'; } // 批量设置多个元素透明度 function setMultipleOpacity(selector, opacity) { const elements = document.querySelectorAll(selector); elements.forEach(element => { sinma.setOpacity(element, opacity); }); } // 使用示例 setMultipleOpacity('.gallery-item', 0.8); // 模态框背景遮罩 function createOverlay() { const overlay = document.createElement('div'); overlay.style.position = 'fixed'; overlay.style.top = '0'; overlay.style.left = '0'; overlay.style.width = '100%'; overlay.style.height = '100%'; overlay.style.backgroundColor = 'black'; overlay.style.zIndex = '9999'; sinma.setOpacity(overlay, 0.5); document.body.appendChild(overlay); return overlay; } ``` --- ### imageToBase64(img) - 图片转Base64 将图片元素转换为Base64编码的数据URL字符串。 #### 参数 - `img` {HTMLImageElement} - 图片元素对象 #### 返回值 - {string} - Base64编码的数据URL字符串 #### 功能代码 ```javascript function imageToBase64(img) { const canvas = document.createElement('canvas'); canvas.width = img.width || img.naturalWidth; canvas.height = img.height || img.naturalHeight; const ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0); return canvas.toDataURL(); } ``` #### 使用方法 ```javascript const img = document.getElementById('myImage'); const base64 = sinma.imageToBase64(img); console.log(base64); // "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." // 指定图片格式 const canvas = document.createElement('canvas'); // ... canvas操作 const jpegBase64 = canvas.toDataURL('image/jpeg', 0.8); // JPEG格式,质量80% ``` #### 使用范例 ```javascript // 图片上传预览 function previewImage(file, callback) { const img = new Image(); img.onload = function() { const base64 = sinma.imageToBase64(img); callback(base64); }; img.src = URL.createObjectURL(file); } // 使用示例 const fileInput = document.getElementById('fileInput'); fileInput.addEventListener('change', (e) => { const file = e.target.files[0]; if (file && file.type.startsWith('image/')) { previewImage(file, (base64) => { const preview = document.getElementById('preview'); preview.src = base64; }); } }); // 图片压缩 function compressImage(img, quality = 0.8, maxWidth = 800) { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); // 计算压缩后的尺寸 let { width, height } = img; if (width > maxWidth) { height = (height * maxWidth) / width; width = maxWidth; } canvas.width = width; canvas.height = height; // 绘制压缩后的图片 ctx.drawImage(img, 0, 0, width, height); return canvas.toDataURL('image/jpeg', quality); } // 批量图片转换 function convertImagesToBase64(images) { return Promise.all( Array.from(images).map(img => { return new Promise((resolve) => { if (img.complete) { resolve({ src: img.src, base64: sinma.imageToBase64(img) }); } else { img.onload = () => { resolve({ src: img.src, base64: sinma.imageToBase64(img) }); }; } }); }) ); } // 使用示例 const images = document.querySelectorAll('.gallery img'); convertImagesToBase64(images).then(results => { console.log('所有图片已转换为Base64:', results); }); // 图片水印添加 function addWatermark(img, watermarkText) { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; // 绘制原图 ctx.drawImage(img, 0, 0); // 添加水印 ctx.font = '20px Arial'; ctx.fillStyle = 'rgba(255, 255, 255, 0.8)'; ctx.fillText(watermarkText, 20, canvas.height - 30); return canvas.toDataURL(); } // 图片缓存管理 class ImageCache { constructor() { this.cache = new Map(); } getBase64(imgSrc) { if (this.cache.has(imgSrc)) { return Promise.resolve(this.cache.get(imgSrc)); } return new Promise((resolve, reject) => { const img = new Image(); img.crossOrigin = 'anonymous'; img.onload = () => { const base64 = sinma.imageToBase64(img); this.cache.set(imgSrc, base64); resolve(base64); }; img.onerror = reject; img.src = imgSrc; }); } clear() { this.cache.clear(); } } const imageCache = new ImageCache(); // 图片编辑器基础功能 class SimpleImageEditor { constructor(img) { this.originalImg = img; this.canvas = document.createElement('canvas'); this.ctx = this.canvas.getContext('2d'); this.reset(); } reset() { this.canvas.width = this.originalImg.naturalWidth; this.canvas.height = this.originalImg.naturalHeight; this.ctx.drawImage(this.originalImg, 0, 0); } adjustBrightness(factor) { const imageData = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height); const data = imageData.data; for (let i = 0; i < data.length; i += 4) { data[i] *= factor; // Red data[i + 1] *= factor; // Green data[i + 2] *= factor; // Blue } this.ctx.putImageData(imageData, 0, 0); return this; } toBase64() { return this.canvas.toDataURL(); } } // 使用示例 const img = document.getElementById('editImage'); const editor = new SimpleImageEditor(img); const brightened = editor.adjustBrightness(1.2).toBase64(); ``` ## 高级用法示例 ### 响应式图片加载 ```javascript // 响应式图片Base64转换 function createResponsiveBase64(img, breakpoints = [480, 768, 1024]) { const results = {}; breakpoints.forEach(width => { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); const ratio = img.naturalHeight / img.naturalWidth; const height = width * ratio; canvas.width = width; canvas.height = height; ctx.drawImage(img, 0, 0, width, height); results[`w${width}`] = canvas.toDataURL('image/jpeg', 0.8); }); return results; } ``` ### 图片懒加载与透明度动画 ```javascript // 图片懒加载管理器 class LazyImageLoader { constructor() { this.observer = new IntersectionObserver(this.handleIntersection.bind(this)); } observe(img) { sinma.setOpacity(img, 0); this.observer.observe(img); } handleIntersection(entries) { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; this.loadImage(img); this.observer.unobserve(img); } }); } loadImage(img) { const tempImg = new Image(); tempImg.onload = () => { img.src = tempImg.src; this.fadeIn(img); }; tempImg.src = img.dataset.src; } fadeIn(element) { let opacity = 0; const timer = setInterval(() => { opacity += 0.05; if (opacity >= 1) { opacity = 1; clearInterval(timer); } sinma.setOpacity(element, opacity); }, 16); } } // 使用示例 const lazyLoader = new LazyImageLoader(); document.querySelectorAll('img[data-src]').forEach(img => { lazyLoader.observe(img); }); ``` ### 图片处理工具集 ```javascript // 综合图片处理工具 class ImageProcessor { static toGrayscale(img) { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; ctx.drawImage(img, 0, 0); const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const data = imageData.data; for (let i = 0; i < data.length; i += 4) { const gray = data[i] * 0.299 + data[i + 1] * 0.587 + data[i + 2] * 0.114; data[i] = gray; data[i + 1] = gray; data[i + 2] = gray; } ctx.putImageData(imageData, 0, 0); return canvas.toDataURL(); } static resize(img, newWidth, newHeight) { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = newWidth; canvas.height = newHeight; ctx.drawImage(img, 0, 0, newWidth, newHeight); return canvas.toDataURL(); } static crop(img, x, y, width, height) { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = width; canvas.height = height; ctx.drawImage(img, x, y, width, height, 0, 0, width, height); return canvas.toDataURL(); } } ``` ## 浏览器兼容性 ### setOpacity 兼容性 - **现代浏览器**: 使用 `opacity` CSS属性 - **IE 6-8**: 使用 `filter: alpha(opacity=n)` - **完全兼容**: IE 6+ 及所有现代浏览器 ### imageToBase64 兼容性 - **Canvas支持**: IE 9+ 及所有现代浏览器 - **图片跨域**: 需要设置 `crossOrigin` 属性 - **文件大小**: 受浏览器内存限制 ## 性能优化建议 1. **图片缓存**: 重复转换的图片应该缓存Base64结果 2. **尺寸控制**: 大图片转换前先压缩尺寸 3. **质量平衡**: 根据使用场景选择合适的图片质量 4. **内存管理**: 及时清理不需要的Canvas元素 ## 注意事项 1. **跨域问题**: 图片转Base64时注意跨域限制 2. **内存占用**: Base64编码会增加约33%的数据大小 3. **性能影响**: 大图片处理会消耗较多CPU和内存 4. **浏览器限制**: 某些浏览器对Base64长度有限制 ## 错误处理 ```javascript // 安全的图片转换 function safeImageToBase64(img) { try { if (!img || !img.naturalWidth) { throw new Error('无效的图片元素'); } return sinma.imageToBase64(img); } catch (error) { console.error('图片转换失败:', error); return null; } } // 安全的透明度设置 function safeSetOpacity(element, opacity) { try { if (!element || typeof opacity !== 'number') { throw new Error('无效的参数'); } if (opacity < 0 || opacity > 1) { throw new Error('透明度值必须在0-1之间'); } sinma.setOpacity(element, opacity); } catch (error) { console.error('设置透明度失败:', error); } } ``` ## 相关模块 - [字符串模块](./string.md) - 提供Base64字符串处理功能 - [工具函数模块](./utils.md) - 提供类型检查等辅助功能 - [数字模块](./number.md) - 提供数值计算功能