2017-10-18 8 views
3

div.textが別のもの(親の中のdiv#element)の上にあるときに検出しようとしていますが、重なりの存在によって親の背景が変わるはずです。奇妙な振る舞いでのテキストの重なり検出

スクリプトが重複していない場合でも、.textはそれぞれの位置を再度比較するため、この問題が発生する可能性があります。

$(".text").each(function() { 
 
    var self_text = $(this), 
 
    self_textid = self_text.attr('id'), 
 
    self_textLeft = self_text.position().left, 
 
    self_textTop = self_text.position().top, 
 
    self_textWidth = self_text.width(), 
 
    self_textHeight = self_text.height(); 
 

 
    $(".text").each(function() { 
 
    var self_shape = $(this), 
 
     self_shapeLeft = self_shape.position().left, 
 
     self_shapeTop = self_shape.position().top, 
 
     self_shapeWidth = self_shape.width(), 
 
     self_shapeHeight = self_shape.height(); 
 

 
    // check if .text overlaps 
 
    if (
 
     (self_textLeft + self_textWidth) > self_shapeLeft && 
 
     self_textLeft < (self_shapeLeft + self_shapeWidth) && 
 
     (self_textTop + self_textHeight) > self_shapeTop && 
 
     self_textTop < (self_shapeTop + self_shapeHeight) 
 
    ) { 
 
     // overlap 
 
     $('#elements').css('background', 'red'); 
 
    } else { 
 
     // no overlap 
 
     $('#elements').css('background', 'green') 
 
    } 
 
    }); 
 
});
#elements, 
 
.text { 
 
    position: absolute; 
 
} 
 

 
.text { 
 
    width: 50px; 
 
    background: blue; 
 
} 
 

 
#elements { 
 
    height: 250px; 
 
    width: 400px; 
 
    background: yellow; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="elements"> 
 
    <div class="text" style="left: 20px; top: 20px;">text1</div> 
 
    <div class="text" style="left: 100px; top: 50px;">text2</div> 
 
    <div class="text" style="left: 10px; top: 200px;">text3</div> 
 
    <div class="text" style="left: 10px; top: 45px;">text4</div> 
 
</div>

はどのようにしても、そのコードが改善される可能性がどのような方法があり、それは.textクラスを変更することなく、再びループするたび自体を無視するためのスクリプトを伝えることができますか?

答えて

4

あなたはdiv要素自体がないようにそれを追加してみてください、に対してチェックするために含まれているためにです:

var $textDivs = $(".text"); // cache this so you are not performing the lookup every time in your loop 
 
$textDivs.each(function() { 
 
    var self_text = $(this), 
 
    self_textid = this.id, 
 
    self_textLeft = self_text.position().left, 
 
    self_textTop = self_text.position().top, 
 
    self_textWidth = self_text.width(), 
 
    self_textHeight = self_text.height(), 
 
    hasNotMatched = true; 
 

 
    $textDivs.not(self_text).each(function() { // added to a not so not checked against itself 
 
    var self_shape = $(this), 
 
     self_shapeLeft = self_shape.position().left, 
 
     self_shapeTop = self_shape.position().top, 
 
     self_shapeWidth = self_shape.width(), 
 
     self_shapeHeight = self_shape.height(); 
 

 
    // check if .text overlaps 
 
    if (
 
     (self_textLeft + self_textWidth) > self_shapeLeft && 
 
     self_textLeft < (self_shapeLeft + self_shapeWidth) && 
 
     (self_textTop + self_textHeight) > self_shapeTop && 
 
     self_textTop < (self_shapeTop + self_shapeHeight) 
 
    ) { 
 
     // overlap 
 
     $('#elements').css('background', 'red'); 
 
     hasNotMatched = false; 
 

 
     return false; // break out of each loop so as no need to process anymore and so overlap doesn't turn back green 
 
    } else { 
 
     // no overlap 
 
     $('#elements').css('background', 'green') 
 
    } 
 
    }); 
 
    
 
    return hasNotMatched; // this will break out of outer loop if matched on inner loop 
 
});
#elements, 
 
.text { 
 
    position: absolute; 
 
} 
 

 
.text { 
 
    width: 50px; 
 
    background: blue; 
 
} 
 

 
#elements { 
 
    height: 250px; 
 
    width: 400px; 
 
    background: yellow; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="elements"> 
 
    <div class="text" style="left:20px; top:20px;">text1</div> 
 
    <div class="text" style="left:100px; top:50px;">text2</div> 
 
    <div class="text" style="left:90px; top:40px;">text3</div> 
 
    <div class="text" style="left:190px; top:30px;">text4</div> 
 
</div>

+0

背景がまだ重複と緑のまま:https://jsfiddle.net/brwzf44w/2/は、任意のは、私はしませんでした別の問題がある。このよう

思った? – Lindow

+0

@Lidow、上記の答えを編集しました - 重複している要素を取得したときにループから脱出する必要があります。そうでなければ、続行すると緑色に戻り、別の要素は重複しません。 fiddleが更新されました:https://jsfiddle.net/brwzf44w/4/ – Pete

+0

.textが別のものの後にある場合は、それでも動作しません。https://jsfiddle.net/brwzf44w/6/ – Lindow

2

はあなたがあります

$(".text").not($(this)) 

で現在の要素を除外することができますまた、ソリューションのロジックに関する問題 - 最後にチェックされた要素が重複しない場合は、背景が緑に変わります。これを処理する1つの方法は、バックグラウンドをデフォルトとして緑色に設定することです。重なりが検出された場合は、背景を赤に変更します。

オーバーラップが検出されるとすぐに終了するような最適化がいくつか追加されています。

$(".text").each(function() { 
 
    $('#elements').css('background', 'green'); 
 

 
    var self_text = $(this), 
 
    self_textid = self_text.attr('id'), 
 
    self_textPosition = self_text.position(), 
 
    self_textLeft = self_textPosition.left, 
 
    self_textTop = self_textPosition.top, 
 
    self_textWidth = self_text.width(), 
 
    self_textHeight = self_text.height(); 
 

 
    $(".text").not($(this)).each(function() { 
 
    var self_shape = $(this), 
 
     self_shapePosition = self_shape.position(), 
 
     self_shapeLeft = self_shapePosition.left, 
 
     self_shapeTop = self_shapePosition.top, 
 
     self_shapeWidth = self_shape.width(), 
 
     self_shapeHeight = self_shape.height(); 
 

 
    // check if .text overlaps 
 
    if (
 
     (self_textLeft + self_textWidth) > self_shapeLeft && 
 
     self_textLeft < (self_shapeLeft + self_shapeWidth) && 
 
     (self_textTop + self_textHeight) > self_shapeTop && 
 
     self_textTop < (self_shapeTop + self_shapeHeight) 
 
    ) { 
 
     // overlap 
 
     $('#elements').css('background', 'red'); 
 
    } 
 
    }); 
 
});
#elements, 
 
.text { 
 
    position: absolute; 
 
} 
 

 
.text { 
 
    width: 50px; 
 
    background: blue; 
 
} 
 

 
#elements { 
 
    height: 250px; 
 
    width: 400px; 
 
    background: yellow; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="elements"> 
 
    <div class="text" style="left: 20px; top: 20px;">text1</div> 
 
    <div class="text" style="left: 100px; top: 50px;">text2</div> 
 
    <div class="text" style="left: 10px; top: 200px;">text3</div> 
 
    <div class="text" style="left: 10px; top: 45px;">text4</div> 
 
</div>

+0

背景はまだ重複して緑色のままです:jsfiddle.net/brwzf44w/2私が考えなかった他の問題はありますか? – Lindow

+0

はい、ロジックにエラーがあります。私は解決策を更新しました。 –

+0

まだ、.textが別のものの後に続く場合、それはそれと動作しません:jsfiddle.net/brwzf44w/7 – Lindow