Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8403375
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 9, 20262026-06-09T22:19:35+00:00 2026-06-09T22:19:35+00:00

UPDATE: (recap, fiddle and bounty) This question hasn’t been getting too much attention, so

  • 0

UPDATE: (recap, fiddle and bounty)

This question hasn’t been getting too much attention, so I’m going to spend some rep on it. I know I tend to be overly verbose in both my answers and questions. That’s why I went ahead and set up this fiddle, which is, in my view, a decent representation of the kind of code I’m currently having to use to come close to a bubbling change event. A couple of issues I’m trying to resolve:

  1. The pseudo-change event doesn’t fire on a select element, unless it looses focus. In some cases the client should be redirected upon selecting a new value. How do I achieve this?
  2. The handler is called both when the labels are clicked, as well as the checkboxes themselves. In itself that’s what you’d expect, but due to the event bubbling it’s (AFAIK) impossible to determine which element was clicked. IE’s event object doesn’t have a realTarget property.
  3. When changing the checked-state of a checkbox in IE by clicking the label, all is well (though it requires some nasty workarounds), but when clicking the checkbox directly, the handler is called, but the checked state remains unchanged, until I click a second time. Then the value changes, but the handler isn’t called.
  4. When I switch to a different tab, and back again, the handler is called multiple times. Three times if the checked state actually changed, twice if I clicked the checbox directly only once.

Any information that could help me resolve one or more of the issues above would be greatly appreciated. Please, I didn’t forget to add a jQuery tag, I like pure JS, so I’m looking for a pure JS answer.


I’ve got a web page with well over 250 select elements on it, and 20~30 checkboxes. I also have to track the users’ actions, and take appropriate actions. It is therefore quite natural for me to delegate the change event, rather then adding hundreds of listeners, IMHO.

Of course, IE -company policy: IE8 has to be supported- doesn’t fire the onchange event when I need it. So I’m trying to fake an onchange event. What I have thus far is working reasonably well apart from 1 thing that really bugs me.
I’m using onfocusin and onfocusout to register the events. In some cases, when the user selects a new value from the a select element, the script should respond immediately. However, as long as the select hasn’t lost focus, this won’t happen.

Here’s what I came up with so far:

i = document.getElementById('content');
if (!i.addEventListener)
{
    i.attachEvent('onfocusin',(function(self)
    {
        return function(e)
        {
            e = e || window.event;
            var target = e.target || e.srcElement;
            switch (target.tagName.toLowerCase())
            {
                case 'input':
                    if (target.getAttribute('type') !== 'checkbox')
                    {
                        return true;
                    }
                    return changeDelegator.apply(self,[e]);//(as is
                case 'select':
                    self.attachEvent('onfocusout',(function(self,current)
                    {
                        return function(e)
                        {
                            e = e || window.event;
                            var target = e.target || e.srcElement;
                            if (target !== current)
                            {
                                return;
                            }
                            self.detachEvent('onfocusout',arguments.callee);//(remove closure
                            return changeDelegator.apply(self,[e]);
                        }
                    })(self,target));
                default: return;
            }
        }
    })(i));//(fake change event, buggy
}
else
{//(to put things into perspective: all major browsers:
    i.addEventListener('change',changeDelegator,false);
}

I’ve tried attaching another event listener inside the onfocusin handler, bound to the onclick event. It fired the onfocusout event of whatever select has focus ATM. The only problem is, 99.9% of the users will click on a select, so the focusin event fires an onclick, too.

