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

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

ただいまの
回答率

90.52%

  • JavaScript

    16373questions

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

  • HTML

    8944questions

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

スマホ用 カレンダーの自由なスクロール

受付中

回答 0

投稿

  • 評価
  • クリップ 1
  • VIEW 107

somatech0428

score 2

現在スマホアプリのカレンダー機能を作っているのですが、一ヶ月ごとにスクロールして現在の日付を取得しているのですが、アニメーションさせずに自由にスクロールしながら日付を取得したいです。

Object.defineProperty(Date.prototype, 'format', {
    get: function () {
        return function (str_format) {
            var f = str_format;
            var o = this;
            if (!f) f = 'yyyy-MM-dd hh:mm:ss.SSS';
            var mon = ["年1月", "年2月", "年3月", "年4月", "年5月", "年6月", "年7月", "年8月", "年9月", "年10月", "年11月", "年12月"];
            var week = ["日","月","火","水","木","金","土"];
            f = f.replace(/MMM/g, '@@@@@');
            f = f.replace(/dddd/g, '@@@@');
            f = f.replace(/ddd/g, '@@@');
            f = f.replace(/yyyy/g, o.getFullYear());
            f = f.replace(/MM/g, ('0' + (o.getMonth() + 1)).slice(-2));
            f = f.replace(/hh/g, ('0' + o.getHours()).slice(-2));
            f = f.replace(/mm/g, ('0' + o.getMinutes()).slice(-2));
            f = f.replace(/ss/g, ('0' + o.getSeconds()).slice(-2));
            f = f.replace(/dd/g, ('0' + o.getDate()).slice(-2));
            if (f.match(/S/g)) {
                var milliSeconds = ('00' + o.getMilliseconds()).slice(-3);
                var length = f.match(/S/g).length;
                for (var i = 0; i < length; i++) f = f.replace(/S/, milliSeconds.substring(i, i + 1));
            }
            f = f.replace(/@@@@@/g, mon[o.getMonth()]);
            f = f.replace(/@@@@/g, week[o.getDay()]);
            f = f.replace(/@@@/g, week[o.getDay()].slice(3));
            return f;
        };
    }
});

