I'm working on a WebExtension that scrapes some data from a web page. The page in question dynamically loads stuff into an iframe, and the iframe contains the stuff I need. The data I need never gets written to the iframe document, it only exists in the JS objects.
From inside of my WebExtension, I'm trying to do the following:
var result = $("iframe")[0].contentWindow.eval("(function() { return $('#grid').jqxGrid('getrows'); }())");
This works flawlessly when using the extension in Firefox. No issues whatsoever.
Unfortunately, trying to do the same thing in Chrome results in the error $ is not defined on the eval.
I've been trying for the last couple of hours to figure out why and I'm at a complete loss. Would really appreciate if someone could point me in the right direction.
I'm still not sure why the eval() works in Firefox but not in Chrome, but here's what I ended up doing to get what I needed:
1) Add an event listener in my extension for a custom event.
window.addEventListener("myCustomEvent", function(e) { HandleResult(e.detail); });
2) Inject a script block with the code to fire the event, including the data I need, into the body of the iframe document.
$("body", $("iframe").contents()).append("<script>top.dispatchEvent(new CustomEvent('myCustomEvent', {detail: $('#grid').jqxGrid('getrows') }));</script>")
Shout-out to wOxxOm for pointing my brain in the right direction.
Related
I've been trying to figure this out for a while now, but I'm at my wit's end and have given up all hope.
Here is my unpacked chrome extension: nexrem.com/test/extension-test2 - Copy.zip
Exhibit A:
Navigate into the template folder
run test.html in Chrome
Click on the "Footer link"
Observe it scroll correctly to the footer
Exhibit B: Currently, the extension basically replaces the entirety of html on the page.
Install the unpacked extension
Go to some website (for the sake of testing, one that isn't filled with all sorts of scripts. or just make a local blank html file)
Click the extension icon in chrome
You will see the exact same page as when you ran just the test.html ;however, the jquery scrolling no longer works. I fail to understand why.
If someone can explain this to me, assist in a solution or at least point in the right direction, I'd greatly appreciate it!
According to load
jQuery uses the browser's .innerHTML property to parse the retrieved document and insert it into the current document. During this process, browsers often filter elements from the document such as <html>, <title>, or <head> elements. As a result, the elements retrieved by .load() may not be exactly the same as if the document were retrieved directly by the browser.
And after digging into your html code after you click the browser action, it seems the body tag is not included.
You can use the following code instead load
var template = chrome.extension.getURL('template/test.html');
console.log(template);
$.get(template, function(data) {
document.open();
document.write(data);
document.close();
$.cache = {};
}, "text");
I'm working on a Drupal 7 site, the mobile version of the site which uses Bootsrap as theme.
There is a custom block (created w/ drupal) using jQuery to move some elements on a page, changing some classes and IDs. This block works just fine.
My problem is in a custom module which renders a block. I have some jQuery code in the module's template that is not running on refresh in Safari, but it runs if I go on the address bar and hit "Go" on the keyboard.
edit: IE and Chrome seem to also have a problem, but the jQuery code runs sometimes, doesn't matter if is a refresh, clear cache or whatever.
Nothing special in browser's console.
My jQuery code is supposed to move some elements in the page, on jQuery(document).ready, but is not even working for a simple alert.
p.s.: the jQuery in my custom module's template doesn't have anything to do with the code or the HTML elements affected by the custom block, but I thought maybe it would be good to mention it.
I hope you can understand the issue :)
Thanks.
I was using jQuery(document).ready to execute my code. I changed to jQuery(window).load and now it works fine. The code executes on first page load and on every refresh.
After like two weeks and almost killing myself, this is only thing that worked for ios safari.
$(window).on('load', function () {
setTimeout(() => {
DoLoad();
}, 180);
});
I had a similar problem and tried probably a dozen or more ways to address an issue with Safari. It looks like Safari triggers $(window).on('load',...) jQuery call before DOM completely builds. Or perhaps there is some kind of timing/racing condition. In my case, it was causing an issue, but only after page reloads, only with Safari, and only with a certain cloud provider. Chrome was fine, on prem hosting was fine. The only way which worked somewhat reliably was to introduce an artificial delay via setTimeout() function.
$(window).on('load', function () {
setTimeout(() => {
$.getScript('{{url}}').done(function(){
$("#element").js_function({
arguments
});
});
}, 360);
});
This answer https://stackoverflow.com/a/10929430/749227
to this question Is possible to debug dynamic loading JavaScript by some debugger like WebKit, FireBug or IE8 Developer Tool? is spot on for debugging dynamic scripts.
The issue I am facing is that I have a page that has a script on it, and after it loads an ajax request fires which returns with some HTML and a script that get put into the page. With the //# sourceURL=myDynamicDocumentFragment.html bit added, I can debug the dynamic script just fine.
But once it's loaded, then the other script that is part of the outer page that initially loaded goes off the rails. I can set breakpoints on blank lines and can't set them on legitimate lines. The debugger will stop on them but it won't be at the place in the code where I'd expect.
What it appears to be is that the dev tools window is showing the original script, and the debugger itself is running on something else - some updated version of code that includes both the outer page's script and the dynamic script that was added later. Or maybe it just hiccups with respect to line numbers it's displaying and what those map to in the code it's actually running.
I wish I had a good simple code snippet to demonstrate the issue, but I don't. Has anyone seen this, and does anyone know of a way to have Chrome 'refresh' the dev tools scripts/debugger without refreshing the page? (it has to be w/o refreshing the page since things work fine when the page loads - it's only after the dynamic script is dropped in that the wheels come off)
Note: I've tagged with Chrome since that's what I'm using (v 38). I don't know how other browsers fare.
You can find scripts injected into head or evaluated, here is a break point added on youtube evaluated (another js file).
You can find this in chrome as well, adding console.log (click on message shown), and voila you have source code you can add break points.
Here mozila print debugging/breakpoint over evaluated script on utube page:
Update
Sorry, I understand chrome was out of the scope, my engrish :)
How I did debugging on chrome over injected scripts, but there are cases when you cannot attach to execution if script is active (page load plus few milliseconds), you need to search for workarounds.
Added this at the begin of the script injected:
//# sourceURL=jseinjectedsource.js
console.log("evaluated");
and voila console:
Better check this way better than my explanation chrome developer
Check to see if your script is using a source map (if you're using TypeScript this is typically on by default for VS projects).
I've found Chrome to be really bad with source maps, often refusing to update them, or stop displaying them after the source map line is removed from the code.
Precondition:
I have an aspx-page with iframe inside. This iframe points to the url handled by MVC on the same site (it's hybrid site, both standard ASP.NET and ASP.NET MVC). The resulting page rendered by MVC contains a lot of scripts references.
Problem:
IE9 throws an exception on every single script it load in iframe. These exceptions are similar to this one:
Error: 'Function' is undefined
That is, it says that the most basic things every window has is somehow absent. Once you clicked through all of these popups, the page just works as designed!
If I load a URL from <iframe /> src attribute in the browser directly, everything works as expected.
If I open the page in another browser (I tried Opera, Firefox), everything works as expected -- no errors.
So, what IE9 wants?
There is this msdn page about this bug (or feature).
You get these kinds of errors when you move the iframe element around in DOM. In such cases, IE 9 garbage collects the iframe (causing your undefined bug) and reloads it at another position.
In general, you should create the element, set its src attribute only once and then put it somewhere in the DOM tree once. It has nothing to do with the code which runs in the iframe itself.
I have encountered this same situation in the wild. Basic symptoms:
You load script code in an iframe
The script code runs early (from the head section or top of body)
IE complains about some missing native object
I found that it can often be prevented by delaying the execution of the script code until onload or DOMContentLoaded... Not much help I know but this is one of the most difficult IE scripting bugs I have ever encountered. I upped the score of your question, hope it will be found by others as well and we can get a more detailed answer.
Also see this question:
Error in Internet Explorer 9 (not earlier versions or other browsers) when including jQuery in an iframe
Placing the following script block at the very top of the iFrame html <head> seems to resolve the issue in my case. Basically, it forces the iframe to reload, which as some have pointed out, solves the issue. It seems relatively safe, because, without things like 'Object' and 'Date', javascript is essentially useless.
<script type="text/javascript">
if(typeof(Object)==="undefined"){
window.location.reload();
}
</script>
Try loading the javascript at the end after complete web page is loaded. I feel the script is executing even before the iframe is completely loaded.
for some suggestion of scripting in IE9 view the given link below
http://blogs.msdn.com/b/ie/archive/2010/06/25/enhanced-scripting-in-ie9-ecmascript-5-support-and-more.aspx
Further investigation revealed that the solution is to add the offending iframe to it's dom location BEFORE setting the 'src' attribute.
Once the 'src' has been set, changing location of the iframe within the DOM stack forces IE9 to garbage collect it.
Once 'src' has been set, iframe can be resized and changed via css positioning, but cannot change the relative location in the DOM stack.
Often times, plugins like dialogs and lightboxes will stuff an iframe with src already set into the dom, then append / prepend or whatever, triggering the GC to take place.
function waitForjQuery(){
if(typeof jQuery!='undefined'){
//Do yor stuff!
}
else{
setTimeout(function(){
waitForjQuery();
},500);
}
}
waitForjQuery();
I am trying to load a webpage using prototype.js in the header after the title.
I keep on getting an exception in the prototype.js within the CoreWrapper function, where the
eventID is seen as a null.
This only happens once and then seems to be okay, thereafter. I have noticed that there is no problems loading the same webpage using Firefox.
Scanned on websites and looked for any possible updates for the javascript (1.6.0.3). Seems that the DOM Object is not loaded? Any ideas of how you can do this for internet explorer?
Please simplify this as I am very new to javascript :-)
Well, without code it's hard, but it might be because you don't wait until the DOM to be loaded or the complete page to be loaded before using some DOM functions. To wait for it just do something like this :
Event.observe(window, 'load', function(){
//your code here
});