質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

1回答

1157閲覧

APIから取得したタイトルに、対応したURLを紐付けて、クリックしたらページ遷移するようにしたい

imm

総合スコア18

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

1クリップ

投稿2021/06/27 04:17

編集2021/06/27 13:35

初歩的な質問であったり、わかりづらい部分があればすみません。

【目標】
青空文庫から、書き出しと作品URLを取得して、
・書き出しをランダムな位置に表示
・書き出しをクリックすればその作品ページにとぶ

というものを制作しています。

【現状】
現在、
・書き出しをランダムな位置に表示
まではできています。

【問題】
・書き出しをクリックすれば作品ページにとぶ
部分について、
書き出しとURLを対応させることができていません。
(現状、どの書き出しをクリックしても、表示された最新の作品ページにとんでしまいます。)

新しく文章が出現するたびに、「その作品ページのURLにとんでね」と「全ての」文章に指示を出してしまっているなというところまではなんとなくわかるのですが、それをどのように解決すれば良いか見当がついておらず、
その解決法にピンとくる方がいらっしゃいましたらご教授をお願いしたく思っております。

下記にコードを添付します。
何卒よろしくお願いいたします。

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>雨降りと文学</title> 8 <link rel="stylesheet" href=style.css> 9 10</head> 11<body> 12 13 <script type="application/javascript" src="index.js"></script> 14 15</body> 16 17</html>

css

1:root { 2 --animationTime: 15000ms; 3 background-color: rgb(255, 255, 255); 4} 5 6body { 7 margin: 0; 8 padding: 0; 9 overflow: hidden; 10} 11 12 13.sentence { 14 color: rgb(0, 0, 0); 15 position: absolute; 16 font-family: "游教科書体","游明朝体",serif; 17 writing-mode: vertical-rl; 18 -ms-writing-mode: tb-rl; 19 /* white-space: nowrap; 改行しない */ 20 font-size: 1em; 21 animation: fade var(--animationTime) forwards linear; 22} 23 24@keyframes fade { 25 from { 26 opacity: 0; 27 } 28 15% { 29 opacity: 1; 30 } 31 25% { 32 opacity: 1; 33 } 34 50% { 35 opacity: 1; 36 } 37 75% { 38 opacity: 1; 39 } 40 85% { 41 opacity: 0.5; 42 } 43 to { 44 opacity: 0; 45 } 46}

JavaScript

1const bookTypesNum = 500; 2const animationTime = 15000; // cssのanimationTimeと一致させる! 3const fetchWeatherInfoInterval = 3600000; 4const maxRainfall = 88.7; 5let url; 6 7let interval; 8const leftPositions = []; 9 10setSentenceByWeatherInfo(); 11setInterval(setSentenceByWeatherInfo, fetchWeatherInfoInterval); 12 13function setSentenceByWeatherInfo() { 14 if (interval) { 15 clearInterval(interval); 16 } 17 18 19 let appearanceRate = 4000; 20 21 console.log(appearanceRate); 22 interval = setInterval(createSentence, appearanceRate); 23 return; 24 25 interval = setInterval(createSentence, appearanceRate); 26 ; 27 } 28 29 30 async function getSentence() { 31 let id = Math.round(Math.random() * bookTypesNum) + 3; 32 let res = await fetch(`https://api.bungomail.com/v0/books/${id}`); 33 let json = await res.json(); 34 35 while ( 36 !("書き出し" in json.book) && 37 !("作品名" in json.book) && 38 !("XHTML/HTMLファイルURL" in json.book) && 39 !("作品ID" in json.book) && 40 json.book["書き出し"] !== "" 41 ) { 42 id = Math.round(Math.random() * bookTypesNum) + 3; 43 res = await fetch(`https://api.bungomail.com/v0/books/${id}`); 44 json = await res.json(); 45 } 46 return json; 47 } 48 49 50function isOverlapSentence(left) { 51 for (let i = 0; i < leftPositions.length; i++) { 52 if (leftPositions[i] - 8.0 < left && left < leftPositions[i] + 8.0) { 53 return true; 54 } 55 } 56 return false; 57 } 58 59 function createSentenceElement(sentence) { 60 const top = (Math.random() * 60).toFixed(2) + "%"; 61 let left = Math.random() * 95; 62 63 if (leftPositions) { 64 while (isOverlapSentence(left)) { 65 left = Math.random() * 95; 66 } 67 } 68 leftPositions.push(left); 69 70 71 let div = document.createElement("div"); 72 div.setAttribute("class", "water"); 73 document.body.appendChild(div); 74 div.style.left = left.toFixed(2) + "%"; 75 div.style.top = top; 76 77 78 79 let h2 = document.createElement("h2"); 80 h2.setAttribute("class", "sentence"); 81 82 document.body.appendChild(h2); 83 h2.innerHTML = sentence; 84 h2.style.left = left.toFixed(2) + "%"; 85 h2.style.top = top; 86 87 88 89 90 91 setTimeout(function () { 92 document.body.removeChild(div); 93 document.body.removeChild(h2); 94 leftPositions.splice(leftPositions.indexOf(left), 1); 95 }, animationTime); 96 97 } 98 99 100 101 102 function createSentence() { 103 getSentence().then((res) => { 104 105 let sentence = res.book["書き出し"] + "――『" + res.book["作品名"]+ "』"+res.book["作品ID"]; 106 url = res.book["XHTML/HTMLファイルURL"]; 107 //jgid = res.book["作品ID"]; 108 //console.log(url) 109 110 111 112 document.body.addEventListener("click" ,function() { 113 114 window.open(url, '_blank'); 115 116 }); 117 118 119 createSentenceElement(sentence); 120 121 122 123 }); 124 125 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

neonemo

2021/06/27 12:54

掲載されているJavaScriptのコードのインデントが狂っているので、見落としが無いかどうかヒヤヒヤしながら読んでいました。 動作するコードを貼っていただけるのはありがたいのですが、質問は編集で直せますので綺麗にしていただけますか?
neonemo

2021/06/28 00:34 編集

一部修正して頂けたようでありがとうございます。 しかし、まだまだ残っています。 手動で直しているとお見受けするので、私の場合について回答に追記しましたのでもしよかったらご覧くださいませ。 とはいえ、今回は面白い動きをするプログラムを見られたので楽しかったです。今後も頑張ってください。
guest

回答1

0

ベストアンサー

ちゃんとソースを追えた訳じゃないんですが、当たりが付いたので書きます。

現状確認

現状、どの書き出しをクリックしても、表示された最新の作品ページにとんでしまいます。

について私の解釈を書いてみます

問題と思う箇所

js

1function createSentence() { 2 getSentence().then((res) => { 3 4 let sentence = res.book["書き出し"] + "――『" + res.book["作品名"]+ "』"+res.book["作品ID"]; 5 url = res.book["XHTML/HTMLファイルURL"]; // 気になる箇所(1) 6 jgid = res.book["作品ID"]; 7 //console.log(url) 8 9 document.body.addEventListener("click" ,function() { 10 window.open(url, '_blank'); // 気になる箇所(2) 11 }); 12 13 createSentenceElement(sentence); 14 //this.onclick = window.open(url, '_blank'); 15 }); 16}

気になる箇所(1)(2)について

(1)でurlを作って、(2)で青空文庫のサイトに飛ぶ訳ですが
bodyに対してイベントハンドラを仕掛けているので、常に最新の一か所にジャンプするようになります。

対策案

方針

クリックイベントの仕掛け先は、bodyではなく、createSentenceElement()の関数内でタグを作っている箇所に対して行った方が良いでしょう。
h2タグを作ったら、そこにクリックイベントを仕掛ける訳です。

具体的な方法

  • createSentence()内での、bodyに対するクリックイベントハンドラ設置を削除する
  • さらに、createSentenceElement(sentence, url);のようにタグ作成時にurlが使えるように引数で渡す
  • createSentenceElement()内で、h2タグを作成と同時にタグに対してクリックイベントハンドラを設置する

ちなみに手元での動作確認は出来ています。
頑張ってください。

以上です。

追記。インデントについて

おそらく手動で直されたのかと思うのですが、漏れがあります。
こういったものはツールを使った方が良いので私がWeb系の言語を扱う場合の方法を書きます。

使用ツールと拡張機能

Visual Studio Code
https://azure.microsoft.com/ja-jp/products/visual-studio-code/

indent-rainbow
https://marketplace.visualstudio.com/items?itemName=oderwat.indent-rainbow
インデントの深さ毎に色を付けてくれる拡張機能

Bracket Pair Colorizer
https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer
カッコのスコープを可視化してくれる拡張機能

一括修正方法

1. 初期状態

イメージ説明

2. 右クリックメニュー⇒ドキュメントのフォーマット を実施

イメージ説明

3. 修正後

イメージ説明

修正自体はVisual Studio Codeのみで出来ますが、紹介した拡張機能を導入する事で、コーディング中にある程度校正しながら実装しやすくなります。

また、インデントやシンタックスハイライトなどは統合開発環境(IDE)と言われるツールであれば大抵搭載されています。
もし、現在ただのテキストエディタを使っている様でしたら乗り換えに一考の余地があると思います。

添削

一部添削した結果を貼っておきます。仕事だと動けばいいと思っているレビュア以外ならこういうの気にするかなと思います。
(自分だけかな…)

イメージ説明

以上です。

投稿2021/06/27 12:52

編集2021/06/28 00:28
neonemo

総合スコア191

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

imm

2021/06/27 13:04

大変親切に教えていただきありがたいです。 試してみます。ありがとうございます!
imm

2021/06/27 13:55

いただいた回答を参考に無事解決することができました! ありがとうございました。
imm

2021/06/28 01:59

インデントについての追記、勉強になります。非常にありがたいです。 感激しております。 参考にさせていただきます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問