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

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

ただいまの
回答率

90.62%

  • JavaScript

    15866questions

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

  • HTML

    8635questions

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

【JavaScript】メッセージのやりとりの処理について

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,164

Sfidante

score 89

WebSocketとJavaScriptを用いて即時性のあるメッセージのやりとりをおこなう
プログラムを書いているのですが、
数カ所、動作がおかしいところがあるので、
ご享受いただければ幸いです。
下記の動作を行いたいです。

1.テキストエリアで入力したあと、テキストエリア内が初期化されずに続けての入力が不可(現在はテキストボックスで代用)

2.メッセージを表示する箇所を常に最新(スクロールの位置を一番下)に持って行きたい(現状はメッセージを送受信してもスクロールは動かずわざわざ下にスクロール)

3.送信ボタンを押すことでメッセージの送信を行えるようにする。(現状はテキストボックスで入力後、Enterを押すことで送信になっている)

調べ方が悪いのか検索しても解決策がわかりません。
よろしくお願いいたします。

下記に現状のJavaScriptとHTMLを記載いたします。

<script type="text/javascript">
function sendMessage(){
    var message = messageInput.value;
    if (webSocket && "" != message) {
        webSocket.send(message);
        messageInput.value = "";
    }
    var webSocket;
    window.onload = function() {
        var forRtoA = document.createElement('a');
        forRtoA.href = "loadMessage";
        webSocket = new WebSocket(forRtoA.href.replace("http://", "ws://").replace("https://", "wss://"));
        var messageArea = document.getElementById("message-list");
        var sessionid = document.getElementById("sessionID").value;
        var photo = document.getElementById("yourphoto").value;
        
        var appendMessage = function(value, session) {
            var messageElement = document.createElement("messageArea");
            var time = new Date();
            var month = time.getMonth() + 1;
            if(month < 10) { month = "0" + month; }
            var day = time.getDate();
            if(day < 10) { day = "0" + day; }
            var hour = time.getHours();
            if(hour < 10) { hour = "0" + hour; }
            var minute = time.getMinutes();
            if(minute < 10) { minute = "0" + minute; }
            var now = month + "/" + day + " " + hour + ":" + minute;
            if(session == sessionid){
                messageElement.innerHTML = '<li class="msg_send"><div class="inner-box"><p class="balloon_right" id="messageArea">' + value + '</p></div></li><p class="time_send">' + now + '</p>';
            }else{
                messageElement.innerHTML = '<li class="msg_recieve"><a href="" target="_blank"><img src="' + photo + '" alt="メッセージ相手写真" class="c-message_photo img-circle c-photo_mini"></a><div class="inner-box2"><p class="balloon_left">' + value + '</p></div></li><p class="time_recieve">' + now + '</p>';
            }
            messageArea.appendChild(messageElement);
        }
        
         webSocket.onmessage = function(message) {
                var data = JSON.parse(message.data);
                appendMessage(data.text, data.sessionid);
            }
    }
}
</script>
    <div class="message_box c-center__margin">
    <ul id="message-list">
                <c:forEach var="messagelist" items="${ requestScope.messageList }">
                <c:if test="${ messagelist.userid == myuserid }" var="my"/>
                <c:if test="${ !my }">
                <li class="msg_recieve">
                    <a href="" target="_blank">
                    <img src="<c:out value='${ UserProfile.photo }'/>" alt="メッセージ相手写真" class="c-message_photo img-circle c-photo_mini">
                    </a>
                    <div class="inner-box2">
                    <p class="balloon_left">${ messagelist.message }</p>
                    </div>
                </li>
                    <p class="time_recieve"><time datetime="2015-07-11T11:11">
                    <fmt:formatDate value="${ messagelist.comment_time }" pattern="MM/dd HH:mm"/>
                    </time></p>
                </c:if>
                <c:if test="${ my }">
                <li class="msg_send">
                    <div class="inner-box">
                         <p class="balloon_right" id="messageArea">${ messagelist.message }</p>
                    </div>
                </li>
                        <p class="time_send">
                        <fmt:formatDate value="${ messagelist.comment_time }" pattern="MM/dd HH:mm"/>
                        </p>
                </c:if>
                </c:forEach>
            </ul>
        </div>
    <div class="message_inner_box c-center__margin">
        <div class="c-center message-area">
            <textarea id="messageInput" class="p-sendbox" name="sendarea"></textarea>
            <p>※<a href="">同意事項</a>に同意の上、送信してください。</p>
            <a href="javascript:;" class="c-btn_chenge" onClick="sendMessage();" id="messageInput"><img src="image/images/send_btn_03.png" alt="送信ボタン" class="p-message_send"></a>
        </div>
    </div>
何か一つだけでもよろしいので、
教えていただけると幸いです。
よろしくお願いいたします。


