jQuery throws an error that iframe.getElementById is not a function - javascript

Any function to target that same iframe object is not working and the following error is thrown:
Uncaught TypeError: target[0].getElementsById is not a function
I want to access the value of objects of an iframe
function fetchmap(target) {
console.log(target[0])
var el = target[0].getElementsByTagName('input #pac-input');
var e = target[0].getElementsById('pac-input')
console.log(el);
};
<div class="col-md-12 px-4 md-form form-group" id="placefinder">
<iframe id="iframe" src="//developers.google.com/my-business/content/tools/placeid-lookup" width="100%" height="400px" onload="fetchmap($(this))"></iframe>
</div>

It's getElementById (singular), not getElementsById (plural). It returns a single element.
Also note that the elements in a document inside the iframe are not descendants of the iframe itself. You have to use iframe.contentDocument.getElementById().

Related

Using vanilla JS to set image src from data-attribute

I'm looking for a way to set the src of an image - in a modal - using the data attribute of a clickable element.
The markup for the element looks like this (there could be multiple of these on a page):
<span class="tooltip" data-imageToSet="someimage.jpg">Click me</span>
<div id="modal">
<img id="image" src="placeholder.jpg" />
</div>
<script>
var modal = document.getElementById('modal'),
modalImage = document.getElementById('image');
document.addEventListener('click', function(event) {
if (event.target.classList.contains('tooltip')) {
modal.classList.toggle('shown');
modalImage.src = event.currentTarget.dataset.imageToSet;
}
});
</script>
From what I've been reading up, this should work? But I keep getting a console error:
Uncaught TypeError: Cannot read property 'imageToSet' of undefined at HTMLDocument.<anonymous> ((index):1)
You have two issues. currentTarget will be the element you bound the click to so it will be document. The second issue is camel case does work with dataset, you need to use dash.
var modal = document.getElementById('modal'),
modalImage = document.getElementById('image');
document.addEventListener('click', function(event) {
if (event.target.classList.contains('tooltip')) {
modal.classList.toggle('shown');
console.log(event.target)
modalImage.src = event.target.dataset.imageToSet;
}
})
<span class="tooltip" data-image-to-set="http://placekitten.com/300/300">Click me</span>
<div id="modal">
<img id="image" src="http://placekitten.com/g/200/300" />
</div>
First you check if the target (i.e. the element that is clicked) has the tooltip class
event.target.classList.contains('tooltip')
But then you use the currentTarget (i.e. the element to which the event handler is bound: document) to read the dataset.
modalImage.src = event.currentTarget.dataset.imageToSet
You need to continue to use the target throughout.

how to close Iframe using paremt post message in javascript

I have a simple block which contains an iframe, I would like a user to be able to close the iframe using a button.
Here is what I have so far
JS
UPDATE
document.querySelector(DOM.videoclosebtn).addEventListener('click', closeIframeContainer);
var closeIframeContainer =function(){
window.parent.postMessage("event=closeiframe", "*");
};
window.addEventListener("message", receiveMessageFromIframe, false);
function receiveMessageFromIframe(msg) {
if (event == "closeiframe") {
document.getElementById('iframe-container').remove();
}else{
alert('hehehe');
}
}
Here is index.html with iframe
<div id="iframe-container">
<iframe src="/videoexplainer/data.html" style="border:none"></iframe>
</div>
Here is data.html
<div id="video-close_btn" class="video-btn">
<img src="images/x.png" />
</div>
Error:
Uncaught TypeError: Cannot read property 'window' of null
at HTMLDivElement.closeIframeContainer (videoexplainer.js:123)
unfortunately its not working, what do I need to do get what I want?
Your code assigns the return value from the .postMessage() call to getIFrameID, but then you expect to use it as a DOM node reference.
var closeIframeContainer = function(){
var getIframeID = document.getElementById('iframe-container');
getIframeID.parent.postMessage("*");
getIframeID.style.display="none";
};
Get the element node reference first, and then do the other operations.

Object returned by Jquery.find behaving unexpectedly with .data()