To get round that, I created closure, and passed the current select-in-focus and it’s original value to it as arguments. But some users do use their keyboard, and these users often tab to the next select box without changing the value. Each time binding a new onclick listener… I do believe there HAS to be an easier way than to check all e.type‘s and treat them separately.
Just as an example: the code with an extra onclick listener: all code is the same as the first snippet, so I’m only pasting the case 'select': block

                case 'select':
                    self.attachEvent('onfocusout',(function(self,current)
                    {
                        return function(e)
                        {
                            e = e || window.event;//(IE...
                            var target = e.target || e.srcElement;
                            if (!(target === current))
                            {
                                return;
                            }
                            self.detachEvent('onfocusout',arguments.callee);//(remove closure
                            return changeDelegator.apply(self,[e]);
                        };
                    })(self,target));
                    self.attachEvent('onclick',(function(self,current,oldVal)
                    {
                        return function(e)
                        {
                            e = e || window.event;
                            var target = e.target || e.srcElement;
                            if (target.tagName.toLowerCase() === 'option')
                            {
                                while(target.tagName.toLowerCase() !== 'select')
                                {
                                    target = target.parentNode;
                                }
                            }
                            if (target !== current)
                            {//focus lost, onfocusout triggered anyway:
                                self.detachEvent('onclick',arguments.callee);
                                return;
                            }
                            var val = target.options[target.selectedIndex].innerHTML;//works best in all browsers
                            if (oldVal !== target.options[target.selectedIndex].innerHTML)
                            {
                                self.detachEvent('onclick',arguments.callee);
                                return target.fireEvent('onfocusout');
                            }
                        };
                    })(self,target,target.options[target.selectedIndex].innerHTML));
                default: return;
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-09T22:19:36+00:00Added an answer on June 9, 2026 at 10:19 pm

    Well, I had another crack at it, and I’ve come up with a fairly decent approach (at work it did the trick – I’ve tried to replicate the code I wrote but after a few beers it might contain some errors but the spirit remains the same)

    window.attachEvent('onload',function ieLoad()
    {
        var mainDiv = document.getElementById('main');//main div, from here events will be delegated
        var checks = mainDiv.getElementsByTagName('input');//node list of all inputs
        var checkStates = {};
        for (var i=0;i<checks.length;i++)
        {
            if (checks[i].type === 'checkbox')
            {//get their checked states on load, this object serves as a reference
                checkStates[checks[i].id] = checks[i].checked;
            }
        }
        mainDiv.attachEvent('onfocusin',(function(initState)
        {//initState holds a reference to the checkStates object
            return function(e)
            {
                e = e || window.event;
                var target = e.target || e.srcElement;
                //id of checkboxes used as key, so no checking for tagName or type required
                if (!initState.hasOwnProperty(target.id) || target.checked === initState[target.id])
                {//don't call method if checkstate is unchanged, either. I'll explain in a minute
                    return e;
                }
                initState[target.id] = target.checked;//set new checked-state
                changeDelegator.apply(target,[e]);//delegate
            };
        })(checkStates));
        window.detachEvent('onload',ieLoad);//avoid mem-leak with onload handler!
    });
    

    I’ve found out that the focusin events fire twice in some cases for radio’s and checkboxes. Using an object that holds the actual checked states of all checkboxes is less expensive than individual handlers, and it allows me to only delegate the event after the value of the element has changed.

    The changeDelegator function is only called when needed, but the anon function that I posted here still gets called Waaaay more than I wanted it, but this approach still outperforms the individual handlers-take.

    I left out the selects, but I got them working, too (similar take, in the full version of my code the closure has 2 objects, and I made it, so I can flag an id, fire the blur event when needed, and the client is redirected).
    At the end of the run, even though I’ve learned some new tricks, the main thing I take away from this exercise is an even more profound hatred of that ghastly, gritty golem of a thing called IE… But if anybody else might ever want to delegate change events in IE, know that it is (almost) possible

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

UPDATE: I've been playing around with this more, and it seems like tmux's clear-history
UPDATE: I'm getting this error: (No route matches /docs/index.html... ) when accessing admin.example.com/docs/index.html The
Ok, this question has been asked many times. Just googling with the error message:
UPDATE: I made a mistake in my debugging - this question is not relavent
Update: Check out this follow-up question: Gem Update on Windows - is it broken?
Update: I reported this as a bug to Apple and they fixed it! All
Update : This is no longer an issue from C# 6, which has introduced
Update : I found almost exact similar question , yet it has slightly different
UPDATE: I've completely changed the question because in reality, I'm having a really hard
UPDATE : A commenter told me to change some codes, this is the new

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.