Chrome扩展开发:如何实现类似Grammarly的文本框随动按钮定位
实现文本框右下角跟随按钮(置于Grammarly左侧)
定位实现思路
要让按钮随文本框移动并固定在右下角,核心是基于文本框的定位父元素做绝对定位:
- 通过
focusin事件获取目标文本框后,找到它最近的非static定位父元素(如果文本框本身是relative/absolute/fixed定位,就以自身为基准)。 - 用
getBoundingClientRect()获取文本框和父元素的视口坐标,计算按钮相对于父元素的bottom和right值,确保按钮贴在文本框右下角。
避免与Grammarly按钮重叠
- 文本框聚焦时,检测页面中Grammarly的按钮(通常类名包含
grammarly-editor-plugin关键词),获取它的宽度。 - 将你的按钮
right值设为「Grammarly按钮宽度 + 8px间隔」,自动排在它左侧;如果没有Grammarly按钮,直接设为8px即可。 - 监听文本框的
resize、scroll事件,实时更新按钮位置,适配文本框尺寸变化或页面滚动。
核心代码示例
document.addEventListener('focusin', (e) => { const target = e.target; // 只处理输入框、文本域和可编辑元素 if (!['INPUT', 'TEXTAREA'].includes(target.tagName) && !target.isContentEditable) return; // 创建或复用按钮元素 let extensionBtn = document.getElementById('my-extension-btn'); if (!extensionBtn) { extensionBtn = document.createElement('button'); extensionBtn.id = 'my-extension-btn'; extensionBtn.textContent = '我的工具'; extensionBtn.style.cssText = ` position: absolute; bottom: 8px; padding: 6px 10px; border: none; border-radius: 4px; background: #2563eb; color: #fff; cursor: pointer; z-index: 9999; font-size: 12px; `; document.body.appendChild(extensionBtn); } // 找到文本框的定位父级 let posParent = target; while (posParent && getComputedStyle(posParent).position === 'static') { posParent = posParent.parentElement; } posParent = posParent || document.body; // 计算按钮位置 const targetRect = target.getBoundingClientRect(); const parentRect = posParent.getBoundingClientRect(); const btnBottom = parentRect.bottom - targetRect.bottom + 8; let btnRight = 8; // 检测Grammarly按钮并调整位置 const grammarlyBtn = document.querySelector('.grammarly-editor-plugin'); if (grammarlyBtn) { const grammarlyRect = grammarlyBtn.getBoundingClientRect(); btnRight += grammarlyRect.width + 8; } // 应用位置样式 extensionBtn.style.bottom = `${btnBottom}px`; extensionBtn.style.right = `${btnRight}px`; extensionBtn.style.display = 'block'; }); // 失去焦点时隐藏按钮(可选) document.addEventListener('focusout', () => { const btn = document.getElementById('my-extension-btn'); if (btn) btn.style.display = 'none'; });
内容的提问来源于stack exchange,提问作者GorvGoyl
相关产品推荐
相关产品推荐

