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

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

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

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

CSS

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

Q&A

解決済

1回答

1639閲覧

【多重構造】14層の<span>

s.k

総合スコア423

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

CSS

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

0グッド

0クリップ

投稿2016/10/31 23:58

編集2016/11/01 00:29

SNS型求人広告サイトを作っていて躓きました。

###前提・実現したいこと
多重<span>構造を取り除き、「もっと読む」機能を実装したい。

###発生している問題・エラーメッセージ

<span>が繰り返し、出力されます。

【該当箇所の出力スタート地点(青い部分)】
イメージ説明

【該当箇所の出力終末地点(青い部分)】
イメージ説明

ブラウザ画面ではこのようになっています。
この多重<span>構造が「もっと読む」機能の実装を妨げているように思われます。

【moreを押す前】
イメージ説明

【moreを押した後】
イメージ説明

本当はこうなってほしい。。。

【moreを押す前】
イメージ説明

【moreを押した後】
イメージ説明

なぜ、<span>が繰り返されるのかがわからないのです。
ちなみにタイムライン上に呼び出される_micropost.html.erbは多重<span>構造のエラーが発生しますが、コメント一覧をみるときにmicropostが呼び出されるshow.html.erbでは正常に作用しています。(moreを押すと隠された文字が表示されます。)

###該当のソースコード

【_micropost.html.erb】

ruby

1<li id="micropost-<%= micropost.id %>"> 2 3 <!-- ユーザーアイコン --> 4 <% if micropost.shop.nil? %> 5 <%= link_to gravatar_for(micropost.user, size: 50), micropost.user %> 6 <% elsif micropost.user.nil? %> 7 <%= link_to gravatar_to(micropost.shop, size: 50), micropost.shop %> 8 <% end %> 9 10 <!-- ユーザー名 --> 11 <% if micropost.shop.nil? %> 12 <!-- User名 --> 13 <span class="user"><%= link_to micropost.user.username, micropost.user %></span> 14 <% elsif micropost.user.nil? %> 15 <!-- Shop名 --> 16 <span class="user"><%= link_to micropost.shop.shopname, micropost.shop %></span> 17 <% end %> 18 19 <!-- User/Shop 共通 --> 20 <span class="content"> 21 <!-- 投稿文 --> 22 <div class="more"> 23 <%= micropost.content %>←ここが問題箇所 24 </div> 25 <!-- 投稿写真 --> 26 <%= image_tag micropost.picture.url if micropost.picture? %> 27 </span> 28 <!-- 投稿時間 --> 29 <span class="timestamp"> 30 Posted <%= time_ago_in_words(micropost.created_at) %> ago. 31 </span> 32 33 34 <% if user_signed_in? %> 35 <!-- 削除リンク User ver--> 36 <% if current_user?(micropost.user) %> 37 <%= link_to "delete", micropost, method: :delete, data: { confirm: "You sure?" } %> 38 <% end %> 39 40 <!-- お気に入り登録リンク user-to-micropost.user--> 41 <% if micropost.shop.nil? %> 42 <% if !current_user?(micropost.user) %> 43 <%= render 'evaluates/evaluate_links', micropost: micropost %> 44 <% end %> 45 46 <% elsif micropost.user.nil? %> 47 <!-- いいね!リンク user-to-micropost.shop --> 48 <% if !current_user?(micropost.user) %> 49 <%= render 'praises/praise_links', micropost: micropost %> 50 <% end %> 51 <% end %> 52 53 54 55 <% elsif shop_signed_in? %> 56 <!-- 削除リンク Shop ver--> 57 <% if current_shop?(micropost.shop) %> 58 <%= link_to "delete", micropost, method: :delete, data: { confirm: "You sure?" } %> 59 <% end %> 60 61 <% if micropost.shop.nil? %> 62 <!-- お気に入り登録リンク shop-to-micropost.user--> 63 <% if !current_shop?(micropost.shop) %> 64 <%= render 'sympathizes/sympathize_links', micropost: micropost %> 65 <% end %> 66 67 <% elsif micropost.user.nil? %> 68 <!-- いいね!リンク shop-to-micropost.shop --> 69 <% if !current_shop?(micropost.shop) %> 70 <%= render 'likes/like_links', micropost: micropost %> 71 <% end %> 72 <% end %> 73 74 75 <% end %> 76 77 <%= link_to 'コメントを見る', micropost_path(micropost.id) %> 78 79</li> 80<script> 81$(document).ready(function() { 82 var showChar = 25; 83 var ellipsestext = "..."; 84 var moretext = "more"; 85 var lesstext = "less"; 86 $('.more').each(function() { 87 var content = $.trim($(this).html()); 88 89 if(content.length > showChar) { 90 91 var c = content.substr(0, showChar); 92 var h = content.substr(showChar, content.length - showChar); 93 94 var html = c + '<span class="moreellipses">' + ellipsestext+ '&nbsp;</span><span class="morecontent"><span>' + h + '</span>&nbsp;&nbsp;<a href="" class="morelink">' + moretext + '</a></span>'; 95 96 $(this).html(html); 97 } 98 99 }); 100 101 $(".morelink").click(function(){ 102 if($(this).hasClass("less")) { 103 $(this).removeClass("less"); 104 $(this).html(moretext); 105 } else { 106 $(this).addClass("less"); 107 $(this).html(lesstext); 108 } 109 $(this).parent().prev().toggle(); 110 $(this).prev().toggle(); 111 return false; 112 }); 113}); 114</script>

【_feed.html.erb】ここのパーシャルはエラーになる

ruby

1<% if @feed_items.any? %> 2 <ol class="microposts"> 3 <%= render @feed_items %> ←ここで_micropost.html.erbを呼び出します。 4 </ol> 5 <%= will_paginate @feed_items %> 6<% end %>

【show.html.erb】→「more」を押すと、隠された文字が表示されます。

ruby

1 <div class="row"> 2 <aside class="col-md-4"> 3 <!-- 投稿 --> 4 <div class="col-md-8"> 5 <%= render @micropost, micropost: @micropost %> ←ここで_micropost.html.erbを呼び出している。 6 </div> 7 8 9 10 11 <!-- コメント --> 12 <div class="col-md-8"> 13 14 <!-- user-to-micropost.user --> 15 16 <% @comments. each do |comment| %> 17 <div> 18 <strong><%= comment.user.username %></strong> 19 </br> 20 <p><%= comment.body %></p> 21 <% if user_signed_in? && comment.user == current_user %> 22 <p><%= link_to 'Delete', comment_path(comment), method: :delete %></p> 23 <% end %> 24 </div> 25 <% end %> 26 27 <!-- user-to-micropost.shop --> 28 29 <% @calls. each do |call| %> 30 <div> 31 <strong><%= call.user.username %></strong> 32 </br> 33 <p><%= call.body %></p> 34 <% if user_signed_in? && call.user == current_user %> 35 <p><%= link_to 'Delete', call_path(call), method: :delete %></p> 36 <% end %> 37 </div> 38 <% end %> 39 <% if user_signed_in? %> 40 <%= render 'calls/form' %> 41 <% end %> 42 <!-- shop-to-micropost.shop --> 43 <% @says. each do |say| %> 44 <div> 45 <strong><%= say.shop.shopname %></strong> 46 </br> 47 <p><%= say.body %></p> 48 <% if shop_signed_in? && say.shop == current_shop %> 49 <p><%= link_to 'Delete', say_path(say), method: :delete %></p> 50 <% end %> 51 </div> 52 <% end %> 53 <% if shop_signed_in? %> 54 <%= render 'says/form' %> 55 <% end %> 56 57 <!-- shop-to-micropost.shop --> 58 59 <% @insists. each do |insist| %> 60 <div> 61 <strong><%= insist.shop.shopname %></strong> 62 </br> 63 <p><%= insist.body %></p> 64 <% if shop_signed_in? && insist.shop == current_shop %> 65 <p><%= link_to 'Delete', insist_path(insist), method: :delete %></p> 66 <% end %> 67 </div> 68 <% end %> 69 <% if shop_signed_in? %> 70 <%= render 'insists/form' %> 71 <% end %> 72 </div> 73 </aside> 74 </div>

###試したこと
・html5.validator → 500 Internal Server Error
・css内で.moreが重複されていないか確認済み
・show,_feed,_micropost.html.erb内のdivを一つ削除しながらmoreが動くか確認済み

###補足情報(言語/FW/ツール等のバージョンなど)

下記URL内の質問が発端です。
より詳細な情報が載っております。

投稿文の開閉設定の変数がうまいこと作用しない。

開閉設定の参考コード
[もっとみる...] / [See more...] をjQueryで実装する(開閉できるタイプ)

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

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

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

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

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

guest

回答1

0

ベストアンサー

javascript

1$('.more').each(function() { 2 var content = $.trim($(this).html()); 3 4 if(content.length > showChar) { 5 6 var c = content.substr(0, showChar); 7 var h = content.substr(showChar, content.length - showChar); 8 9 var html = c + '<span class="moreellipses">' + ellipsestext+ '&nbsp;</span><span class="morecontent"><span>' + h + '</span>&nbsp;&nbsp;<a href="" class="morelink">' + moretext + '</a></span>'; 10 11 $(this).html(html); 12 } 13 14 });

このコードが悪いです。

viewのjavascriptからviewを動的domを初期化するのは基本的にアンチパターンです。
ajaxとform_builderを使うようにしましょう。
またjavascriptはviewに書かずcoffeescriptなどを利用した方がいいと思います。モデルが関連したUIにjavascriptを使うとrailsとロジックを接続する必要が生じるため二度手間になります。基本的にUIのアニメーションやデザインのみにjsを使う方がいいと思います。

またviewファイルの整理はもっと頑張った方がいい気がします。現状読みたくないコードになっています。基本的にロジックはhelperに切り出しviewは最低限のロジックで済ませましょう。formはformbuilderとモデルの関連ごとにpartial_templateを使って実装したほうが問題が部分的に切り出しやすくなります。そうすればviewファイル全てを載せなくても部分的にコードを載せられるので質問もしやすく回答する側も答えやすくなります。さらに言うと質問前にバグに気付きやすくなります。

viewの実装が汚いことに悩んだ時にはそれを解消するgemも色々あります。

・gon
・cocoon
・reform
・haml
・simple_form

このあたりを調べてみるといいと思います。

また,jsメインで行きたいなら,railsのformbuilderを捨ててjsのライブラリやフレームワークに実装を委ねてしまった方がメンテしやすくなります。railsはreactやvueと親和性が高いので,jsに懲りたい場合はこちらを利用することをお勧めします。

多少まさかり投げさせていただきましたが,railsのデザインパターンをもう少し意識してコードを書いてもらえると開発時間も短くなり,バグも減りいいプロダクトを作れるようになると思うので頑張ってください。

投稿2016/11/01 01:20

編集2016/11/01 01:24
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

s.k

2016/11/01 02:11

tkowさん ありがとうございます! 昨日から、悩んでいましたので助かりました… アンチパターン気を付けます… とりあえず、試験的にあのjs機能を試してみたかったのでこのようなコードにしてしまいました。 「viewに直接かくのはよくはないけど、書いてもエラーにはならない」と勘違いしていました。 このjsをajaxにするのは大変そうですね(ajaxは簡単なものしかできないので) でも、やってみます! form_builderですが、これは今から調べます。 コードの汚さは申し訳ないです(´;ω;`) 整理せず走り書きしてきましたので、こんな状態です。 tkowさんにいただいた情報をもとに 整理してみます!
退会済みユーザー

退会済みユーザー

2016/11/01 07:35 編集

jsの動作確認したい時はchromeのsnippets使うといいですよ(他のブラウザにもあるかも)。 書いたコードをrunで実行できて保存できます。macだとcmd+o ->ファイル選択->cmd+Enterで実行できて楽です。 ブックマークレットでもできますがappendでsrc属性を書いてjsライブラリやcssロードもできます。 >ajaxは簡単なものしかできないので 実はajaxは難しそうに見えて,form builderで作ったフォームであればformにremote=true属性とpartial templateを送信するjsを作るだけで出来てしまいます。気をつけるのはform丸々変更する場合security_tokenまで差し替えてしまったり逆にワンタイムトークンの時はform毎書き換えないとerror吐くのに注意するくらいでしょうか。後者の場合formが複数存在してしまう場合は諦めてredirectで対応したりします。 頑張ってください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問