追記
解決後
<script type="text/javascript">
var webSocket;
window.onload = function() {
    var forRtoA = document.createElement('a');
    forRtoA.href = "loadMessage";
    webSocket = new WebSocket(forRtoA.href.replace("http://", "ws://").replace("https://", "wss://"));
    var messageArea = document.getElementById("message-list");
    var sessionid = document.getElementById("sessionID").value;
    var photo = document.getElementById("yourphoto").value;
    
    var appendMessage = function(value, session) {
        var string = value.replace("/\r\n|\n|\r/g", "<br>");
        var messageElement = document.createElement("messageArea");
        var time = new Date();
        var month = time.getMonth() + 1;
        if(month < 10) { month = "0" + month; }
        var day = time.getDate();
        if(day < 10) { day = "0" + day; }
        var hour = time.getHours();
        if(hour < 10) { hour = "0" + hour; }
        var minute = time.getMinutes();
        if(minute < 10) { minute = "0" + minute; }
        var now = month + "/" + day + " " + hour + ":" + minute;
        if(session == sessionid){
            messageElement.innerHTML = '<li class="msg_send"><div class="inner-box"><p class="balloon_right" id="messageArea">' + string + '</p></div></li><p class="time_send">' + now + '</p>';
        }else{
            messageElement.innerHTML = '<li class="msg_recieve"><a href="" target="_blank"><img src="' + photo + '" alt="メッセージ相手写真" class="c-message_photo img-circle c-photo_mini"></a><div class="inner-box2"><p class="balloon_left">' + string + '</p></div></li><p class="time_recieve">' + now + '</p>';
        }
        messageArea.appendChild(messageElement);
        var message_box = document.getElementById("message_box");
        message_box.scrollTop = message_box.scrollHeight;
    }
    
     webSocket.onmessage = function(message) {
            var data = JSON.parse(message.data);
            appendMessage(data.text, data.sessionid);
        }
    
     var messageInput = document.getElementById("c-btn_chenge");
     var messageText = document.getElementById("messageInput");
     messageInput.onclick = function() {
             var message = messageText.value;
             if (webSocket && "" != message) {
                 webSocket.send(message);
                 messageText.value = "";
             }
     }
}
</script>
<div class="message_box c-center__margin" id="message_box">
    <ul id="message-list">
                <c:forEach var="messagelist" items="${ requestScope.messageList }">
                <c:if test="${ messagelist.userid == myuserid }" var="my"/>
                <c:if test="${ !my }">
                <li class="msg_recieve">
                    <a href="" target="_blank">
                    <img src="<c:out value='${ UserProfile.photo }'/>" alt="メッセージ相手写真" class="c-message_photo img-circle c-photo_mini">
                    </a>
                    <div class="inner-box2">
                    <p class="balloon_left">${ messagelist.message }</p>
                    </div>
                </li>
                    <p class="time_recieve"><time datetime="2015-07-11T11:11">
                    <fmt:formatDate value="${ messagelist.comment_time }" pattern="MM/dd HH:mm"/>
                    </time></p>
                </c:if>
                <c:if test="${ my }">
                <li class="msg_send">
                    <div class="inner-box">
                         <p class="balloon_right" id="messageArea">${ messagelist.message }</p>
                    </div>
                </li>
                        <p class="time_send">
                        <fmt:formatDate value="${ messagelist.comment_time }" pattern="MM/dd HH:mm"/>
                        </p>
                </c:if>
                </c:forEach>
            </ul>
        </div>
    <div class="message_inner_box c-center__margin">
        <div class="c-center message-area">
        <textarea id="messageInput" class="p-sendbox" name="sendarea"></textarea>
            <p>※<a href="">同意事項</a>に同意の上、送信してください。</p>
            <a href="javascript:;" id="c-btn_chenge"><img src="image/images/send_btn_03.png" alt="送信ボタン" class="p-message_send"></a>
        </div>
    </div>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

僕自身もコードに問題はないとおもっていたのですが、どうもうまくいかずに困っていました

以下のテストコードを書いてみたのですが、きちんとクリアされるようです。
<!DOCTYPE html>
<html>
    <head>
        <title>test</title>
        <meta charset="utf-8" />
        <script type="text/javascript">
            function getAndClear(){
                var txt = document.getElementById("tarea");
                alert(txt.value);
                txt.value="";
            }
        </script>
    </head>
    <body>
        <textarea id="tarea"></textarea>
        <button id="btn" onClick="getAndClear();">test</button>
    </body>
</html>

Chromeをお持ちでしたら、開発者ツールを起動させてみてもらえますか?
何かエラー出ていませんか?

最下部に持っていくやり方をお教えいただくことはできますでしょうか?

