How to change the src and reload an iframe with DOJO? - javascript

I want to click on a link, pull the src of the link, and use that src to refresh an iframe in my page.
dojo.ready(function() {
dojo.query(".link").onclick(function(e) {
var node = e.target;
var url = dojo.attr(node, "href");
document.getElementById("audioiframe").src = url;
dojo.stopEvent(e);
});
});
I could do this quickly in OG Javascript or jQuery, but need to use DOJO.
Thank you
UPDATE: After incorporating Strife25 answer my code is:
dojo.ready(function() {
dojo.query(".audiolink").forEach(function(link){
dojo.connect(link, "onclick", null, function(e){
var node = e.target;
var url = dojo.attr(node, "href");
dojo.query("#audioiframe").attr("src", url);
dojo.stopEvent(e);
});
});
});
The event is attached to the links, the iframe src attribute is updated, but the onclick event is not canceled and the page behaves as if the link is clicked. It appears as if dojo.stopEvent(e); is not working (asking where to download the MP3 File). Also, the iframe is not reloading but I believe that is due to the click not being canceled.
UPDATE:
I am the bug, not the code! I was linking to the MP3 versus the page that housed the MP3 (long story). It works. Thank you.

You're attaching the click event in the wrong way, you should use dojo.connect to attach event handlers. Also, dojo.query() returns a NodeList when it runs instead of a single node.
The proper way to use dojo in this instance would be:
dojo.query(".link").forEach(function(link){
dojo.connect(link, "onclick", null, function(e){
//do your stuff
});
});
If you only have one button that performs the onclick event you are proposing, you should instead use dojo.byId like so:
var link = dojo.byId("linkId"); //retrieves a reference to a DOM node with the given id
dojo.connect(link, "onclick", null, function(e){
//do you stuff
});
Here is the doc page of dojo.connect, which also explains how you can clean up event handlers on object destruction / page unload: http://www.dojotoolkit.org/reference-guide/dojo/connect.html

Related

EventListener not working with anchor tel:XXXXXXXXX