Take a look at this example :
let ele = $(`
<div></div>
<div class="test" id="test" data-test="test"></div>`
);
const ele1 = ele.find('.test'); //undefined
const ele2 = ele.find('#test'); //undefined
console.log(ele1.data());
console.log(ele2.data());
ele = $('<div class="test" id="test" data-test="test"></div>');
console.log(ele.data()); //works
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
There seems to be a difference between the object returned by .find() and the one returned by $()
I'm assuming it has something to do with the first ele being two siblings with no parent, but considering this can't be changed, how can I get #test's data?
I couldn't find anywhere what's the expected behaviour when you create an element with no parent like I did, and why does this happens.
Fiddle : https://jsfiddle.net/xpvt214o/26285/
You can just wrap that HTML inside a single div to be able to use find() on it. But, if you can't change the HTML, you can do it using filter(), since it's a collection of jQuery elements:
// Your element, as you defined it in your question
let ele = $(`
<div></div>
<div class="test" id="test" data-test="test"></div>`
);
console.log(ele.filter('.test').data());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Find if there's a img in a #wrapper with plain javascript [duplicate]

This question already has answers here:
Get element inside element by class and ID - JavaScript
(8 answers)
Closed 6 years ago.
So I want to see if there's an <img>inside my <div id="wrapper">
I know how to do this with jQuery. Now I want to translate it to plain JavaScript but I'm not sure how to use DOM selector to replicate the jQuery.
My jQuery solution
if ($('#wrapper img').length !== 0) {
alert("img");
} else {
alert("no img");
}
if ($('#wrapper2 img').length !== 0) {
alert("img");
} else {
alert("no img");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="wrapper">
</div>
<div id="wrapper2">
<img src="" alt="">
</div>
Here's a simple solution
if( document.getElementById('wrapper').getElementsByTagName('img').length > 0) {
// Image present
}
You can use:
document.getElementById('wrapper').getElementsByTagName('img');
alongside with an if statement where you check if there's an image in the div with wrapper id:
if (document.getElementById('wrapper').getElementsByTagName('img').length !== 0) {
console.log('img found');
}else{
console.log('no img');
}
<div id="wrapper">
</div>
<div id="wrapper2">
<img src="" alt="">
</div>
You can read more about: document.getElementById() and getElementsByTagName()
querySelector() is the DOM API method that you should use.
You should use this instead of querySelectorAll() (as some have mentioned) as this will perform better because it only looks for a single match and stops after finding one. Depending on the depth of your DOM, using querySelector() instead of querySelectorAll() or getElementsByTagName() can positively impact performance of the code.
This snippet shows a simple function that you can call anytime you need to do this check. If a nested <img> element is found, then you have a "truthy" result that you can test for with an if and if no nested <img> is found, then you have a "falsy" result that the same if condition can test for.
// Get DOM references to the wrappers you wish to test:
var wrap1 = document.getElementById("wrapper");
var wrap2 = document.getElementById("wrapper2");
// General function to test any DOM element for a descendant image.
function testImage(wrap){
// querySelector will return the first element that matches the query
// If no element is matched, no element is returned (null)
// Using the JavaScript "ternary" operator here to test the "truthy" or
// "falsy" result of querySelector on the supplied DOM object. If there is
// a nested image message becomes an empty string, but if there is no nested
// image, message becomes " not". Of course, you can change this to any
// values/operations you want to perform based on the result of the test.
var message = wrap.querySelector("img") ? "" : " not";
// Write a message and use the string determined in the previous line:
console.log("There is" + message + " an image inside " + wrap.id)
}
// Run the function as often as you liike:
testImage(wrap1);
testImage(wrap2);
<div id="wrapper">
</div>
<div id="wrapper2">
<img src="" alt="">
</div>
You can use querySelectorAll function - see demo below:
if (document.querySelectorAll('#wrapper img').length !== 0) {
console.log("img");
} else {
console.log("no img");
}
if (document.querySelectorAll('#wrapper2 img').length !== 0) {
console.log("img");
} else {
console.log("no img");
}
<div id="wrapper">
</div>
<div id="wrapper2">
<img src="" alt="">
</div>

how to add an object in a div

let's say I have the following code:
var cont = <div id="foo">
imgSection.find('video').each(function(_ind)
{
cont.append('<div class="fullScreenBg"> '+ $(this) +' </div>');
});
which results in:
<div id="foo">
<div class="fullScreenBg"> [object Object] </div>
</div>
But I actually want do display the html of the Object/Video. When I use instead:
$(this).html()
I get pretty close, but it shows, as expected, only the innerHtml of the videoTag.
So how do I do this right?
You need to wrap the video element in the div and append the object. The issue at the moment is that you are appending the object as a string which is causing the object to string conversion, resulting in [object Object].
imgSection.find('video').each(function(_ind) {
cont.append($(this).wrap('<div class="fullScreenBg"></div>').parent());
});
Alternatively, create DOM elements instead of using HTML:
var $parent = $('<div class="fullScreenBg" />');
$parent.append(this).appendTo(cont);

Categories