Detect clicks of images inside iframe - javascript

I cant figure out why this isn't working. It's probably something simple. The iframe is from the same domain as parent page.
I know I can use jQuery, but I want to learn to do it in pure JavaScript.
My code so far:
document.getElementById('my_iframe').onload = function() {
document.getElementById('my_iframe').contentWindow.document.getElementsByTagName('img').onclick = function() {
alert("image in iframe was clicked");
}
}

Forget the frame business for a second, and look at this code:
document.getElementsByTagName('img').onclick = function() {
Will that ever work? No. You are getting an object (a NodeList, to be precise) containing all the img elements in the document. You are adding an onclick property to that object. Not to the elements themselves: to an object that points to them. The function will never be fired because it is never applied to any elements.
You should do exactly the same as you normally would: loop though all the images you've found and apply the function to them individually.
var onclickFn = function() {
alert("image in iframe was clicked");
},
images = document.getElementById('my_iframe').contentWindow.document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
images[i].onclick = onclickFn;
}

document.getElementsByTagName is returning a collection of images. You can't just set a click handler on the entire collection. You need to loop through them one at a time.
var allimgs = document.getElementById('my_iframe').contentWindow.document.getElementsByTagName('img');
for (var i = 0; i < allimgs.length; i++) {
allimgs[i].onclick = function() {
alert("image in iframe was clicked");
};
}

Related

Why my Chrome extension event doesn't work?

I'm trying to create a chrome extension. I had a problem with the affectation of event for the new element that i append to the dom of site with content. Js
If I add an event to an element' 'for example class' exist already in the page, it works correctly. Just for my new appended element((in the code iadded a button ,the event is just an alert to test))
function tst() {
myclass = $("._3hg-._42ft");
myclass = myclass.not(".supp");
myclass.addClass("supp");
var patt = /https:\/\/(.)*\.facebook\.com\/(.)*\/(posts|photos|videos)\/(\w|\.|\d)*/g;
for (i = 0; i < myclass.length; i++) {
result = patt.exec(myclass[i]);
myclass.append('<button class="fact" id=' + result[0] + ' style="position: absolute;">fact</button>');
};
/* this is a simple event*/
/***********************/
$(".fact").on('click', function() {
alert("no event work ");
});
Making somewhat broad assumption here in my answer that it is JavaScript/jQuery related and is NOT an extension...or is so still in that context.
You need to attach the event to the container here perhaps for the dynamically created elements. Lots of global stuff, suggested to not do that, updated there.
Appends a lot of buttons perhaps? might need to only hit DOM once but left as-is in this isolated function.
function tst() {
let myclass = $("._3hg-._42ft")
.not(".supp");
myclass.addClass("supp");
//let result = {};
var patt = /https:\/\/(.)*\.facebook\.com\/(.)*\/(posts|photos|videos)\/(\w|\.|\d)*/g;
var i = 0; //avoid global
for (i; i < myclass.length; i++) {
// broad assumption of the returned value from patt.exec() here
// not even sure why it needs an id, have a class, use for css
let result = patt.exec(myclass[i]);
myclass.append('<button class="fact" id="' + result[0] + '">fact</button>');
}
/* attache event to pre-existing element */
/***********************/
myclass.on('click', ".fact", function() {
alert("event works");
});
}
button.fact {
position: absolute;
}

Rewrite Parallax-Script so it reads multiple Classes instead of one Id

Heyo,
is there any way I can get this script:
function parallax (){
var paralax_effect = document.getElementById('div1');
paralax_effect.style.top = -(window.pageYOffset / 4)+'px';
}
window.addEventListener('scroll', parallax, false);
to run multiple Classes instead of one Id?
I tried this:
function parallax (){
var paralax_effect = document.getElementsByClassName('div1');
paralax_effect.style.top = -(window.pageYOffset / 4)+'px';
}
window.addEventListener('scroll', parallax, false);
but this somehow doesn't work.
Thanks in advance!
getElementsByClassName returns not a single element but a whole list of elements, whereas getElementById (notice the difference in the word Element/Elements) returns only a single element.
So in your second code, you store a list of elements with the class "div1" in var paralax_effect. In order to manipulate those elements you have to loop over them with for. Example:
for (var i = 0; i < paralax_effect.length; i++) {
current_element = paralax_effect[i]
current_element.style.top = -(window.pageYOffset / 4)+'px';
}
This requires your HTML to have at least one element with class="div1".

Can you use "this" attribute on onclick of an HTML tag?

Can you use the this tag for the onclick on an HTML tag?
Here's my JS code...
function changeImage() {
this/*<-- right there <--*/.src=a;
}
document.getElementsByTagName('img').onclick = function(){
changeImage();
} ;
Am I doing something wrong?
Use it this way...
function changeImage(curr) {
console.log(curr.src);
}
document.getElementsByTagName('img').onclick = function(){
changeImage(this);
} ;
You could use the .call() method to invoke the function with the context of this.
In this case, you would use:
changeImage.call(this)
Example Here
function changeImage() {
this.src = 'http://placehold.it/200/f00';
}
document.getElementsByTagName('img')[0].onclick = function(){
changeImage.call(this);
};
As a side note, getElementsByTagName returns a live HTMLCollection of elements. You need to apply the onclick handler to an element within that collection.
If you want to apply the event listener to the collection of elements, you iterate through them and add event listeners like this:
Updated Example
function changeImage() {
this.src = 'http://placehold.it/200/f00';
}
Array.prototype.forEach.call(document.getElementsByTagName('img'), function(el, i) {
el.addEventListener('click', changeImage);
});
Or you could simplify it:
Example Here
Array.prototype.forEach.call(document.getElementsByTagName('img'), function(el, i) {
el.addEventListener('click', function () {
this.src = 'http://placehold.it/200/f00';
});
});
You are doing two things wrong.
You are assigning the event handler to a NodeList instead of to an element (or set of elements)
You are calling changeImage without any context (so this will be undefined or window depending on if you are in strict mode or now).
A fixed version would look like this:
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
images[i].onclick = function () {
changeImage.call(this);
};
}
But a tidier version would skip the anonymous function that does nothing except call another function:
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
images[i].onclick = changeImage;
}
And modern code would use addEventListener.
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
images[i].addEventListener('click', changeImage);
}
However, images are not interactive controls. You can't (by default) focus them, so this approach would make them inaccessible to people who didn't use a pointing device. Better to use controls that are designed for interaction in the first place.
Generally, this should be a plain button. You can use CSS to remove the default padding / border / background.
If you can't put a button in your plain HTML, you can add it with JS.
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
var image = images[i];
var button = document.createElement('button');
button.type = "button";
image.parentNode.replaceChild(button, image);
button.appendChild(image);
button.addEventListener('click', changeImage);
}
function changeImage(event) {
this.firstChild.src = a;
}

