To detect dynamic loading of Frame - javascript

I am working with such kind of frame design. Consider this image as brief overview of more complex design.
I am recursively iterating each frame, so as to add event listeners to it.
For the very first $(window).load() , I am able to add listeners successfully.
But the real trick is;
Frame 2.1 is navigationFrame whereas Frame 2.2 is detailFrame.
As name suggests whenever we click any link of 2.1, Frame 2.2 is loaded again.
Due to this, it looses listeners attached.
Since new frame is loaded, I can't keep track of newly loaded frame.
Though I've tried
element.onunload = function(){
#add listeners recursively using element.parent
}
//where element is of type window
//created using
/*for(var i=0;i<window.frames.length;i++){
var element = window.frames[i];
}
*/
I've also tried ('frame').load, but didn't work.
I cant use #frameID since this work is generic to any web application (whether or not it use frame.)
Please suggest me any way to deal this kind of situation.

Related

Google tag manager single page app get element on history change

I have created a few variables for custom dimension on pageviews.
Pageview trigger: windowload or history change
The data is being pushed through, but it's only getting previous pages'
for example,
page/1 div class "page date" is 25th Jul, I would get undefined, but
when I click onto page/2, i would get the page/1's "page date"
function() {
return window.document.getElementsByClassName('page date')[0].innerText;
}
It seems that the history event is triggered before the corresponding page content is loaded into the DOM. This is nothing you can blame GTM for (GTM sees a history change, inspects the DOM, and grabs whatever it finds there, and that's the normal/expected behaviour).
Your solutions:
Make sure content is updated in DOM BEFORE the history event is triggered: this is something to sort out on the application side, and that may not be easily changed (if you use a framework like react it's probably best if you don't start hacking its core behaviour).
Delay the history event triggers: have a look at this solution which describes how to achieve this. Please note that solutions based on delays are never 100% reliable because there's a race condition between your delay and the loading of content, and you don't know for sure who will come first (and increasing the delay too much can cause the side effect of users changing pages in quick successions before analytics had a change to capture them).
Detect DOM changes: a more robust alternative would be to monitor the DOM for a particular element that is unique to each page (eg a <meta> element with the page ID or URL). You could use a tag to initiate the monitoring of this element when you receive the history change, and when the element actually changes it means the DOM has been updated, and you could fire your own trigger. This could be done via the MutationObserver or using a setInterval/setTimeout loop to check manually. However if the DOM is changed in several phases (blocks by blocks) this would not work (your <meta> element would have changed but not the div you're looking for), requiring you to start monitoring on a per-element or per-block level, which will be quite some work.
Push a dataLayer from your application: this would be my preferred option. I would hook into the logic of your application (you should be able to extend the routing method or the app framework should give you event listeners you can bind a custom function of yours with in which you can tell GTM that the page has been changed (eg dataLayer.push({'event': 'page_changed'});)

How to detect whether all element's content has been loaded?

I'm wondering how can I detect whether all content inside dynamically appended HTML element is loaded. The element's content might be both text and images, maybe videos. I need to detect it to get a correct element's height value.
I believe that MutationObserver is not right solution for that as this only detects whether node has been changed or its attributes. I have to detect when element's content has been loaded.
Delegating load events to parent doesn't change anything.
Any suggestions?
You can do this by using a callback function on your AJAX call. Off the top of my head I can't remember how that works in vanilla javascript, but in jquery it would look like this:
$.ajax({
url: 'my-url'
}).done(function(){
// This only fires once the AJAX request / response has complete
populateElement();
fixElementHeight();
});
By doing it this way you ensure you have all the content before updating your element. Once the element has been updated, you are then able to measure its height. If part of the new content is an image, or some other content type which needs to be fetched, then I would do the fetching in the populateElement function:
var contentImage = new Image(imgWidth, imgHeight);
$(contentImage).click(function(event){
...
});
contentImage.src = 'source of image';
You will most likely need a javascript that has a constant setTimeout checking for the length of an element. (an element that is not loaded usually has a length of 0 or is invalid)
This is something we encountered awhile back and probably applies to your situation as well. It's for a youtube thing for detecting when certain elements have finished loading, but seeing your question, the concept applies as well.
http://www.gambit.ph/how-to-use-the-javascript-youtube-api-across-multiple-plugins/
I decided to use Javascript promises to handle images load events. I'm creating a new promise for each image and updating my app after all images are loaded.
So there's no other way round to make delegation on parent to detect whether all images were loaded.

How to determine when an HTML5 element has been viewed?

I am wondering if there are any HTML5 events associated with whether or not an element has been viewed or "scrolled into view" by the user.
An example could be a longer page with elements at the bottom, which has yet to be scrolled into the users view...
I have seen jQuery solutions to this problem, however I am only interested in figuring out if weather or not this is achievable purely though the use of HTML5 events and JavaScript.
It should be noted that I have already had a look at the "onfocus" event, which (from it's official description) seems to only be applicable if the user selects or "clicks" somewhere on or within the element itself.
In plain JavaScript you can use the event "scroll" along with getBoundingClientRect().bottom <= window.innerHeight to determine if an html element has come into view.
document.addEventListener("scroll", inView);
function inView() {
if (document.getElementById("viewElement").getBoundingClientRect().bottom <= window.innerHeight) {
console.log("in view");
// uncomment below if you only want it to notify once
// document.removeEventListener("scroll", inView);
}
}
The console prints "in view" when the element comes into view.
<div id="viewElement">Hello there!</div>
There are no built-in events that tell you when an entire DOM element has become viewable/visible on the page due to scrolling or window resizing.
The only way to do this is to keep track of resize and scroll events (which can each cause more or less of your page to be visible) and then use the scroll position and window height and DOM element positions to calculate if your entire DOM element is visible.
Some relevant pieces of code you can either consider using or look into how they work (these tend to be jQuery-based because they are harder to share if not based on a common DOM library):
Lazy Load Plugin for jQuery
Element "in view" Event jQuery Plugin
Check if Element is Visible After Scrolling - plain JS
I had to do something similar to this when I built http://f1circle.com.
When the bottom banner becomes visible, I have to show a spotlight to the user asking him to login.
The code that achieves it using angularjs can be viewed at https://github.com/rajegannathan/angularUtilities/blob/master/directives/eagerload.js
Though it is an angularjs directive, the main logic is in plain javascript. Basically I check if the the last feed's bottom edge is visible and then trigger the spotlight.
I can explain more if required.
As already mentioned, there is no "event" but someone already wrote a method to "detect if a DOM Element is Truly Visible" (the title). It doesn't require JQuery. You might want to check for the value on several events like the document load, scroll or window resize.

listen elements rendering after DOM initially loads

Is there anyway to listen for elements adding themselves to the DOM after load? Currently I have a bunch of tables using DataTables and I have a bunch of other elements that I would like to manipulate when and if the type of element I am looking for is found to have "appeared" on the page. Seeing as what I am attempting to do only works on elements currently on the page when loaded but not after they load such is the case with many elements currently in play.
Ultimately I am currently looking for a means of avoiding going back through the entire code base just to make something happen only if something is found on the page, but after its loaded.
There's no "element added to dom" sort of event that's cross-browser compatible, and the ones that exist for specific browsers are generally discouraged as they tend to cause more issues than they solve.
Usually the issue with elements not existing in the DOM is that they miss event-binding. jQuery has awesome event-delegation that can be used to bind events to a container so that when an event bubbles up to the container, the callback is fired in the context of the element that received the event.
For example, you could bind events using:
$('a').click(doStuff);
but that would not work for any new links, instead you could use something like:
$('#some-container').on('click', 'a', doStuff);
which would intercept all click events on all links in the #some-container element, regardless of when they were added to the page.

check document if there is mouse moving or touching like screensaver

as the title says, i would like to know if theres any possibility in javascript (jquery) to check if there is any action in the document, and if not. something like a screensaver should pop up!
if someone is on the page and looks here, looks there and after a while he doesnt do anything, the mouse (or touch finger) stands still, i want to say the document after a minute without activity...
function noactivity() { //after 60000ms start something here }
i want that global for the whole document!
thanks ted
It can be done relatively simply in jquery using:
setTimeout();
http://jsfiddle.net/bernie1227/hNkTy/1/
I had this issue a while back while I was working on an iframe resizing issue. What I wanted was to tell the parent page whenever there is a change in height of the document.
What I found was that jQuery does not give such facility directly. The main reason for this is that there are too many activities happening to DOM which are not visible, when you are watching it (bind). You could however watch for a specific property like mouse moving on a document.
$(document).mousemove(function(e){
console.log(e.pageY);
console.log(e.pageX);
});
But then again that does not at all mean that the user is interacting with your page. That merely signifies that the user is on your page and his mouse is moving. The user might also be not moving the mouse and merely using his keyboard to interact with your page. So now you would have to watch for keyboard interaction aswell.
$(document).keyup(function(e){
console.log('active');
});
Using these you could create a countdown function which checks for a flag after a set interval of time. You could set the flag if user makes an activity. And after a set amount of time that function the 'noactivity()' function id the flag has not been set.
Another approach to watching the document activity could be you watching the DOM subtree being modified.
jQuery(document).bind('DOMSubtreeModified', function() {
console.log('active');
});
This works for Chrome/FireFox/IE8+ but not on Opera (any version). The main reason being that the operation is too heavy on your browser's resources. And I would discourage using this approach because listening for DOM mutation events may harm performance and the relevant W3C working groups are trying to find a better way to do this and deprecate DOM mutation events for this reason - it's hard or impossible to make a good and performant implementation.
I am not saying that the other options that I mentioned above are good either. They are also expensive operations if you are watching document and should be avoided. Another issue with those options is that the iframe content is not particularly the part of your document and these options will not work if user is interacting with iframe content.
So the conclusion is that W3C did not yet finalize a cheap way where user can watch changes in document subtree.

Categories