junkerstock
 tt-test3 

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>画像選択デモ (コピー機能付き)</title>
<style>
/* 全体のスタイル */
body {
font-family: sans-serif;
margin: 20px;
}

/* 画像を並べるコンテナのスタイル */
#image-container {
display: flex; /* 画像を横に並べる */
flex-wrap: wrap; /* 画面幅で折り返す */
gap: 15px; /* 画像間のスペース */
margin-bottom: 20px;
}

/* 各画像とそのタイトルのコンテナ */
.image-item {
text-align: center; /* タイトルを中央揃えに */
cursor: pointer; /* クリックできることを示すカーソル */
border: 2px solid #ccc;
border-radius: 8px;
padding: 10px;
transition: all 0.2s;
}

/* 画像自体のスタイル */
.image-item img {
width: 100px;
height: 100px;
display: block;
margin-bottom: 5px;
}

/* 選択された時のスタイル */
.image-item.selected {
border-color: #007bff; /* 枠線の色を変更 */
background-color: #e7f3ff; /* 背景色を変更 */
}

/* 改行用の要素のスタイル */
.image-newline {
flex-basis: 100%; /* 親要素の幅いっぱいに広がり、次の要素を次の行に送る */
height: 0; /* 高さは不要なので0 */
margin: 0; /* マージンも不要 */
padding: 0; /* パディングも不要 */
}

/* テキストエリアとボタンのコンテナ */
.output-area {
display: flex;
align-items: flex-start; /* 上端揃え */
gap: 10px; /* 要素間のスペース */
}

/* テキストボックスのスタイル */
#output-box {
width: 100%;
padding: 10px;
font-size: 16px;
box-sizing: border-box; /* paddingを含めて幅100%にする */
flex-grow: 1; /* 残りのスペースを埋める */
}

/* コピーボタンのスタイル */
#copy-button {
padding: 10px 15px;
font-size: 16px;
cursor: pointer;
border: 1px solid #007bff;
background-color: #007bff;
color: white;
border-radius: 5px;
transition: background-color 0.2s;
}
#copy-button:hover {
background-color: #0056b3;
}
</style>
</head>
<body>

<h1>画像を選択してください</h1>
<p>クリックで選択/選択解除できます。<br>データ内の `type: 'newline'` で改行されます。</p>

<div id="image-container"></div>

<div class="output-area">
<textarea id="output-box" rows="5" placeholder="選択した画像に関連するテキストがここに表示されます..."></textarea>
<button id="copy-button">コピー</button>
</div>

<script>
// 画像のデータ。ここに `{ type: 'newline' }` を挿入すると、そこで改行されます。
const imageData = [
{ id: 'a1', src: './pic/a1.png', title: 'タイトル A1', text: 'abcde fff' },
{ id: 'a2', src: './pic/a2.png', title: 'タイトル A2', text: 'wqqww eeew qq' },
{ id: 'a3', src: './pic/a3.png', title: 'タイトル A3', text: 'ppp' },
{ type: 'newline' }, // ここで改行されます
{ id: 'b1', src: './pic/b1.png', title: 'タイトル B1', text: 'sample text 1' },
{ id: 'b2', src: './pic/b2.png', title: 'タイトル B2', text: 'hello world' },
{ id: 'b3', src: './pic/b3.png', title: 'タイトル B3', text: 'JavaScript demo' },
{ type: 'newline' }, // ここでも改行されます
{ id: 'c1', src: './pic/c1.png', title: 'タイトル C1', text: 'new line example' },
// さらに画像や改行を追加する場合は、この形式で追記してください
];

// ページが読み込まれたときに実行する処理
document.addEventListener('DOMContentLoaded', () => {
const container = document.getElementById('image-container');
const outputBox = document.getElementById('output-box');
const copyButton = document.getElementById('copy-button'); // ★追加

// 1. データに基づいて画像要素または改行要素をHTMLに生成する
imageData.forEach(data => {
if (data.type === 'newline') {
// 改行用の要素を挿入
const newlineDiv = document.createElement('div');
newlineDiv.classList.add('image-newline');
container.appendChild(newlineDiv);
} else {
// 各画像アイテムの親要素(div)を作成
const itemDiv = document.createElement('div');
itemDiv.classList.add('image-item');
// クリックで使うデータを保存しておく (data-* 属性)
itemDiv.dataset.text = data.text;

// 画像(img)を作成
const img = document.createElement('img');
img.src = data.src;
img.alt = data.title; // 画像が表示されない時代わりに表示されるテキスト

// タイトル(p)を作成
const title = document.createElement('p');
title.textContent = data.title;

// 作成した要素を組み立てる
itemDiv.appendChild(img);
itemDiv.appendChild(title);
container.appendChild(itemDiv);

// 2. 各画像アイテムにクリックイベントを追加する
itemDiv.addEventListener('click', () => {
// 'selected' クラスがあれば削除、なければ追加する (トグル)
itemDiv.classList.toggle('selected');
// テキストボックスを更新する関数を呼び出す
updateTextBox();
});
}
});

// 3. テキストボックスを更新する関数
function updateTextBox() {
// 'selected'クラスが付いている全ての要素を取得
const selectedItems = document.querySelectorAll('.image-item.selected');

// 選択された要素から関連テキストを取り出し、新しい配列を作成
const selectedTexts = Array.from(selectedItems).map(item => item.dataset.text);

// テキストをカンマ区切りで連結し、最後にもカンマを付ける
// 何も選択されていない場合は空文字列にする
outputBox.value = selectedTexts.length > 0 ? selectedTexts.join(',') + ',' : '';
}

// 4. コピーボタンにクリックイベントを追加する ★ここからが追加部分
copyButton.addEventListener('click', () => {
// テキストエリアが空の場合は処理をしない
if (outputBox.value.length === 0) {
alert('コピーするテキストがありません。');
return;
}

// クリップボードにテキストを書き込む
navigator.clipboard.writeText(outputBox.value)
.then(() => {
// 成功したときのフィードバック
const originalText = copyButton.textContent;
copyButton.textContent = 'コピー完了!';
setTimeout(() => {
copyButton.textContent = originalText;
}, 1500); // 1.5秒後にボタンのテキストを元に戻す
})
.catch(err => {
// 失敗した場合の処理
console.error('クリップボードへのコピーに失敗しました: ', err);
alert('コピーに失敗しました。');
});
});
// ★ここまでが追加部分
});
</script>

</body>
</html>


使用変数

alt
charset
class
container
content
copyButton
data
err
id
imageData
img
item
itemDiv
lang
length
name
newlineDiv
originalText
outputBox
placeholder
rows
scale
selectedItems
selectedTexts
src
text
textContent
title
type
updateTextBox -------( Function )
value
width