jQuery effect on iframe parent document - javascript

Just wondering if anyone else has experienced this or knows why I am getting an error. I'm using javascript from within an iframe to call a parent dom element then use jQuery UI's effect core to shake it. Here is an example:
$(document).ready(function(){
if ($("form").length>0)
{
$("form").submit(function(){
var oParentDoc = $(parent.document).find("div#element");
var action = $(this).attr("action");
var postdata = $(this).serialize();
$(oParentDoc).addClass("loading");
$.post(action,postdata,function(data){
$(oParentDoc).removeClass("loading").effect("shake",{"times":3,"distance":10},60);
});
return false;
});
}
});
It works without the effect, but when I use an effect it gives me this error:
uncaught exception: [Exception...
"Component returned failure code:
0x80040111 (NS_ERROR_NOT_AVAILABLE)
[nsIDOMCSSStyleDeclaration.getPropertyValue]"
nsresult: "0x80040111
(NS_ERROR_NOT_AVAILABLE)"
Thanks in advance for any insight :)

I'm not sure if this will work but you could try setting up a bind event in the parent, then in the iFrame try triggering that event in the parent.
Parent JavaScript
$(document).ready(function(){
$('#iframe').bind('shakeFrame',function(){
$('#iframe').effect("shake",{"times":3,"distance":10},60);
});
});
iFrame JavaScript
$(document).ready(function(){
$(parent.document).find('#iframe').trigger('shakeFrame');
});

It could be that your Iframe's specifications are defined. Therefore not allowing any movement / change with the Iframe?

Have you loaded the necessary jQuery files into the parent document as well as the iframe document?
UPDATE: A little research on the internet indicates that the 'effect' code is probably calling 'getPropertyValue' and Firefox is claiming that method doesn't exist. I know - not very helpful. Unfortunately I believe you're going to have to debug the 'effect' code to find out more specifically whose bug this is, or perhaps find that its a limitation of the iframe scenario you're trying to run.

Related

How to simulate a *real* mouse click on element in iframe

$(selector).click() results in nothing happening.
this answer works in the browser console with the javascript context set to the iframe, but not the main page:
simulateMouseClick($("iframe").contents().find(selector))
results in:
Uncaught TypeError: targetNode.dispatchEvent is not a function
at triggerMouseEvent (:5:20)
at :8:9
at Array.forEach ()
at simulateMouseClick (:7:52)
at :1:1
$("iframe").contents().find(selector).text() gives me what's expected so it's the correct element.
how can I achieve this?
Edit: adding this as people apparently can't read:
$("iframe").contents().find(selector).click()
has absolutely no effect as .click() does not simulate a REAL mouse click.
With jQuery :
$("iframe").contents().find(selector).click();
With Vannila JS :
Using window.frames gives you access to the iframes' window object, as mentionned in the Mozilla doc
You can use this object to find elements in the iframe and use them in your script. For example :
var iframeWindow = window.frames[0];
var element = iframeWindow.document.getElementsByClassName("selector")[0];
element.click();
Get the element inside your jQuery Object, and use the vanillaJS .click() method:
$("iframe").contents().find(selector)[0].click();
That's it.
PS: I know this is an old question, but I had the same problem and solved it that way :)

Something causing interference

