I'm making a plugin for wordpress post page and I'm trying to detect div with id "matched". I can see the div with browser tools, however console throws the message that the div wasn't found. I think that's because script is loading before the page contents. How can I make it to load after the post contents has rendered?
<script type="text/javascript">
var question = document.getElementById("matched");
window.onload = function afterWebPageLoad() {
if(question){
console.log("id 'matched' exists");
} else {
console.log("id 'matched' not found");
}
}
</script>
You were calling document.getElementById before waiting for the page to load with the onload listener.
Move the variable declaration inside the onload listener so that it is only called when the page is loaded.
What your code should look like:
<script type="text/javascript">
window.onload = function afterWebPageLoad() {
var question = document.getElementById("matched"); // <-- Moved inside
if (question) {
console.log("id 'matched' exists");
} else {
console.log("id 'matched' not found");
}
}
</script>
<p id="matched">match element</p>
You can use setInterval like this;
let checker = setInterval(function () {
if (document.getElementById("matched") !== null) {
console.log("found")
clearInterval(checker)
} else {
console.log("checking..")
}
}, 100)
Also, you must check the element in afterWebPageLoad function. You must move question variable to the function.
I know this has been covered extensively as separate issues; I've tried copying verified answers, but I'm having trouble homologating Javascript conditional statements and a link URL change.
Essentially, what I need to do is detect mobile users and change a conference call URL to a tel link. I've been using if (screen.width <=699) { as the condition and it works on redirects. Here's what I've tried:
<script type="text/javascript">
<!--
var call=document.getElementByID('phone');
if (screen.width <= 699) {
call.write('<a href="tel:!PHONENUMBER!">');
else
call.write('<a href="!URL!" target="blank">);
}
//--!>
</script>
</head><body>
...
...
I've also tried these with corresponding else statements to no avail:
no var and document.getElementByID('phone').write
onclick = function() { window.location.href ='tel:!PHONENUMBER!};.
call.src.replace('tel:!PHONENUMBER!');
call.setAttribute("href",'tel:!PHONENUMBER!');
I apologize if this is a super basic issue - I'm still learning Javascript. Thank you in advance.
Will
You need to either wait for the page to finish loading before you execute your JavaScript or move your script block to the bottom of the HTML.
If you want to wait for the page to finish loading, then wrap your code in the following:
window.onload = function () {
// your code goes here
}
Figured it out with help from #sepbot.
<body onload="mobileURL()">
<div id="phone"></div>
<script type="text/javascript">
function mobileURL() {
var a = document.createElement("a");
a.innerHTML="!LINKTEXT!";
var myPhone = document.getElementById('phone');
if (screen.width <= 699) {
a.setAttribute('href', '!TELEPHONE!');
myPhone.appendChild(a);
} else {
a.setAttribute('href', '!URL!');
myPhone.appendChild(a);
}
}
</script>
My JSP is calling from a backbone application. In this JSP, I have CSS and script tags. But some how My script is not loading first in Backbone app. Same JSP is working in Java application, but not backbone application. I tried several things like keeping script in starting of the page and end of the page. But no luck.
Is there anyway I can execute JSP script first in backbone?
I would like to execute window.location.replace(url) first from below code when ever this jsp is loaded from backbone app. But currently it is loading CSS first and redirecting another page, this is causing page delay before redirecting
<script>
var entitle = "${Data.entitle}";
var optIn = "${OptIn}";
var isModel = ("${Data.Model}" == "true") ? false : true;
if(entitle == "true" && optIn == "IN") {
showWindow("some url", true);
}
function showWindow(url, isModel) {
if(isModel) {
var newWindow = window.open(url,'name','height=800, width=1200, resizable=yes, scrollbars=yes');
//popup is blocked
if(!newWindow){
//Some Logic
});
}
else if (window.focus) {
newWindow.focus();
}
}
else {
window.location.replace(url);
}
return false;
}
}
</script>
<style type="text/css">
// My styles
</style>
<div class="ticket">
// My HTML content
</div>
So i have 2 windows.. my main browser window (foo), then it has a href that calls a bit of JS that will make a mini window (bar) pop up.. The mini window contains a form which posts to itself and query a database and updates fields.. It works fine.
if($edit_type == "email")
{
if($update == true)
{
$form_email = $_POST['form_email'];
$queryreg = mysql_query("
UPDATE users
SET `email` = '$form_email'
WHERE username = '$username';
");
}
//Other code to run when the page hasnt been posted
}
My question is, when its submitted, and the DB is queried, would it be possible to close bar automatically and then refresh foo to see the updated data?
PS.
The script im using to open my popup is as follows:
<script language="javascript" type="text/javascript">
<!--
function myPopup(target)
{
window.open( target, "myWindow", "status = 1, height = 600, width = 600, resizable = 0" )
}
//-->
</script>
Thanks guys
It is possible to refer to the main window from your bar pop-up.
window.opener in this case is your foo.
if(window.opener && !window.opener.closed) { //Check whether opener is open
window.opener.location.href = window.opener.location.href ; //Refresh main
window.close(); //Close itself
}
We are using jQuery thickbox to dynamically display an iframe when someone clicks on a picture. In this iframe, we are using galleria a javascript library to display multiple pictures.
The problem seems to be that $(document).ready in the iframe seems to be fired too soon and the iframe content isn't even loaded yet, so galleria code is not applied properly on the DOM elements. $(document).ready seems to use the iframe parent ready state to decide if the iframe is ready.
If we extract the function called by document ready in a separate function and call it after a timeout of 100 ms. It works, but we can't take the chance in production with a slow computer.
$(document).ready(function() { setTimeout(ApplyGalleria, 100); });
My question: which jQuery event should we bind to to be able to execute our code when the dynamic iframe is ready and not just it's a parent?
I answered a similar question (see Javascript callback when IFRAME is finished loading?).
You can obtain control over the iframe load event with the following code:
function callIframe(url, callback) {
$(document.body).append('<IFRAME id="myId" ...>');
$('iframe#myId').attr('src', url);
$('iframe#myId').load(function() {
callback(this);
});
}
In dealing with iframes I found good enough to use load event instead of document ready event.
Using jQuery 1.3.2 the following worked for me:
$('iframe').ready(function() {
$('body', $('iframe').contents()).html('Hello World!');
});
REVISION:!
Actually the above code sometimes looks like it works in Firefox, never looks like it works in Opera.
Instead I implemented a polling solution for my purposes. Simplified down it looks like this:
$(function() {
function manipIframe() {
el = $('body', $('iframe').contents());
if (el.length != 1) {
setTimeout(manipIframe, 100);
return;
}
el.html('Hello World!');
}
manipIframe();
});
This doesn't require code in the called iframe pages. All code resides and executes from the parent frame/window.
In IFrames I usually solve this problem by putting a small script to the very end of the block:
<body>
The content of your IFrame
<script type="text/javascript">
//<![CDATA[
fireOnReadyEvent();
parent.IFrameLoaded();
//]]>
</script>
</body>
This work most of the time for me. Sometimes the simplest and most naive solution is the most appropriate.
Following DrJokepu's and David Murdoch idea I implemented a more complete version.
It requires jQuery on both the parent and iframe and the iframe to be in your control.
iframe code:
var iframe = window.frameElement;
if (iframe){
iframe.contentDocument = document;//normalization: some browsers don't set the contentDocument, only the contentWindow
var parent = window.parent;
$(parent.document).ready(function(){//wait for parent to make sure it has jQuery ready
var parent$ = parent.jQuery;
parent$(iframe).trigger("iframeloading");
$(function(){
parent$(iframe).trigger("iframeready");
});
$(window).load(function(){//kind of unnecessary, but here for completion
parent$(iframe).trigger("iframeloaded");
});
$(window).unload(function(e){//not possible to prevent default
parent$(iframe).trigger("iframeunloaded");
});
$(window).on("beforeunload",function(){
parent$(iframe).trigger("iframebeforeunload");
});
});
}
parent test code:
$(function(){
$("iframe").on("iframeloading iframeready iframeloaded iframebeforeunload iframeunloaded", function(e){
console.log(e.type);
});
});
Found the solution to the problem.
When you click on a thickbox link that open a iframe, it insert an iframe with an id of TB_iframeContent.
Instead of relying on the $(document).ready event in the iframe code, I just have to bind to the load event of the iframe in the parent document:
$('#TB_iframeContent', top.document).load(ApplyGalleria);
This code is in the iframe but binds to an event of a control in the parent document. It works in FireFox and IE.
This function from this answer is the best way to handle this as $.ready explicitly fails for iframes. Here's the decision not to support this.
The load event also doesn't fire if the iframe has already loaded. Very frustrating that this remains a problem in 2020!
function onIframeReady($i, successFn, errorFn) {
try {
const iCon = $i.first()[0].contentWindow,
bl = "about:blank",
compl = "complete";
const callCallback = () => {
try {
const $con = $i.contents();
if($con.length === 0) { // https://git.io/vV8yU
throw new Error("iframe inaccessible");
}
successFn($con);
} catch(e) { // accessing contents failed
errorFn();
}
};
const observeOnload = () => {
$i.on("load.jqueryMark", () => {
try {
const src = $i.attr("src").trim(),
href = iCon.location.href;
if(href !== bl || src === bl || src === "") {
$i.off("load.jqueryMark");
callCallback();
}
} catch(e) {
errorFn();
}
});
};
if(iCon.document.readyState === compl) {
const src = $i.attr("src").trim(),
href = iCon.location.href;
if(href === bl && src !== bl && src !== "") {
observeOnload();
} else {
callCallback();
}
} else {
observeOnload();
}
} catch(e) {
errorFn();
}
}
Basically what others have already posted but IMHO a bit cleaner:
$('<iframe/>', {
src: 'https://example.com/',
load: function() {
alert("loaded")
}
}).appendTo('body');
Try this,
<iframe id="testframe" src="about:blank" onload="if (testframe.location.href != 'about:blank') testframe_loaded()"></iframe>
All you need to do then is create the JavaScript function testframe_loaded().
I'm loading the PDF with jQuery ajax into browser cache. Then I create embedded element with data already in browser cache. I guess it will work with iframe too.
var url = "http://example.com/my.pdf";
// show spinner
$.mobile.showPageLoadingMsg('b', note, false);
$.ajax({
url: url,
cache: true,
mimeType: 'application/pdf',
success: function () {
// display cached data
$(scroller).append('<embed type="application/pdf" src="' + url + '" />');
// hide spinner
$.mobile.hidePageLoadingMsg();
}
});
You have to set your http headers correctly as well.
HttpContext.Response.Expires = 1;
HttpContext.Response.Cache.SetNoServerCaching();
HttpContext.Response.Cache.SetAllowResponseInBrowserHistory(false);
HttpContext.Response.CacheControl = "Private";
This was the exact issue I ran into with our client. I created a little jquery plugin that seems to work for iframe readiness. It uses polling to check the iframe document readyState combined with the inner document url combined with the iframe source to make sure the iframe is in fact "ready".
The issue with "onload" is that you need access to the actual iframe being added to the DOM, if you don't then you need to try to catch the iframe loading which if it is cached then you may not. What I needed was a script that could be called anytime, and determine whether or not the iframe was "ready" or not.
Here's the question:
Holy grail for determining whether or not local iframe has loaded
and here's the jsfiddle I eventually came up with.
https://jsfiddle.net/q0smjkh5/10/
In the jsfiddle above, I am waiting for onload to append an iframe to the dom, then checking iframe's inner document's ready state - which should be cross domain because it's pointed to wikipedia - but Chrome seems to report "complete". The plug-in's iready method then gets called when the iframe is in fact ready. The callback tries to check the inner document's ready state again - this time reporting a cross domain request (which is correct) - anyway it seems to work for what I need and hope it helps others.
<script>
(function($, document, undefined) {
$.fn["iready"] = function(callback) {
var ifr = this.filter("iframe"),
arg = arguments,
src = this,
clc = null, // collection
lng = 50, // length of time to wait between intervals
ivl = -1, // interval id
chk = function(ifr) {
try {
var cnt = ifr.contents(),
doc = cnt[0],
src = ifr.attr("src"),
url = doc.URL;
switch (doc.readyState) {
case "complete":
if (!src || src === "about:blank") {
// we don't care about empty iframes
ifr.data("ready", "true");
} else if (!url || url === "about:blank") {
// empty document still needs loaded
ifr.data("ready", undefined);
} else {
// not an empty iframe and not an empty src
// should be loaded
ifr.data("ready", true);
}
break;
case "interactive":
ifr.data("ready", "true");
break;
case "loading":
default:
// still loading
break;
}
} catch (ignore) {
// as far as we're concerned the iframe is ready
// since we won't be able to access it cross domain
ifr.data("ready", "true");
}
return ifr.data("ready") === "true";
};
if (ifr.length) {
ifr.each(function() {
if (!$(this).data("ready")) {
// add to collection
clc = (clc) ? clc.add($(this)) : $(this);
}
});
if (clc) {
ivl = setInterval(function() {
var rd = true;
clc.each(function() {
if (!$(this).data("ready")) {
if (!chk($(this))) {
rd = false;
}
}
});
if (rd) {
clearInterval(ivl);
clc = null;
callback.apply(src, arg);
}
}, lng);
} else {
clc = null;
callback.apply(src, arg);
}
} else {
clc = null;
callback.apply(this, arguments);
}
return this;
};
}(jQuery, document));
</script>