Object.defineProperty(Date.prototype, 'add', {
    get: function () {
        return function (interval, str_target) {

            var t = str_target.toLowerCase();
            var o = this;

            if(t=='y' || str_target=='M'){
                var y, M, d;
                y = o.getFullYear();
                M = o.getMonth(); /* between 0 to 11 */
                d = o.getDate();

                if(t=='y'){/*Year*/
                    y += interval;
                }
                else{ /*Month*/
                    M += interval;
                    y += Math.floor(M / 12);
                    M = (M + 12) % 12;
                }
                var max = [31, 28 + (y % 4 == 0 && (y % 100!=0 || y % 400==0)), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
                if(d > max[M]){ d = max[M]}

                return new Date(
                    y,
                    M,
                    d,
                    o.getHours(),
                    o.getMinutes(),
                    o.getSeconds(),
                    o.getMilliseconds()
                );
            }

            else if(t=='d'){/*Day*/
                return new Date(o.getTime() + interval * 86400000);
            }
            else if(t=='h'){/*Hour*/
                return new Date(o.getTime() + interval * 3600000);
            }
            else if(str_target=='m'){/*Minute*/
                return new Date(o.getTime() + interval * 60000);
            }
            else if(t=='s'){/*Second*/
                return new Date(o.getTime() + interval * 1000);
            }
            else {
                return new Date(o)
            }
        };
    }
});

var sel_date = new Date();
$(function(){
  create_fullcal();

  //表示位置の設定
  reposition();

  //イベント追加
  var elm = document.getElementsByClassName("scroll-area")[0];
  elm.addEventListener('touchstart', touchstart);
  elm.addEventListener('touchmove', touchmove);
  elm.addEventListener('touchend', touchend);
  elm.addEventListener('mousedown', dragstart);
  window.addEventListener('mousemove', drag);
  window.addEventListener('mouseup', touchend);

  window.addEventListener('resize', reposition);
});

function create_fullcal(){

  //タイトルを追加
  $(".cal_title").text(sel_date.format('yyyyMMM'));



  //カレンダー作成
  var frame = $(".scroll-area");
  $(makeCal(sel_date.add(-2, 'M'), -1)[0].childNodes).appendTo(frame);
  $(makeCal(sel_date.add(-1, 'M'), -1)[0].childNodes).appendTo(frame);
  $(makeCal(sel_date, 0)[0].childNodes).appendTo(frame);
  $(makeCal(sel_date.add(1, 'M'), 1)[0].childNodes).appendTo(frame);
  $(makeCal(sel_date.add(2, 'M'), 1)[0].childNodes).appendTo(frame);
}

function modify_cal(flg){
  //タイトルを変更
  $(".cal_title").text(sel_date.format('yyyyMMM'));

  //逆方向に2ヶ月離れた月は削除対象
  var delete_date = sel_date.add(-1 * flg * 3, 'M').format('yyyy-MM-');
  var delete_date2 = sel_date.add(-1 * flg * 4, 'M').format('yyyy-MM-');

  //削除対象月の日付入りのLineを削除
  var lines = document.getElementsByClassName('scroll-area')[0].childNodes;
  for(var i=lines.length-1; i>=0; i--){
    var line = lines[i];
    if((line.firstChild.attributes['date'].value.indexOf(delete_date)>=0 || line.firstChild.attributes['date'].value.indexOf(delete_date2)>=0)
      &&
      (line.lastChild.attributes['date'].value.indexOf(delete_date)>=0 || line.lastChild.attributes['date'].value.indexOf(delete_date2)>=0))
    {
      line.parentNode.removeChild(line);
    }
  }

  //正方向に新しい月を追加
  var append_elm = makeCal(sel_date.add(flg * 2, 'M'), flg);
  var frame = $(".scroll-area");
  if(flg>0){
    $(append_elm[0].childNodes).appendTo(frame);
  } else {
    $(append_elm[0].childNodes).prependTo(frame);
  }
}

function reposition(){
  $(".scroll-area").scrollTop(0);
  var top;
  var firstDay = new Date(sel_date.format('yyyy-MM-01'));
  if(firstDay.getDay()==0){
    top = $("[date='"+firstDay.add(-7,'d').format('yyyy-MM-dd')+"']").parent().position().top;
  } else {
    top = $("[date='"+sel_date.format('yyyy-MM-01')+"']").parent().position().top;
  }
  $(".scroll-area").scrollTop(top);
}

var touch_pos = {};
function touchstart(e){
  if(e.touches.length > 1 || touch_pos.start) return;
  touch_pos = {
    scrollPos: $(".scroll-area").scrollTop(),
    start: e.touches[0].pageY,
    pos: e.touches[0].pageY
  };
}

function dragstart(e){
  if(touch_pos.start) return;
  touch_pos = {
    scrollPos: $(".scroll-area").scrollTop(),
    start: e.pageY,
    pos: e.pageY
  };
}

function touchmove(e){
  if (e.touches.length > 1 || !touch_pos.start) return;
  var pos = e.touches[0].pageY;
  $(".scroll-area").scrollTop(touch_pos.scrollPos + (touch_pos.start - pos));
  touch_pos.pos = pos;
  e.preventDefault(); /* Disable 'pull to refresh' for Android Chrome */
}

function drag(e){
  if (!touch_pos.start) return;
  if (e.buttons == 0){ touch_pos = {}; return; }
  var pos = e.pageY;
  $(".scroll-area").scrollTop(touch_pos.scrollPos + (touch_pos.start - pos));
  touch_pos.pos = pos;
}



// アニメーション
function touchend(e){
  var limit = $(".scroll-area").height() * 0.33;
  if(Math.abs(touch_pos.start - touch_pos.pos) > limit){
    var sgn = Math.sign(touch_pos.start - touch_pos.pos);
    //表示位置の設定
    var top = $("[date='"+sel_date.add(sgn, 'M').format('yyyy-MM-01')+"']").parent().position().top;
    $(".scroll-area").animate({scrollTop:$(".scroll-area").scrollTop() + top}, 200, 'linear',
      function(){
        sel_date = sel_date.add(sgn, 'M');
        //カレンダーの再作成
        modify_cal(sgn);
        //表示位置の設定
        reposition();
        // touch_pos = {};
      }
    );
  } else {
    // 元の場所に戻す(ぼよよーん)
    $(".scroll-area").animate({scrollTop:touch_pos.scrollPos}, 200, 'linear');
    touch_pos = {};
  }
}
// アニメーション


function makeCal(date, flg){
  var frame = $("<div/>");

  //年月を取得する
  var this_year = date.getFullYear();
  var this_month = date.getMonth() + 1;

  //1日の曜日を取得する
  var first_day = (new Date(this_year, this_month -1, 1));

  var start_week = first_day.getDay();

  var start_day, end_day;

  if(flg == -1){ //先月用
    //同じ週の日曜日の日付を取得する
    start_day = first_day.add(-1 * first_day.getDay(), 'd');
    //末日の曜日ぶん引く
    end_day = first_day.add(1,'M').add(-1,'d');
    if(end_day.getDay() < 6){
      end_day = end_day.add(-1 * end_day.getDay() - 1, 'd');
    }
  } else
  if(flg == 0){
    //同じ週の日曜日の日付を取得する
    start_day = first_day.add(-1 * first_day.getDay(), 'd');
    //末日の取得
    end_day = first_day.add(1,'M').add(-1,'d');
  } else
  if(flg == 1){ //来月用
    //末日の取得
    end_day = first_day.add(1,'M').add(-1,'d');
    //開始日を次の週の日曜日にする
    if(first_day.getDay() > 0){
      first_day = first_day.add(7-first_day.getDay(), 'd');
      start_week = first_day.getDay();
    }
    start_day = first_day;
  }

  //日曜日から先月の末まで追加
  var line = $('<div class="week-line"/>');
  for(var i=0; i<start_week; i++){
    var day = start_day.add(i, 'd');
    $('<div class="days" date="'+ day.format('yyyy-MM-dd') +'">'+ '<span>' + day.getDate() + '</span>' + '</div>').appendTo(line);
    if(day.getDay()==6){
      line.appendTo(frame);
      line = $('<div class="week-line"/>');
    }
  }

  //今月の1日から末まで順に追加
  for(var i=0, day=first_day; day.getDate() < end_day.getDate(); i++){
    day = first_day.add(i, 'd');
    $('<div class="days" date="'+ day.format('yyyy-MM-dd') +'">'+ '<span>' + day.getDate() + '</span>' + '</div>').appendTo(line);
    if(day.getDay()==6){
      line.appendTo(frame);
      line = $('<div class="week-line"/>');
    }
  }

  //末日の曜日を取得
  var end_week = end_day.getDay();

  //土曜日までの残りの枠を次の月頭で埋める
  for(var i=(end_week+1), j=1; i<7; i++, j++){
    var day = end_day.add(j, 'd');
    $('<div class="days" date="'+ day.format('yyyy-MM-dd') +'">' + day.getDate() + '</div>').appendTo(line);
    if(day.getDay()==6){
      line.appendTo(frame);
      line = $('<div class="week-line"/>');
    }
  }
  return frame;
}
  <div class='cal_frame'>
    <div class='cal_title'></div>
    <div class='week-line'></div>
    <div class='scroll-area'></div>
  </div>


おそらく
// アニメーション のコメントアウトが入っているところが原因だと思うのですが・・・
うまく日付を取得する機能とアニメーションが切り離せなくて困っています。

お願いいたします!

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

まだ回答がついていません

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

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

関連した質問

  • 解決済

    日にちと曜日の場所の合わせ方

    カレンダーを作るときに、曜日と日にちの場所を合わせるコードの書き方が分かりません。 インターネットで調べたのですが、どれを参考にしたらいいのか、どれがあっているのか分からなかった

  • 解決済

    ajaxでのページ切り替えについて

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <script src="https://code.jquery.co

  • 解決済

    jQueryを使ってボタン操作でsection移動をうまくしたい

    現状・目標 シンプルに下ボタンを押せば下に、上ボタンを押せば上に 指定したクラスに一個ずつスクロールするjsを組みたいです。 参考URLを参考に作りました。 これの、逆

  • 解決済

    配列を用いカレンダーのチェックボックスを制御する

    前提・実現したいこと 「曜日」と書かれたチェックボックスチェックをすると、その曜日のすべての日が選択されるカレンダーを作りました。 動くサンプル 逆にクリックで、セルを一つ一

  • 解決済

    document.writeを使わず毎月○○日(複数)に指定したhtmlを表示したい

    ★実現したいこと はじめまして 友人が経営する喫茶店のサイトを作っています。 htmlとcssは一生懸命勉強したのですが、jsがちんぷんかんぷんで助言をいただきたいです。

  • 解決済

    jsにてクリックイベント

    jQuery、もしくはJavaScriptで挙動を制御しようとしております。 やりたいこととしては、よくスマホゲーム等である画面のどこかしらをタップすると画面内の特定の要素が次、次

  • 解決済

    Fuelphp プルダウンを年月で作成したい

    fuelphp:1.7.0にて プルダウンを作成したいのですが 条件が 開始年月が2017/06 終了範囲が現在の年月(現在なら2017/08) のような自動で毎月プルダウ

  • 受付中

    SpriteKitでのタッチ判定について

    SpriteKitで動いている画像にタッチ判定をつけて,タッチされると表示されている文字が変化するようにしたいのですが,タッチ判定が出ません.touchesBeganに問題があると

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

  • JavaScript

    16373questions

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

  • HTML

    8944questions

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