So I've got the following code that works in jsfiddle, but not on the actual website, which leads me to believe that the only way I'm going to get it working is for someone with more experience than I to look through the source and see what's interfering.
<script>
$(document).ready(function(){
var $elements = $('body').children('div[class^=class]').on('click', function () {
$elements.removeClass('classname')
.not('.' + this.className)
.addClass('classname');
});
});
</script>
Website: http://sinfulgurotesque.tumblr.com/recs
Edit: I've removed a section of code from the website that had nothing to do with this part. (It was the deprecated code, and it didn't offer much in terms of functionality anyways.)
You're using jQuery 1.10.1 in your page, and the error you're getting:
jquery.style-my-tooltips.js:26 Uncaught TypeError: undefined is not a
function
is referring to the .live() function used by the plugin which was removed in jQuery 1.9
$(".smt-current-element").live("mouseout mousedown click",function(){
It looks like you're calling depracated JS functions. I got:
TypeError: $(...).live is not a function
when opening your page. Try changing .live() to .on()
Like so
$("body").on("mouseout mousedown click", ".smt-current-element", function(){...

Javascript: Uncaught TypeError: Cannot call method 'addEventListener' of null

I'm trying to do something fairly simple, but for the reason of me probably not being good enough to search documentation, I can't get this to work.
I have a functioning inline JS that looks like this:
<A title="Wolfram IP Calc" href="javascript:txt=prompt('Enter%20IP%20address,%20e.g.%2010.20.30.40/29','1.2.3.4/5');%20if(txt)%20window.open('http://www.wolframalpha.com/input/?i='+txt);void(O);">Compute!</A>
For various reasons, I'm trying to seperate the JS, and this is where I hit a snag.
I've created the following test page that gives me the error Uncaught TypeError: Cannot call method 'addEventListener' of null:
<HTML> <HEAD profile="http://www.w3.org/2005/10/profile"> <script type="text/javascript">
var compute = document.getElementById('compute');
compute.addEventListener('click', computeThatThing, false);
function computeThatThing() {
txt=prompt('Enter%20IP%20address,%20e.g.%2010.20.30.40/29','1.2.3.4/5');
if(txt) {
window.open('http://www.wolframalpha.com/input/?i='+txt);
}
}
</script></HEAD>
<BODY>
<A title="Wolfram IP Calc" id="compute" href="javascript:void(O);">Test</A>
</BODY>
</HTML>
The only thing I've been able to find that points to a problem like that is that addEventListener can't work with <A> but should handle <IMG> (which suits me fine as I'm going to pour this on some images), so I tried adding the following to no avail:
<img id="compute" src="http://products.wolframalpha.com/images/products/products-wa.png" />
Thanks in advance for pointing out what I'm doing wrong. It is probably glaringly obvious, but I have close to zero experience with JS and I have gone mostly by cargo culting when I've needed it until now.
Your code is in the <head> => runs before the elements are rendered, so document.getElementById('compute'); returns null, as MDN promise...
element = document.getElementById(id);
element is a reference to an Element object, or null if an element with the specified ID is not in the document.
MDN
Solutions:
Put the scripts in the bottom of the page.
Call the attach code in the load event.
Use jQuery library and it's DOM ready event.
What is the jQuery ready event and why is it needed?
(why no just JavaScript's load event):
While JavaScript provides the load event for executing code when a page is rendered, this event does not get triggered until all assets such as images have been completely received. In most cases, the script can be run as soon as the DOM hierarchy has been fully constructed. 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...
...
ready docs
Move script tag at the end of BODY instead of HEAD because in current code when the script is computed html element doesn't exist in document.
Since you don't want to you jquery. Use window.onload or document.onload to execute the entire piece of code that you have in current script tag.
window.onload vs document.onload

Stop a Vimeo Video with Jquery

I need to stop a Vimeo video embedded with new oembed api (universal player) but when I try to add an event I get this error:
Uncaught TypeError: Object #<an HTMLIFrameElement> has no method 'addEvent'
But I don't why I get this error, I added jquery and the frogaloop api, also I added ids to the iframes, but it still doesn't work: :(
The full code is here:
http://tv.bisaccia.info
Eli, please edit your post. As Joe said, you are partially misinformed. While postMessage is needed for cross-domain communication, it is implemented through a DOM method added by a call to "Froogaloop.init();"
is_embed_iframe = _this.iframe_pattern.test(cur_frame.getAttribute('src'));
if (is_embed_iframe) {
cur_frame.api = _that.api;
cur_frame.get = _that.get;
cur_frame.addEvent = _that.addEvent;
}
Note: you will need to grab froogaloop.js (or the min variant) from the Vimeo site.
Be sure the iFrame "src" is set prior to calling init(), otherwise froogaloop will do nothing.
As per Mike's suggestion, invoking:
Froogaloop.init();
Does make the control API work. In my case:
<iframe id="player_1" src="http://player.vimeo.com/video/26859570?js_api=1&js_swf_id=player_1&title=0&byline=0&portrait=0" width="620" height="354" frameborder="0"></iframe>
<script>
$(document).ready(function() {
Froogaloop.init();
$("#player_1").moogaloop({
load: function(element) {
$("#segment1").click(function() { element.moogaloop('seekTo', "7"); });
}
});
});
</script>
Weird... Moogaloop's author demo page does work without the init() call. Anyway, worked for me.
Thanks for your time!
This is not the correct answer, but may work for your situation as it did for mine. I simply wanted to stop my Vimeo from playing when I closed its containing DOM element. I was collapsing its container and that hid it visually but the audio continued to play and use browser resources unnecessarily.
What I do now is simply store the iframe in a variable, remove it from the DOM, then replace it immediately. I have NOT tested across browsers, only the latest version of Chrome and Safari Mobile.
var container = $("#VimeoContainer");
var iframe = container.find("iframe");
iframe.remove();
container.append(iframe);
Again, Froogaloop is really the way to go, however I've had issues with it in the past so for this situation I was looking for something simple. Obviously you could do this without JQuery with the same results.
You can't.
There's no DOM addEvent method.
You don't have cross-domain access to Vimeo, so you are not permitted to have JavaScript interface with the iframe's document or abstract view.
If you wanted to interface with Vimeo via JavaScript, you would have to get them to implement a postMessage API that also accepts your domain.

Adding an event listener to an iframe

Is it possible to add an event listener to an iframe? I've tried this code, but it doesn't seem to work:
document.getElementsByTagName('iframe')[0].contentWindow.window.document.body.addEventListener('afterLayout', function(){
console.log('works');
});
I've also just tried using getting the element by id and adding my listener via the JavaScript framework I'm using, like this:
Ext.fly("iframeID").addListener('afterLayout', function(){ alert('test'); });
I can call functions in the iframe, so I don't think security is an issue. Any ideas?
I never tried to handle 'afterLayout' event but for more browser compatible code
you'll use (iframe.contentWindow || iframe.contentDocument) instead of iframe.contentWindow .
try something like
var iframe = document.getElementsByTagName('iframe')[0],
iDoc = iframe.contentWindow // sometimes glamorous naming of variable
|| iframe.contentDocument; // makes your code working :)
if (iDoc.document) {
iDoc = iDoc.document;
iDoc.body.addEventListener('afterLayout', function(){
console.log('works');
});
};
Hope it'll help.
If you are doing serious iframe work in Ext, you should look into the ManagedIFrame user extension:
http://www.extjs.com/forum/showthread.php?t=40961
It features built-in events and cross-frame messaging, as well as many other benefits.
Reasons for failure could be:-
The URL to which the iframe is directed from a different domain as the container, hence code is prevented by cross-domain script blocking.
The code is running before the frame content is loaded

Categories