9

I have some variables and i want to retain their values between function calls, Can anyone please share how to do this in javascript. I have tried using global variables but that is not helping. help greatly appreciated, for example in the below code, inside function jump whenever it is called the alerted values are always the same it doesn't increment for every function call. alert(this.prevVal); and alert(this.currentVal);

// We're using a global variable to store the number of occurrences
var MyApp_SearchResultCount = 0;
var currSelected = 0;
var countStr = 0; 




//var prevEl,el;

// helper function, recursively searches in elements and their child nodes
function MyApp_HighlightAllOccurencesOfStringForElement(element,keyword) {
  if (element) {
    if (element.nodeType == 3) {        // Text node
      while (true) {
        var value = element.nodeValue;  // Search for keyword in text node
        var idx = value.toLowerCase().indexOf(keyword);

        if (idx < 0) break;             // not found, abort

        var span = document.createElement("span");
        var text = document.createTextNode(value.substr(idx,keyword.length));
        span.appendChild(text);
        span.setAttribute("class","MyAppHighlight");
        span.style.backgroundColor="yellow";
        span.style.color="black";
        text = document.createTextNode(value.substr(idx+keyword.length));
        element.deleteData(idx, value.length - idx);
        var next = element.nextSibling;
        element.parentNode.insertBefore(span, next);
        element.parentNode.insertBefore(text, next);
        element = text;
        window.MyApp_SearchResultCount++;   // update the counter
        //countStr = MyApp_SearchResultCount;   

      }
    } else if (element.nodeType == 1) { // Element node
      if (element.style.display != "none" && element.nodeName.toLowerCase() != 'select') {
        for (var i=element.childNodes.length-1; i>=0; i--) {
          MyApp_HighlightAllOccurencesOfStringForElement(element.childNodes[i],keyword);
        }
      }
    }
  }
}

// the main entry point to start the search
function MyApp_HighlightAllOccurencesOfString(keyword) {

    alert("test");

  //MyApp_RemoveAllHighlights();
  MyApp_HighlightAllOccurencesOfStringForElement(document.body, keyword.toLowerCase());
    alert(window.MyApp_SearchResultCount);  
}

// helper function, recursively removes the highlights in elements and their childs
function MyApp_RemoveAllHighlightsForElement(element) {
  if (element) {
    if (element.nodeType == 1) {
      if (element.getAttribute("class") == "MyAppHighlight") {
        var text = element.removeChild(element.firstChild);
        element.parentNode.insertBefore(text,element);
        element.parentNode.removeChild(element);
        return true;
      } else {
        var normalize = false;
        for (var i=element.childNodes.length-1; i>=0; i--) {
          if (MyApp_RemoveAllHighlightsForElement(element.childNodes[i])) {
            normalize = true;
          }
        }
        if (normalize) {
          element.normalize();
        }
      }
    }
  }
  return false;
}

// the main entry point to remove the highlights
function MyApp_RemoveAllHighlights() {
  window.MyApp_SearchResultCount = 0;
  MyApp_RemoveAllHighlightsForElement(document.body);
}


function goNext(){
    jump(1);
}
function goPrev(){
    jump(-1);
}

var prevSelected = 0;
var currSelectedGlo = 0; 

this.prevVal = 0; 
this.currentVal = 0;

function jump(howHigh){

    this.prevVal = this.currentVal; 
    this.currentVal = this.currentVal + 1; 

    alert(this.prevVal);
    alert(this.currentVal);


    prevSelected = currSelected;
    currSelected = currSelected + howHigh;
    //window.currSelectedGlo = currSelected + howHigh; 
    //currSelected = window.currSelectedGlo;

    //alert("prevSelected" +prevSelected);
    //alert("window.currSelected "+ currSelected);

    //alert(window.MyApp_SearchResultCount);
    //alert(currSelected);
    if (currSelected < 0){  
        currSelected = window.MyApp_SearchResultCount + currSelected;
    }
    if (currSelected >= window.MyApp_SearchResultCount){
        currSelected = currSelected - window.MyApp_SearchResultCount;
    }

    prevEl = document.getElementsByClassName("MyAppHighlight")[prevSelected];
    //alert(window.prevEl);
    if (prevEl){
        prevEl.style.backgroundColor="yellow";
    }
    el = document.getElementsByClassName("MyAppHighlight")[currSelected]; 
    el.style.backgroundColor="green";
    el.scrollIntoView(true); //thanks techfoobar



}

Thanks djrecker

John Dvorak
  • 26,799
  • 13
  • 69
  • 83
Max
  • 5,380
  • 6
  • 42
  • 66

4 Answers4

6

You could use a global variable:

var value = 0;

