<!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 |