I have an Iframe embedded like this:
<iframe id="foo" src="http://www.something.com" style="width: 90%; height: 300px"></iframe>
Each time the page loads focus gets lost from the top of the page and switches to this Iframe that is in the footer.I was wondering how can i remove the focus from this and make the page load "normally"?
Thanks!
Update: Yes, iframe is being loaded from another source (not the same domain)
if assumed the iframe is not served from the same domain.. you can place any other focusable dom element after the iframe in the footer with autofocus set as true. And if that does not work please try the following in the parent main window:
$(window).on('load', function() {
setTimeout(function(){$("body").focus()}, 100);
};
OR going by vanilla JS
window.onload = function() {
document.getElementById("some-focusable-element-from-parent-window").focus();
};
Well there is too much things we can do, for example on window load we scroll to the top with scrollTop function, ...etc
But with such methods, where we take off the focus and move back to the top when the window is completely loaded, it will come with a glitch and no well effect.
After a while of thinking, and experiences, i come with that:
We remove the iframe with display:none, when the dom is ready. Next when the window is completely loaded, we bring it back. To do that efficienly, we write a style class like that:
.display_none{
display:none;
}
and we will add this class to our iframe, when the document is ready, and remove this class when the window is fully loaded. There is the code :
$(document).ready(function(){
$("#myFrame").addClass("display_none");
$(window).load(function(){
$("#myFrame").removeClass("display_none");
});
});
Now there is a situation where this will not work! if the iframe is created and added with another script, then the dom may be loaded but not the iframe element itself (because the script may not have create it yet)! And that was the case in my case .
SOLUTION:
put the iframe in a container, let say a div container, and apply the method above to this container. All should work nickel! On dom load the div is hidden, next when the window is fully loaded, it restore it back! and you get your iframe, which will be loaded and get displayed. No glitch, and efficient.
We can use sandbox attribute to block automatically triggered features (such as automatically playing a video or automatically focusing a form control).
<iframe src="https://muthukumaran-m.github.io/" sandbox></iframe>
Check this for more info
Assuming you have iframe in a same domain:
You can do this :
$("#foo").on('load', function() {
$("body",parent.document).focus()
};
It is already 2019 and I kept on having the same issue on some of my mobile websites. The focus kept on being stolen by the contact form near the footer.
My rushed method may not be the most elegant way of doing this, but by modifying your iframe form to be hidden on mobile devices, with an expand/collapse button to make it visible on demand, you'll stop this jump from happening.
The simplified code:
<div class="d-block d-sm-none visible-xs"><!-- show only on mobile devices -->
<a class="btn" data-toggle="collapse" href="#blockToControlID" role="button"
aria-expanded="false" aria-controls="blockToControlID">
Expand/Collapse iframe Block
</a>
<div class="collapse" id="blockToControlID">
<div class="card card-body">
<iframe src="path-to-form"></iframe>
</div>
<div>
</div>
<div class="d-none d-sm-block hidden-xs"><!-- hide on mobile devices -->
<iframe src="path-to-form"></iframe>
</div>
For bootstrap 3 you would use visible-xs and hidden-xs to hide or show the snippets of code.
For bootstrap 4 you would use the "d-block d-sm-none" to show the mobile-only code; and "d-none d-sm-block" to hide the mobile-only code.
Scripts needed on footer:
<script src="js/jquery/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.6/umd/popper.min.js"></script>
<script src="js/bootstrap/bootstrap.bundle.min.js"></script>
The jQuery version will depend on your bootstrap 3 or 4 setup.
popper.js must be loaded before bootstrap.js, otherwise it'll fail to work.
Prior to reaching this hack, I tried every possible thing. Sadly, none of the JS, jQuery and reCaptcha hacks posted by other members and forums worked. The page load would always default to the form.
While the solution could be nicer with some js/ajax/jquery or even php, this simple code is quick and works fine with bootstrap enabled websites. Modify as needed.
I hope this helps
Related
I have 4 images that when I click them they show information under the images and when I click the last ones the images go under the page and whens the new page loads with that information I have to go down with scroller to see the image and information of the last image.
I want to put focus to the last image when the new page loading.
I do this but it's not working:
<script>
function setFocusToTextBox(){
document.getElementById("abc").focus();
}
</script>
<img src="images/Practidose.fw.png" alt="" width="770" height="150" id="abc" onclick="setFocusToTextBox()"/>
Picture of the 4 images and when I click the last one I want to focus that image when the new page loads:
.focus() can normally only be applied to links or form inputs.
However, you can use it on arbitrary elements by giving the element a tabindex attribute.
This is usually a good idea for accessibility reasons anyway if you want to make use of onClick handlers, as this will help keyboard navigation and other accessibility tools understand that your element is supposed to be clickable.
I am not fully sure of why you want to focus the image you are ON, but try
function setFocusToTextBox(){
document.getElementById("abc").scrollIntoView();
}
If onload:
window.onload=function(){
document.getElementById("abc").scrollIntoView();
}
I use the tabber script shown on http://www.barelyfitz.com/projects/tabber/ to provide a tabbed page. Generally it works well, and my only complaint is that the tabs don't show until the content has fully loaded, and then there is a jump as the screen writes itself properly. (See www.littlehotels.co.uk/spain/noves.php for an example of what I mean.)
I thought the solution would be to hide the div containing all the tabbed content like this
<div class="tabber" id="tabber" style="display:none">
and then reveal it with a small javascript function which is called by
<body onLoad="ShowTabber()">
The javascript itself is
<script type="text/javascript">
function ShowTabber() {
document.getElementById('tabber').style.display = "block";
}
</script>
My little function appears to stop the external javascript (tabber.js) from working because the page displays the content of all the tabs in line, without the the tabs themselves at the top. This is the same result as if I delete the reference to the external script from the of the page.
What am I doing wrong?
More explanation:
When the tabber.js file is missing, the page displays the content of all the tabs one after the other(as you would expect). Running the script as explained above has exactly the same effect; hence I am concluding that the script blocks the main javascript from running.
'onLoad': function(argsObj) {
/* Display an alert only after tab */
if (argsObj.tabber.id == 'tab') {
alert('Finished loading tab!');
}
}
By default select a tab.Then after completion loading that tab it will show a message.
see here
Well, I solved the problem (sort of) with jQuery, but it has now raised another problem.
In response to PSR, I looked more deeply into jQuery. It would have been too complicated to change over to .tabs(), but I did use jQuery to hide and show some divs at the appropriate moments.
I placed a simple little line in fron of the tabber div to show a "Loading" message.
<div id="loading" align="center" style="position:relative;top:70px"><h6>Loading ...</h6></div>
Then I put this script in the head, under the jQuery line.
<script type="text/javascript">
$(document).ready(function(){
$("#tabber").hide();
$("#loading").hide();
$("#loading").fadeIn(1000);
});
$(window).load(function(){
$("#loading").hide();
$("#tabber").fadeIn(300);
});
function checkResize(id){
var win=document.getElementById(id).contentWindow.document.body.scrollHeight;
alert(win);
}
</script>
That works fine, but a couple of the tabs have iframes for their content, and this script breaks autoResize script I use on those iframes. I'll open a new question to see if anyone has an answer to that.
Some background;
By default when you click a link to a separate HTML page JQM loads the first data-role="page" on that page and attaches it to the DOM of the first page, the thing is JQM only loads that page div and not any scripts etc. that are outside that container.
I have a jQuery mobile app with 5 pages "login.html" "menu.html" "account.html" "settings.html" ..etc
I change pages with like;
$.mobile.changepage("account.html")
Also I put all my page load logic to my first page login.html like this;
<script>
$(document).on('pageinit', '#loginpage', function() {
//do some stuff run some ajax scripts and add some html to its body
});
$(document).on('pageinit', '#accountpage', function() {
//do some stuff run some ajax scripts and add some html to its body
});
$(document).on('pageinit', '#settingspage', function() {
//do some stuff run some ajax scripts and add some html to its body
});
</script>
While this app works well, Problem is I find it very fragile and hard to survive from unexpected errors. for example;
Since how every page's body html will load is defined in login.html, this means if any moment user manually refreshs any of these pages, the page will load without running those scripts and load an empty page a without a body. In that moment since the correct DOM is deleted from memory, user is stuck in an app with full of empty pages, only way is he is smart enough to go and type "login.html" to address bar and only then all process can start smoothly.
I think we cant %100 hide address bar, it is visible again after scroll down.
SO this is one problem I come up with, some other weird things can happen and if somehow the DOM gets corrupted only way to use app again is typing login.html address bar, which users probably will not thing about it.
How can I make this app more robust like detecting any DOM corruption or refresh and forward the user to login.html, so he does not stuck in an app with empty pages.
One way to alleviate some pain is to put your page-specific scripts inside data-role="page" element in the appropriate html files and keep scripts that are the same for every page outside that element (at the and of the body and/or head).
That way even if the user refreshes the page all necessary scripts will still be executed.
One problem though, before binding any handlers you need to unbind them first. Otherwise you'll end up having multiple handlers attached.
To illustrate this:
in login.html (updated):
<div data-role="page" id="loginpage">
<script>
$(document).off('pageinit', '#loginpage').on('pageinit', '#loginpage', function() {
$(document).off('click', '#btnaccount').on('click', '#btnaccount', function(){
$.mobile.changePage("jqmaccount.html", {reloadPage: true});
});
console.log("paginit in loginpage");
});
$(document).off('pageshow', '#loginpage').on('pageshow', '#loginpage', function() {
console.log("pageshow in loginpage");
});
</script>
<div data-role="content">
<a id="btnaccount" href="#" data-role="button">Account</a>
</div>
</div>
in account.html (updated):
<div data-role="page" id="accountpage">
<script>
$(document).off('pageinit', '#accountpage').on('pageinit', '#accountpage', function() {
$(document).off('click', '#btnlogout').on('click', '#btnlogout', function(){
$.mobile.changePage("jqmlogin.html", {reloadPage: true});
});
console.log("pageinit in accountpage");
});
$(document).off('pageshow', '#accountpage').on('pageshow', '#accountpage', function() {
console.log("pageshow in accountpage");
});
</script>
<div data-role="content">
<a id="btnlogout" href="#" data-role="button">Logout</a>
</div>
</div>
In this setup if the user refreshes account.html the Logout button on that page will still work.
I have a script that will display a loading text while the content of the iframe is loaded.
The first time i open the page, it will work perfectly.
But on this page i have links that will be launched inside the iframe, and the loading text is not displayed for those links :(
See example here:
http://www.ndnm.co.cc/test.php
it will work the first time you load the page, but if you click on "TEST LINK" the loading text won't be displayed :(
Note: the iframe is loading an EXTERNAL domain
How can i fix that ?
Thanks a lot
You could try putting an on-click event on the link, so everything someone clicks it, the image "Page is loading.." will be shown, and the hided by the already--there "hideProgress()" function.
Something like:
TEST LINK<br>
Something like this: http://jsfiddle.net/SFjS2/ (remember, the second page is loaded VERY fast, so the "Page Loading" image will not be seen easily..try putting some more things there :P)
I am going to give you a jquery solution as you tagged it as such.
The solution code is located at http://jsfiddle.net/nPWAp/1/ however the HTML is
<body>
<div>
TEST LINK
</div>
<iframe id="frame"></iframe>
<div id="statement"></div>
</body>
and the jQuery is
$(document).ready(function() {
$("#testlink").click(function() {
// --- set statement --
$("#statement").show(); // show the div in case it was hidden.
$("#statement").text("Loading content..."); // replace the text
$("#statement").hide(5000); // hide after 5 seconds
// --- Scrape content --- //
$("#frame").attr('src', "http://www.test.com");
});
});
add a dash of CSS
#frame{
wdith: 100%
height: 50em;
border: 1px solid #ccc;
}
and it should all purr. Obviously you will want to check out jquery for some funkier options.
HTH
I'm designing an HTML page which has one button. The user clicks the button and a simple jQuery script animates that div away, revealing lower page content. You can see it here.
I've noticed that it looks/works fine the first time, but if I refresh the page with the browser button, it doesn't fully reset. The initial container is only half on the page. If I enter the URL again and load the page, it resets as expected.
NOTE: This only happens if you scroll down a bit after clicking the initial button... which seems weird.
I had no idea that there was any difference between these two operations, but there clearly is. What is the difference and how can I fix this problem from happening?
Here's my jQuery code, in case it's relevant:
$(document).ready(function(){
var faqs = $("#FAQ");
$("#learnmore").click(
function(){
$("#home").animate({top:'-=1066px'},600);
$("#more").animate({top:'-=1066px'}, 600, function() {$("#background").hide();} );
$("body").css('overflow-y', 'scroll');
//$("#home").slideUp();
console.log("jquery loaded");
}
);
});
It happens because it is cached by the browser.
If you styles are regularly modiefied, then as easy fix is to attach a unique id on the end of the reference, like
<link href="style.css?time=168768234928" ..../>
What it does, it makes the browser think it is a new request everytime it loads.
It happens because browser trying to scroll to the same position, what was before page reload. To check it, try press button and don't scroll to bottom of page and then reload page.
Okey, the reason is clear.
Now we need solution. Try this:
#more {display:none}
in your css. And then use
$("#more").show().animate(...
in your $("#learnmore").click() function. I hope this will solve the problem.