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

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

ただいまの
回答率

90.62%

  • jQuery

    6522questions

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

  • jQueryプラグイン

    477questions

    jQueryの拡張機能。 様々な種類があり、その数は膨大です。公開済みのプラグインの他にも、自作することもできます。 jQueryで利用できるようにしておくだけで、導入およびカスタマイズが比較的容易に行なえます。

ボタングループの活性、非活性の制御ができるJqueryのプラグイン化をしたい

解決済

回答 2

投稿 編集

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

freedomman

score 17

困っているところ・躓いているところ

データ属性が連番で増えていくこと想定したプログラムを組みたいのですが、
繰り返し処理を複数要素に対してかけるところから躓いております。
また、関数の引数に対しての条件分岐の方法も模索しております。

前提・実現したいこと

ボタングループの活性、非活性の制御ができるJqueryのプラグイン化を考えております。
関数の引数に「0」の値を入れたら「disable」、「1」の値を入れたら「enable」の制御を行いたいです。

■HTML
<div class="item button" data-item="1">オプション1-1</div>
<div class="item button" data-item="2">オプション1-2</div>
<div class="item button" data-item="3">オプション1-3</div>



<div class="item button" data-item="8">オプション1-8</div>

■JQuery
<script>
$(function(){
$('.groupA #selectOption1').groupAop1Control(1, 1, 0);
$('.groupA #selectOption2').groupAop2Control(1, 0, 0);
$('.groupB #selectOption1').groupBop1Control(1, 1, 1);
$('.groupB #selectOption2').groupBop2Control(1, 1, 1);
});
</script>

のように、ボタン要素の上から順番に引数の指定をすれば、enable・disableの制御を行える様にしたいです。
また、疑似的なdisable状態を
「.button」クラスの状態、「e.preventDefault();」でクリックイベントの処理をキャンセルしたいと考えております。

長文になり申し訳ございませんがご教授よろしくお願いいたします。

コード

<!-- 商品グループA -->
<div class="groupA">
    <div id="selectOption1">
        <h3>オプション1を選択</h3>
        <div class="item button" data-item="1">オプション1-1</div>
        <div class="item button" data-item="2">オプション1-2</div>
        <div class="item button" data-item="3">オプション1-3</div>
    </div>
    <div id="selectOption2">
        <h3>オプション2を選択</h3>
        <div class="item button" data-item="1">オプション2-1</div>
        <div class="item button" data-item="2">オプション2-2</div>
        <div class="item button" data-item="3">オプション2-3</div>
    </div>
</div>
<!-- //商品グループA -->
<!-- 商品グループB -->
<div class="groupB">
    <div id="selectOption1">
        <h3>オプション1を選択</h3>
        <div class="item button" data-item="1">オプション1-1</div>
        <div class="item button" data-item="2">オプション1-2</div>
        <div class="item button" data-item="3">オプション1-3</div>
    </div>
    <div id="selectOption2">
        <h3>オプション2を選択</h3>
        <div class="item button" data-item="1">オプション2-1</div>
        <div class="item button" data-item="2">オプション2-2</div>
        <div class="item button" data-item="3">オプション2-3</div>
    </div>
</div>
<!-- //商品グループB -->
$(function() {
    //defaultで「商品グループB」ボタングループは非表示
    $('.groupB').css('display', 'none');

    //「商品グループA」と「商品グループB」の表示切替
    $('.btn-a').on('click', function() {
        $('.mod-usual').show();
        $('.mod-regular').hide();
    });
    $('.btn-b').on('click', function() {
        $('.mod-usual').hide();
        $('.mod-regular').show();
    });

    //ボタンの非活性 
    function btnDisable(e) {
        e.preventDefault();
        return false;
    }

});
/* ボタンが「enable」、選択できる状態のクラス */
.button-click {
    border: 1px solid #332821;
    color: #332821;
    cursor: pointer;
    box-shadow: 0px 0px 5px #332821;
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
}

/* ボタンがマウスオーバーされた状態のクラス */
.button:hover {
    border: 1px solid #000;
    color: #000;
    opacity: 0.8;
    box-shadow: 0px 0px 5px #CCC;
}

/* ボタンが「disable」、ニュートラルの状態のクラス */
.button {
    border: 1px solid #332821;
    color: #332821;
    cursor: pointer;
    opacity: 0.6;
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
}

試したこと

    //プラグイン側
    (function($) {
        //プラグイン定義
        $.fn.btnControl = function(btnDecision) {

            //enable,disableの判別
            var btnDecision;
            //対象のボタンを格納
            var btnObjects = $(this).data('item');

            return this.each(function(btnObjects) {
                if (btnDecision == 1) {
                    $(this).addClass('button-click');
                } else if (btnDecision == 0) {
                    return false;
                }
            });

            //【確認用】クリックイベントがキャンセルされているか
            $(this).click(function() {
                alert('クリックイベントチェック');
            });

        };
    })(jQuery);


    //呼び出し側
    var groupA = $('.groupA #selectOption1 div');

    $(function() {
        $(groupA).btnControl(1, 0, 0);
    });

試したこと2

    $(function() {
        //defaultで「商品グループB」ボタングループは非表示
        $('.groupB').css('display', 'none');

        //「商品グループA」と「商品グループB」の表示切替
        $('.btn-a').on('click', function() {
            $('.groupA').show();
            $('.groupB').hide();
        });
        $('.btn-b').on('click', function() {
            $('.groupA').hide();
            $('.groupB').show();
        });

        //ボタンの非活性
        function btnDisable(e) {
            e.preventDefault();
            return false;
        }

    });

    (function($) {
        //プラグイン定義
        $.fn.btnControl = function(btnDecision) {

            this.each(function() {
                if (btnDecision == 1) {
                    $(this).addClass('button-click');
                } else if (btnDecision == 0) {
                    element.onmousedown = function (e){event.preventDefault()};
                }
            });

            //【確認用】クリックイベントがキャンセルされているか
            $(this).click(function() {
                alert('クリックイベントチェック');
            });

        };
    })(jQuery);



    //ターゲット
    var groupA = $('.groupA #selectOption1 div');

    $(function() {
        $(groupA).btnControl(1, 0, 0);
    });

成果物

//呼び出し側
$(function() {
    //グループセレクタ
    var groupA = $('.mod-usual #selectRoast div');
    var groupB = $('.mod-usual #selectBeans div');
    //ボタンのenable・disableの切り替え
   $(groupA).btnControl(1, 1, 0);
   $(groupB).btnControl(1, 0, 0);    

});

//プラグイン側
$(function() {
    //defaultは「定期商品」ボタングループは非表示
    $('.groupB').css('display', 'none');

    //「通常商品」と「定期商品」の表示切替
    $('.btn-a').on('click', function() {
        $('.mod-usual').show();
        $('.mod-regular').hide();
    });
    $('.btn-b').on('click', function() {
        $('.mod-usual').hide();
        $('.mod-regular').show();
    });

    //選択状態のボタン
    $("#groupA div, #groupB div").on("click", function() {
        var id = $(this).parent();
        var length = $(id).find(".button").length;
        var num = $(id).find(this).data("item");

        for (i = 0; i < length + 1; i++) {
            $(id).find('.is-decision').removeClass('is-decision').addClass("is-cancel").fadeTo(500, 0.6);
        }

        $(id).find('[data-item="' + num + '"]').removeClass('is-cancel').addClass('is-decision').fadeTo(250, 1);
    });
});

// enable,disableの判別
(function($) {
    $.fn.btnControl = function() {
        var btnDecision = Array.prototype.slice.call(arguments);
        return this.each(function(index, btnObjects) {
            if (btnDecision[index]) {
                $(btnObjects).addClass('button-click').removeClass('button-noclick');
            } else {
                $(btnObjects).removeClass('button-click').addClass('button-noclick');
            }
        });
    };
})(jQuery);
.button-click,
.is-cancel {
    border: 1px solid #332821;
    color: #332821;
    cursor: pointer;
    box-shadow: 0px 0px 5px #332821;
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    opacity: 0.8 !important;
}

.button-noclick {
    pointer-events: none;
}

.is-decision {
    background-color: #eeeeee;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • freedomman

    2017/09/21 16:33

    input要素ではないのでdisableを使わず「return false;」で指定している箇所になります。

    キャンセル

  • x_x

    2017/09/21 16:42

    ちょっとわかりません。each()はcallbackを即座に実行します。そこでreturn falseとすればループを終了するだけです。これ自体はイベントとは関係がありません。http://api.jquery.com/each/

    キャンセル

  • キャンセル

回答 2

checkベストアンサー

+2

まだ仕様がはっきりとしていないと思いますが現状でするとすれば、
とりあえず

.button-noclick {
    pointer-events: none;
}
    $.fn.btnControl = function() {
        // enable,disableの判別
        var btnDecision = Array.prototype.slice.call(arguments);

        return this.each(function(index, btnObjects) {
            if (btnDecision[index]) {
                $(btnObjects).addClass('button-click').removeClass('button-noclick');
            } else {
                $(btnObjects).removeClass('button-click').addClass('button-noclick');
            }
        });
    };

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/09/21 17:52

    なぜか途中で切れました。とりあえず「CSSに一つ追加します。」

    キャンセル

  • 2017/09/21 17:56

    すみません、ありがとうございます。挙動確認させていただきます。

    キャンセル

  • 2017/09/21 18:05 編集

    $(function() {
    $(groupA).btnControl(0, 1, 0);
    });
    と引数を複数指定しましたが、挙動は意図した動きになりました。
    pointer event: noneはIE10以下は対応していないですが、IE9まで対応したい場合の記述方法はありますか?いろいろすみませんがアドバイスお願いします。

    キャンセル

  • 2017/09/21 18:29

    どこのイベント処理の話なのかで方法が変わってくると思います。質問への追記依頼はそのためです。
    pointer-events: noneの代替はこの記事にあるようです。
    https://tetrachroma.co.jp/blog/140522_ad_disable-links/

    キャンセル

  • 2017/09/22 00:11

    参考文献ありがとうございます。
    現在のCSSに追加して動作確認をしてみます。

    キャンセル

  • 2017/09/26 16:54

    今回はIE10以下を捨てることにしました。
    この度は本当にありがとうございました。

    最終的な成果物を追記させて頂きました。

    キャンセル

+2

複数の要素を処理していくならeachを使えばよいです。

【jquery プラグイン/作成 - Qiita】
http://qiita.com/k4zzk/items/11e5dbd53cb93edb8b4d

【【jQuery】プラグインの様々な作り方(定義パターン)】
http://matometaru.com/jquery-plugin-define-patterns/


関数の引数が不定数なら、オブジェクトとか配列を使うか、arguments を使ってみてください。

【arguments - JavaScript | MDN】
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments

【argumentsの簡単な使用例 - Qiita】
http://qiita.com/kanamin/items/63b9fcd705e680372dfb

【JavaScriptのargumentsオブジェクトについて - Tatsuya Oiwa】
http://tatsuyaoiw.com/2015/01/28/javascript-arguments-object/

最近のブラウザなら可変長引数も使えると思います。

【ES2015 (ES6)についてのまとめ - Qiita】
http://qiita.com/tuno-tky/items/74ca595a9232bcbcd727#可変長引数

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/09/21 15:57

    > 「each」で試しましたが、クリックイベントのキャンセルとaddClassの挙動が両方出てしまい、

    追記されたコードで言えば、「ボタンの非活性」のコードがありません。

    > 引数の複数指定もできませんでした。

    1つずつ解決されることをお勧めします。

    キャンセル

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

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

関連した質問

  • 解決済

    常にNavi要素の一部を表示させたい

    前提・実現したいこと navのタブのうちの1つを、ページを開いた瞬間から常に選択した状態にしたいのですが、どのようにコードを書いたらいいのでしょうか? 具体的には、"今日"というタ

  • 解決済

    ページ上部にスクロール設定について

    ページの右下に、クリックするとページ上部に行く設定をしたのですが、スクロール位置を1000以下にすると非表示に設定をhead内に記述したのですが実行できません。 ご教授頂けますと嬉

  • 解決済

    railsでページの上部にflashでメッセージを表示させる

    いつもお世話になります。 現在railsでページを作っており、フォームとボタンを用意しております。ボタンを押した際に保存成功のメッセージをflashを用いて画面上部に表示し一定

  • 解決済

    JS クリックイベントについて WP

    画像をクリックするとクリックした、画像にのみCSSが効き、別の画像をクリックしたらその画像にのみCSSが効くというのを作りたいのですがなかなかうまく行きません。わかる方教えてくださ

  • 解決済

    position:absoluteの値をjavascriptでランダムに決める

    実現したいこと javascript超初心者です。 javascriptでposition:absoluteの数値をランダムに決めたいのですが乱数をpositionの値に入れる方法

  • 解決済

    jQuery 2つのボタンのCSSを切り替える

    前提・実現したいこと jQueryを使用し、2つのボタンのCSSを切り替えたいと思っています。 現在のソースコードでは2つともONの状態にできるようになってしまい、if文の書き方が

  • 受付中

    iOSでドロワーを開いた際にコンテンツ側のスクロールを無効にしたい。

    iOS11や10などで、ドロワーを開いた際はコンテンツ側はドロワーの下に隠れるようになりますが、コンテンツ側もスクロールできてしまいます。 ドロワーを開いた際にコンテンツ上にバック

  • 解決済

    JavaScriptで入力用サブウィンドウ作成

     前提・実現したいこと 「visual basic」などでのプログラミングは慣れているのですが、 「JavaScript」の初心者です。 大変恐縮ですが、JavaScriptで

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

  • jQuery

    6522questions

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

  • jQueryプラグイン

    477questions

    jQueryの拡張機能。 様々な種類があり、その数は膨大です。公開済みのプラグインの他にも、自作することもできます。 jQueryで利用できるようにしておくだけで、導入およびカスタマイズが比較的容易に行なえます。