I have a tag with href="tel:XXXXXXXXX", and I need catch the click event.
I have tested the following code on chrome: $(document).on('click',console.log). If i click on this tag browser it calls the application, but does not trigger a click event.
$("a[href^='tel']").on('click', console.log);
This is working, but I my have a problem with content load by ajax. My code has loaded a page and after some time application added content by ajax. When i use $(document).on('click', ("a[href^='tel']", console.log), there is a problem.
$("a[href^='tel']").on("click", function(e){
e.preventDefault(); e.stopPropagation();
console.log(this);
alert(this.getAttribute("href"));
})
//or if you want to delegate your function
$(document).on('click', "a[href^='tel']", function(e){
e.preventDefault(); e.stopPropagation();
console.log(this);
alert(this.getAttribute("href"));
});
This will bind an event listener to all click on a tags with a href attribute and prevent the click itself. After click, you'll be able to use your console to see which element was click and what href was used.
Ok, i found resolve.
I use earlier event "mousedown" and change attr "href" to "only number" for disable action click.
Code:
const click2dial_Event = function(e) {
e.preventDefault();
let a = $(this), number;
if (a.attr('href') !== '#') {
number = a.attr('href');
number = number.substr(4);
a.attr('href', '#');
a.attr('data-dial', number)
a.addClass('click-to-dial');
} else {
number = a.attr('data-dial');
}
//...
};
$(document).on('mousedown', "a[href^='tel']", click2dial_Event);
$(document).on('mousedown', '.click-to-dial', click2dial_Event);
This would get the phone number from the a tag starting with a value of tel upon clicking it.
$("a[href^='tel']").on("click", function(e) {
var hrefText = this.getAttribute("href");
var str = hrefText;
var res = str.split(":");
alert(res[1]);
});
On Initial Load
I would first recommend that you wait for the initial DOM to be ready before binding any events to elements.
// DOM ready shorthand
$(function() {
$("a[href^='tel']").on('click', function(e) {
// Do work here
});
});
AJAX Content
If you are adding additional elements after the initial load you will have to bind events to those new elements as well.
You could also do something like adding a data attribute to the elements that you've bound click events to and only add to ones that don't yet have that data attribute - but that's additional unnecessary work.
Full Example Code
// DOM Ready Shorthand
$(function() {
// Click Handler
function clickEvent(e) {
// Do work here
}
// Bind click event to initial tels
$("a[href^='tel']").on('click', clickEvent);
// Arbitrary AJAX request for demonstration (wherever yours may be)
$.ajax('/newContent')
.done(function(html) {
// Adding our response HTML to the page within #someElement
$('#someElement').append(html);
// Bind click event to the new tel elements scoped to the returned html
$("a[href^='tel']", html).on('click', clickEvent);
});
});

JS not executing on page loaded with .load

I'm working on a single page application website. All the navigation happens inside a div. I use addEventListener click to find the link, prevent regular href and open it inside the div.
With this code I can change pages, keeping the head and footer without refresh the entire page.
var spa_array = Array.from(document.getElementsByClassName('spa')); // Array with history (for the back button)
spa_array.forEach( function(b) {
var id = b.id;
b.addEventListener('click', function(e) {
event.preventDefault(); // Prevent href
history.pushState({id:id}, null, id); // Change url on browser
openPage(id);
});
});
window.addEventListener('popstate', function(e) {
openPage(e.state.id);
});
function openPage(url) {
var encodedUrl = encodeURI(url);
$("#spa").load(encodedUrl); // open link inside the div
}
This is where the problem happens: I use JS to load a new page on the div, index_2.html for example. The links on index_2.html page will not trigger the JS addEventListener, so it will refresh the page and open the new link.
JS is not being applied to the page opened inside the .load. Is there a way to apply the same script, without calling it again (which causes many a lot of trouble)?
Use a delegated event handler:
$("#spa").on('click', '.spa', function(e){
var anchor = this,
id = anchor.id;
e.preventDefault();
history.pushState({id:id}, null, id);
openPage(id);
});
You can register the handler on a DOM node that does not get removed (in your case, the container whose contents change, but the element itself stays the same), and pass in a selector as a second argument to check if the click occurred on an element inside it that matches the selector.
This is necessary because once you .load() additional content it will replace whatever was there in the element before, including any event listeners that you attached, once, on first load. You'd need to call your loop each time the content is changed, but this is a much less resource intensive solution that will save you the hassle.
I would extract the logic for adding the event listeners as shown below:
function bindLinks() {
var spa_array = Array.from(document.getElementsByClassName('spa'));
spa_array.forEach( function(b) {
var id = b.id;
b.addEventListener('click', function(e) {
event.preventDefault(); // Prevent href
history.pushState({id:id}, null, id); // Change url on browser
openPage(id);
});
});
}
That way you can call bindLinks() after the html is loaded into your div. You can do that by passing it as the second argument to .load().
function openPage(url) {
var encodedUrl = encodeURI(url);
$("#spa").load(encodedUrl, bindLinks);
}

Document click not working on dynamic element

Content script:
var $ = window.$.noConflict(true); // Required for IE
function startFunc() {
$('a').mouseover(function(e){
var anchor=this;
var href=$(anchor).attr('href');
if(href!='#'){
$('.klik-me').remove();
const xPos=e.pageX-20;
const yPos=e.pageY-20;
let $klikMe=$('<span class="klik-me">Click Me!!</span>').css({
'padding':'5px',
'background':'#000',
'color':'#FFF',
'font-size':'12px',
'position':'static',
'top':yPos,
'left':xPos,
'text-align':'center',
'z-index':999999
});
$(anchor).append($klikMe);
}
});
}
$('body').on('click','.klik-me',function(){
const href_in=$(this).parent().attr('href');
kango.console.log(href_in);
kango.dispatchMessage('storeHref', {href:href_in});
});
kango.addMessageListener('hrefSuccess', function(event) {
kango.console.log(event.data.link);
});
Background Script:
kango.addMessageListener('storeHref', function(event) {
event.target.dispatchMessage('hrefSuccess', {link:event.data.href});
});
I am adding a pop up for all anchor tags on the page (this is working fine),i added a click event in Jquery(I love this) and using kango.dispatchMessage for sending message to background script. Nothing seems to be working.
Any help would be appreciated.
PS: i use to work with crossrider(Awesome) framework previously.
What I think is happening is the click event is bubbling up to your <a> element and triggering the default navigation action.
Stopping bubbling / default behaviour in delegated event handling is difficult. What I would do instead, is remove the <span> as a child of the <a>. For example
let $klikMe = $('<span class="klik-me">Click Me!!</span>')
.css({ ... })
.data('href', href) // set the href data into the <span>
$(document.body).append($klikMe) // append to body, not anchor
and in your click handler
$(document).on('click', '.klick-me', function() {
const href_in = $(this).data('href')
// then continue as in your original code
return false // the click should have no default action
})
Use the snippet below is what I'm reading everywhere, I can't get it working however.
Currently trying to do somewhat the same: jQuery click event after new page loads
Maybe it can be of some use.
Cheers.
$(parent).on('click', child , callback);

Return false not working sometimes

I have a page with photo gallery http://dev.dolina-imeniy.ru/fotogalereya/kp_usadba_tishnevo/
I use this to bind click event and return it false
$('a.link_photo').click(function(e) {
var new_img = $(this).attr('href');
var photo_title = $(this).attr('title');
var photo_info = $('.photo_info', this).html();
$('#photo_view img').attr({
src : new_img
});
$('#photo_title').html(photo_title);
$('#photo_info').html(photo_info);
return false;
});
But on some images it not work! Why it appears?
Try click on 10 image (ut-1-foto.jpg) in my example to see it.
For some reason you code is breaking, so it does not reach to return false.
You can use e.preventDefault(); to stop the default action
e.preventDefault();
The reason for this is that the function only binds to the elements that are already in existent when it is called. Every link created after the the document has loaded will not be bound to this function. To listen for the creation of these elements and to then bind the function to them, you could use the jQuery plugin liveQuery. I hope that helps.
trying calling e.preventDefault()
For more info look here:
http://api.jquery.com/event.preventDefault/
I don't think return false; or event.preventDefault() has anything to do with it. I'm guessing it has to do with how your carousel works. It's no coincidence that your code breaks once the images start repeating - the click event is probably no longer bound. If the element is just being moved, the events should still be set, but if it's being cloned or copied the events might not be.
edit: I can confirm by debugging that your script isn't even called on the 'broken' links.

How can I get Iframe event before load?

In my site, I use an iframeA in an iframeB, and, when the iframeA changes it's content I have to set the src. I can set it only with the onload event, but this called when the site is loaded. I am looking for some event or trigger, that helps me detect the location/src change before it starts loading. I don't want to wait the whole page load, before the src set. I have no direct access to iframeA (just the script below)
Some code:
var myframe = document.getElementById('frameB').contentWindow.document.getElementById('frameA');
myframe.onload=function (funcname) {...};
Check this gist or my answer to this question. The code there does exactly that:
function iframeURLChange(iframe, callback) {
var unloadHandler = function () {
// Timeout needed because the URL changes immediately after
// the `unload` event is dispatched.
setTimeout(function () {
callback(iframe.contentWindow.location.href);
}, 0);
};
function attachUnload() {
// Remove the unloadHandler in case it was already attached.
// Otherwise, the change will be dispatched twice.
iframe.contentWindow.removeEventListener("unload", unloadHandler);
iframe.contentWindow.addEventListener("unload", unloadHandler);
}
iframe.addEventListener("load", attachUnload);
attachUnload();
}
It utilizes the unload event. Whenever a page is unloaded, a new one is expected to start loading. If you listen for that event, though, you will get the current URL, not the new one. By adding a timeout with 0 milliseconds delay, and then checking the URL, you get the new iframe URL.
However, that unload listener is removed each time a new page is loaded, so it must be re-added again on each load.
The function takes care of all that, though. To use it, you only have to do:
iframeURLChange(document.getElementById("myframe"), function (url) {
console.log("URL changed:", url);
});
What will be changing the source of the iframe? If you have access to that code then you can do whatever is in your onload function then.
If a link has it's target attribute set to the iframe and that is how the source is changing then you can hi-jack the link clicks:
$('a[target="frameB"]').bind('click', function () {
//run your onload code here, it will run as the iframe is downloading the new content
});
Also, just a side-note, you can bind an event handler for the load event in jQuery like this:
$('#frameB').bind('load', function () {
//run onload code here
});
UPDATE
SITE -> frameB -> frameA
$("#frameB").contents().find("#frameA").bind('load', function () {
//load code here
});
This selects the #frameB element (that is in the current top level DOM), gets it's contents, finds the #frameA element, and then binds an event handler for the load event.
Note that this code must be run after #frameB is loaded with the #frameA element already present in it's DOM. Something like this might be a good idea:
$('#frameB').bind('load', function () {
$(this).contents().find('#frameA').bind('load', function () {
//run load code here
});
});
UPDATE
To hi-jack links in the #frameB element:
$('#frameB').contents().find('a[target="frameA"]').bind('click', function () {
/*run your code here*/
});
This will find any link in the #frameB element that has its target attribute set to frameA and add a click event handler.
And again, this will only work if the #frameB iframe element has loaded (or atleast gotten to the document.ready event) so you can select it's elements.
You could also try taking the approach of detecting when your iframe is going to leave its current location. This may be useful in some situations. To do this, put the following code in you iFarme source.
$(window).on('beforeunload', function () {
alert('before load ...');
});
I think adding inline onload attribute with appropriate event handler to iframe tag will solve your problem.
function onIframeLoad(){
//Write your code here
}
Markup change
<iframe src='..' onload='onIframeLoad()' />

Categories