function next() {
    return value++;
}

console.log(next());
console.log(next());

or better, an object with a property and a method:

function Counter() {
    this.value = 0;
}

Counter.prototype.next = function() {
    return this.value++;
};

var counter = new Counter();
console.log(counter.next());
console.log(counter.next());
Douglas
  • 36,802
  • 9
  • 76
  • 89
1
this.prevVal = 0; 
this.currentVal = 0;

function jump(howHigh){    
    this.prevVal = this.currentVal; 
    this.currentVal = this.currentVal + 1; 

This is not the usual way to create global variables, and it's prone to mistakes if used for that purpose. Also, you may run into extra obstacles when using the strict mode.

To make your variables reliably global, do

var prevVal = 0; 
var currentVal = 0;

function jump(howHigh){ 
    prevVal = currentVal; 
    currentVal = currentVal + 1; 

fiddle (I changed +1 to +howHigh as well): http://jsfiddle.net/4uGZ3/

You can't get much more global than that, but if you want your variables to survive page navigation, reloads etc. you have to use LocalStorage (won't work in IE7) or cookies:

function jump(howHigh){ 
    var currentVal = +localStorage.getItem("currentVal"); // + to cast to number
    prevVal = currentVal; 
    currentVal = currentVal + 1; 
    localStorage.setItem("currentVal", currentVal); // store back

Again, fiddle: http://jsfiddle.net/uKtcY/7/


This is the usual usage pattern with this:

function X(){
    this.prevVal=0;
    this.currenVal=0;
}
X.prototype.jump = function(){
    this.prevVal = this.currentVal; 
    this.currentVal = this.currentVal + 1; 
...

//test:
var x1 = new X();
var x2 = new X();

x1.jump(1); // 0=>1
x2.jump(2); // 0=>2
x1.jump(3); // 1=>4

...
John Dvorak
  • 26,799
  • 13
  • 69
  • 83
  • i have removed this and tried the usual way still the values are not incremented. – Max Jan 06 '13 at 20:37
  • @djrecker I added a jsFiddle showing that the general approach is correct. I don't see a reason why it shouldn't work in your case either. – John Dvorak Jan 06 '13 at 20:53
  • @djrecker updated my answer. Perhaps you're performing page navigation? – John Dvorak Jan 06 '13 at 21:09
  • ACtually i am using UIWebview of the iOS to work on. Any idea please suggest. – Max Jan 07 '13 at 15:54
  • @djrecker did you try using the localStorage? – John Dvorak Jan 07 '13 at 15:58
  • Does local storage work in UIWebView of iOS – Max Jan 07 '13 at 15:59
  • @djrecker then you should have mentioned this from the very start, and tag appropriately. – John Dvorak Jan 07 '13 at 16:03
  • @djrecker why don't you try? It works in any decent browser - even IE8. I don't know if UIWebView is a decent browser. I don't even know if it supports cookies. If it supports neither, you'll need to pass the data across pages through the hash string. – John Dvorak Jan 07 '13 at 16:05
  • I will tag this question with UIWebView, because i am facing this problem only with UIWebView and not browsers. because with browser it works completely fine. I thought both behave same but thats to the case. – Max Jan 07 '13 at 16:09
  • the first one works fine in browser, also to increase my rating i am not here i think this is the place where i get the most help from people like you, no intentions of increasing any rating. Thanks – Max Jan 07 '13 at 16:12
  • @djrecker anyways, this question is closed now. You should frame your new question as "how to pass variables across pages in UIWebView; this is what I've tried", not "fix my code please (but I won't actually post it)". – John Dvorak Jan 07 '13 at 16:15
0

There are two ways to do this:

1) A global variable:

 someVar = 0;

 function increaseSomeVar(){

      someVar++;
 }

2) return a variable:

 var someVar = 0;

 function increaseSomeVar(somelocalVar){
    somelocalVar++;
    return(somelocalVar);   
 }

 someVar = increaseSomeVar(someVar);
Abraham P
  • 15,029
  • 13
  • 58
  • 126
  • hi i just tried this the value if someVar just remain one it doesn't increment after multiple calls of increaseSomeVar, can you please suggest something else – Max Jan 06 '13 at 20:32
0

firstly, using global variables is usually a bad idea.

Since javascript passes objects by reference, you can use a object that has a number as a property which you update. Typically you can just pass this object around as you wish, unless you're calling a function that makes you lose your current scope like setTimeout. In that case, you can use jquery's bind function to keep track of the variable and scope, e.g.

 MyApp_HighlightAllOccurencesOfStringForElement.bind(this, element, keyword);
Chris Montgomery
  • 2,344
  • 2
  • 19
  • 30