flagによってhtmlを変えるボタンを2つ、スイッチのように動かす

投稿者: Anonymous

box1とbox2のボタンはクリックすると中の文字が変わるようになっています。
htmlを変えるので、toggleclassではうまくいきません。

やりたいことは、
box1が開いているときにbox2を押すと、box1は閉じて、box2が開き、
box2が開いているときにbox1を押すと、box2は閉じて、box1が開くということなのですが、あと1歩(???)のところでうまくいきません

お互いが開いているのかどうか、要素をlengthやvisibleなんかで参照して、開いていたら.clickでお互いを押させて相手を閉じさせるように試みていますが、片方しかうまくいきません。

再現できるコードこちらです。どなたかお願いサミアドンします

html

<div class="wrapping">
<div class="buttontoggle1">
<div>box1</div>
    </div>

    <div class="content1">
green1
    </div>
</div>

<div class="wrapping">
<div class="buttontoggle2">
<div>box2</div>
    </div>

    <div class="content2">
green2
    </div>

    </div>

css

.wrapping{
position:relative;float:left;margin-right:20px;}
.content1,.content2{
    display:none;
    position: absolute;
    top: 50px;
    width:50px;
    height:50px;
    background-color:green;
}

.buttontoggle1,.buttontoggle2{
float:left;
width: 50px;
height:50px;
background-color:red;
    margin-right:10px;
}

.close1,.close2{
    height:50px;
    width:50px;
    border:white solid 2px;
}

.active{background-color:blue;}

Jquery

<!--box1 -->
<script>
$(function(){
  $(".content1").css("display","none");
  $(".buttontoggle1").on("click", function() {
    $(".content1").slideToggle();
    $(this).toggleClass("active");
  });
});
</script>

<script>
$(function(){
  var flg = "off";
  $('.buttontoggle1').on('click', function(){
    if(flg == "off"){
      $(this).html("<div class='close1'>clicked</div>");
      flg = "on";
    }else{
      $(this).html("<div>box1</div>");
      flg = "off";
    }
  });
});
</script>

<script>
$(function () {
  $(".buttontoggle1").click(function (e) {
   if($(".content1").length>0)
      $(".content1").show();
      e.stopPropagation();
   });
});

   $(document).click(function() {
    if($(".close1").length>0)
     $(".buttontoggle1").click();
});
</script>




<!--box2 -->
<script>
$(function(){
  $(".content2").css("display","none");
  $(".buttontoggle2").on("click", function() {
    $(".content2").slideToggle();
    $(this).toggleClass("active");
  });
});
</script>

<script>
$(function(){
  var flg = "off";
  $('.buttontoggle2').on('click', function(){
    if(flg == "off"){
      $(this).html("<div class='close2'>clicked</div>");
      flg = "on";
    }else{
      $(this).html("<div>box2</div>");
      flg = "off";
    }
  });
});
</script>

<script>
$(function () {
  $(".buttontoggle2").click(function (e) {
   if($(".content2").length>0)
      $(".content2").show();
      e.stopPropagation();
   });
});

   $(document).click(function() {
    if($(".close2").length>0)
     $(".buttontoggle2").click();
});
</script>




<!--ここから先で互いにボタンを押させようとしています -->

<script>
$(function(){
$('.buttontoggle2').on('click', function(){
if($(".close1").length>0)
$(".buttontoggle1").click();
});
});
</script>


<script>
$(function(){
$('.buttontoggle1').on('click', function(){
if($(".close2").length>0)
$(".buttontoggle2").click();
});
});
</script>

解決

ポイントは2つあって
(1)クリックイベントが実行されたときにクリックイベントをつなげて発火してしまっているのでおそらく混乱している
(2)トグル操作で何もかもやろうとしている。

Javascriptでイベントとアクションをまず切り離す作業をしたほうがいいです。

まずはイベントとしては
トグル1の領域をクリックする
トグル2の領域をクリックする
それ以外の領域をクリックする

の3つがあります。

次にアクションは
トグル1の領域をclickedにする&トグル1の領域のgreen1を表示する
トグル2の領域をclicledにする&トグル2の領域のgreen2を表示する
トグル1の領域をboxにする&トグル1の領域のgreen1を非表示する
トグル2の領域をboxにする&トグル2の領域のgreen2を非表示する
の4つがあります。

これらアクションは関数化しておくと良いでしょう。
openToggle1
openToggle2
closeToggle1
closeToggle2

ポイントはtoggle~は使わないことです。
明確に表示する&非表示にするというアクションをしましょう。

次にこれらをつなげます。
例えば
トグル1の領域をクリックしたら
トグル1の領域が閉じていればopenToggle1&closeToggle2を実行
もしくはトグル1の領域が開いていればcloseToggle1を実行

トグル2の領域をクリックしたら
トグル2の領域が閉じていればopenToggle2&closeToggle1を実行
もしくはトグル2の領域が開いていればcloseToggle2を実行

それ以外の領域をクリックしたら
トグル1の領域が開いていればcloseToggle1を実行
トグル2の領域が開いていればcloseToggle2を実行

_x000D_

_x000D_

$(function(){_x000D_
  $(".content1").css("display","none");_x000D_
  $(".buttontoggle1").on("click", function(e) {_x000D_
    if($(".close1").length == 0){_x000D_
      openToggle1();_x000D_
      closeToggle2();_x000D_
    }else{_x000D_
      closeToggle1();_x000D_
    }_x000D_
    e.stopPropagation();_x000D_
  });_x000D_
});_x000D_
_x000D_
$(function(){_x000D_
  $(".content2").css("display","none");_x000D_
  $(".buttontoggle2").on("click", function(e) {_x000D_
    if($(".close2").length == 0){_x000D_
      openToggle2();_x000D_
      closeToggle1();_x000D_
    }else{_x000D_
      closeToggle2();_x000D_
    }_x000D_
    e.stopPropagation();_x000D_
  });_x000D_
});_x000D_
_x000D_
$(document).click(function(e) {_x000D_
  if($(".close1").length>0) closeToggle1();_x000D_
  if($(".close2").length>0) closeToggle2();_x000D_
  _x000D_
_x000D_
});_x000D_
_x000D_
_x000D_
_x000D_
function openToggle1() {_x000D_
    $(".content1").slideDown();_x000D_
    $(".buttontoggle1").addClass("active");_x000D_
    $(".buttontoggle1").html("<div class='close1'>clicked</div>");_x000D_
}_x000D_
_x000D_
function openToggle2() {_x000D_
    $(".content2").slideDown();_x000D_
    $(".buttontoggle2").addClass("active");_x000D_
    $(".buttontoggle2").html("<div class='close2'>clicked</div>");_x000D_
}_x000D_
_x000D_
function closeToggle1() {_x000D_
      $(".content1").slideUp();_x000D_
      $(".buttontoggle1").removeClass("active");_x000D_
      $(".buttontoggle1").html("<div>box1</div>");_x000D_
}_x000D_
_x000D_
function closeToggle2() {_x000D_
      $(".content2").slideUp();_x000D_
      $(".buttontoggle2").removeClass("active");_x000D_
      $(".buttontoggle2").html("<div>box2</div>");_x000D_
}

_x000D_

.wrapping{_x000D_
position:relative;float:left;margin-right:20px;}_x000D_
.content1,.content2{_x000D_
    display:none;_x000D_
    position: absolute;_x000D_
    top: 50px;_x000D_
    width:50px;_x000D_
    height:50px;_x000D_
    background-color:green;_x000D_
}_x000D_
_x000D_
.buttontoggle1,.buttontoggle2{_x000D_
float:left;_x000D_
width: 50px;_x000D_
height:50px;_x000D_
background-color:red;_x000D_
    margin-right:10px;_x000D_
}_x000D_
_x000D_
.close1,.close2{_x000D_
    height:50px;_x000D_
    width:50px;_x000D_
    border:white solid 2px;_x000D_
}_x000D_
_x000D_
.active{background-color:blue;}

_x000D_

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>_x000D_
<div class="wrapping">_x000D_
<div class="buttontoggle1">_x000D_
<div>box1</div>_x000D_
    </div>_x000D_
_x000D_
    <div class="content1">_x000D_
green1_x000D_
    </div>_x000D_
</div>_x000D_
_x000D_
<div class="wrapping">_x000D_
<div class="buttontoggle2">_x000D_
<div>box2</div>_x000D_
    </div>_x000D_
_x000D_
    <div class="content2">_x000D_
green2_x000D_
    </div>_x000D_
_x000D_
    </div>

_x000D_

_x000D_

_x000D_

本来は上のソースに表示非表示制御をきれいにするために「状態」を意識してflg制御や動作フローを考えると良いですが、今回はclose1close2があるかどうかで切り替えを行っています。
今はまずはイベントとアクションが分けられる&トグルを使わないができれば良いと思います。

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *