How to add 2 myFunctions? - javascript

I have added a myFunction code to my site. No problem, it works. Then I tried to add a second myFunction. The problem is, if I ad a second myFunction it doesn't work. It will only run succesfully when I use 1 myFunction. I tried everything to do, changed the name (myFunction2), people said me to do that but it doesn't work.
My question is now: How to add 2 myFunctions?
Script 1:
var myVar;
function myFunction(loader) {
myVar = setTimeout(showPage, 3000);
}
function showPage(loader) {
document.getElementById("loader").style.display = "none";
document.getElementById("myDiv").style.display = "block";
}
Script 2:
window.onscroll = function(scroller) {myFunction(scroller)};
function myFunction(scroller) {
if (document.body.scrollTop > 550 || document.documentElement.scrollTop > 550) {
document.getElementById("content").className = "slideUp";
}
}

You can't have more than one function with the same name. Try changing the second script to myScrollerFunction and when you call it, change it to myScrollerFunction as well.
No two functions can share the same name.

function UniqueFunctionName(parameters){
//put code here
}
UniqueFunctionName(startparameters); //not necessary
That is how to make a function.
function AnotherFunctionName(parameters){
//put code here
}
AnotherFunctionName(startparameters); //not necessary
That is how to make another function.
In your case this should be:
function myFunction1(){
//code in here
}
function myFunction2(){
//code in here
}
myFunction1(); // or not
myFunction2(); // or not
If it is like that the the specific code in the function needs to be debugged.
From what you have said i think that you just need to debug the code.
http://five.agency/javascript-debugging-for-dummies/
Learn to find and remove mistakes in your code and all will be easier.
If the code is flawless then the only other possibility is that it is not called.
To test for that insert this code like so:
function myFunction2(){
console.log('The function loads!');
//put code here
console.log('The function works!');
}
Save the code and open the webpage.
Open a debugger and search for the console.
If you see both messages then the code does not work the way it is expected.
If you see the first message and an error message then the code NEEDS debugging.
If you see neither messages then the code does not even load and you need to debug the input mechanisms/setInterval/setTimeout and/or parameters depending on the error message. If you have no input mechanisms/setInterval/setTimeout then add one or call the function directly from the code like shown in most of my code blocks above otherwise the code will never EVER load.
EDIT: parameter scroller is not defined. change 'function(scroller) {myFunction(scroller)};' to 'function(){myFunction2()};' and 'function myFunction(scroller) {' to 'function myFunction2(){'

Related

Business catalyst prototype-core.ashx Refused to set unsafe header "Connection" conflicts

I currently use Adobe Business Catalyst on an ecommerce site and it run into the same problem:
When clicking add to cart the log shows:
prototype-core.ashx Refused to set unsafe header "Connection"
all custom javascript I have and jQuery breaks and does not ready some functions.
I tried using methos such as jQuery noConflicts();
var j = jQuery.noConflict();
Still nothing works well, I cant provide a sample code because everything is working from the server and I use another method to have a work around it for the time being.
Any suggestions please advise.
If you have a look into the prototype-core.ashx you will find this
if(!MS.Browser.isIE) {
this.xmlHttp.setRequestHeader("Connection", "close") // Mozilla Bug #246651
}
This is not an issue, it is just a line of code your browser does not understand, if you use Mozilla you will not see this error in your console, but you will see a bunch of different warnings.
There is quite a lot on Stackoverflow about the issue that JavaScript doesn't work after an Ajax call.
What you can do to fix it is call all your functions again after the add to cart button has been pressed.
So first I have my JavaScript functions FirstFunction(); SecondFunction(); ThirdFunction(); and then I call them like this
function FirstFunction() {
//do whatever you want to do
}
function SecondFunction() {
//do whatever you want to do
}
function ThirdFunction() {
//do whatever you want to do
}
$(document).ready(function () {
// do it once onload
FirstFunction();
SecondFunction();
ThirdFunction();
$('.main_content').on('click',function() {
// do it again onclick
FirstFunction();
SecondFunction();
ThirdFunction();
});
});
This way all your functions are loaded again when you click on inside .main_content.

assertExists with if-else statement

