Is it possible, with Javascript or some other technology to determine which hyperlink a user has clicked on, without changing the hyperlink source code.
For example:
Can you click on a 'tag' button, then click on a hyperlink hosted in a different iframe, and be able to calculate which hyperlink the user clicked on, without changing any of the source code in that iframe?
Using jQuery, you are able to set the context of your selection. i.e.
$('a', $('#iframe-id')).click(function() {...});
You can then implement an event handler that will handle the iFrame hyperlink clicks. The "this" property within the handler will allow you to interrogate the hyperlink and obtain properties such as innerText etc.
you need to put an event on each a link ,
and then you will get all the information about the specific click.
this will work only in the some document,
so if you try to do a test between the link inside an iframe and a link in your page you will not get an event for the iframe link.
in order to attach the event for all link you need to run on all the links in the page ,
the best way to do that is by jQuery selector. or other js framework like YUI
$("a").click(function () {
alert('')
});
getElementsByTagName("a") - will give you all the links in the page.
I just thought of a solution, would this work, or are there other options?
The solution would be to proxy the content of the iframe soruce page, replacing href's with code to call a javascript function which would identify which href was clicked on.
This could then be used in conjunction with the tag'ing click to accurately tag a link.
This would also mean the original source, doesn't need to change at all.
What do you need ?-)
If you got an iframe, you use as a target for links, you must do some server-side processing or add something to the url of the links, that you can read when the page loads ...
But detecting time of page-load requires a script in the page, that is inside the iframe, or a function which tests the availability of the elements in the page in the iframe in short intervals ...
-- but you can only succeed if the page comes from the same domain as the main-page, as cross-domain scripting is illegal and thus impossible !-)
I think it should be possible. The contents of an IFrame is accessible from the outer document (the page in which the iframe is embedded) so you should be able to add event handlers (see other answers) on those elements after the iframe has loaded.
See also Wikipedia on Iframe which gives some examples and frameworks which actually work on content within an IFrame.
You can inject code into an iframe, but only if that iframe is on the same domain as the page you're injecting from, for obvious security reasons.
<iframe id="framedpage" src="framedpage.html"></iframe>
<button type="button" id="tagbutton">Tag</button>
<script type="text/javascript">
function framedclicks_bind() {
var f= document.getElementById('framedpage');
var fdoc= f.contentDocument;
if (!fdoc) fdoc= f.contentWindow.document; // for IE
if (fdoc)
for (var i= fdoc.links.length; i-->0;)
fdoc.links[i].onclick= framedclicks_click; // bind to all links
}
function framedclicks_click() {
alert('You clicked on '+this.href);
return false; // don't follow link
}
document.getElementById('tagbutton').onclick= framedclicks_bind;
</script>
Might want to cleaning-up depending on application needs (eg. to ensure the frame is always loaded before trying to bind, or that unbinding can happen, or that any onclicks from the original links are remembered), but that'd be the general shape of things.
Good solution to find out which element was clicked is to use event delegation. If you attach event listener to each element using a loop (over document.links or document.getElementsByTagName), you have two problems:
- browser has many listeners to maintain
- events are attached only to elements that were in the DOM when you called the loop; any element dynamically added later doesn't have an event listener.
A simple example of event delegation:
document.onclick = function(e){
e = e || window.event;
var t = e.target || e.srcElement;
if(t.nodeName=='A'){
alert( t.href );
}
}
If you want to find clicked link inside an iframe just use iframe's contentDocument instead of document.
Related
I am binding the scroll events to all my html elements. To get the all the elements i am using the below filter
var element = $(myelemt).parentsUntil("html").add($(window));
return element
here element will return the body, window and all parents htmls tags.
For this html elements i am binding the events like below code:
element.on("scroll", function (e) {
$("#mywrapper3").html($("#mywrapper3").html() + "scrolling<br>");
}
Here i want to prevent particular child div element only from binding. How i can achive this?.
For example in my page for one div element(element with mywrapper id in sample) i dont want to bind this scroll event.
Also, I have to filter the element like in first code only. So how to achieve this instead of using stop propagation. Is there any way to do this.
I have prepared the one jsfiddle.Please get the link below
https://jsfiddle.net/khkcjb6o/
Thanks for any help
The .off() method is what you need. Originally I had started answering with an iframe solution and came up with the better solution later.
Since an iframe's context is different than it's parent, it is not included if you register everything on the parent page.
In the PLUNKER, the first section has an iframe with srcdoc and content within. Scroll the iframe and you'll notice that it isn't triggering the scroll counter.
Same thing with the second section that has a normal iframe.
The third and fourth section have scrolling content.
As expected, both trigger the scroll event.
Click the IV OFF button which uses the .off() method.
Now scroll section IV and notice the scroll counter isn't increasing.
.off() is what you need. Make sure to use this expression:
$('*').on('scroll', function() {....
That * will register everything but iframe content on a page so you don't have to write all of that code you had in your question.
You could jus use the :not() CSS selector
var element = $(myelemt + ':not(#mywrapper3)').parentsUntil("html").add($(window));
element.on("scroll", function (e) {
$("#mywrapper3").html($("#mywrapper3").html() + "scrolling<br>");
}
I am using the google search API and I want that when you click on an image, this image will be copied to a different location.
I created a fiddle here: http://fiddle.jshell.net/wjewg062/
It works this way: The user types in a term in the input field and images will be displayed. When he/she clicks on one twice it will displayed in the image div.
I put the onClick event listener on to the searchresults div, hence the extra click in the beginning. However, I want it to be displayed on the first click.
Now, if I comment this out
var searchresults = document.getElementById('searchresults');
searchresults.addEventListener("click", function(event){
event.preventDefault();
imageing();
});
it doesn't work. The images will be links. I believe the reason for this is that the results are displayed in gs-image-box and not created yet. I tried calling the imaging function in different other functions like the searchImg or the OnLoad but nothing work.
I thought of using a check if element is clicked function described here Detect if I'm clicking an element within an element
but I think there must be an easier way.
I'm running out of ideas, can anyone give an idea or hint?
Thanks !
The images are dynamically created right? Check out this post Event binding on dynamically created elements?
In short, events are attached to elements upon pageload. so a newly created dynamic element such as the ones that google creates, aren't attached to the event. so google probably has a way to circumvent the whole "you need to load the page to attach events to elements" thing but it requires an extra click. Using the syntax found in the post should help you.
By the way. Using Jquery doesn't really show down your site because it's usually cached in the client's browser.
The info you need is already in your searchresults eventListener. The target of this event will be the image you click, even if you add the event on a div higher in the structure.
A javascript event will by default be dispatched from the top element (window) all the way through the element that received the click, then will go back to the top. Any element that is an ancestor of the element that was clicked will receive the event info, so you can listen on any ancestor, but the target remains the element that was actually clicked.
In your case, by simply passing the target to your imageing() function, you can apply the behaviors you want without any extra manipulations.
One problem you might face, is if user clicks on searchresult but not on an img element. Then you'll have a bug, so you should handle these cases.
Something like this:
var searchresults = document.getElementById('searchresults');
searchresults.addEventListener("click", function (event) {
console.log(event.target, this);
event.preventDefault();
if(event.target.tagName == 'IMG'){
imageing(event.target);
}
});
function imageing(targetImg) {
var imageresult = document.getElementsByClassName('gs-image-box');
var xu = document.getElementById('companylogo');
var imgsrc = targetImg.src;
xu.src = imgsrc;
}
http://fiddle.jshell.net/pwjLrfnt/3/
How can I capture a click or mousedown event on a div surrounding an iframe. I've tried attaching the function to click event on the div but since the iframe never bubbles the event up to the surrounding div the function is never called. Is there a way I can capture the event on the div and then propagate it to the iframe for default action?
If the click is in the iframe area, the iframe context handles the click event, it does not bubble up to the iframe parent. So the div will never register the click event at all if it happened in the iframe area.
Furthermore, if the iframe contains a page that does not belong to the same domain as the iframe parent, any interaction is prohibited (re. same origin policy).
When the same origin policy is met, there are a few things you can do, you could call a method in the iframe parent context:
top.parentFunction();
So in the iframe you add an event listener that delegates to the iframe parent (accessible with the top reference.
Propagating events is a lot more complicated, so I'm simply going to refer to Diego Perini's NWEvents library. I believe his event system to be one of the better ones out there and he's particular on iframe interaction.
I certainly would not start writing your own code to achieve this, this can easily be a year long project if you want to do it properly and even then will be inferior to Diego's work.
There's no "good" way to do it, but if you really need to detect a click on an Iframe, you can kind-of do it in the latest browsers.
<iframe src="http://mtw-ed.com/" id="iframe" style=""></iframe>
<script type="text/javascript">
var inIframe = false;
function checkClick() {
if (document.activeElement
&& document.activeElement === document.getElementById("iframe")) {
if (inIframe == false) {
alert("iframe click");
inIframe = true;
}
} else
inIframe = false;
}
setInterval(checkClick, 200);
</script>
This script will check every 200ms whether the user is in the Iframe. Of course, they may not have clicked on the Iframe to get there, but I'm afraid this is the best you can do without #BGerrissen's solution.
It will detect the first 'click' only, unless you click out again. It only works in really modern browsers.
You can use a library like porthole to pass messages between parent and iframe, even across domains. Using this wouldn't exactly propagate the event (you won't be able to get the event object), but you can create your own event in the form of a simple message, and then handle it in the parent as a click.
Here's their example
However, I've used Brendon's answer as it's simpler works for my current need.
If you land here because you need to track a click on a PayPal button (like me), and you have access to the JavaScript SDK, you can listen to the click by adding the onClick callback in the initialization.
Example:
paypal.Buttons({
onClick() {
// here you can track the click
}
}).render('#paypal-container');
Link to the docs: https://developer.paypal.com/sdk/js/reference/#link-oninitonclick.
I'm developing an extension for Firefox. The extension adds event listener to "appcontent" element on "load" event.
How to determine the event came from the main document of the tab? At the moment all events from different elements of the page come (for example image and even the extension document if it fires one). I would like to exclude all the cases, including frames, iframe and so on, only the url typed in the location bar.
Just an answer for those who gave points to the question itself and who might find the question through the search.
The task is solved with the line
if (Event.originalTarget == content.document)
worked for me.
Found in some newsgroup
Can you compare event.srcElement.ownerDocument the main page document? You could also use the .location.href properties. Quick and dirty example:
//- on event
var doc = event.srcElement.ownerDocument;
if (doc && (doc.location.href == currentUrl))
runFunction();
https://developer.mozilla.org/En/DOM/Node.ownerDocument
Have a look at originalTarget and explicitOriginalTarget attributes of event object. https://developer.mozilla.org/en/DOM/event.originalTarget
Use it as something like:
if(event.explicitOriginalTarget == theHookedObject) {
// do your stuff
}
Where theHookedObject is the object to which you've attached your listener to.
I have a modal dialog plugin written in jquery, that binds to the click event of all of the <a> elements with a specific class.
The modal dialog 'fetches' a page via AJAX, which is declared under the 'href' parameter of the <a> element.
Everything works fine, but - when a user clicks the <a> link before the page was fully loaded and ready (before the click event is binded to the element) - the browser navigates to the page declared in the 'href' parameter.
Any ideas of how to prevent this behavior? An ideal situation would be to ignore clicks on these elements before the page has fully loaded. Client-side performance is crucial.
If you need to avoid inline scripting, then you could utilise jQuery's live() method to bind an event handler for elements that have not yet been added to the DOM:
1) Be sure to include jQuery in the <head> and not the <body>, since we need to initiate the following code before any elements in the body are created.
2) Include the following, also in the <head> (e.g. as an external js file):
$("a").live("click", function(){// Use a more specific selector than "a" if poss.
getAjax( // This is your Ajax function. Adapt as required.
$(this).attr('href') // Pass in the <a>'s href attribute.
);
return false; // Cancel the default click handler, to prevent page redirect.
});
Typically you'll avoid directly coding any href into the tag. Instead set href="javascript:void(0)" and handle the submission with jQuery.
Do something like this:
<a onclick="SomeJQueryCall()" href="javascript:void(0)">Click Me!</a>
And here's the jQuery script:
function SomeJQueryCall() {
//ask the web server for some AJAX xml
$.get(SomeUrl, null, SomeCallBackFunction(), "xml");
}