Non-independence of two javascript scripts - javascript

He Guys,
I have two scripts that work fine separately. One is for loading images and one is for loading Youtube iframe embeds.
However they don't seem to work together. Could you help out?
<iframe width="560" height="315" frameborder="0" data-src="https://www.youtube.com/embed/fKnbOJ4NAvS" src=""></iframe>
<a rel="nofollow" target="_blank" href="https://plus.google.com/share?url=https%3A%2F%2Fwww.domain.com"><img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="googleplus.png"></a>
<script>
function init() {
var imgDefer = document.getElementsByTagName('img');
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;
</script>
<script>
function init() {
var vidDefer = document.getElementsByTagName('iframe');
for (var i=0; i<vidDefer.length; i++) {
if(vidDefer[i].getAttribute('data-src')) {
vidDefer[i].setAttribute('src',vidDefer[i].getAttribute('data-src'));
} } }
window.onload = init;
</script>

You have made a couple of invalid assumptions.
Firstly, all scripts occupy the same global name space. Multiple <script>...</script> tags are not independent, therefore.
<script>
//script 1
</script>
<script>
//script 2
</script>
is equivalent to :
<script>
//script 1
//script 2
</script>
Secondly, repeated assignments of functions to window.onload are not cumulative. With window.onload = init followed by a second window.onload = init, the second assignment will override the first.
Now you should understand that your second script nullifies the first.
To fix, you could give the two functions unique names, and call them from a single (anonymous) window.onload handler :
<script>
function init_1() {
var imgElements = document.getElementsByTagName('img');
for (var i=0; i<imgElements.length; i++) {
if(imgElements[i].getAttribute('data-src')) {
imgElements[i].setAttribute('src', imgElements[i].getAttribute('data-src'));
}
}
}
function init_2() {
var vidElements = document.getElementsByTagName('iframe');
for (var i=0; i<vidElements.length; i++) {
if(vidElements[i].getAttribute('data-src')) {
vidElements[i].setAttribute('src', vidElements[i].getAttribute('data-src'));
}
}
}
window.onload = function() {
init_1();
init_2();
};
</script>
You could alternatively omit init_1() and init_2(), and write everything direcly inside an anonymous window.onload handler :
<script>
window.onload = function() {
var imgElements = document.getElementsByTagName('img');
var vidElements = document.getElementsByTagName('iframe');
var i;
for (i=0; i<imgElements.length; i++) {
if(imgElements[i].getAttribute('data-src')) {
imgElements[i].setAttribute('src', imgElements[i].getAttribute('data-src'));
}
}
for (i=0; i<vidElements.length; i++) {
if(vidElements[i].getAttribute('data-src')) {
vidElements[i].setAttribute('src', vidElements[i].getAttribute('data-src'));
}
}
};
</script>
It is perfectly OK to reuse the variable i in this way.
You will notice that I renamed you variables to avoid "Defer", which has a very specific meaning in JavaScript.

Related

Two Scripts are Conflicting - One that is second in order works - looking for solution

Here are the two scripts in question. Only the second will run. I can reverse them and whichever one is second will run. How can I resolve this conflict?
SCRIPT 1
<script>
function init() {
var vidDefer = document.getElementsByTagName('iframe');
for (var i=0; i<vidDefer.length; i++) {
if(vidDefer[i].getAttribute('data-src')) {
vidDefer[i].setAttribute('src',vidDefer[i].getAttribute('data-src'));
} } }
window.onload = init;
</script>
SCRIPT 2
<script>
window.onload = function() {
richSnippetReviewsWidgets({
store: "www-majorsafety-com",
primaryClr: "#f47e27",
widgetName: "floating-widget",
numReviews: 40,
floatPosition: "right",
contentMode: "company;third-party",
hideDates: false
});
};
</script>
window.addEventListener('load', function(){ ... });
Add an event listener, otherwise onload = does a complete replace of any previous set to that single property.
You can only have one function set in window.onload for the page.
To work around this, just use addEventListener.
The first script becomes:
<script>
function init() {
var vidDefer = document.getElementsByTagName('iframe');
for (var i=0; i<vidDefer.length; i++) {
if(vidDefer[i].getAttribute('data-src')) {
vidDefer[i].setAttribute('src',vidDefer[i].getAttribute('data-src'));
} } }
window.addEventListener('load', init)
</script>
The second script becomes:
<script>
window.addEventListener('load', function() {
richSnippetReviewsWidgets({
store: "www-majorsafety-com",
primaryClr: "#f47e27",
widgetName: "floating-widget",
numReviews: 40,
floatPosition: "right",
contentMode: "company;third-party",
hideDates: false
});
})
</script>

How change href value after window loading

here is a a link with text:
<a id="linkk" href="/allgemeinen/sfsdf-sd-d-d-fd/"><p class="posttt">blablabla</p></a>
I want to delete nlinked after window loadend, here is js code:
<script>
window.onload = function() {
var aEl = document.getElementById('linkk');
aEl[0].href = "javascript:void(0)";
};
</script>
here is a example: https://geburtstagsplanet.com/allgemeinen/sfsdf-sd-d-d-fd/
but it doesn't work, why?
<srcipt>
window.onload = function() {
var aEl = document.getElementsByClassName('linkk');
aEl[0].href = "javascript:void(0)";
};
</script>
or
<srcipt>
window.onload = function() {
var aEl = document.getElementsByClassName('linkk');
aEl[0].removeAttribute('href');
};
</script>
document.getElementsByClassName() returns a collection of elements. You probably need to refer to a specific element in the collection. So
aEl.href
should actually be
aEl[0].href
Firstly, your open script tag is misspelled. Should be <script> not <srcipt>
Secondly, getElementsByClassName returns an array. If you are trying to do this operation for all links, you need to iterate over the result:
<script>
window.onload = function() {
var aEl = document.getElementsByClassName('linkk');
for(var link in aEl) {
link.href = "javascript:void(0)";
}
};
</script>
Also, if you are using getElementsByClassName, you should update your HTML accordingly:
<a class="linkk" href="/allgemeinen/sfsdf-sd-d-d-fd/"><p class="posttt">blablabla</p></a>
Below code should work.
<script>
window.onload = function() {
const elem = document.getElementsByClassName('linkk');
for( let i = 0; i < elem.length; i++ ){
elem[i].href = '#';
}
}
</script>

addeventlistener not working

(function() {
var divs = document.getElementsByClassName('data');
var myFunction = function()
{
alert("hello");
var el = this;
var st = window.getComputedStyle(el, null);
var tr = st.getPropertyValue("transform") ||
st.getPropertyValue("-moz-transform") ||
st.getPropertyValue("-ms-transform") ||
st.getPropertyValue("-o-transform") ||
st.getPropertyValue("transform") ||
"Either no transform set, or browser doesn't do getComputedStyle";
console.log(tr);
}
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('mouseover', myFunction, true);
}
})();
<div class="data">data1</div>
<div class="data">data2</div>
<div class="data">data3</div>
<div class="data">data4</div>
I am using pure javascript to add event listener to the div .
The add event listener not working
Some guys said to me to add the event listener at window.load but i am getting my dom objects here in this javascript.
Any help?
There is no error in your code. you just need to put your code below the DOM.
Best place to add your script is before the end of body tag. Use external script files instead of internal of script.
For example only I am using script inside html. You should use script as external file which is best practice.
Working Code -
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
<div class="data">data1</div>
<div class="data">data2</div>
<div class="data">data3</div>
<div class="data">data4</div>
<script>
document.addEventListener("DOMContentLoaded", function() {
(function() {
var divs = document.getElementsByClassName('data');
var myFunction = function()
{
alert("hello");
var el = this;
var st = window.getComputedStyle(el, null);
var tr = st.getPropertyValue("transform") ||
st.getPropertyValue("-moz-transform") ||
st.getPropertyValue("-ms-transform") ||
st.getPropertyValue("-o-transform") ||
st.getPropertyValue("transform") ||
"Either no transform set, or browser doesn't do getComputedStyle";
console.log(tr);
};
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('mouseover', myFunction, true);
}
})();
});
</script>
</body>
</html>
DOMContentLoaded event will execute your code after DOM is loaded and parsed. so it will not give error.
Your code works. You must run your script after DOM is loaded, or you must write
DOMContentLoaded eventListener:
document.addEventListener("DOMContentLoaded", function(event) {
(function() {
var divs = document.getElementsByClassName('data');
var myFunction = function()
{
//.... Your code
}
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('mouseover', myFunction, true);
}
})();
});

How to collect all script tags of HTML page in a variable

I would like to collect all the <script> ....</script> code section present in the HTML page in some variable.
What should be the simpler way to do this, Any idea how it can be retrieved using JavaScript.??
Any help will be greatly appreciated.
To get a list of scripts you can use
document.getElementsByTagName("script"); by tag
document.scripts; Built-in collection
document.querySelectorAll("script"); by selector
$("script") jQuery by selector
var scripts = document.getElementsByTagName("script");
for (var i = 0; i < scripts.length; i++) {
if (scripts[i].src) console.log(i, scripts[i].src)
else console.log(i, scripts[i].innerHTML)
}
// To get the content of the external script
// - I use jQuery here - only works if CORS is allowing it
// find the first script from google
var url = $("script[src*='googleapis']")[0].src;
$.get(url,function(data) { // get the source
console.log(data.split("|")[0]); // show version info
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
console.log("Inline script");
</script>
<script>
function bla() {
console.log("Other inline script");
}
</script>
The simplest way is probably document.scripts
You would do:
var scripts = document.getElementsByTagName( 'script' );
Now scripts is a NodeList (like an array), and you can access each one using scripts[0], scripts[1] and so on.
try this
var scripts = document.getElementsByTagName("script");
Without jQuery :
var scripts = document.getElementsByTagName("script");
With jQuery :
var scripts = $("script");
Here you go --
(function () {
'use strict';
let logscript = function () {
let js = document.scripts;
for (let i = 0; i < js.length; i++) {
if (js[i].src) {
console.log(i, js[i].src);
} else {
console.log(i, js[i].innerHTML);
}
}
};
if (document.readyState === 'complete') {
logscript();
} else {
window.addEventListener('load', logscript);
}
})();

Internet Explorer throwing error on getElementById

I'm having trouble with some javascript which uses getElementById. It works fine in FF, Safari and Chrome, but IE(8 - haven't tried others) bails out.
The relevant bit of html is a div called topnav:
<div id="topnav">
... some HTML ...
<div>
<div id="sub_1" class="lowernav">
... some HTML ...
</div>
<div id="sub_2" class="lowernav">
... some HTML ...
</div>
In my javascript, I want to find topnav. The full code (up to where it bails) is this:
<script>
window.onload = init();
function init() {
// Show current menu
showCurrentMenu();
}
function showCurrentMenu() {
hideMenus(); // Hide all menus and then show the current one
topnav = document.getElementById('topnav');
... rest of code ...
}
function hideMenus() {
var divlist = document.getElementsByTagName('div');
for(var ii=0; ii<divlist.length; ii++) {
if(divlist[ii].className != divlist[ii].className.replace('lowernav','')) {
divlist[ii].className += ' hidden';
}
}
}
... then some other code it hasn't reached yet...
Am I doing something wrong here? It may well be something really obvious, but for the life of me, I can't see it! All advice is much appreciated.
ETA: Ok, here's the whole code, as it currently stands:
<script>
window.onload = init;
function init() {
// Show current menu
showCurrentMenu;
// Attach 'onmouseover' event to main menu items
topnav = document.getElementById('topnav');
// Get all items in list
var menulist = topnav.getElementsByTagName('a');
for(var ii=0; ii<menulist.length; ii++) {
menulist[ii].onmouseover = showMenu;
}
document.getElementById('mainHomeNav').onmouseout = restoreMenu;
}
function restoreMenu(e) {
var targ;
if (!e) var e = window.event;
if (e.target) targ = e.target;
else if (e.srcElement) targ = e.srcElement;
if (targ.nodeType == 3) // defeat Safari bug
targ = targ.parentNode;
if (targ.id == "mainHomeNav") {
showCurrentMenu;
}
}
function hideMenus() {
var divlist = document.getElementsByTagName('div');
for(var ii=0; ii<divlist.length; ii++) {
if(divlist[ii].className != divlist[ii].className.replace('lowernav','')) {
divlist[ii].className += ' hidden';
}
}
}
function showCurrentMenu() {
hideMenus;
topnav = document.getElementById('topnav');
// Get all items in list
var menulist = topnav.getElementsByTagName('a');
for(var ii=0; ii<menulist.length; ii++) {
if(menulist[ii].className != menulist[ii].className.replace('thisSection','')) {
var thisid = menulist[ii].id;
var thissubmenu = document.getElementById(thisid + '_sub');
thissubmenu.className = thissubmenu.className.replace(/hidden/g,'');
}
}
}
function showMenu() {
hideMenus;
// show this menu
var submenu_id = this.id + '_sub';
var submenu = document.getElementById(submenu_id);
submenu.className = submenu.className.replace(/hidden/g,'');
}
</script>
The problem is
window.onload = init();
This will call the init function immediately, and then use its return value as the page's onload function. You need:
window.onload = init;
which will call the init function only after the page has fully loaded.
I found the problem - I didn't have 'var' in front of 'topmenu'.
So instead of
topnav = document.getElementById('topnav');
it should have been
var topnav = document.getElementById('topnav');
Thanks everyone for the help.
Your problem lies in the following line:
window.onload = init(); // this will CALL init() and assign the return value
Since init doesn't return anything, window.onload will be undefined.
Now the reason for it not working in IE, but in other Browsers is that those other Browsers might already have parsed a part of the DOM and therefore the call to showCurrentMenu works.
But that could just as well break, since from a technical point of view the document is not guaranteed to be loaded, to fix that you have to assign the actual function reference to window.onload by doing:
window.onload = init;

Categories