I've been working on speeding up my page loading speed. I have these two defers script to minimize loading time and improve performance.
The problem is only the last function will work. ex. if 'imgDefer' is in the last, only image will load on the front page. The same as 'vidDefer' if in last, only video will load and the image will not
I don't know how to combine these two init(). I'm not good at javascript.
These are the codes: (I place these codes in footer area)
video
<iframe src="" frameborder="0" allowfullscreen="allowfullscreen" data-src="https://www.youtube.com/embed/xxxxxx"></iframe>
image
<img class="img-responsive" src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="imagesrource" alt="">
Video script
function init() {
var vidDefer = document.getElementsByTagName("iframe");
for (var s = 0; s < vidDefer.length; s++) {
if(vidDefer[s].getAttribute('data-src')) {
vidDefer[s].setAttribute('src',vidDefer[s].getAttribute('data-src'));
}
}
}
window.onload = init;
Image Script
function init() {
var imgDefer = document.getElementsByClassName("img-responsive");
for (var i = 0; i < imgDefer.length; i++) {
if (imgDefer[i].getAttribute('data-src')) {
imgDefer[i].setAttribute('src',imgDefer[i].getAttribute('data-src'));
}
}
}
window.onload = init;
So basically what it sounds like is that you'd like to be able to run multiple functions when the window.onload event gets triggered.
You could create two separate functions, like so:
function runVideoScript() {
var vidDefer = document.getElementsByTagName('iframe')
// ...
}
function runImageScript() {
var imgDefer = document.getElementsByClassName('img-responsive')
// ...
}
Then you can create an init function. This way, both functions will be called from the init function, and init will be called when window.onload gets triggered:
function init() {
runVideoScript()
runImageScript()
}
window.onload = init
In your current setup, the reason why only the last function gets called is because you're replacing window.onload with another function, and basically disregarding the first function.
Just make one init function which will be for example initVideo function and after it's executed run initImage.
function initVideo() {
var vidDefer = document.getElementsByTagName("iframe");
for (var s = 0; s < vidDefer.length; s++) {
if(vidDefer[s].getAttribute('data-src')) {
vidDefer[s].setAttribute('src',vidDefer[s].getAttribute('data-src'));
}
}
initImage();
}
function initImage() {
var imgDefer = document.getElementsByClassName("img-responsive");
for (var i = 0; i < imgDefer.length; i++) {
if (imgDefer[i].getAttribute('data-src')) {
imgDefer[i].setAttribute('src',imgDefer[i].getAttribute('data-src'));
}
}
}
window.onload = initVideo();
Related
I want to create a JavaScript program who allow the user to switch between
image by using previous and next button. But i can't use window.onload to load the next image cause window.onload overwrite the previous window.onload. I want to know if their exist any solution to make window.onload work with two functions in the same time. If window.onload can't be usable for this kind of program you can suggest me another solution.
Thank you.
var i =0;
var image = [];
image[0]= 'image.jpg';
image[1]= 'image2.jpg';
image[2]= 'panther.jpg'
function next(){
document.slide.src = image[i];
if(i<image.length-1){
i++;
}
else{
i=0;
}
document.getElementById('bouton1').addEventListener('click',next);
}
function previous(){
document.slide.src = image[i];
if(i>0){
i--;
}
else{
i=image.length-1;
}
document.getElementById('bouton2').addEventListener('click',previous);
}
window.onload = next;
window.onload = previous;
Needed a couple of changes, can you test it like this. Note we changed the onload to attach listeners. See comment.
var i =0;
var image = [];
image[0]= 'image.jpg';
image[1]= 'image2.jpg';
image[2]= 'panther.jpg'
function next(){
document.slide.src = image[i];
if(i<image.length-1){
i++;
}
else{
i=0;
}
}
function previous(){
document.slide.src = image[i];
if(i>0){
i--;
}
else{
i=image.length-1;
}
}
// This is window.onload
(function(){
// Move calls to attach event listeners here
document.getElementById('bouton2').addEventListener('click',previous);
document.getElementById('bouton1').addEventListener('click',next);
})();
addEventListener is a better method for adding an event handler without replacing an existing one.
window.addEventListener('load', e => { /* ... */ });
As a rule of thumb, any on(blah) attributes in the DOM can be replaced with addEventListener(blah, ...).
I'm not exactly sure about your idea behind window.onload, if you want to preload images (so the user does not have to wait for the image to load on buttons click...) than you could use new Image() and something like:
const EL_slide = document.getElementById("slide");
const EL_prev = document.getElementById('prev');
const EL_next = document.getElementById('next');
const image = [
'//placehold.it/800x600/0bf?text=1',
'//placehold.it/800x600/f0b?text=2',
'//placehold.it/800x600/0fb?text=3'
];
const n = image.length;
let i = 0;
// Preload images
image.forEach(src => {
var img = new Image();
img.src = src;
});
// Animation logic
function anim() {
if((/prev|next/).test(this.id)) i = this.id === "next" ? ++i : --i;
i = i<0 ? n-1 : i%n; // Index fixer (prevents out of bound index)
EL_slide.style.backgroundImage = `url('${image[i]}')`
}
// Events
[EL_prev, EL_next].forEach(EL => EL.addEventListener('click', anim));
// Load first!
anim();
#slide {
height: 70vh;
transition: 0.3s;
background: none 50% 50% / cover no-repeat;
}
<button id="prev">←</button>
<button id="next">→</button>
<div id="slide"></div>
and just make sure to place your Javascript right before the closing </body> tag.
window.onload = init;
function init(){
var allSelect = document.getElementsByTagName("option");
for (var i = 0; i < allSelect.length; i++){
allSelect[i].onchange = loadLink;
}
}
function loadLink(){
alert("TEST");
}
So I'm working on this problem for a class and the functions are incredibly simple. I replaced the code needed with a simple alert because even tracking break point by point it doesn't run the loadLink() function. AllSelect is populated and are all have the onchange value with the specified code in the {}.
I have also tried putting it into the html element by hand and it still doesn't work.
Any Ideas? I'm running locally on my computer with both IE and Chrome if anyone cares to know. Thanks ahead of time.
The onchange event belongs on the select element, not the option elements. So:
window.onload = init;
function init(){
var allSelect = document.getElementsByTagName("select");
for (var i = 0; i < allSelect.length; i++){
allSelect[i].onchange = loadLink;
}
}
function loadLink(){
alert("TEST");
}
I think you want
var allSelect = document.getElementsByTagName("select");
You are instead querying the option elements within selects in the DOM.
I have two JS functions: a load() function that displays a progress bar and a kill () function that stops the execution of the load once the page is loaded.
Now when another page is loaded the progress bar is not displayed, knowing that the load function is called on every page.
Any hints on where the problem might be and if there is a way to fix it.
Here is my code:
<script type="text/javascript">
var count=0;
function load(i) {
j = parseInt(i);
document.getElementById("progressBar").style.display = "block";
count=count+1;
if (document.all) {
document.all.btn1.value=count+'%';
document.all.progressbar.pic1.width=2*count;
}
else {
document.getElementById("pic1").width=2*count;
document.getElementById("bar").width=count+'%';
}
if (count<100) {
setTimeout('load(j)',j);
}
if(count==100) {
document.getElementById("progressBar").style.display = "none";
count=0;
}
}
function kill(){
if (document.applets[0].isActive()) {
document.getElementById("progressBar").style.visibility = "hidden";
}
}
</script>
Thank you in advance !
In load() you're changing display to block, but in kill() you set visibility to hidden; you should set display to none instead, so it can properly be set to block again next time. Read about visibility.
Optimized code:
<script type="text/javascript">
var count = 0,
win = window,
doc = document,
progressBar = doc.getElementById("progressBar"),
t, j;
function load(i) {
j = parseInt(i);
progressBar.style.display = "block";
count++;
// no actual need to check if doc.all is available
// just select through id
doc.getElementById("pic1").style.width = 2*count;
doc.getElementById("bar").style.width = count+'%';
if (count < 100) {
t = win.setTimeout('load(j)',j);
} else {
progressBar.style.display = "none";
win.clearTimeout(t);
count = 0;
}
}
function kill(){
if (doc.applets[0].isActive()) {
progressBar.style.display = "none";
}
}
</script>
If you assign setTimeout to a variable, you can use clearTimeout on it to stop it.
E.g.
set the timeout with
t = setTimeout('load(j)',j);
then stop it with
clearTimeout(t); Let me know if that helps, and makes sense :)
So I have this eventListner that calls an Class, works like a charm but only once since inte call the add class with index 0.
Im trying to create a loop that will call every add class inside the script, but i cant get loop...
This is the event listner without the loop
var AddEvent = "add";
var addClass = document.getElementsByClassName(AddEvent)[0]
addClass.addEventListener("click", addDiceEvent, false);
function addDiceEvent() {
dicesides_funcfunc();
}
And this is what Im trying to create.
function AddDice(){
for (i = 0; i < 5; i++) {
var addClass = document.getElementsByClassName("add");
addClass.addEventListener("click", addDiceEvent, false);
function addDiceEvent(){
dicesides_funcfunc();
}
}
} AddDice();
Any ideas ?
Hope this work.......
var addClassArr= document.getElementsByClassName(AddEvent);
for (var x in addClassArr)
{
var addClass = addClassArr[x];
addClass.addEventListener("click", addDiceEvent, false);
}
function addDiceEvent() {
dicesides_funcfunc();
}
You need to create new skope in for loop, try this:
function AddDice(){
for (i = 0; i < 5; i++) {
(function(){
var addClass = document.getElementsByClassName("add");
addClass.addEventListener("click", function(){
dicesides_funcfunc();
}, false);
})();
}
}
I'd like to keep all my JavaScripts in a separate document and I like it that way. Now I've had problems with the last bit of code to move from my HTML-code into my separate JavaScript document.
I got two eventhandlers that looked like this:
<a href="http://www.commercial.se" onclick="confirmLeave()" target="_blank">
and
<IMG SRC="folder/pic_small.jpg" alt="Description" onClick="view(this);">
This is the javascript code for the two eventhandlers:
function confirmLeave()
{
if(confirm("Vill du lämna Blomstermåla-Bladet?")) {
return true;
} else {
if(window.event) {
window.event.returnValue = false;
} else {
e.preventDefault();
}
return false;
}
}
And
function view(img) {
imgsrc = img.src.split("_")[0] + "_big.jpg";
viewwin = window.open(imgsrc,'viewwin', "width=790,height=444,location=0");
viewwin.focus();
}
I've managed to solve my problem of not having the javascript code in my HTML document for the first onClick eventhandler by changing my HTML to this:
<a href="http://www.commercial.com" id="external-link" target="_blank">
And adding this to my javascript document:
function init()
{
var link = document.getElementById("external-link");
link.onclick = confirmLeave;
}
window.onload = init;
I've tried adding a similar solution to the other eventhandler but I can't figure out the code I need to use for it to work. I would like to know how to add that event handler into the init function as well.
Try this
<a href="http://www.commercial.com" class="external-link" target="_blank">
<IMG SRC="folder/pic_small.jpg" alt="Description" id = "external-image">
function init() {
var link = document.getElementById("external-link");
var links = document.getElementsByClassName("external-link");
for (var i = 0; i < links.length; i++) {
links[i].onclick = confirmLeave;
}
var image = document.getElementById("external-image");
image.onclick = view;
}
window.onload = init;
Instead of img in your function just use this
function view() {
imgsrc = this.src.split("_")[0] + "_big.jpg";
viewwin = window.open(imgsrc,'viewwin', "width=790,height=444,location=0");
viewwin.focus();
}
If you don't want to change the view function, you can do something similar, with the slight difference that you need to pass the image as an argument to the view function. You can do this by setting an anonymous function as the click handler.
<IMG SRC="folder/pic_small.jpg" alt="Description" id="some-img">
function init()
{
var img = document.getElementById("some-img");
img.onclick = function(){
view(this);
};
}