Skip to content

Instantly share code, notes, and snippets.

@kohki-shikata
Created September 21, 2024 10:18
Show Gist options
  • Save kohki-shikata/59c2afaca1ecf6467d3b971647fa3859 to your computer and use it in GitHub Desktop.
Save kohki-shikata/59c2afaca1ecf6467d3b971647fa3859 to your computer and use it in GitHub Desktop.
let isEnabled = false; // フラグを初期化
let selectedElement = null; // 現在選択されている要素を保持
// ページロード時にユニーククラスを適用
document.addEventListener('DOMContentLoaded', () => {
applyUniqueClasses();
toggleSelectionMode(false); // 初期状態で選択モードを無効にする
});
// 選択モードの切り替えボタン
document.getElementById('toggleSelectionMode').addEventListener('click', (event) => {
event.stopPropagation();
isEnabled = !isEnabled;
toggleSelectionMode(isEnabled);
});
// ユニーククラスを全要素に適用
function applyUniqueClasses() {
const allElements = document.querySelectorAll('*:not(#toggleSelectionMode)');
allElements.forEach((el, index) => {
const uniqueClass = `unique-element-${index}-${Date.now()}`;
el.classList.add(uniqueClass);
el.classList.add('border-outline');
el.style.position = 'relative';
el.style.zIndex = 10;
});
}
// 選択モードの切り替え(イベントリスナーの登録・解除のみ)
function toggleSelectionMode(active) {
const allElements = document.querySelectorAll('*:not(#toggleSelectionMode)');
allElements.forEach((el) => {
if (active) {
el.addEventListener('click', handleElementClick);
el.addEventListener('mouseover', handleMouseOver);
el.addEventListener('mouseout', handleMouseOut);
} else {
el.removeEventListener('click', handleElementClick);
el.removeEventListener('mouseover', handleMouseOver);
el.removeEventListener('mouseout', handleMouseOut);
}
});
// モードが無効になったときに選択状態をリセット
if (!active && selectedElement) {
selectedElement.classList.remove('selected-element');
selectedElement = null;
}
}
// クリックした要素の処理
function handleElementClick(event) {
event.stopPropagation();
const element = event.currentTarget;
// 以前選択されていた要素から 'selected-element' クラスを削除
if (selectedElement) {
selectedElement.classList.remove('selected-element');
}
// 現在のクリックされた要素に 'selected-element' クラスを追加
element.classList.add('selected-element');
selectedElement = element;
// CSSセレクターの生成
const cssSelector = getCssSelector(element);
console.log('CSS Selector:', cssSelector);
// XPathの生成
const xpath = getXPath(element);
console.log('XPath:', xpath);
}
// CSSセレクターを生成する関数
function getCssSelector(element) {
if (!(element instanceof Element)) return;
const path = [];
while (element) {
let selector = element.nodeName.toLowerCase();
if (element.classList.length > 0) {
selector += `.${Array.from(element.classList).join('.')}`;
}
path.unshift(selector);
element = element.parentElement;
}
return path.join(' > ');
}
// XPathを生成する関数
function getXPath(element) {
if (!(element instanceof Element)) return;
const path = [];
while (element) {
let selector = element.nodeName.toLowerCase();
if (element.classList.length > 0) {
selector += `[contains(@class,"${Array.from(element.classList).join('") or contains(@class,"')}")]`;
}
path.unshift(selector);
element = element.parentElement;
}
return '/' + path.join('/');
}
// マウスオーバー時の処理
function handleMouseOver(event) {
event.stopPropagation();
event.currentTarget.classList.add('hover-highlight');
}
// マウスアウト時の処理
function handleMouseOut(event) {
event.stopPropagation();
event.currentTarget.classList.remove('hover-highlight');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment