我想弄清楚子元素在父元素中是否可见。通过这样做,我测试父母的width
是否大于或小于孩子position().left
。
由于我有许多单独的父元素和子元素,因此我运行each
个函数。
//Each p in instagram feed
jQuery('#instagram-feed .meta-data p').each(function(){
// Get width of this p element
var parentWidth = jQuery(this).width();
// Each a element within this p
jQuery(this).children('a').each(function(){
// Compare p element width of with position of this a
if(parentWidth < jQuery(this).position().left) {
// If position is larger then width
jQuery(this).css('color', 'green');
console.log("Not inside element");
} else {
// If position is smaller then width
jQuery(this).css('color', 'red');
console.log("Inside element");
}
console.log(jQuery(this).position().left);
});
});
我做了一个小提琴,你可以看到并测试:http://jsfiddle.net/fprm7mgd/9/(确保三个元素是水平的,以便看到&#34; bug&#34;)
问题在于,在第三个父元素中,似乎position().left
从第一个父元素或父元素上方计数。为什么第三个父级中的链接变为绿色?因为它在父母的内部,所以应该是红色的...我做错了什么?
答案 0 :(得分:2)
您可以使用jQuery(this).position().left - parent.position().left
来计算a
元素的左侧,如下所示:
//Each p in instagram feed
jQuery('#instagram-feed .meta-data p').each(function(){
// Get width of this p element
var parentWidth = jQuery(this).width();
var parent = jQuery(this);
// Each a element within this p
jQuery(this).children('a').each(function(){
var elementLeft = jQuery(this).position().left - parent.position().left;
// Compare p element width of with position of this a
if(parentWidth < elementLeft) {
// If position os larger then width
jQuery(this).css('color', 'green');
console.log("Not inside element");
} else {
// If position os smaller then width
jQuery(this).css('color', 'red');
console.log("Inside element");
}
// ...
});
});
看到这个工作小提琴:http://jsfiddle.net/fprm7mgd/29/
答案 1 :(得分:1)
如果您阅读jQuery.position
的文档,您会发现该位置相对于offset parent 是。示例中的偏移父项是<html>
元素,所有左侧值都与该元素相关。
解决方案是为CSS添加一个小调整:制作段落元素position: relative
。
jQuery(window).on("load resize", function() {
jQuery("#instagram-feed .meta-data p").each(function() {
var parentWidth = jQuery(this).width();
console.log("parent", this, "width", parentWidth);
jQuery(this).children("a").each(function() {
var childLeft = jQuery(this).position().left;
console.log("child", this, "left", childLeft, "offset parent", this.offsetParent);
if (parentWidth < childLeft) {
jQuery(this).css("color", "green");
} else {
jQuery(this).css("color", "red");
}
});
});
});
&#13;
.meta-data {
float: left;
margin-right: 50px;
}
p {
width: 160px;
padding: 5px;
white-space: nowrap;
background: silver;
display: inline-block;
/* added */
position: relative;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="instagram-feed">
<div class="meta-data">
<p>fgdfgfdg fdgf df df <a href="#">link</a></p>
</div>
<div class="meta-data">
<p>fgdfgfdg fdgf df df dsfsdf <a href="#">link</a></p>
</div>
<div class="meta-data">
<p>fgdfgfdg fdgf <a href="#">link</a></p>
</div>
</div>
&#13;
答案 2 :(得分:1)
offset
而不是position
来更安全。那是因为根据http://api.jquery.com/offset/:.offset()方法允许我们检索一个的当前位置 元素相对于文档。将此与.position()对比, 它检索相对于偏移父项的当前位置
offset
或position
会返回包含left
和top
属性的对象。您真正需要比较的是left
锚点与父级right
。因此,只需将父{的width
添加到其offset().left
即可。现在将其与主播的left
进行比较。像这样:
$('#instagram-feed .meta-data').each(function(){
var parentRight = $(this).offset().left + $(this).width();
$(this).find('a').each(function(){
var self = $(this);
if(self.offset().left > parentRight) {
self.css('color', 'green');
} else {
self.css('color', 'red');
}
});
});
演示小提琴:http://jsfiddle.net/abhitalks/fprm7mgd/33/
演示代码段
$('#instagram-feed .meta-data').each(function(){
var parentRight = $(this).offset().left + $(this).width();
$(this).find('a').each(function(){
var self = $(this);
if(self.offset().left > parentRight) {
self.css('color', 'green');
} else {
self.css('color', 'red');
}
});
});
.meta-data {
float: left;
margin-right: 50px;
border: 1px solid #ddd;
}
p {
width: 160px;
padding: 5px;
white-space: nowrap;
background: silver;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="instagram-feed">
<div class="meta-data">
<p>
fgdfgfdg fdgf df df <a href="#">link</a>
</p>
</div>
<div class="meta-data">
<p>
fgdfgfdg fdgf df df dsfsdf <a href="#">link</a>
</p>
</div>
<div class="meta-data">
<p>
fgdfgfdg fdgf <a href="#">link</a>
</p>
</div>
</div>
更好的解决方案是使用Javascript getBoundingClientRect方法,该方法返回元素的大小及其相对于视口的位置。
var parents = document.querySelectorAll('.meta-data');
[].forEach.call(parents, function(elem) {
var parentBounds = elem.getBoundingClientRect(),
anchor = elem.getElementsByTagName('A')[0],
anchorBounds = anchor.getBoundingClientRect()
;
if (anchorBounds.left > parentBounds.right) {
anchor.classList.add('red');
} else {
anchor.classList.add('green');
}
});
演示小提琴2:http://jsfiddle.net/abhitalks/n0ak4y7w/
Demo Snippet 2:
var parents = document.querySelectorAll('.meta-data');
[].forEach.call(parents, function(elem) {
var parentBounds = elem.getBoundingClientRect(),
anchor = elem.getElementsByTagName('A')[0],
anchorBounds = anchor.getBoundingClientRect()
;
if (anchorBounds.left > parentBounds.right) {
anchor.classList.add('green');
} else {
anchor.classList.add('red');
}
});
.meta-data {
float: left;
margin-right: 50px;
border: 1px solid #ddd;
}
p {
width: 160px;
padding: 5px;
white-space: nowrap;
background: silver;
display: inline-block;
}
.red { color: #f00; }
.green { color: #3c3; }
<div id="instagram-feed">
<div class="meta-data">
<p>
fgdfgfdg fdgf df df <a href="#">link</a>
</p>
</div>
<div class="meta-data">
<p>
fgdfgfdg fdgf df df dsfsdf <a href="#">link</a>
</p>
</div>
<div class="meta-data">
<p>
fgdfgfdg fdgf <a href="#">link</a>
</p>
</div>
</div>
答案 3 :(得分:0)
最终解决方案:
//This will only work properly if margin-left and margin-right is equal. Same for padding.
function removefromTabindex(myElement, ellipsisSize){
var ellipsisSizeInit = ellipsisSize;
if (ellipsisSizeInit === undefined || ellipsisSizeInit === null) {
ellipsisSizeInit = 0;
}
jQuery(myElement).each(function(){
var myMargin = (jQuery(this).outerWidth(true) - jQuery(this).width()) / 2;
myMargin = myMargin + ellipsisSizeInit;
var parentRight = (jQuery(this).position().left + jQuery(this).outerWidth(true)) - myMargin;
jQuery(this).find('a').each(function(){
if((jQuery(this).position().left) > parentRight) {
jQuery(this).attr('tabindex', '-1');
} else {
if ( jQuery(this).attr('tabindex') === '-1') {
jQuery(this).removeAttr('tabindex')
}
}
});
});
};
//Run function
jQuery(document).ready(function(){
removefromTabindex('#instagram-feed .meta-data p');
});
//For a responsive view
jQuery(window).resize(function () {
removefromTabindex('#instagram-feed .meta-data p');
});
这包括填充和边距,但只有当左边和右边的边距和填充相等时才能正常工作,因为我没有找到任何完美的方法来获取边距和填充作为int像素(如果边距由百分比或ems设置)。我必须通过元素的内部和外部宽度来计算边距和填充。
它在开始时加载,但也在调整大小时加载,以确保它在响应式设计中重新计算值。现在也可以通过参数向函数添加更多元素。还添加了省略号宽度作为参数,以便您可以将该宽度添加到计算中。
通过使用此脚本,您可以使用CSS缩短文本并从tab-index中删除溢出的链接,这可能是一件好事。