I use this code:
var x = require('casper').selectXPath;
...
casper.waitForSelector(x("//a[contains(#id,'cell_13_1')]"), function() {
this.test.assertExists(x("//a[contains(#id,'cell_13_1')]"), 'Clickable');
this.click(x("//a[contains(#id,'cell_13_1')]"));
});
I am trying to use if-else with assertExists to click another element if the first is not there:
casper.waitForSelector(x("//a[contains(#id,'cell_13_1')]"), function() {
if(this.test.assertExists(x("//a[contains(#id,'cell_13_1')]")==="PASS"){
this.click(x("//a[contains(#id,'cell_11_1')]"));}
else{
this.click(x("//a[contains(#id,'cell_22_1')]"));
}
});
But that does not seem to work. How would one do it correctly?
That's exactly what casper.exists() is for. You can also explicitly pass or fail some things:
casper.waitForSelector(x("//a[contains(#id,'cell_13_1')]"), function() {
if(this.exists(x("//a[contains(#id,'cell_13_1')]")){
this.test.pass("Clickable");
this.click(x("//a[contains(#id,'cell_11_1')]"));
} else {
this.test.fail("Clickable");
//this.click(x("//a[contains(#id,'cell_22_1')]"));
}
});
This code is equivalent to your first snippet. Comment the fail() call and uncomment the last click in order to get your "intended" behavior.
Btw, it doesn't make sense to fail some assertion and still continue with the script. You have to think about what exactly you want to test and what part of your script is supposed to be navigation to the component under test.

Ajax .load() won't work when triggered initially

So I have a simple tab system which I handle with the .load function to load the desired content. The problem is that the page itself which contains this tab system is a ajax loaded content. And for some reason the initial call of the tab function to display the initial tab content won't work. But after manually choosing a tab, the load function loads the content properly.
her some code to look at:
The tab handler:
function loadTab(tab) {
$(".tab_a:eq("+otab+")").removeClass("tab_slc");
$('#tab_content').hide();
$('#tab_content').load("include/tab_downloadVersions.html .tab:eq("+tab+")");
$(".tab_a:eq("+tab+")").addClass("tab_slc");
$('#tab_content').fadeIn(function() {});
otab = tab;
}
at the end I call loadTab(tab); and the thing should be initialized. but for some reason the content remains empty. As soon as you manually click on a tab (I have an on click function which calls loadTab(tab) everything starts working)
Because the code by itself works, I think the problem is caused by the other script which handles the page itself. It is also a .load function which loads the page, which loads this tab system.
So do multiple .loads don't like each other? and if so, what can I change?
Thanks in advance ;)
EDIT: I could't post the entire code for some reason, but if you go here you can see the site in action with all the scripts:
n.ethz.ch/student/lukal/paint.net
The tab system is on the download page.
EDIT:-----------------------------------------------------------------------------------------------------------------------------
Big Update
So this is still the same issue but with a slight twist: I did what was recommended in the comments and put my secondary .load() call inside the success call of the first one.
$("#content").load("pages/contact #contentInside", function() {
$("#OtherContent").load("include/info #OtherContentInside");
});
So this works.
But now I had the great idea to make a giant load function. It is a slightly better function than just the plain load, cause it does some fading and stuff. But now I have the same problem, but even more complicated. I created the load function as a "plugin" so the function itself is in a different script file and therefore I can't access the inside of the success function. I solved this problem with a return $.ajax(); and a .done() call. The problem here is that there is some rare case where it just skips the secondary load function. So I am searching for a guaranteed way of controlling the order of the .load calls. Any idea?
The mock-up website is up to date with the new scripts if you wish to take a look. And people were complaining about potential virus spread from my link. For some reason I can't post long code snippets so the site is the best source I got to show everything. If you know a more trustworthy way to share my code please let me know.
We cannot see the rest of your code to tell where the initial call is being invoked from. A set up like the following should work:
$(function() {
var tab = 0;
loadTab( tab );
});
function loadTab(tab) {
//WHAT IS otab???
$(".tab_a:eq("+otab+")").removeClass("tab_slc"); //<<<==== otab
$('#tab_content').hide();
$('#tab_content').load("include/tab_downloadVersions.html .tab:eq("+tab+")");
$(".tab_a:eq("+tab+")").addClass("tab_slc");
$('#tab_content').fadeIn(function() {});
otab = tab;
}
Update
The reason it does not work initial is because otab is not defined the first time the function is called. You have initialized otab at the end of the function but you are using it at the beginning of the function.
UPDATE 2
I have had a chance to look at your code and I just found out what the issues are:
You do not have DOM ready
You are not calling the function on page load.
The following version of your code should work -- try not to use global variable as you're doing with otab. Since you're loading this script at the end of the page (an you are using event delegation) you may get away with DOM ready. Adding .trigger('click') or click() as indicated below should resolve the issue.
//Tab-loader
//Haeri Studios
var tab = 0;
var otab = tab;
var counter = 0;
//click detect
$(document).on('click', '.tab_a', function() {
tab = counter == 0 ? tab : ($(this).attr('id'));
loadTab(tab);
counter++;
return false;
})
.trigger('click'); //<<<<<===== This will call the function when the page loads
//Tab setup
function loadTab(tab) {
//Content Setup
$(".tab_a:eq("+otab+")").removeClass("tab_slc");
$('#tab_content').hide();
$('#tab_content').load("include/tab_downloadVersions.html .tab:eq("+tab+")");
$(".tab_a:eq("+tab+")").addClass("tab_slc");
$('#tab_content').fadeIn(function() {});
otab = tab;
}
//Initialize << WHAT ARE YOUR INTENTIONS HERE .. DO YOU REALLY NEED THIS PIECE?
$.ajax({success: function() {
loadTab(tab);
}});
A partial answer to this problem was to call the loadTab function inside the success call of the page load function, like charlietfl pointed out. But the problem is that there is no need to call the tabloader every time a new page gets called. So I would rather not have a rare call in every page setup function.
I am a bit disappointed by the system on stackoverflow. It seems like if you have not a high reputation level, no one gives a "S" about your questions. Well but at least some input was give, for which I am very thankful.
So by digging deeper into google I found out that the callback can be manually placed in the function where ever you like.
so if we have a function:
foo(lol, function() {
//This after
});
this does stuff after foo() is done. But what if we have another function inside foo() which we also need to wait for:
function foo(lol) {
bar(troll, function() {
//This first
});
}
The bar function is not relevant to the success call of foo. This causes the unpredictable outcome of calls.
The trick is to control when the success function of foo gets called.
If we add a parameter(callback) inside foo and call this "parameter" (callback();) inside the success call of bar, we can make sure the order is guaranteed.
And that's it:
function foo(lol, callback) {
bar(troll, function() {
//This first
callback(); //<-This callback placement defines when it should be triggered
});
}
foo(lol, function() {
//This after
});
We get:
//this first
//this after

JavaScript two onload functions

I am quite new to JavaScript programming and I'm trying to create some scripts that would save me time in maintaining one of my websites.
Now I have two functions in the same script that I'm calling from the head of my document and I'm trying to get them both to load at the same time with an onload event handler. I am doing that with window.onload command in my script (I want to make my script as unobtrusive as possible so I'm just calling the script in the header).
The problem is that only the first function loads and the second one doesn't. Can both functions be called with:
window.onload=function(){
function1();
function2();
}
or is there a different code I need to use to accomplish this?
I would really appreciate it if you could make your explanations as simple as possible as I am very new to JavaScript and programming in general.
P.S. If more than one function can't be loaded with onload, could you please explain to me why this is the case so I know in the future.
Ok, I see by the answers that my question probably left too much for assumption so here is the entire code of the functions I am trying to call (this is the script I am calling in the head of my html document):
I was trying to avoid putting the code here because my variables are written in Serbian language (as I am from Serbia), but I hope that you will still be able to look through it without much confusion.
In the code below I am calling at the bottom of the script two functions (lista() and ostale()) and the moveover() function is just a helper function called by the lista() function.
In essence the first one (lista()) lists through all elements of div "boje" (in English translated to "colors") and depending on the color the user hovers their mouse over, the background image changes. It also adds a few attributes to those image elements that the user is supposed to hover over.
The second one (ostale() (Translated to English "others") is supposed to only add attributes to the rest of the color images that are not supposed to do anything if the user hovers over them.
But when I open the page in localhost it doesn't show in Firefox's inspect element that any attributes have been added to the images within the div "ostale".
function lista()
{
var boje = document.getElementById('boje');
var broj = boje.childNodes.length;
for(i=1; i<broj; i++)
{
var stavka = boje.childNodes.item(i);
stavka.setAttribute("id", i);
stavka.setAttribute("onmouseover", "moveover(src)");
stavka.setAttribute("alt", "Boja");
stavka.setAttribute("class", "boja");
stavka.hspace="2";
stavka.height="23";
}
}
function moveover(adresaBoje)
{
var izvor = adresaBoje;
var slika = izvor.slice(0, izvor.length-4);
var pocetak = "url(";
var ekstenzija = ".jpg)";
var novaSlika = pocetak.concat(slika, ekstenzija);
document.getElementById('slika').style.backgroundImage=novaSlika;
}
function ostalo(){
var ostaleboje = document.getElementById('ostale');
var ostalebroj = ostaleboje.childNodes.length;
for(n=1; n<ostalebroj; n++)
{
var ostalestavka = ostaleboje.childNodes.item(n);
ostalestavka.setAttribute("alt", "Boja");
ostalestavka.hspace="2";
ostalestavka.height="23";
}
}
window.onload=function(){
try
{
lista();
ostalo();
}
catch(err)
{
alert(err);
}
}
After I try to load the page it alerts me with an error: "TypeError: stavka.setAttribute is not a function".
This is the html document I am trying to manipulate:
<div id="slika" style="background-image: url(images/nova_brilliant/1.jpg)">
</div>
<div id="tekst">
<h1>Nova Brilliant</h1>
<div id="sadrzaj">
<p>Pređite mišem preko željene boje da biste videli kako izgleda ova kuhinja u toj boji:</p>
<div id="boje">
<img src="images/nova_brilliant/1.gif"><img src="images/nova_brilliant/2.gif"><img src="images/nova_brilliant/3.gif">
</div>
<p>Ostale dostupne boje:</p>
<div id="ostale">
<img src="images/nova_brilliant/4.gif"><img src="images/nova_brilliant/5.gif"><img src="images/nova_brilliant/6.gif">
</div>
</div>
</div>
I ran into the same problem. I came across a couple of help but this one was easy to understand and it worked for me:
window.addEventListener("load", func1); window.addEventListener("load", func2);
just like #Quentin You can read more about it here
Yes you can. However, if the first goes wrong, the second won't fire.
Use this to catch errors:
try { //try executing the functions
function1();
function2();
}
catch(error) { // If there's an error
alert(error); // alert the error.
}
It is a good practice to put try and catch when experimenting with javascript.
Edited: Sorry i confused childNodes[] with childNodes.item().
By the way, I tried something like this, and it works just fine:
<head>
<script>
window.onload = function() {
div = document.getElementById("someDiv");
length = div.childNodes.length;
first();
second();
}
function first() {
for(var i=0;i<length;i++) {
var set = div.childNodes.item(i);
set.setAttribute("name", "span " + (i+1));
}
}
function second() {
for(var i=0;i<length;i++) {
name = div.childNodes[i].getAttribute("name");
console.log(name);
}
}
</script>
</head>
<body>
<div id='someDiv'><span id='span1'></span><span id='span2'></span></div>
</body>
UPDATE: I found the error:
Actually there's nothing wrong with your code. It works just fine, however, the last item of boje is empty space, which means, a text node. That's why the error keeps showing up. Change for(i=1; i<broj; i++) with for(i=1; i<broj-1; i++) and everything should be good.
Can both functions be called with
Yes. If you add event handlers by assigning to DOM properties, then you can only assign a single function to each but that function can call other functions.
However, if you do that and the first function throws an error then the second function won't fire at all. It will also discard the context and arguments, as they won't be passed to the called functions.
You could work around those problems like so:
window.onload=function(){
try {
function1.apply(this, arguments);
} catch (e) { }
try {
function2.apply(this, arguments);
} catch (e) { }
}
or is there a different code I need to use to accomplish this?
You should use addEventListener instead. That avoids the need to fiddle with apply, and protects you from errors being thrown. See the MDN events documentation for more details.
window.addEventListener('load', function1);
window.addEventListener('load', function2);

Dynamically changing the size of a <div> element

I'm trying to resize a <div> when the function is called from this if statement. I know the if statement is working because when the function mTr() is called it works and I know the function myFun() works but for some reason the function myFun() isnt getting called.
if (window.screen.height==568) { // iPhone 4"
document.querySelector("meta[name=viewport]").content="width=320.1";
myFun("divId");
mTr();
}
function myFun(id)
{
var obj = document.getElementById(id);
if (obj)
{
obj.setAttribute("style", "height:300px;");
}
}
function mTr()
{
alert("Hello World!");
}
There are several reasons that myFun() wouldn't be getting called:
window.screen.height is not exactly 568
document.querySelector("meta[name=viewport]").content="width=320.1"; generates a script error that causes script execution to stop
There is some error before this code that causes execution to stop
Your code is executing too early before the DOM has been loaded and thus it can't find the relevant DOM elements.
The first thing to do is to examine your browser error console and see what script errors (if any) are reported.
The second thing to do it to set a breakpoint on the if statement in your javascript debugger (built into most browsers) and then step through each of the following statements to see what is happening.
You can also embed console.log("xxx") statements in your code to create a breadcrumb trail in the console to tell you what's going on.
I retested everything. I think I found your problem. You had an error in your code.
Error was here:
document.querySelector("meta[name=viewport]").content="width=320.1";
Instead, it should be:
document.querySelector("meta[name=viewport]").setAttribute('content', 'width=320.1');
Complete Javascript:
if (window.screen.height==568) {
document.querySelector("meta[name=viewport]").setAttribute('content', 'width=320.1');
myFun("divId");
mTr();
}
function myFun(id)
{
var obj = document.getElementById(id);
if (obj)
{
obj.setAttribute("style", "height:300px;");
}
}
function mTr()
{
alert("Hello World!");
}
You can test it out here:
http://jsfiddle.net/KwGwd/

Categories

Resources