0

100x100px の div がいくつかあります。

ここに画像の説明を入力

3 つのブロックの HTML コード:

<div id="plane">
   <div class="tile tile3" block-id="1" style-id="3" style="left:50px; top:50px"></div>
   <div class="tile tile1" block-id="2" style-id="1" style="left:150px; top:50px"></div>
   <div class="tile tile3" block-id="3" style-id="3" style="left:250px; top:50px"></div>
</div>

ssdiv をクリックすると、クリックした div/block を黄色にするというクラスを追加します。私はこれを次のコードで動作させています:

 el.innerHTML = html.join('');
       $(el).find('.tile').click(function () {
       var clickedBlock = $(this); 
       clickedBlock.addClass('ss'); 
 });

問題は、クリックしたブロック (div) にのみクラスを追加し、ss少なくとも 1 つの側面 (左または右) を解放したいことです。他のブロックが付かないように。スクリーンショットの場合、緑色のブロックは片面が透明なのでss、クリックするとクラスを取得できるはずです。赤いものには自由な面がないので、クリックしてもクラスは追加されません。

私はインターネットで解決策を検索し、いくつかのものを読んで、offsetこれtypeofを使用できると考えました。要するに、ブロックをクリックして、それを取得し、同じ(左側の場合)およびstyle left右側のtopdiv があるかどうかを確認します。あれば真を返す。片側が true または両側が false を返す場合 (左右にブロックがない場合)、ブロックは「フリー」であり、クリックされたブロックにクラスを追加する必要があります。style left -100+100top = 0ss

私はこのコードを試しました(成功しませんでした):

el.innerHTML = html.join('');
    $(el).find('.tile').click(function () {
        var clickedBlock = $(this); 
        var offset = $(this).offset(); //get the top and left px

        if (typeof clickedBlock[offset.left-100][offset.top=clickedBlock.attr('top')] == 'true') { //check the left side
            if (typeof clickedBlock[offset.left+100][offset.top=clickedBlock.attr('top')] == 'false') { //check the right side
                clickedBlock.addClass('ss'); 
            }
        } else { //if left side is already false, it really doesn't matter if the right side is clear or not since 1 side needs to be clear
                clickedBlock.addClass('ss'); 
        }
});

私の質問: これを機能させるにはどうすればよいですか? これはこれを行うための最良のアプローチですか、それともより良い方法がありますか? もしそうなら、どれですか?

また、次のオプションも可能です。

ここに画像の説明を入力

この HTML コードは次のとおりです。

<div id="plane">
  <div class="tile tile3" block-id="1" style-id="3" style="left:50px; top:50px"></div>
  <div class="tile tile1" block-id="2" style-id="1" style="left:150px; top:100px"></div>
  <div class="tile tile2" block-id="3" style-id="2" style="left:50px; top:150px"></div>
  <div class="tile tile3" block-id="4" style-id="3" style="left:250px; top:150px"></div>
</div>

ここでは、緑と青のブロックが「無料」です。したがって、この場合、left-100と、 、 、、でdivもチェックするようにコードを調整する必要があります。つまり、合計 6 つのチェック (左に 3 つ、右に 3 つ)top-50left-100top+50left+100top-50left+100top+50

結論として、(クリック時に)片側(または両方)が空いている場合は、ssクラスを追加します。私の質問が明確で、誰かが助けてくれることを願っています。

敬具

4

3 に答える 3

1

気分を害することはありませんが、あなたのアプローチは機能しているとは思えません。単一の要素を表すjQueryオブジェクトを、さまざまなオフセットによって魔法のようにインデックス付けされた多次元配列として扱い、ブール値を生成することを期待してtypeofを適用していますか? ここで非常に遅いので、すべて間違って読んでいる場合は申し訳ありません...

編集: http://jsfiddle.net/AcmLR/1/でフィドルを作成しました。いくつかの間違いを修正し、うまく機能しているようです。以下のコードも更新されます。

たぶん、次のようなことを試してください:

var tiles = $('.tile');
tiles.click(function(){
  var me = $(this); //To save a few lookups
  /*Read out the top and left attributes, remove 'px' to 
  get the numeric part and force them to be numbers using the + (not really needed)*/
  var myLeft = +me.css('left').replace('px', '');
  var myTop = +me.css('top').replace('px', '');
  var leftFree = true, rightFree = true; //Assume both sides are free to begin with
  tiles.not(me).each(function(){
    if(!leftFree && !rightFree){
      return; //No need processing any more boxes
    }
    var me = $(this); //To save a few lookups
    var left = +me.css('left').replace('px', '');
    var top = +me.css('top').replace('px', '');
    if(top < myTop-100 || top > myTop+100){
      return; //This box is completely above or below the clicked box
    }
    if(left == myLeft-100){
      leftFree = false;
      return;
    }
    if(left == myLeft+100){
      rightFree = false;
      return;
    }
  });
  if(leftFree || rightFree){
    me.addClass('ss'); //In this scope me still refers to the clicked box
  }
});

ボックスが移動するかどうかなど、正確な要件に応じて、より効率的またはコンパクトなソリューションが存在する場合があります。

于 2013-03-23T01:11:11.873 に答える
1

あなたの例では、次のように言うことができるようです:

$('.tile').on({
    click : function () {
        if($(this).css('left') != '150px') {
            $(this).addClass('ss');
        }
    }
});

中央の div だけがその特定の宣言を持つため、クリックされたものはすべて外側の div であることが常にわかります。

これは、コードが日常的にこの特定のものである場合に機能します。それがよりダイナミックで流れるようなものである場合 (div のグループが左に浮いているとします)、上に投稿したものと同様のことを行うことができます。

$('.tile').on({
    click : function () {
        var prevEleOffSet = $(this).prev('.tile').offset().left,
            nextEleOffSet = $(this).next('.tile').offset().left,
            thisEleOffSet = $(this).offset().left;

        if(prevEleOffSet > thisEleOffSet || nextEleOffSet < thisEleOffSet) {
            $(this).addClass('ss');
        }
    }
});

まず、クリックした $('.tile') の prev('.tile') が画面の左端にあるかどうかを確認します。そうであれば、上の行にあると推測できます。prev('.tile') が同じ行にあることが判明した場合は、next('.tile') を確認します。クリックした $('.tile') ほど左にない場合は、クリックした div のすぐ隣ではなく、次の行にあると想定できます。

これらのステートメントのいずれかが当てはまる場合、私たちはあなたのクラスを平手打ちし、黄色に変えて、私たちの仕事に取り掛かります.

それが役立つことを願っています。

于 2013-03-23T02:42:51.433 に答える
0

私は何かを試してみますが、これはすべての場合にうまくいくとは限りません

1番目-そのボックス内のすべてのdivをループし、「左」のcss値(Jqueryオフセットまたはcss)を収集して配列に保存します。しかし、私はそれらすべてを収集するのではなく、独自の値を取ります。したがって、(50,50,150,200,200) の左に 5 div です。(50,150,200)だけ集めます。(これは while ループで簡単に実行できます)。

2 番目 - 配列の長さが 2 より大きいかどうかを確認します。<=2 の場合、すべてのボックスが黄色に変わる可能性があります。

3番目 - >2の場合、最初と最後の値のみが黄色に変わるボックスの値です

繰り返しますが、これは単一の行がある場合に理想的に機能します。複数の行がある場合は、それらの配置を互いに確認する必要があります...

それが私のベストショットでした@_o

于 2013-03-23T01:02:34.030 に答える