昨日は面倒な気がしていましたが、すみません、意外と簡単そうでした。
<div class="message_box c-center__margin">にIDを足して
<div class="message_box c-center__margin" id="message_box">

appendMessage 関数の最後に、
var message_box = document.getElementById("message_box");
message_box .scrollTop = obj.message_box ;
を追加でいかがでしょう?

送信処理に関して上記のコードに変えてみて行ったのですが、どうもうまくいかなかったです。

すみません、処理全体を関数で囲うのではなく、送信処理のみを囲うという意味でした。
ただ、私のアドバイスも悪くて、
window.onload = function(){
に囲まれたスコープではonClickから参照できませんね。

以下でどうでしょう?

<script type="text/javascript">
var webSocket;
    window.onload = function() {
        var forRtoA = document.createElement('a');
        forRtoA.href = "loadMessage";
        webSocket = new WebSocket(forRtoA.href.replace("http://", "ws://").replace("https://", "wss://"));
        var messageArea = document.getElementById("message-list");
        var sessionid = document.getElementById("sessionID").value;
        var photo = document.getElementById("yourphoto").value;
        
        var appendMessage = function(value, session) {
            var messageElement = document.createElement("messageArea");
            var time = new Date();
            var month = time.getMonth() + 1;
            if(month < 10) { month = "0" + month; }
            var day = time.getDate();
            if(day < 10) { day = "0" + day; }
            var hour = time.getHours();
            if(hour < 10) { hour = "0" + hour; }
            var minute = time.getMinutes();
            if(minute < 10) { minute = "0" + minute; }
            var now = month + "/" + day + " " + hour + ":" + minute;
            if(session == sessionid){
                messageElement.innerHTML = '<li class="msg_send"><div class="inner-box"><p class="balloon_right" id="messageArea">' + value + '</p></div></li><p class="time_send">' + now + '</p>';
            }else{
                messageElement.innerHTML = '<li class="msg_recieve"><a href="" target="_blank"><img src="' + photo + '" alt="メッセージ相手写真" class="c-message_photo img-circle c-photo_mini"></a><div class="inner-box2"><p class="balloon_left">' + value + '</p></div></li><p class="time_recieve">' + now + '</p>';
            }
            messageArea.appendChild(messageElement);
        }
        
         webSocket.onmessage = function(message) {
                var data = JSON.parse(message.data);
                appendMessage(data.text, data.sessionid);
            }
        //sendMessageをwindowスコープに定義
        window.sendMessage = function(){
          var messageInput = document.getElementById("messageInput");
          var message = messageInput.value;
          if (webSocket && "" != message) {
              webSocket.send(message);
              messageInput.value = "";
           }
        }
    }
</script>

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/08/03 15:31

    ご丁寧にご回答ありがとうございます。
    おかげさまですべての問題点を解決出来ました。
    ありがとうございます。

    一応解決後のコードを追記として載せておきました。

    また、もしわかれば教えていただきたいのですが、
    現状、テキストエリアを改行してしまいますと
    JavaScriptでの表示ができません。
    改行コードを記載しているのですが、
    それがうまく処理できていないようです。

    よろしくお願いいたします。

    キャンセル

  • 2015/08/03 16:09

    正規表現間違っていませんか?
    value.replace("/[\r\n|\n|\r]/g", "<br />");
    でいかがでしょう?

    キャンセル

  • 2015/08/03 16:21

    ご回答ありがとうございます。
    そちらでおこなってもうまくいきませんでした。

    キャンセル

  • 2015/08/03 19:49

    調べたところ、<br />ではなく、&#13;を入れるみたいです。
    以下、他人様のブログですが。。。
    http://blog2.elephantech.net/htmlcss/tml%EF%BC%9Atextarea%EF%BC%88%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%82%A8%E3%83%AA%E3%82%A2%EF%BC%89%E3%81%AE%E4%B8%AD%E3%81%A7%E3%80%81%E6%96%87%E5%AD%97%E5%88%97%E3%82%92%E3%81%A7%E6%94%B9%E8%A1%8C/

    私も初めて知りました。勉強になりました。

    キャンセル

  • 2015/08/03 21:27

    わざわざ調べてくださりありがとうございます。
    &#13;でおこなってみたのですが、
    結果は変わらずでした。

    そして、
    下記のようにalert();で出力していったところ
    var appendMessage = function(value , session){
    alert(value);
    var string = value.replace(/[\r\n|\n|\r]/g , "&#13;");
    改行した場合、
    この位置でもエラーになったので、
    Java側(サーバー側)でうまく処理できていないのかなと考えております。

    キャンセル

+1

前提として、jQueryのようなライブラリを使ったほうが色々便利な気がしますが、とりあえず使わない前提でお答えします。

1.テキストエリアで入力したあと、テキストエリア内が初期化されずに続けての入力が不可(現在はテキストボックスで代用)

これについては、ソースを拝見した限り動きそうな気がしますが。。。
一瞬、valueではなくinnerHTMLやinnerTextを操作すべきかと疑いましたが、
ここによるとvalueで合っていそうですね。
ちなみにブラウザは何を使われていますか?

2.メッセージを表示する箇所を常に最新(スクロールの位置を一番下)に持って行きたい(現状はメッセージを送受信してもスクロールは動かずわざわざ下にスクロール) 

スクロールさせるのはそこそこ大変なような気がするので、
メッセージを下に追加するのではなく、上に追加していく(つまり、一番上が最新)のではダメでしょうか?

であれば、
messageArea.appendChild(messageElement);
の代わりに、
messageArea.insertBefore(messageElement, messageArea.childNodes[0]);
でいかがでしょう?

3.送信ボタンを押すことでメッセージの送信を行えるようにする。(現状はテキストボックスで入力後、Enterを押すことで送信になっている)

送信処理を、
function sendMessage(){
                var message = messageInput.value;
                if (webSocket && "" != message) {
                    webSocket.send(message);
                    messageInput.value = "";
                }
}
というように関数で囲って、
<a href="javascript:;" class="c-btn_chenge" onClick="sendMessage();" id="messageInput">
のようにonClickで指定してあげればOKのはずです。
尚、onclickではなくonClickです。


投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/08/03 09:26

    ご回答ありがとうございます。

    ご連絡が遅くなり、申し訳ございません。

    >これについては、ソースを拝見した限り動きそうな気がしますが。。。
    >一瞬、valueではなくinnerHTMLやinnerTextを操作すべきかと疑いましたが、
    >ここによるとvalueで合っていそうですね。
    >ちなみにブラウザは何を使われていますか?
    僕自身もコードに問題はないとおもっていたのですが、
    どうもうまくいかずに困っていました。
    ブラウザは、Chrome、firefox、safari、operaで確認しています。
    唯一IEでの確認はしていませんが、
    IE以外はどれもうまくいっていません。

    >スクロールさせるのはそこそこ大変なような気がするので、
    >メッセージを下に追加するのではなく、上に追加していく
    >(つまり、一番上が最新)のではダメでしょうか?
    UI等を考えた時に、上に最新ですとよろしくないかと思っております。
    大変申し訳無いのですが、
    最下部に持っていくやり方をお教えいただくことはできますでしょうか?

    送信処理に関して
    上記のコードに変えてみて行ったのですが、
    どうもうまくいかなかったです。
    JavaScriptに関する知識がない状態ですので、
    間違っている可能性がありますので、
    記載コードを改変した載せますので、
    ご確認いただいてもよろしいでしょうか?

    onClick関数に関して、
    ご指摘ありがとうございます。
    どちらでもよいと思っておりました。

    キャンセル

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

  • ただいまの回答率 90.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 受付中

    websocket実装方法

    websocketを使ってチャットを作成したいです。 IDEはNetBeansを使用しています。 実装方法を詳しく教えてください。

  • 受付中

    JavaScriptの綺麗なコードの書き方

    JavaScriptの綺麗なコードの書き方がわかりません。 例えば下記のような関数があった場合、皆さんならどのようにまとめますか?   function userLogin() {

  • 解決済

    JavaScriptでギャラリーを作りたい

    現在JSでギャラリー的なものを作ろうとしています 仕様としては 画面上段に画像(原寸より小さいもの)を表示し、クリックされると下にその画像の原寸大が表示されるというものです ですが

  • 受付中

    innerHTMLの追加と削除

    こんにちは 現在JSでToDoメモのようなものを作ろうと思っているのですが 問題点が2つ出てきました。 1、innerHTMLにtextに書き込まれた内容を書き込めるが追加ができな

  • 受付中

    JavaScriptの時刻を更新したい

    下記のコードは時刻を取っているのですがこれをデジタル時計みたいにほっておいても時間が変わっているという風にするにはどうすればいいですか? <!doctype html> <html

  • 受付中

    JavaScriptで収支表を作りたい

    下記のコードはパチスロの収支表です 少し問題が起きていてご質問させてください ・結果データ出力の部分が保存されない ・データを一回しか書き込めない 理想はボタンをクリックすれば何

  • 解決済

    javascriptのsetTimeoutを使って表示したい

    <!doctype html> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=devic

  • 解決済

    JavaScriptを使ってツイッターに投稿したい

    5秒当てゲームのようなものをつくっています 自分のタイムをツイッターに投稿できるようにしたいのですが、ゲームの関数とツイートする関数が別なため、タイムをtwitTexを関数に

同じタグがついた質問を見る

  • JavaScript

    15866questions

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

  • HTML

    8635questions

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