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

$(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 :)

Related

Trigger click() for dynamically created elements

Ok, there are a couple approaches to the problem of triggering a click() for a dynamically-generated element. First, this will work for Chrome but not IE or FF:
var href="/myUrl";
var link = $("<a>");
link.prop("href", href);
link[0].click()
So, if the thinking is that using click() on an element that doesn't exist won't work in IE or FF, what's the best approach?
var href="/myUrl";
var link = $("<a>");
link.prop("href", href);
$(document).append(link); // Attach it to the DOM so it exists
link[0].click()
Or is there something even simpler that I'm missing? Thanks for any helpful tips.
You've said you want to trigger the download of a file. Another simple way to do that is to have an invisible iframe on the page:
<iframe src="about:blank" style="display: none" id="downloader"></iframe>
...then when you want to trigger the download:
$("#downloader").attr("src", "/myUrl");
As with your current solution, it's important that the response containing the file have a Content-Disposition header identifying it as an "attachment" (the same header can also suggest a name), to get consistent handling across MIME types.
The following is a function that I've used in production code, it's a bit different from yours but it might be what you need.
function psuedoClick(href, target){
if(!target) target = '_self';
var falseAnchor = $('<a/>').attr({
'href' : href,
'target' : target
}).appendTo('body');
falseAnchor[0].click();
falseAnchor.remove();
};
Just pass in the arguments when you call the function and it'll work.

jQuery .click() does not work in Safari

I have seen several similar posts with solutions that seemed to have worked for those people, but I CANNOT get this to work.
I am using http://tutorialzine.com/2013/05/mini-ajax-file-upload-form/ in my project. It works PERFECTLY, in all browsers, except in Safari the "BROWSE" button does not open a file dialog. The following code exists in script.js (which is included for the plugin to work):
$('#drop a').click(function(){
// Simulate a click on the file input button
// to show the file browser dialog
$(this).parent().find('input').click();
});
The .click() does not fire in Safari. I have tried the solution as per jQuery .click() works on every browser but Safari and implemented
$('#drop a').click(function(){
var a = $(this).parent().find('input');
var evObj = document.createEvent('MouseEvents');
evObj.initMouseEvent('click', true, true, window);
a.dispatchEvent(evObj);
});
But then I get the error that dispatchEvent is not a function. I then did some research on this, and tried the jQuery.noConflict() route, but this did not resolve the error. Also, I use a LOT of jQuery in my main file and I cannot have the noConflict() mode activated for the entire page. There is also no reason that the jQuery should be conflicting with anything as I am only using jQuery and normal javascript and I am not using anything like prototype or angular. Does anybody know of another way to simulate a click in Safari?
UPDATE: Just FYI, I have added an alert('test') in the mentioned function (which triggers when "BROWSE" is clicked), and I do get the alert in Safari, but it is not simulating the click of the file input element, i.e: it is not openening the file dialog.
The second section of code in my original question turned out to work, except for 2 things.
1) The method does not like jQuery, so instead of
var a = $(this).parent().find('input')[0];
I assigned an ID to my file input and instead called
var a = document.getElementById('upload_select');
2) Safari blatantly ignores this if the input is hidden (display:none;), which is was, so instead I made the input font-size = 1px; and opacity = 0.
Implementing these two changes got the code working.
You need to read that answer more closely. :-)
dispatchEvent is a function on the DOM element, not the jQuery object. You're trying to call it on the jQuery object. So:
$('#drop a').click(function(){
var a = $(this).parent().find('input')[0];
// Change here -----------------------^^^
var evObj = document.createEvent('MouseEvents');
evObj.initMouseEvent('click', true, true, window);
a.dispatchEvent(evObj);
});
Using the [0] on the jQuery object gives you the first DOM object in the jQuery object, or undefined if the jQuery object is empty.

How to remove an event out of content script scope?

I'm trying to unbind an event from a specific element and upon research, I found this. Which is useful. In itself. I didn't know you could do that. But:
Is there a way to make it work in a browser/Chrome extension? I'm talking about content scripts.
The reason why this doesn't work the way it's described there is that the website which has attached the event in question with its own script is using a different jQuery object than the one in my extension's includes/ folder. And I can try to search the event via jQuery._data(el, 'click'); but that is my jQuery object, not the one of the website where the events are apparently stored. I'm glad I figured that out after hours of fiddling around.
Or maybe it is possible to access the website's jQuery object itself?
EDIT:
What I'm ultimately trying to achieve works in theory but … it's complicated. The original script uses a plugin event and keeps reinstalling it with .on('mouseleave',….
Anyway, this is what I got thanks to you, pdoherty926:
var $el = $('div.slideshow');
$('h2', $el).click(function(){ console.log('ouch!'); }); // test event
var $slides = $('.slides', $el).detach();
$copy = $el.clone(false);
$slides.prependTo($copy);
$el.replaceWith($copy);
The test event doesn't get triggered but the event I'm actually trying to remove still fires. I can imagine figuring it out, though, now that I got closer to my goal.
Okay, the aforementioned re-installation on mouseleave really messed up this otherwise satisfying suggestion. (The site is using the jQuery Timer plug-in by Cyntaxtech). So here's how I solved it instead: I simply changed the class name (-.-' )
Now the re-installation code cannot find the element anymore.
This is how my finished script looks like:
function stop_happening() {
var $el = $('div.fullwall div.slideshow');
$el
// first, stop the current automation.
.timer('stop') // Timer plug-in
// next, change class name in order to prevent the timer
// from being started again.
.removeClass('slideshow').addClass('slideshow-disabled-automation');
//--- copied some extra code from the website itself for the onclick
// events which are supposed to keep working. I wish I could do *that*
// programmatically but I'm glad I got as far as I got. ---//
// […]
}

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.

jQuery effect on iframe parent document

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.

Categories