My webpage need to show about 40 images. For the amount to image to be downloaded from server, it cause 429 error randomly.
I want to guarantee my websites to show all the images for advertisement.
how can I avoid 429 too many requests error? Is there any work around?
I use lazy loading to solve this problem.
image won't be requested to server if user not scroll down to image tag itself.
First I set data-srcto which I want to apply lazy loading.
<img data-src="../img2.png" class="lazy"/>
<img data-src="../img2.png" class="lazy"/>
<img data-src="../img2.png" class="lazy"/>
inject script after body tags.
here I wrote js script
document.addEventListener("DOMContentLoaded", function () {
const lazyLoadImages = document.querySelectorAll(".lazy");
let lazyLoadThrottleTimeout;
function lazyLoading() {
if (lazyLoadThrottleTimeout) {
clearTimeout(lazyLoadThrottleTimeout);
}
lazyLoadThrottleTimeout = setTimeout(function () {
const scrollTop = window.pageYOffset;
lazyLoadImages.forEach(function (image) {
if (image.offsetTop < window.innerHeight + scrollTop) {
image.src = image.dataset.src;
image.classList.remove("w_lazy");
}
});
if (lazyLoadImages.length) {
document.removeEventListener("scroll", lazyLoading);
window.removeEventListener("resize", lazyLoading);
window.removeEventListener("orientationchange", lazyLoading);
}
}, 35);
}
document.addEventListener("scroll", lazyLoading);
window.addEventListener("resize", lazyLoading);
window.addEventListener("orientationchange", lazyLoading);
});
the main idea is eventListener "scroll" and "resize" wait until user scrolling down to image tag, put src image path using data-src
you can use IntersectionObserver rather than eventListener, then you will need polyfill for IE user.
Related
I tried global event listeners pane in Chrome DevTools, I tried to put a debugger; inside document/window.addEventListener("unload", ...) and it is not working.
I tried to step over the statements in the file main.ts and nothing is breaking the code in there when I click on a link that should open another page than the one it is opening. I checked its HTML attributes and the correct URL is set in its href attribute. The link has a single class which is not used to open another page in the page's code as far as I know.
I also searched for all the places in my code where the (window.)location is changed.
I also updated npm packages using npm update.
I use KnockOut.js and I have this static HTML for the links that go to wrong pages:
<ul class="main-nav" data-bind="foreach: mainMenuItems">
<li>
<a data-bind="attr: { href: url, title: text }, text: text, css: { active: $data == $root.activeMenuItem() }"></a>
<div class="bg"></div>
</li>
</ul>
And this is a part of the TypeScript code (sorry for the ugly code, it is WIP):
let vm = new PageViewModel(null, "home", () => {
sammyApp = $.sammy(function () {
// big article URLs w/ date and slug
this.get(/\/(.+)\/(.+)\/(.+)\/(.+)\/(.*)[\/]?/, function() {
vm.language("ro");
vm.isShowingPage(false);
vm.isShowingHomePage(false);
let slug : string = this.params['splat'][3];
vm.slug(slug);
console.log('logging', { language: vm.language(), slug: vm.slug() });
vm.fetch();
vm.isShowingContactPage(false);
vm.activeMenuItem(vm.getMenuItemBySlug(slug));
});
// any other page
this.get(/\/ro\/(.+)\//, function () {
console.log('pseudo-navigating to /ro/etc.');
vm.language("ro");
vm.isShowingPage(true);
vm.isShowingHomePage(false);
let slug : string = this.params["splat"][0];
//slug = slug.substr(0, slug.length - 1);
if (slug !== 'contact') { // this page is in the default HTML, just hidden
vm.slug(slug);
vm.fetch();
vm.isShowingContactPage(false);
} else {
vm.isShowingContactPage(true);
window.scrollTo(0, 0);
}
vm.activeMenuItem(vm.getMenuItemBySlug(slug));
});
this.get(/\/en\/(.+)\//, function () {
console.log('pseudo-navigating to /en/etc.');
vm.language("en");
vm.isShowingPage(true);
vm.isShowingHomePage(false);
let slug : string = this.params["splat"][0];
//slug = slug.substr(0, slug.length - 1);
if (slug !== 'contact') { // this page is in the default HTML, just hidden
vm.slug(slug);
vm.fetch();
vm.isShowingContactPage(false);
} else {
vm.isShowingContactPage(true);
, () => {
uuuuucons
}9 function
window.scrollTo(0, 0);
}
vm.activeMenuItem(vm.getMenuItemBySlug(slug));
});
// the home page
this.get("/", function () {
console.log(`pseudo-navigating to /${vm.language()}/home`);
sammyApp.setLocation(`/${vm.language()}/home`);
});
});
sammyApp.run();
});
I have this code that catches the click event:
$("a").on("click", () => {
debugger;
});
But after this finding I do not know what I can do to find the source of the problem.
When the click is catched by the 3 LOCs above, I get this:
What could be the issue?
Thank you.
Update 1
After seeing these questions and their answers (the only thing I did not try was using an iframe):
How can I find the place in my code or page where the location is set?
Breakpoint right before page refresh?
Break javascript before an inline javascript redirect in Chrome
If I have a page for which I check the beforeunload and unload event checkboxes in the Event Listener Breakpoints pane in Chrome DevTools' tab Sources, and I click on a link which should not reload the page but it does, and the two breakpoints (beforeunload and unload) are not triggered in this process, what should I do next?
Is this a known bug? If so, can someone give me an URL?
Thank you.
I've checked out the other threads about this, but couldn't really find what I'm after.
I've embedded a YouTube video in iFrame form. It's set to autoloop. Here's the parameters:
?showinfo=0&rel=0&autoplay=1&loop=1&controls=0&playlist=SeFzUzde5BM
The problem is that before the video starts, there's a black screen with a loading bar. That in itself isn't too bad, but then when the video goes to loop, it does that again! Why does it need to load itself twice? Is there anyway to have it seamlessly loop, without the loading screen breaking up each loop?
Your question seems to be answered here:
YouTube embedded video auto loop without refresh screen
However if that link becomes un-available the answer is using a Youtube Embed Api code. called player.getPlayerState() .You basically check that the video has "ended" and then run the .playVideo(); function. which starts it again immediately.
Youtube API : focused on Playback Status
I added this 'if' statement to the code provided at the top of the Youtube API page.
if (event.data === YT.PlayerState.ENDED) {
player.playVideo();
}
NOTE: As you can see you have to set it up as a separate script first instead of running it in-line in the html (it's easier to keep track of too). I suggest looking at the YouTube API linked above for extra help.
Jimmy's solution looks good. I ended up using an HTML video player, but if anyone is curious, this is the solution that was working for me when I was using the iframe.
I had to know the time of the video (15s) and set it to loop .1s before that (14.9s). Otherwise, there'd be a little "blip" effect. I used an interval to constantly check the time. If there's a way to dynamically hook into the 0.1s spot before video end, I'd recommend that, but I couldn't find that. I also use a little fade effect so the transition is smoother.
<div id="player"></div>
<script>
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: YOUR_ID_HERE,
playerVars: {
controls: 0,
showinfo:0,
rel:0,
},
events: {
'onReady': onPlayerReady,
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
var interval_is_stopped = false;
setInterval(function (){
var current_time = event.target.getCurrentTime();
if (current_time > 14.9 && !interval_is_stopped) {
interval_is_stopped = true;
jQuery('#player').fadeTo(400, 0.7, function(){
player.seekTo(0);
jQuery(this).fadeTo(400, 1, function(){
interval_is_stopped = false;
});
});
}
}, 10);
}
</script>
I have an iFrame in my jsp page where in page load it should have height and width as 600 and 400 respectively. This iFrame contains some page having some forms in it, once the form is filled and submitted, it will redirected to a thank you page. At that time I need the height of the iFrame as 200(because the page contents are less and I need to reduce the white space in it). how to achieve this? I get n number of links in stack exchange itself but nothing is useful in this case.
Is there any way to check if the iFrame src url is changed? If so I can make a condition and do the below code to reduce the height.
<script type="text/javascript">
function iframeLoaded() {
var iFrameID = document.getElementById('idIframe');
if(iFrameID) {
iFrameID.height = "200";
iFrameID.width = "400";
iFrameID.height = iFrameID.contentWindow.document.body.scrollHeight + "px";
iFrameID.width = iFrameID.contentWindow.document.body.scrollHeight + "px";
}
}
</script>
The above function is working fine if i give it in iFrame page load but I need to set this only when I get the thank you page inside iFrame.
Request to kindly help on this.
you can use something like cookie.js (https://github.com/js-cookie/js-cookie) for creating a helper cookie for each step in your iframe.
(function($) {
$( '#submit-button').on( "click", function() {
Cookies.set('isSubmitted', true);
});
})(jQuery);
Now you can check if the cookie is set and resize the iframe
(function($) {
if(Cookies.get('isSubmitted') === true) {
$('#iFrameID').height(200);
}
})(jQuery);
After this you can delete this cookie
Cookies.remove('isSubmitted');
You can do iFrame url change check in the parent page like this:
function check(){
$('#idIframe').load(function() {
console.log("the iframe has changed");
});
};
$("#idIframe").on("mouseenter",function(){
window.setInterval(check, 100); // 100 ms
});
Here is the code I am using on my page,
<li>Sound</li>
(in a menu which appears on all pages)
<a id="Sound"><a>
(on the page where i want to link to)
I have tried adding content to the tags with an id. But only in chrome the browser will not scroll down to the tag. These anchors work in IE&FF
Any ideas?
Turns out this was a bug in certain versions of chrome, posting workaround for anyone who needs it! :)
$(document).ready(function () {
var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
if (window.location.hash && isChrome) {
setTimeout(function () {
var hash = window.location.hash;
window.location.hash = "";
window.location.hash = hash;
}, 300);
}
});
The workaround posted didn't work for me, however after days of searching this finally worked like a charm so I figured it was worth sharing:
$(function() {
$('a[href*="#"]:not([href="#"])').click(function() {
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
$('html, body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}
}
});
});
If you somehow ended up here like me when finding out the anchor link to a SPA site doesn't work from an external site. Yep, the browser is just working too fast to load the skeleton of the page. And it couldn't find your anchor when it loads the page.
To work around this, just add in the lifecycle of your SPA (useEffect in React and mounted in Vue) some lines to check the url hash and do the scrolling yourself.
example using React
useEffect(()=> {
if(document.location.hash === '#some-anchor') {
setTimeout(()=> {
document
.querySelector("#some-anchor")
.scrollIntoView({ behavior: "smooth", block: "start" })
}, 300)
}
}, [])
I was having this problem as well (same page navigation using links) and the solution was very easy (though frustrating to figure out). I hope this helps - also I checked IE, Firefox, and Chrome and it worked across the board (as of 05-22-2019).
Your link should looks like this:
Word as link you want people to click
and your anchor should look like this:
<a name="#anchorname">Spot you want to appear at top of page once link is clicked</a>
Try using :
For menu page
<li>Sound</li>
in a menu which appears on all pages
<a id="#Sound"><a>
This works well in the all versions of Chrome!
I have tested it on my browser.
This answer is for someone who encountered same problem, but scripts didn't work. Try to remove loading='lazy' and decoding='async' from all images on the page or set width and height attributes to them.
It worked like a charm for me.
Here is my version of #Jake_ answer for Chrome / angular not scrolling to a correct anchor on initial page load up using ui-router (the original answer would throw my code into 'Transition superseeded' exceptions):
angular.module('myapp').run(function($transitions, $state, $document, $timeout) {
var finishHook = $transitions.onSuccess({}, function() { // Wait for the complete routing path to settle
$document.ready(function() { // On DOM ready - check whether we have an anchor and Chrome
var hash;
var params;
var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
finishHook(); // Deregister the hook; the problem happens only on initial load
if ('#' in $state.params && isChrome) {
hash = $state.params['#']; // Save the anchor
params = _.omit($state.params, ['id', '#']);
$timeout(function() {
// Transition to the no-anchor state
$state.go('.', params, { reload: false, notify: false, location: 'replace' });
$timeout(function() {
// Transition back to anchor again
$state.go('.', _.assign($state.params, { '#': hash }), { reload: false, notify: false, location: 'replace' });
}, 0);
}, 0);
}
});
}, {invokeLimit: 1});
});
Not sure if this helps at all or not, but I realized my anchors in IE were working but not in Firefox or Chrome. I ended up adding ## to my anchors and this solved the issue.
example:
a href="##policy">Purpose and Policy Statement
instead of :
a href="#policy">Purpose and Policy Statement
<html>
<body>
<li>
Sound
</li>
<a id="Sound" href="www.google.com">I AM CALLED</a>
</body>
</html>
use this as your code it will call the anchor tag with id value sound
Simply change the call on your link to external.
I know that onload event waits for page resources to load before firing - images, stylesheets, etc.
But does this include IFrames inside the page? In other words, is it guaranteed that all the child Frames' onloads will always fire before the parent's does?
Also, please let me know if behavior varies between browsers.
No, it doesn't. If you want to do something like that, you'll need to add an onload handler for the iframe. You can do this nicely with jQuery:
<iframe src="http://digg.com"></iframe>
<script>
var count = $('iframe').length;
$(function() {
// alert('loaded'); // will show you when the regular body loads
$('iframe').load(function() {
count--;
if (count == 0)
alert('all frames loaded');
});
});
</script>
This would alert when all the frames are loaded.
See the example:
http://jsbin.com/azilo
Or plain javascript should work..
function checkIframes() {
if(!i) { i = 0; }
if(document.getElementsByTagName('iframe')[i]) {
document.getElementsByTagName('iframe')[i].onload = function () { i++; checkIframes(); }
}
else { yourFunctionInHere(); }
}
haven't really tested this, but should work... than refer to it with document.onload = function() { checkIframes(); }
I don't really like libraries like jQuery, because so far I found I can achieve more with less code, with regular javascript.
As I see on my pages, each iframe got independent onload, and top-frame onload doesn't wait for iframes to fire.
I got gif/png banners on my site that sometimes loads very slowly, so I put them into iframe and that made whole site and onload event to work faster.