Reset the html element using jquery

I am having a div with lot of elements inside the div. For some scenario i want to reset the value for the div's element to the initial status.
Is there any way to do this??
if($(window).width()<=960){
$('#desktopCart').html(/i want to reset this element/);
}
if($(window).width()>960){
$('#mobileCart').html("/i want to reset this element/");
}
try:
$( document ).ready(function() {
var initialValue =$('#mobileCart').html();
});
if($(window).width()<=960){
$('#desktopCart').html(initialValue);
}
if($(window).width()>960){
$('#mobileCart').html(initialValue);
}
use .empty() of jquery
$("#divId").empty();
It will remove all the child elements and text in that particular element.
If you want to restore the initial state of the div, you should save the initial innerHtml to a variable a document.ready().
Like,
var desktopCart;
var mobileCart;
$(document).ready(function(){
desktopCart=$('#desktopCart').html();
mobileCart=$('#mobileCart').html();
});
Then restore the html whenever you want,
if($(window).width()<=960){
$('#desktopCart').html(desktopCart);
}
if($(window).width()>960){
$('#mobileCart').html(mobileCart);
}
First clone the element instead of saving the content. Then use replaceWith to restore it.
$(document).ready(function() {
var divClone = $("#mobileCart").clone();
if($(window).width()<=960){
$('#desktopCart').html(/i want to reset this element/);
}
if($(window).width()>960){
$("#mobileCart").replaceWith(divClone);
}
});
For further reference, please see the below link.
How can I "reset" <div> to its original state after it has been modified by JavaScript?
What if I have multiple elements ? And want to save the elements' state at regular intervals ? And regularly reset them ? There might not be just one of them .... maybe I will have a and p and div and too many of them. But I want to reduce typing ? What do I do ?
I am glad you asked.
// Write Once: Use Anywhere functions
$.fn.reset = function () {
var list = $(this); // list of elements
for(var i = 0, len = list.length; i < len; i++){
list.eq(i).text(list.eq(i).data("initValue"));
}
};
$.fn.saveState = function () {
var list = $(this); // list of elements
for(var i = 0, len = list.length; i < len; i++){
list.eq(i).data("initValue", list.eq(i).text());
}
}
$("div").saveState(); // simple call to save state instantly !
// value change!
$("div:nth-child(2)").text("99999");
$(window).resize(function () {
if ($(window).width() <= 960) {
$("div").reset(); // simple call to reset state instantly !
}
});
DEMO Resize window

Remove onclick event from img tag

Heres my code:
<div id="cmdt_1_1d" class="dt_state1" onclick="sel_test(this.id)">
<img id="cmdt_1_1i" onclick="dropit('cmdt_1_1');" src="/site/hitechpackaging/images/items/bags_menu.jpg ">
<span class="dt_link">
BAGS
</span>
</div>
Unfortunately I cannot modify this file, is there a way using javascript to disable the onclick from the img tag only.
I was using this script but it disable the onclick event from all images. But i want only from this component
var anchorElements = document.getElementsByTagName('img');
// for (var i in anchorElements)
// anchorElements[i].onclick = function() {
// alert(this.id);
// return false;
// }
Any ideas will be appreciated.
Edited:
Is there a way to stop the function dropit from executing, is it possible using javascript. On page load, etc.
another option is can i rename the img file using javascript??
document.getElementById('cmdt_1_1i').removeAttribute("onclick");
var eles = document.getElementById('cmdt_1_1d').getElementsByTagName('img');
for (var i=0; i < eles.length; i++)
eles[i].onclick = function() {
return false;
}
Lots of answers, but the simplest is:
document.getElementById('cmdt_1_1i').onclick = '';
try something like this:
var badImage = document.getElementById("cmdt_1_1i");
badImage.onclick = null;
badImage.addEventlistener("click",function(e){
e.preventDefault();
e.stopPropagation();
return null;
},true);
If you later need to restore the onclick property, you can save it in a field before overwriting it:
document.getElementById(id).saved=document.getElementById(id).onclick;
document.getElementById(id).onclick = '';
so that later you can restore it:
document.getElementById(id).onclick=document.getElementById(id).saved;
This can be useful especially in the case, in which the original onclick property contained some dynamically computed value.
You can programmatically reassign event listeners. So in this case, it might look something like:
const images = document.querySelectorAll('#cmdt_1_1d img')
for (let i = 0; i < images.length; i++) {
images[i].onclick = function() => {}
}
...where the query above returns all of the img tags that are descendants of the element with ID cmdt_1_1d, and reassigns each of their onclick listeners to an empty function. Therefore no actions will take place when those images are clicked.

Categories