Getting the height of an iframe including only the rendered elements - javascript

I am trying to calculate the minimum height an iframe needs to be fully displayed.
To realise this, I tried the following approach:
var neededSize = $(window.document).height();
// Get the jquery of the parent in order to resize the frame
var par = window.parent;
if(par != null) {
var jq = par.jQuery;
var frameParent = jq('#' + window.frameElement.id);
frameParent.height(neededSize);
}
The problem with this approach is that the iframe contains some hidden elements (display: none;). When I use jQuery.height() it returns the minimum height it needs including the hidden elements.
Does anyone know an approach through jquery or standard javascript to get the minimum height excluding the height the hidden divs take or should i calculate this myself? (get all the hidden fields and substract each height?)

Try wrapping it in the document ready handler shorthand:
$(function(){
//your code here
});
Documentation:
The handler passed to .ready() is guaranteed to be executed after the DOM is ready, so this is usually the best place to attach all other event handlers and run other jQuery code. When using scripts that rely on the value of CSS style properties, it's important to reference external stylesheets or embed style elements before referencing the scripts.
So the code will be executed after all DOM elements are rendered. And probably the height is consistent then with the hidden elements. (they are probably shown in a split second because the .css is still loading)

Related

Is this jQuery code consistent across all versions?

I've read somewhere that when you capture a jQuery object in a variable, say:
div = $("#someDiv");
A screenshot of that element is captured, so if you do something like this:
div2 = $("#someDiv"); // another handle
div2.css('background-color', 'rgb(12,75,54)');
and then do:
div.css('background-color'); // should NOT output "rgb(12, 75, 54)"
And yet, this is what happens, the div handle is aware of any changes that happen to the element. So I was thinking: maybe this behavior is introduced to a newer version of jQuery? Was this always true for all jQuery versions?
Even though div = $("#someDiv"); creates a different jQuery object than div2 = $("#someDiv"); the actual dom element within those jQuery objects is still the same
There can only be one of those and objects are passed as reference not by copying them.
Anything that happens within the dom node represented by div will be reflected in div2's dom node....they are one and the same

How to get all selectors by class name that were dynamically appended in vanilla JavaScript?

I need to get / count how many elements with a common class target name are "available". None on those elements physically exists in the DOM. Those items have been added later when the page was fully loaded.
Below
var targets = document.getElementsByClassName('target');
when I console.log(targets); I get [].
When I click those square brackets, they expand and target items seems to appear but next to them there's a message:
Object value at left was snapshotted when logged, value below was
evaluated just now.
So I assume that I did console.log when DOM hasn't been populated with target elements yet. How do I get information about dynamically added elements?
EDIT:
I checked hsh's functions and
document.body.addEventListener('DOMSubtreeModified', function(event) {
var targets = document.getElementsByClassName('target');
console.log(targets.length);
/**
* If I have 40 target elements, this will be called 40 times :/ showing first bunch of zeros then finally number will reach to 40
*/
});
/**
* So this would be ideally (called only once) but this always shows empty array and 0
*/
document.addEventListener('DOMContentLoaded', function(event) {
var targets = document.getElementsByClassName('marker');
console.log(targets); // always shows []
console.log(targets.length); // always shows 0
//while I can play with those target selectors in Chrome Dev Tools
});
PS. No jQuery please.
You can call your check script in DOMContentLoaded event:
document.addEventListener('DOMContentLoaded', function(event) {
var targets = document.getElementsByClassName('target');
console.log(targets);
});
Also you can use DOMSubtreeModified event if you're expecting that something will be added during the runtime.
document.body.addEventListener('DOMSubtreeModified', function(event) {
var targets = document.getElementsByClassName('target');
console.log(targets);
});
JSFiddle
Your question is very confusing.
I need to get / count how many selectors
A "selector" is a way of targeting/addressing elements. A selector is used to find, or match, elements. For instance, .foo is a selector, which matches elements with the class "foo". In your case, you mean you want to get/count how many elements.
I need to get / count how many elements with a common class target name are "available". None on those elements physically exists in the DOM.
So the elements are available, but not in the DOM? What does that mean?
Those items have been added later when the page was fully loaded.
What do you mean by fully loaded? Same as DOMContentLoaded? Or fully loaded in the sense that all JS to help build the page has also completed?
The easiest thing to do is to wait until all the logic which adds elements has finished running, then evaluate getElementsByClassName. Why can't you do that?
If for some reason you evaluate getElementsByClassName earlier, or on page load, you will find that at any given point in time it still reflects an up-to-date list of elements, since getElementsByClassName returns a live collection, which is updated as your document changes. That also means you don't need to run anything at load time, or watch arcane events such as DOMSubtreeModified.
At any point in time, including after your elements have been added, the value of targets will include all elements with that class, and targets.length will give the total number of such elements.
From MDN:
elements is a live HTMLCollection of found elements.

Getting the width of a newly added element

I need to get the width of a newly added item using JavaScript or jQuery. I know if I need to bind an event to a newly added element I can use event delegation or the .on() method in jQuery. But in this case I’m not binding an event I just need to get the width of that element. How can I do that?
$('#box').width(); // won’t work
document.getElementById("box").width; // won't work either
To get the width
You can just use jQuery's .width() method:
$('#box').width() // Should give you the pixel width with no px/rem/%
// Or plain ol' Vanilla JS
document.getElementById('box').offsetWidth
// Or mix it up
$('#box')[0].offsetWidth
Possible issues
Make sure your element has been created, it is visible and you added it to the DOM.
Your element contains floated elements or absolutely positioned elements and therefore has not gained any width.
You're trying to retrieve the elements width prior to the DOM rendering.
Make sure your element is not affected by any stylesheet and has somehow become inline.
Loading issue
Make sure that your script is on the bottom of the page and/or you are using jQuery's .ready() method:
$(document).ready(function(){
$('#box').width();
});
// Shorthand for the above
$(function(){
$('#box').width();
});
Demos
VanillaJS Demo
jQuery Demo
If anyone can think of other issues or solutions please contribute to the answer.
Try this:
var box = document.getElementById('box');
alert(window.getComputedStyle(box).width);

