Is it possible to get only hidden text of an element? - javascript

Selenium Webdriver contains a function that returns only visible text inside element. I'd want to write a function that will get only hidden text inside element (i.e. all text that isn't visible in meaning of Selenium Webdriver W3C spec). According to to this spec element is visible only if all following conditions are met:
The element must have a height and width greater than 0px.
The element must not be visible if that element, or any of its ancestors, is hidden or has a CSS display property that is none.
The element must not be visible if there is a CSS3 Transform property that moves the element out of the viewport and can not be scrolled to.
OPTIONs and OPTGROUP elements are treated as special cases, they are considered shown if and only if the enclosing select element is visible.
MAP elements are shown if and only if the image it uses is visible. Areas within a map are shown if the enclosing MAP is visible.
Any INPUT elements of "type=hidden" are not visible
Any NOSCRIPT elements must not be visible if Javascript is enabled.
The element must not be visible if any ancestor in the element's transitive closure of offsetParents has a fixed size, and has the CSS style of "overflow:hidden", and the element's location is not within the fixed size of the parent.
Is it possible to write a JS function that will return only hidden text contained inside element? Do you know of any library that contains such function? How slow will such function be?

Yes, it is possible to write such code if you are just monitoring for display: none, visibility: hidden and no size or even an absolute/relative position that is off the screen. You would have to iterate every element in the page, determine if the element is visible and, if so, collect the text from any text nodes in that element.
It will be no slower or faster than any other function that iterates every node in the document. The total time will depend upon how efficiently the iteration code is written (it can skip all children of a hidden element for example) and on how long/complicated the document is.
If you want to be able to tell the difference between text that is outside the edges of an element with overflow:hidden or elements that might be marked for visibility, but be off-screen or out of view or out of the current viewable scroll area or pieces of text that might be obscured by other elements, that would be very difficult and honestly I don't know if all of that can be figured out from pure javascript.

Related

How can I find a top element in the viewport?

I want to get a top element (Element Object) from the viewport of a web page with JavaScript. (If any part of the top boundary of an html element is visible on the viewport that element is within the viewport)
The approach I came up was:
Find all the elements with document.body.getElementsByTagName("*")
Check if each element is in the viewport with How can I tell if a DOM element is visible in the current viewport?
Get the element with the lowest el.getBoundingClientRect().top value from the matching elements of the step 2
If there are many element at the same level (Eg: parents and children), matching any of them would be ok.
This seems to be too much code for a small requirement. Is there a shorter approach?

How to add class to elements which are not fully visible in viewport?

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.

Changing div text layouts the whole document

I want to change the text inside a div with javascript (jQuery is ok too).
There are a few to do that:
element.innerText
element.innerHTML
element.textContent
$(element).text()
$(element).html()
But when I use the above methods, the whole document is affected and not only the div.
See chrome timeline below which refers to this fiddle
Is there a way to update the text inside the div without affecting the whole document?
Because updating the text affects the width/height of the element and the flow of the page, the entire document usually has to be laid out again whenever the DOM changes. However, you can do stuff so only part of the document needs to be re-laid out.
From http://wilsonpage.co.uk/introducing-layout-boundaries/
To be a layout boundary, the element must:
Be an SVG root (<svg>).
Be a text or search <input> field.
or:
Not be display inline or inline-block
Not have a percentage height value.
Not have an implicit or auto height value.
Not have an implicit or auto width value.
Have an explicit overflow value (scroll, auto or hidden).
Not be a descendant of a table element.
If you make the element you're updating a layout boundry, only the part of the document inside your element needs to be updated. However, keep in mind were talking about optimizations of less than a millisecond, and pre-mature optimizations are generally considered bad practice.
Note: Do not start an id attribute with a number. It may cause problems in some browsers.
http://www.w3schools.com/jquery/sel_id.asp

Performance: Calculating Div Positions

I set up at test case on jsperf here: http://jsperf.com/rect-vs-offsettopmsa
Now a lot of the results there seem intuitive and make sense, however there is one thing that bothers me regarding ScrollTop and OffsetTop.
Why is it that ScrollTop is almost 3-4x faster than OffsetTop if they are both DOM Element properties? Especially since OffsetTop is also only a read-only property according to the msdn: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop
I can't say for sure — you'll have to examine source code to be sure. But the obvious reason for the offsetTop poorer performance is that it is simply more complicated to compute.
To calculate Element.scrollTop browser just needs to explore the Element you asking for — it can get all the input data it needs just from it.
But to calculate Element.offsetTop you need to calculate the element's position AND it's parent's — and then compare them to get the relative position. Hence more time needed to perform it.
Here you can find a description of how Element.offsetTop works according to spec.
If the element is the HTML body element or does not have any associated CSS layout box return zero and terminate this algorithm.
If the offsetParent of the element is null return the y-coordinate of the top border edge of the first CSS layout box associated with the element, relative to the initial containing block origin, ignoring any transforms that apply to the element and its ancestors, and terminate this algorithm.
Return the result of subtracting the y-coordinate of the top padding edge of the first CSS layout box associated with the offsetParent of the element from the y-coordinate of the top border edge of the first CSS layout box associated with the element, relative to the initial containing block origin, ignoring any transforms that apply to the element and its ancestors.
So yeah, even if it looks like a simple property, it still can trigger some calculations on the element.
UPDATED:
It looks that my answer is still incorrect because of this interface declared in the same spec:
partial interface HTMLElement {
readonly attribute Element? offsetParent;
readonly attribute long offsetTop;
readonly attribute long offsetLeft;
readonly attribute long offsetWidth;
readonly attribute long offsetHeight;
};
So, yes, both this properties are readOnly, so the fact that one is 3 times faster then other doesn't make much sense. Ignore what I've written earlier.

Javascript - get width of child within some relative set to display:none

I have some list items that are hidden because of a hidden grandparent (or greater relative). I can recurse through the relatives and set each one to display:block;position:absolute;left:999em; then take the child width or shoudl I just offer an option argument in the getwidth function to take the hidden relative if one exists?
Or does anybody have a more elegant solution? This is in javascript no libraries.
I'm not 100% sure at this, but I've read somewhere (I think it was w3schools) that elements that are display="hidden" can be calculated upon (width/height), where as elements that are display="none" cannot.
So one solution could be to use display="hidden" instead of none?
But when do you want to get the width/height? When the element is hidden or visible?
Molle

Categories