0

I need help with this JavaScript code. for some reason variable "index" always ends up being the last index of the array no matter what link I click.

var linkElements = document.getElementsByTagName('a');
var index;
var origOnClickArr = [];
for (index = 0; index < linkElements.length; ++index) {
    origOnClickArr.push(linkElements[index].onclick);
    linkElements[index].onclick = function (e) {
        if (confirm(message)) {
            origOnClickArr[index]();
        }
    };
}
j08691
  • 204,283
  • 31
  • 260
  • 272
user1173894
  • 55
  • 2
  • 9
  • 1
    clousre's concept should be apply to fix it. – Suman Bogati Mar 21 '14 at 17:14
  • 1
    As @Suman *nearly* said ;-) do a search for `closures`. It's not an easy concept to get your head around, but it explains what the issue is here. There are [plenty of question already on SO](http://stackoverflow.com/search?q=closures) on the subject – freefaller Mar 21 '14 at 17:21
  • Closures are unnecessary here. The problem is that Javascript is not block-scoped, it is functionally scoped. You *could* use a closure to solve the problem, but as the accepted answer points out, it isn't the only way to solve the problem. – Katie Kilian Mar 21 '14 at 19:31

2 Answers2

2

Try something like this

var linkElements = document.getElementsByTagName('a');
var index;
var origOnClickArr = [];
for (index = 0; index < linkElements.length; ++index) {
(function (index) {
    origOnClickArr.push(linkElements[index].onclick);
    linkElements[index].onclick = function (e) {
        if (confirm(message)) {
            origOnClickArr[index]();
        }
    };
})(index)
}

wrap the code inside the for loop inside a self invoking anonymous function and pass the value of index for each loop.

Abhishek Prakash
  • 964
  • 2
  • 10
  • 24
0

You can add to the list of event listeners using addEventListener or remove an event listener. Ideally, you would create functions and use javascript to assign the entire function you want to get called + the wrapper function that does the confirmation instead of inline assignment to the onclick event. (http://www.quirksmode.org/js/events_advanced.html).

One way to achieve what you're doing is to use event capturing/bubbling techniques.

Event capture happens from the parent element to the child followed by the event bubbling up from the child to the parent.

You could assign a capture event handler to do the confirmation. If the user confirms, let the event continue propagating. If not, then stop propagation.

Untested but may work:

var message = 'Confirm';
function doConfirm()
{
   if (!confirm(message))
   {
       if (window.event)
       {
          if (window.event.stopPropagation) // w3c compliant browsers
          {
              event.stopPropagation();
          }
          else // Old IE browsers (ie 8 or ie 9 if i remember correctly)
          {
             event.cancelBubble = true;
          } 
       }
   }
}

var arr = document.getElementsByTagName("a");
for (var i = arr.length-; i >= 0; i--)
{
   arr[i].addEventListener("click", doConfirm, true); // true indicates capture phase.
}
Abhishek
  • 359
  • 1
  • 8
  • that only works for links with "href" though. I have a mix of links some with hrefs and others with onClick. They all call different functions. basically I have a bunch of links of all kinds – user1173894 Mar 21 '14 at 17:51
  • basically I have a bunch of links of all kinds here 1 2 3 4 5 i am trying to popup a confirmation when each link is clicked. if they agree with the message, the href or the onclick is executed; otherwise nothing happens – user1173894 Mar 21 '14 at 17:57
  • so where there is an onClick: I am trying to preserve it with origOnClick and reformat the onClick to popup a confirm dialog and execute origOnClick if they click OK where there is an href: I need to do the event.stopPropgation or preventDefault to stop the href from executing, popup a confirmation and then execute the href if the click OK – user1173894 Mar 21 '14 at 18:00