I have a slider that contains N elements. Each element will by translated by N pixels when the user click on the next button. When the element is out of the wrapper div, it disappears because it is overflowed by another element.
My plugin does not use any margins, just the transform property.
I would like to know if there is a way to know if my element is out of the div. :visible does not work for my problem because the element is already visible but overflowed.
If I understand correctly, one way to do it would be to compare the position of this element to the size (width/height or both) of his parent.
With Jquery you could do it this way:
<script>
//This is the position of the right side of the element
//relative to his parent
var rightPos = $("#element").position().left + $("#element").width();
//And bottom side
var botPos = $("#element").position().top + $("#element").height();
if (rightPos > $("#element").parent().width()) {
//The element is outside the right limit of the the parent block
} else if (botPos > $("#element").parent.height()) {
//It's outside the bottom limit of the parent block
}
</script>
If it's not the parent you could then adapt this code to compare the position to the width of the correct div, preferably by using the jquery offset() method instead of position().
By determine parent width and get child width then use if condition
if($('span').width() > divWidth){
alert('Overflowed!');
// do something!
}
jsFiddle Demo
if you update your question with your html then I can update with your codes.
You could give the wrapper div the CSS property of overflow: hidden
This would mean that any elements inside of it are not visible when they leave the bounds of the wrapper.
Otherwise you could check whether your element is outside of the wrapper div using jQuery to compare the position to that of the parent.
There is a nice tool for testing if an element is visible on the screen.
Detect if a DOM Element is Truly Visible
It looks at an object and checks each of its parents to see if it’s still visible to the user.
Related
I have something like a carousel with elements inside of a container with overflow: hidden
I can scroll left and right and I want to determine which elements are not visible at all or only half is visible (like on this picture) and when add to this invisible and half visible elements a class.
Width of each element is for example 100px but width of container depends on screen size. I can get number of elements which are visible (by dividing offsetWidth of container by width of one element)
Alse I know that there is such thing as getBoundingClientRect() but not sure how to use it in this case.
example
Here you can see how I try to implement getBoundingClientRect but I can't figure out which elements to target. I want to add class to the div which is partially seen (4th) and if on the first click part of the first div would be seen - to it too.
I used this code.
Math.abs($('.hd-termometro').offset().top - $('.ft-termometro').offset().top);
to try to get the distance between 2 divs. I do it with this code, but my page automatically refreshes and the second div is zero. There is another method to calculate the distance ?.
I did this in jquery. perhaps angular another method exists.
Usually i do this in order to resize the middle to push the footer at the bottom of my page.
For this i take the window.height and i remove the height of my header and footer element. Then i bind a listener to a resize event of the object window to recomptue the height whenever it's needed.
If we want to make it general this would mean to take the height of the parent component and substract the 1st and the last and add a $watch on the whole height of the parent element.
However height and width properties in javascript (and even jquery) are tricky. They don't compute the whole height taken by the element. Margins and border are excluded.
So in orde to get the right thing you have to wrapped your element with an inner padding
<section id="header">
<div id="header-content">[content]</div>
</section>
With header having a padding property on it (if you need) and header-content having the border (if you need it). Then you can get the height of your header by looking for height element.
This has not really anything to do with angular, the only thing is the $watch part to detect changes. But if it's for header/footer like me, you can just use raw javascript to listen for window resize.
Do it in a function so that you can reuse it
function getDistance() {
var div1 = $('.hd-termometro');
var div2 = $('.ft-termometro');
return div2.offset().top - (div1.offset().top + div1.height())
}
Using it for the first time
$scope.distance = getDistance();
Update scope when distance changes
$(window).resize(function(){
$scope.distance = getDistance();
});
I am adding elements like div dynamically in the page using jquery.The div CSS is position : absolute .Now my problem is when i add more than 1 div element at the same time than it all overlaps each other. Is there any way so that without changing my element's position property these are not overlaps?
Check out masonry plugin. It is dynamic layout plugin that auto arranges the div elements as the new elements are added in document it prevents the overlaps of the elements. Check out this link.
Simply specify the container div let it with id container you need to call function
$(".container").masonry();
and then when you add more div inside container you just need to call the function
var $newElems = $( newElements );
$(".container").masonry( 'appended', $newElems );
You define place of absolutely positioned objects with top, bottom, left, right css properties . So you have to alter these dynamically as well.
For example: The first element has top: 0, left:0 , the second top: 0, left: 50 and so forth...
When you add an element as positioned absolute and provide no valid top and left values the element will be positioned absolutes with both top and left as 0.
In your case all the elements you are adding should be taking position (0,0) so they are overlapping one above other.
One solution is to calculate the positions of each and layout them using adding corresponding top and left values to them along sith css({'position' : 'absolute'}) but that requires some math in most cases.
Dont worry, your browser already knows that math and you can use it in most cases, so add the divs without 'position' 'absolute'. Now browser layouts them well. After the browser has finished laying out them, take the DIVs and get their present position and use the position to layout them using absolute position.
for(var i=0; i < noOfDivs; i++){
{
$('#parentDiv').append('<div class="childDiv"/>');
}
$('.childDiv').css({
'position': 'absolute,
'top' : $(this).position().top,
'left' : $(this).position().left
});
The code is not tested, if DIVs are positioned one by one it should again cause problems, you should either iterate them from last to first or save all positions and apply them later. If jQuery is updating all positions in a single DOM access this will work fine.
I have a DIV with some text inside. But the height of the DIV starts at 0px, it also has an 'overflow:hidden'. After that i'm using an animation system to increase the height of the DIV. But i can't give the DIV a fixed height because the length of the text inside the DIV varies.
Is there a way to tell what the height of the DIV will be when its big enough to fit all content inside it?
I have done a horrible hack but see if this is good enough.
Basically you get the content height by setting the height to auto, then resetting it to zero and finally using your animation function, like this :
var tempHeight = $(".sample").css({"height" : "auto"}).height();
$(".sample").css({"height" : "0px"}).animate({
height : tempHeight
},1000);
Where .sample is the reference to the div with the variable text content. Check out the demo for a better understanding.
Pure Javascript Version :
document.getElementById("sample").style.height = "auto"; //The id of this div is 'sample'
var tempheight = document.getElementById("sample").offsetHeight;
document.getElementById("sample").style.height = "0px";
/*
Custom Animation function, Use tempheight to get the full content
*/
DEMO For The Jquery Version
Maybe you can try this:
Put the text inside another DIV like...
<div>
<div>some text</div>
</div>
Then animate the outer div (which as an hidden overflow) according to the height of the inner div (which has not an hidden overflow).
Hope this helps
Depending on what you're doing/using you don't need to know the height because setting it to "auto" will ensure it expands to fill the content.
However, you could also not set the heights to 0 until you know the height by using javascript to get it. For example in jQuery:
$("div").each(function()
{
$(this).attr("data-height", $(this).height()).css({"height": "0", "overflow": "hidden");
});
Now each div has an attribute called "data-height" that has the value of it's original height. You can then use this to expand the div when you need to.
Just before animating the showing of the div, clone the div and get rid of the height:0px constraint (change the height to auto, for example). Then grab the height of that cloned div for use in your animation.
In jQuery, this would look something like:
var myDiv = $('div');
var myDivClone = div.clone().insertAfter(myDiv).css('height','auto');
var myDivHeight = myDivClone.outerHeight();
myDivClone.remove();
myDiv.animate({height: myDivHeight}, 250);
Note the importance of actually cloning the element in question as opposed to just creating a new one and filling it with the same contents. You need to recreate the element exactly (other than the height modification you do afterwards), including classes, etc.
ALSO note the importance of injecting it into the DOM immediately after myDiv. This is so that the same CSS will affect it as affects myDiv at time of height calculation. The only potential exception to this is if you're using a :last-child selector in your CSS, and the clone ends up becoming the last child of the parent element. But that kind of issue should be easy enough to get around.
how about dropping the text in a off screen div first and getting the dimensions from that?
if(el.scrollHeight > el.offsetHeight || el.scrollWidth > el.offsetWidth)
{
//keep making element bigger
el.style.height = parseInt(el.style.height) + 2 + "px"
}
You could stick this snippet inside some sort of recursive function or while loop. Essentially you are checking to see if there is more content outside of the viewable area that a scroll-bar would show.
I'm trying adding fancy close buttons dynamically to html elements
code is:
function add_close_box(element,img_close_box,base_url_close_box){
var i;
$.each($('.'+element),function(i){
$(this).addClass('close_box'+i);
var x = $('.close_box'+i).offset().left;
var y = $('.close_box'+i).offset().top;
$('body').append('<img src="'+base_url_close_box+img_close_box+'">');
$('.img_close_box_'+i).css({'position':'absolute','top':y-10,'left':x+$('.close_box'+i).width()-20});
$('.img_close_box_'+i).live('click',function(){
var hei = $('.'+element).height();
$('.img_close_box_'+i+','+'.close_box'+i).hide();
$.each('.'+element,function(e){
$('.img_close_box_'+(e)).animate({
'top':'-='+hei
},0);
});
});
});
}
it works good but when click on button and element is fadeOut() other close buttons doesn't follows their own related element cause of absolute position they remain in same positions while elements scroll up (first element fadeOut next element scroll up and close button remain in same position)
i would like that close buttons could follow their related element.
Also cause my lazy mind i would like to know if anyone knows some good jquery plugin to do what I'm trying to code, something with also ajax callback after closebox button click (do not reply to watch jQuery UI please :) )
thanks ;)
I have to make a few assumptions because you haven't posted your markup. I think Diodeus is on the right track. You're using absolute positioning for your new close button. Absolute positioning will look up in the DOM until it finds a relatively positioned element to anchor the coordinates. if the element you pass in doesn't have the property position:relative then the button could be positioned anywhere.
Two possible fixes:
Add relative positioning to everything you add the close button to:
element.css({'position':'relative'});
Obviously this will replace any other previously set positioning. There's a chance this blows up your layout if you're adding close buttons all over the place.
The second option is to make sure the only relatively positioned element is something high in the DOM, so all of your close buttons are positioned based on the same thing. It's a little hacky, but then you can position them based on the x and y of the element:
var x = element.position().x;
var y = element.position().y;
// you can add the necessary offsets like element width or height