環境:Mac、Atom
ProgateのjQueryにて下記のコードでアコーディオンを作成しました。
(※これは、自分で1から作成したコードではなく、Progateで用意されていたものを使用)
※質問は下にあります。
HTML/CSS/jQueryのコード
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery練習</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<div class="faq-wrapper">
<div class="heading">
<h2>FAQ</h2>
</div>
<div class="faq">
<ul id="faq-list">
<li class="faq-list-item">
<h3 class="question">質問質問質問質問質問質問</h3>
<span>+</span>
<div class="answer">
<p>回答回答回答回答回答回答</p>
</div>
</li>
<li class="faq-list-item">
<h3 class="question">質問質問質問質問質問質問</h3>
<span>+</span>
<div class="answer">
<p>回答回答回答回答回答回答</p>
</div>
</li>
<li class="faq-list-item">
<h3 class="question">質問質問質問質問質問質問</h3>
<span>+</span>
<div class="answer">
<p>回答回答回答回答回答回答</p>
</div>
</li>
</ul>
</div>
</div>
<script src="../JavaScript/jquery-3.4.1.min.js"></script>
<script src="../JavaScript/script.js"></script>
</body>
</html>
body {
margin: 0;
}
a {
text-decoration: none;
}
.faq-wrapper {
background-color: #e6ecf0;
text-align: center;
padding-bottom: 80px;
color: #5f5d60;
}
#faq-list {
width: 500px;
margin: 0 auto;
padding: 0;
list-style: none;
}
.faq-list-item {
margin:10px;
border-bottom:1px solid #ccc;
position:relative;
cursor:pointer;
text-align: left;
}
.faq-list-item h3 {
font-size: 14px;
}
.faq-list-item span {
position:absolute;
top:0;
right:5px;
color:#ccc;
font-size:13px;
}
.answer {
font-size: 12px;
padding: 5px 0px;
margin-bottom: 15px;
display: none;
}
/*↑displayはnoneに */
$(function() {
$('.faq-list-item').click(function() {
var $answer = $(this).find('.answer');
if ($answer.hasClass('open')) {
$answer.removeClass('open');
$answer.slideUp();
$(this).find("span").text("+");
} else {
$answer.addClass('open');
$answer.slideDown();
$(this).find("span").text("-");
}
});
});
質問 2つあります。
質問タイトルが的確ではないかも知れませんが、短文で記載する上で的確な文章が思い当たらなかった為。
①
このjQueryコードが表している意味を、文章で書くとしたら何と表現しますか?
このような意味であっていますか?(論理的に頭に入れた方が、理解しやすい為)
違う場合は訂正願います。↓
「.faq-list-itemセレクタをクリックした際の話。
まず、$answerには、クリックした際にそのクリックイベントが起こった要素で、その子要素の.answerを代入。
もし、$answerにopenと言うクラスが入っていた場合、
$answerからopenクラスを取り除き、$answerをslideUpして隠し、
クリックされた要素の中のspan要素のテキストを + に変更する。
もし、$answerにopenと言うクラスが入っていない場合、
$answerには、openクラスを付与し、$answerをslideDownで表示し、
クリックされた要素の中のspan要素のテキストを - に変更する。」
②
ここで出てくる、 open は一体何者なんですか?
removeClassやaddClassがある事からも、クラスと言う事はわかりますが、
cssにはそのopenセレクタは記載どこにもありません。
試しにopenを適当な文字に置き換えても出来たと言う事からも、jQueryで完結していると思うのですが。
この open は具体的に「何」でどう作用しているのでしょうか?
何故、open クラスがついた要素はもともとhtmlには存在しないのに、
jqueryの if文では、「もしopenが合った場合、もしopenがなかった場合」というコードなるのですか?
elseの「もしない場合」は、 open クラスを付与するとの命令ですが、
openクラスつけたところで、cssでopenセレクタで指定しているわけでもないので、
何がどう変わるか理解出来ない状況です。
上記2点、宜しくお願いします。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
- メールアドレスの認証
メールアドレスの認証
- 質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+4
直接的な回答をしない理由
まず、「$answer.addClass('open')
が何のためにあるのか」を一から十まで筋道立てて説明する事は可能です。
しかし、そうした場合、質問者さんは回答にある考えの流れをなぞって答えを出すことになり、「自分の頭で真に理解した」とはいえないだろうと考えています。
「自分の頭で真に理解した」というのは、回答にある文章を全て忘れて、一から自分の言葉で全てを説明できる状態の事です。
これが出来る人は、回答で構成されている中核となる要素を分解して自分の頭で考えを再構築し、自分の言葉で説明しなおすという作業をしています。
経験上、そういう方の質問は「このコードはこういう動きをしており、こうなるはずなのですが、なぜかこうなってしまいます」のように自分の考えを添えながら、「自分の考えから想定される結果」と「事実上の結果」に相違がある部分を質問します。
「わからない部分」がより明確で具体的です。
残念ながら、質問者さんはそうした質問ではない為、一から十まで説明するのはかえって理解から遠ざかると考えています。
ヒント
というわけで、考え方のヒントだけを出します。
- 1回目のクリック時の動きはどうなっているか
- 2回目のクリック時の動きはどうなっているか
- 1回目/2回目の動きが異なる場合、どうやってその違いを認識しているか
基本的にはコードの動きをなぞるだけではダメで、設計者の気持ちになって、「この機能をどうやって実装しようか」という観点に立つのが重要と思います。
車輪の再発明
「設計者の気持ちになってみる」という観点では、一から自分で作り直してみるのも有効です。
一般に車輪の再発明はプログラミングでは敬遠される行為ですが、再発明する事で原理をよく理解できるようになります。
※余談ですが、「もっと良い実装があるのに…」と思ってしまう問題なので、別の実装法を考えてみるのも面白いと思います。
おそらく、Progate出題者はjQuery APIを熟知していません(APIを知っていれば、jQueryを使用していながら、独自コードに頼らない部分があります)。
Re: muchitaro さん
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+2
①
論理的・・・で言うとコードをそのまま文章化しただけのものはあまり有用とは言えません。
大目的部分がどうなっているか→それを実現するための処理 と考えた方が良いでしょう。
同じ目的のことを実現するやり方は1つではないという観点から、「合ってるか」という質問であればここはお答えしかねます。
むしろ「同じ目的を別のやり方で実現するとしたらどうなるか」を考えた方がロジカルと言えるでしょう。
②
CSSにないからとそのクラス名をつけられないわけではないので「何者か」と言うと
「付け外しされているだけのクラス」としか表現しようがないと思います。
何のためか?というと今回提示された内容だけでは判断が不可能です。
オンライン学習使ったことはないですが章立てで進んでいるものなんでしょうし
今後何かで使う機会もあるかもしれませんね。
ほぼほぼ同じようなところをやっていそうな質問があるので参考にされてみてはと。
投稿
- ユーザーランキング月間1位
- Laravel総合1位
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
ここで出てくる、 open は一体何者なんですか?
openしてるかどうかの判断に使いたかっただけだから、$answer.attrで取得しても良いし、addClassじゃなくてattrやdataを使っても良い
hasClassって書いてあるのが読みやすい(と思ったから)使ってるんだろうけど、勉強する立場からしたらattrとかで書いてくれてる方が理解しやすいだろうと思う
投稿
score 490
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
おす、おら、goku。
おめぇは「なんでopenクラスを付けたり外したりしてるのか全くわかんねぇぞ」って言ってるみてぇだが、
それは、すげぇ簡単な事だぞ。
openクラスはプログラミングで昔から使われている「フラグ」の代わりだぞ。
例えば、アコーディオンが1つだけだったとするだろ?
その場合は、すっげぇ簡単に書くとこうなる。
$(function()
{
var answer_opened = false; // ←アコーディオン開閉フラグ
$('.faq-list-item').click(function()
{
var $answer = $(this).find('.answer');
if (answer_opened === true) // アコーディオンが開いていたら
{
$answer.slideUp(); // アコーディオンを閉じて
$(this).find("span").text("+");
answer_opened = false; // 開閉フラグを下げる
}
else // 開いて無かったら
{
$answer.slideDown(); // アコーディオンを開いて
$(this).find("span").text("-");
answer_opened = true; // フラグを立てる
}
});
});
だけんど、アコーディオンは沢山あんだろ? そしたらおめぇ、開閉フラグはその数だけ作んなくちゃ行けねぇ。
管理も大変になってくる。おら、そんなめんどくせぇ事はしたくねぇ。
だからな、フラグをDOM要素そのものに埋め込んじまおうってのが、その「open」だ。
openクラスが無いアコーディオンは閉じているアコーディオンだから、クリックされたら開く動作をさせる、
openクラスがあるアコーディオンは開いているアコーディオンだから、クリックされたら閉じる動作をさせるってぇわけだ。おもしれぇだろ? おら、わっくわくすっぞ。
質問のサンプルは結構めぇから使われてるやり方だが
最近はclassに埋め込むよりも、HTML5で実装されたカスタムデータ属性を使って
$(selector).attr("data-opened", true);
ってやった方がいいと思うぞ。
ただ、openってクラス名はダメだと思うぞ。既に開いている状態を示すフラグなんだから、過去形にしねぇとな。
Progate の奴らはまともな命名も出来ねぇらしいな。修行が足んねぇぞ。
おらの説明はこんな感じだ。chi-chiが晩飯のオカズ狩って来いってうるせぇからそろそろで行ってくっぞ。
おめぇももっと修行して天下一武道会でおらと握手だ。
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
check解決した方法
-4
他の質問サイトでの回答が一番わかりやすかった為、一応自己解決とします。
ちなみにその回答が下記です↓ (こう言う回答が欲しかった)
アコーディオンメニューのコーディングに関して、回答します。
①は、概ね合っています。
var $answer = $(this).find('.answer');
>$answerには、クリックした際にそのクリックイベントが起こった要素で、
その子要素の.answerを代入。
変数「 $answer」は、
「faq-list-item」クラス属性が付いた要素の配下における
「answer」クラス属性のHTMLコレクションです。
②の「 open は一体何者なんですか?」
また、
「この open は具体的に「何」でどう作用しているのでしょうか?」
について
テクニカルタームとしては、「フラグを立てる」という作業です。
具体的に言い換えると、
マラソンで折り返し地点に到達した時に、
「このランナーはここまで来たんだ」ということで、
マジックペンで手に色を付けられます。
何かの目印を付けないと、
折り返し地点に到達していないのに
引き返されても、まったくわかりませんからね。
それと同様のことをしている訳です。
HTMLのタグには、いろいろな属性が付けられます。
このアコーディオンメニューの場合は、
質問という「question」クラスの付いたH3タグをクリックしたら、
・その直下のSPANタグ内の記号を変える
・かつ、「answer」クラスの付いたDIVタグの表示属性を変える
そういう処理をしている訳ですね。
その際、H3タグのクリック時に、
回答のタグが開いているのか、閉じているのかわかりません。
そこで「open」というクラスを用意しています。
・そのクラス属性が在るなら、閉じる
その時は、「open」クラスを取ってしまう
・そのクラス属性が無いなら、開く。
開けた目印として、
「開けましたよ」という意味付けの「open」クラスを付けておく
そうした処理をしていることになります。
>試しにopenを適当な文字に置き換えても出来た
そうです。どんな文字でもいいんです。
ただ、モノを開けたら「オープン」と言うので、
便宜的に「open」という単語を使っているだけです。
投稿
score -16
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
質問への追記・修正、ベストアンサー選択の依頼
mts10806
2019/06/01 20:16
自身で組まれたコードなのに他人に説明求めるのは如何なものでしょうか。
muchitaro
2019/06/01 20:39
Progateという、web学習教材にあったコードです。
注意書きで、
「※これはProgateと言う学習教材にあったコードで、自分で1から記述したコードではございません。」
と記載すべきでしたか?
①と②の回答を聞きたいのですが、いかがでしょうか。
宜しくお願いします。
mts10806
2019/06/01 20:52
別から持ってきたものであれば出典の明記は必要です。何も記載がなければ主語は投稿者です。
muchitaro
2019/06/01 21:08
なるほど、確かにそうですね。
仮に自分で記述したコードだったとしても、
質問の趣旨からニュアンスを汲み取って頂けると思ってました。
追記しました。
ご回答、宜しくお願いします。
mts10806
2019/06/01 21:21
ちょっと細かいこと言うと、回答者観点では「自身で書いたコードは自分が一番分かっているもの」という前提があります。例えコピペであっても目的を実現するためであれば意味をきちんと理解して持ってこないと使いこなせないので。
コピペ元のコードが理解できないのであれば、「自身のコードに組み込んだコピペコード」よりも「このサイトのこのコード」と提示された方が見やすいです(ただコードの解説依頼って厳密に言うと非推奨質問にあたるので、私も今回ちゃんとは答えてません)