たぼさんの部屋

いちょぼとのんびり

アコーディオン実装済最新iframe.js(*question.cssも変更した)

iframe.js

ver 2,2
亜子オーディオんの実装

//------------------------------------------------------------
/*
*  iframe.js
* ver 2.2
* Q&Aページのアコーディオンを実装
* !!!questtion.cssも同時に変更しています。
* 本番実装時には、cssの変更も同時に必要です。
*
* ver 2.1.14
* FlickEventHandlerを修正
* touchmove時にある程度のx移動でメニュー開閉するように。
* ver 2.1.1
* last update 4/22
* 画面の向きを変更したときのコンテンツの高さ調節機能を実装  4/22
*/
//------------------------------------------------------------
( function() {"use strict";
        var webMessaging = ( function() {
                var target = parent.postMessage ? parent : (parent.document.postMessage ? parent.document : undefined);
                return {
                    send : function(message) {
                        //jsonオブジェクトで記述しました。
                        var jsonMessage = JSON.stringify(message);
                        //json形式に変換
                        target.postMessage(jsonMessage, "*");
                    }
                };
            }());

        /**
         * @constructor
         */
        var FlickEventHandler = function(sourceContainer) {
            this.container = sourceContainer;

            this.initialize();
        };
        FlickEventHandler.prototype = {
            initialize : function() {
                this.container.addEventListener('touchstart', this, false);
                this.container.addEventListener('touchmove', this, false);

            },
            handleEvent : function(event) {
                var message = {};
                switch(event.type) {
                    case "touchstart":
                        this.movedFlg = false;
                        this.start = {
                            pageX : event.touches[0].pageX,
                            pageY : event.touches[0].pageY,
                            time : Number(new Date())
                        };
                        //onTouchMoveで利用するための初期化設定です。
                        this.isScrolling = undefined;
                        break;
                    case "touchmove":
                        //movedFlgがtrueならなにもしない
                        if (this.movedFlg) {
                            return;
                        }
                        // タッチが1本のときだけ実行します。
                        if (event.touches.length > 1 || event.scale && event.scale !== 1) {
                            return;
                        }
                        this.deltaX = event.changedTouches[0].pageX - this.start.pageX;
                        this.deltaY = event.changedTouches[0].pageY - this.start.pageY;
                        this.deltaTime = Number(new Date()) - this.start.time;
                        //スクロールかどうかの判定です。スクロールイベントは連続して発生するため、onTouchStart-onTouchMove-onTouchEndの一連の動作の中で、最初に一度だけテストします。
                        if ( typeof this.isScrolling === 'undefined') {
                            this.isScrolling = !! (this.isScrolling || Math.abs(this.deltaX) < Math.abs(this.deltaY) );
                        }
                        if (this.isScrolling) {
                            return;
                        }
                        if (Math.abs(this.deltaX) > 50) {

                            if (this.deltaX < 0) {
                                //閉じる
                                message = {
                                    "flick" : "close"
                                };
                            }
                            if (this.deltaX > 0) {
                                //開く
                                message = {
                                    "flick" : "open"
                                };
                            }
                            //postMessageを送信
                            webMessaging.send(message);
                            this.movedFlg = true;
                        }
                        break;
                }
            }
        };

        /**
         * AutoFontSpan
         */
        var AutoFontSpan = function(target, size) {
            //sizeは1が普通サイズ
            this.target = target;
            this.size = size;

            this.setSize();
        };

        AutoFontSpan.prototype = {
            BASE_RATIO : 1 / 360,

            setSize : function() {
                try {
                    this.target.style.fontSize = Math.round(this.getDocWidth() * this.BASE_RATIO * this.size * 100) + '%';
                } catch(e) {
                    alert(e);
                }
            },
            getDocWidth : function() {
                return document.documentElement.clientWidth;
            }
        };
        var getHeight = function() {

            return document.body.scrollHeight;
        };
        function init() {
            //フォント調節をセットします.
            var autoFontSpans = [];

            var elms = document.getElementsByTagName('span');
            for (var i = 0; i < elms.length; i++) {
                if (elms[i].getAttribute('size')) {
                    var autoFontSpan = new AutoFontSpan(elms[i], elms[i].getAttribute('size'));
                    autoFontSpans.push(autoFontSpan);
                }
            }

            //Flick event set
            new FlickEventHandler(document.body);

            /*
            * postMessage
            */
            // iframe.bodyの高scrollHeightさをpostMessageで送信します。
            var message = {
                "iframeload" : {
                    "height" : getHeight()
                }
            };
            webMessaging.send(message);

            //
            //  EventHandler set
            //

            //resize
            window.addEventListener("resize", function() {
                //autoFontSpan変更
                for (var i = 0; i < autoFontSpans.length; i++) {
                    autoFontSpans[i].setSize();
                }

                var message = {
                    "resize" : {
                        "height" : getHeight()
                    }
                };
                webMessaging.send(message);
            }, false);

            //Q&Aのアコーディオン実装
            var questions = document.getElementsByClassName('que');

            if (questions.length > 0) {
                var answers = document.getElementsByClassName('ans');
                var Accordion = function(i) {
                    this.index = i;
                    questions[i].addEventListener('touchend', this, false);
                };
                Accordion.prototype = {
                    handleEvent : function(event) {
                        for (var i = 0; i < answers.length; i++) {
                            answers[i].style.display = "none";
                        }
                        answers[this.index].style.display = "block";

                        //高さ調整
                        var message = {
                            "resize" : {
                                "height" : getHeight()
                            }
                        };
                        webMessaging.send(message);
                    }
                };
                for ( i = 0; i < questions.length; i++) {
                    new Accordion(i);
                }
            }

        }

        //init call
        window.addEventListener('load', init, false);

        //parentからの受信用
        window.addEventListener('message', function(event) {
            //未使用
        }, false);

    }());