2015年1月1日木曜日

jQuery+CSSでウィンドウの最小化を実現してみた(+最大化改善)

jQuery+CSSでウィンドウの最小化を実装。
ついでにウィンドウをドラッグしたときに移動できるようにもしてみました。



まともにテストしていない & 例外処理甘いです。
特定の操作組み合わせで変な動作します。


Window.html
<!DOCTYPE html>
<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="./css/Window.css">
        <script src="./js/vendor/jquery-2.1.1.js"></script>
        <script src="./js/vendor/jquery-ui.js"></script>
        <script src="./js/Window.js"></script>
    </head>
    <body>
        
        <button class="show">ウィンドウを表示</button>
        
        <div class="window">
            <div class="title">
                ウィンドウのタイトル
            </div>
            <button class="minimize">-</button>
            <button class="maximize">□</button>
            <button class="close">×</button>
            <div class="content">
                コンテンツの内容はこんな感じですよ。
                コンテンツの内容はこんな感じですよ。
                コンテンツの内容はこんな感じですよ。
                コンテンツの内容はこんな感じですよ。
                コンテンツの内容はこんな感じですよ。
                コンテンツの内容はこんな感じですよ。
                コンテンツの内容はこんな感じですよ。
                コンテンツの内容はこんな感じですよ。
                コンテンツの内容はこんな感じですよ。
                コンテンツの内容はこんな感じですよ。
                
            </div>
        </div>
    </body>
</html>
Window.css
.window {
    position:absolute;
    width: 260px;
    height: 180px;
    border-style: solid;
    border-width: 2px;
    border-color: rgb(150, 150, 150);
    background: rgb(218, 218, 218);
}

.window > .title {
    position: absolute;
    left: 0px;
    display: inline-block;
    background-color: rgb(0, 0, 230);
    border-color: rgb(0, 0, 180);
    border-width: 2px;
    height: 20px;
    width: 260px;
    margin: 0px;
    color: white;
}

.window > button {
    position: absolute;
    display: inline-block;
    border-width: 2px;
    border-style: solid;
    border-color: rgb(150, 150, 150);
    background-color: rgb(218, 218, 218);
    height: 20px;
    margin: 0px;
}

.window > .minimize {
    right: 40px;
}
.window > .maximize {
    right: 20px;
}
.window > .close {
    right: 0px;
}

.window > .content {
    position: relative;
    display: block;
    overflow: scroll;
    top: 20px;
    width: 260px;
    height: 160px;
}

.show {
    position: relative;
    display: block;
    top: 0px;
    left: 0px;
}
Window.js
$(function(){
    
    var $window = $('.window'),
        $maximize = $window.find('.maximize'),
        $minimize = $window.find('.minimize'),
        $close = $window.find('.close'),
        $title = $window.find('.title'),
        $contents = $window.find('.content'),
        $showButton = $('.show'),
        $baseWindow = $(window);


        /*
         * ドラッグできるようにする。
         */
    jQuery('.window').draggable();
    
    /*
     * (ブラウザ全体の)ウィンドウサイズを取得する。
     */
    var width = $baseWindow.width(),
        height = $baseWindow.height();
    
    
    /*
     * もともと表示されているウィンドウサイズを取得する。
     */
    var originalWidth = $window.width(),
        originalHeight = $window.height();
    
    /*
     * ウィンドウの幅、高さ、位置を記録するための変数を準備
     */
    var windowWidth, windowHeight, windowOffset;     
    
    var duration = 750;
    
    
    /*
     * 初期サイズ合わせ。
     */
    windowWidth = $window.width();
    $title.css({ width: windowWidth+'px' });
    
    /*
     * 閉じるボタン(×)をクリック時の挙動
     */
    $close.on('click', function(){
        $window.css({ display: 'none' });
    });
    
    /*
     * 最大化ボタン(□)をクリックした時の挙動
     */
    $maximize.on('click', function(){
        width = $baseWindow.width();
        height = $baseWindow.height();
        /*
         * miximizedクラスを使って最大化フラグを管理
         */
        $(this).toggleClass('maximized');
        if($(this).hasClass('maximized')){
            /*
             * 最大化フラグがあるときは
             * ブラウザウィンドウの横幅、縦幅まで
             * ウィンドウサイズを拡張、
             * 位置は左上に移動する。
             */
            
            /*
             * 最大化解除の際の位置戻しができるように
             * ウィンドウの位置を事前に記憶しておく。
             */
            windowOffset=$window.offset();
            $window.stop(true).animate({
                top: '0px',
                left: '0px',
                width: width+'px',
                height: height+'px'
            }, {
                duration: duration,
                queue: false
            });
            $title.stop(true).animate({
                width: width+'px'
            },{
                duration: duration,
                queue: false
            });
            $contents.stop(true).animate({
                width: width+'px',
                height: height+'px'
            },{
                duration: duration,
                euque: false
            });
        } else {
            /*
             * ウィンドウの位置を記憶しておく。
             */
            $window.stop(true).animate({
                top: windowOffset.top+'px',
                left: windowOffset.left+'px',
                width: originalWidth+'px',
                height: originalHeight+'px'
            }, {
                duration: duration,
                queue: false
            });
            $title.stop(true).animate({
                width: originalWidth+'px'
            },{
                duration: duration,
                queue: false
            });
            $contents.stop(true).animate({
                width: originalWidth+'px',
                height: originalHeight+'px'
            },{
                duration: duration,
                euque: false
            });
        }
        $contents.css({display:'inline-block'});
    });
    
    /*
     * ウィンドウを表示 ボタンをクリックしたときの挙動
     */
    $showButton.on('click', function(){
        $window.css({ display: 'inline-block' });
    });
    
    

    /*
     * 最小化(-)ボタンをクリックしたときの挙動
     */
    $minimize.on('click', function(){
        var height = $(window).height();
        var titleHeight = $title.height();

        /*
         * minimizedクラスで最小化フラグを管理
         */
        $window.toggleClass('minimized');
        if($window.hasClass('minimized')){
            /*
             * 最小化フラグありの場合は
             * ウィンドウの現在位置を記録した後に
             * コンテンツ非表示、ウィンドウの横幅を
             * 変更した後に画面最下部に移動させる。
             */
            windowOffset= $window.offset();
            windowWidth = $window.width();
            windowHeight = $window.height();
            $contents.css({ display: 'none' });
            $window.animate({
                top: height - 20 +'px',
                left: '0px',
                width: originalWidth+'px',
                height: titleHeight+'px'
            },{
                duration: duration,
                queue: false
            });
            $title.animate({
                width: originalWidth+'px'
            },{
                duration: duration,
                queue: false
            });
        } else {
            /*
             * 最小化フラグを持たない場合は
             * コンテンツを再表示したのち、ウィンドウサイズ、位置を
             * 以前の状態に戻す。
             */
            $contents.css({ display: 'inline-block'});
            $window.animate({
                width: windowWidth+'px',
                height: windowHeight+'px',
                top: windowOffset.top+'px',
                left: windowOffset.left+'px'
            },{
                duration: duration,
                queue: false
            });
            $title.animate({
                width: windowWidth+'px'
            },{
                duration: duration,
                queue: false   
            });
        }
    });
});

0 件のコメント:

コメントを投稿