using jQuery to change, only the elements that were loaded via ajax

For each checkbox on the web page, I replace it with a slider that I borrowed from jsfiddle.net/gnQUe/170/
This is done by going through the elements when the document is loaded.
Now the problem is that when more content is loaded via ajax, the new checkboxes are not transformed.
To solve the problem, I used AjaxComplete event to go through all the elements again and replace the checkboxes with sliders.
Now the problem happens that elements that were already replaced, get two sliders. To avoid that I check if the checkbox is hidden and next element is div of class "slider-frame", then don't process the re-process the element.
But I have a lot of other such controls as well, and I am presume I am not the only one that has this problem. Is there another easy way around it?
There exists jQuery live/on( http://api.jquery.com/on/ ) event but it requires an event as an argument? whereas I would like to change the look of my controls when they are rendered.
Another example of the same problem is to extend some controls that are loaded via ajax with jQuerys autocomplete plugin.
Is there a better way to accomplish this other than changing some attributes on the element.
To summarize, on document load I would like to process every element in DOM, but when more elements are loaded via ajax then I want to change only the new elements.
I would assume that when the element's are transformed into a slider, a class is added to them. So just add a not clause.
$(".MySelector").not(".SomeClassThatSliderAddsToElement").slider({});
So in the case of your code do something like this
$('.slider-button').not(".sliderloaded").addClass("sliderloaded").toggle(function(){
$(this).addClass('on').html('YES');
$('#slider').val(true);
},function(){
$(this).removeClass('on').html('NO');
$('#slider').val(false);
});
Since you said you do not want to add anything else, how about you change the toggle function to click.
$(document).on("click", ".slider-button", function(){
var elem = $(this);
elem.toggleClass("on");
var state = elem.hasClass("on");
elem.text(state?"YES":"NO");
elem.parent().next().val(state);
});
Running fiddle: http://jsfiddle.net/d9uFs/

How to detect if an element is not visible in a fast way in JavaScript?

In the past we used the CSS attribute "display" to show and hide DOM elements. To check if an element is visible, we could just use:
element.offsetWidth > 0
Since we had some problems with Flash and Java Applets (they stop when they get display:none) we switched to the CSS attribute "visibility".
I am now looking for a fast and easy way to check if an element is not visible.
I have tried the following:
Checking the attribute itself on the element and and all parents => too slow
Checking the calculated style directly from the browser (element.currentStyle or window.getComputedStyle() plus getPropertyValue(style property)) => also too slow
Do you know any other way or shortcut to see if an element is visible?
use JQuery and the you can do this
var isVisible = $('#foo').is(':visible');
Remember that visibility:hidden makes an element hidden, but that element still occupies its space, which may have some unexpected consequences on the layout (it may be an advantage as well if you are aware of this).
I would use absolute positioning to move the element far to the left, outside possible screen width. This gets the element out of the flow so the hidden element has no impact on layout, makes the element practically invisible, and it doesn't have the disatvantages of display:none.
.hide {
position:absolute;
left:-3000px;
}
Then to determine if an element is hidden you can use its offsetLeft property:
if( myElement.offsetLeft < 0 ){ /* it's hidden */ }
If you need to determine if a child element is off the screen (you don't know if it's the hidden element or its child) you can use .offsetParent and a while loop, as described in PPK's Find Position article.
Toggling Element Visibility by Kent is an unobtrusive, semantically valid way of presenting content that will degrade nicely for non-CSS-aware browsers.
After the page loads completely, we crawl through the entire document tree and look for block-level elements styled with class name toggle. If we find one that says toggle closed, we immediately hide its next sibling element, by styling it with class name hidden.
When we find one, we tell it to listen for mouse clicks.
When one of our pet elements hears a click, it leaps into action, hiding (or showing) its next available sibling, the same way we did it during the initial crawl.
All three class names (toggle, closed, and hidden) are fed in at the bottom in the init call, and may be changed to any valid class name.
Also look at this DevX article which compares the Display and Visibility properties.
Checking the focus would work, either parent is visible or not.
var isVisible = true;
try{
document.getElementById("target").focus();
}catch(err){
isVisible = false;
}
It obviously should work on input or link, but for other element, I'm not sure.
I have studied the same problem before using jQuery, but that time my aim is to focus the first availabe field on a form. The resulting code is like:
$(":text:visible:enabled").filter(function(){
return $(this).parents.filter(function(){
return this.style.display == "none";
}).size()==0;
}).slice(0,1).focus();
It would also work for hidden/invisble parent.
CSS selectors are optimised to find sets of matching elements. There are several libraries implementing this functionality. JQuery, ExtJS Core to name a couple.
Using Ext Core, I could write a javascript function that checks for visibility as follows:
// Checks whether the element is currently visible using
// both visibility and display properties
if(Ext.get(el).isVisible()){
alert('it\'s visible');
};
see http://extjs.com/products/extcore/docs/?class=Ext.Element for more Ext Core Ext.Element functionality.
function isVisible(elem) {
return elem.style.visibility !== "hidden";
}

Categories