Link to home
Start Free TrialLog in
Avatar of VirtualLNK
VirtualLNK

asked on

Javascript - Capture Click Event Before Blur

I have a custom drop down menu which I show upon clicking on a hyperlink. I display a div with other hyperlinks on it for the user to select from. I have a blur event on the div which fires as expected when you click away from the div. The div also goes away upon clicking a hyperlink located on the div. The problem is that the click events of the hyperlinks in the div do not get raised if the div is set to display:nothing upon raising the blur event.

In other words the click events do not get fired because my blur event is hiding the div. If i remove the hiding of the div, the click events get raised as expected. I'm basically trying to get the same behavior as a combobox, where you can click away to close it. I need to save the option selected upon clicking something in the div, which is where my problem is. I tried using option buttons as well, but this did not work either.

So any way to hide the div on blur and still allow the click event to be completed?


<a onclick="popup_show(this);" id="pimpin" class="dodoman" href="javascript:;">Click Here To Make
                    Popup Menu Appear</a><br />
                
<div onblur="popup_hide(this);" id="pimped" style="display: none; position: absolute; left: 15px;"
                    <asp:Image runat="server" class="imgDodo" ImageUrl="~/images/testme2.png" />
                   <br />
                   <a href="#" onclick="javascript:RefreshCurrentPanel();">Test This</a>
                   <br />
</div>

Open in new window

Avatar of bugada
bugada
Flag of Italy image

what you're saying is that when you click on an internal hyper link ("test this") the blur event is raised before the click event. Quite strange, beacause on mu IE7 the blur event is not raised at all by clicking the internal <a>. The blur event is fired only if i click outside the div.

Avatar of VirtualLNK
VirtualLNK

ASKER

Fires in both IE8 and Firefox for me. Anything I place in the div (if it can receive focus) fires the blur event. Firefox requires "tabindex="0", which I have already.



      
ok now it's clear: your problem is "event bubbling", i.e. if an element raises an event, that event is raised even on parent elements unless otherwise specified.

You can follow two ways:

- explicitly stop the blur bubbling calling the stopBubble function in every element you have in your container

- discriminating between element in the onblur events, executing the onblur element only if the originating target is your container.

Since you can have multiple entry in your combo, i suggest you to follow the second case:

on the blur event call the new popup_blur() and in the onclick event of every inner links, call explictly popup_hide() just after completing the onclick action.

Hope this helps.

/* FIRST CASE: must be invoked on every onblur event */
function stopBubble(e) {
      if (e && e.stopPropagation) 
         e.stopPropagation(); // W3C compliant
      else
         window.event.cancelBubble = true; //IE
}
 
<a onclick="popup_show(this);" id="pimpin" class="dodoman" href="javascript:;">Click Here To Make
                    Popup Menu Appear</a><br />
                
<div onblur="popup_hide(this)" id="pimped" style="display: none; position: absolute; left: 15px;"
                    <asp:Image runat="server" class="imgDodo" ImageUrl="~/images/testme2.png" />
                   <br />
                   <a href="#" onclick="RefreshCurrentPanel();" onblur="stopBubble(e)">Test This</a>
                   <br />
</div>   
 
 
 
 
/* SECOND CASE: find the originating element */
function popup_blur(e) {   
   e = e || window.event;
   var elem = e.target || e.srcElement;
   
   if (elem.id == "pimpin")  {
       popup_hide(elem);
   }  
}
      
      
      
<a onclick="popup_show(this);" id="pimpin" class="dodoman" href="javascript:;">Click Here To Make
                    Popup Menu Appear</a><br />
                
<div onblur="popup_blur(e)" id="pimped" style="display: none; position: absolute; left: 15px;"
                    <asp:Image runat="server" class="imgDodo" ImageUrl="~/images/testme2.png" />
                   <br />
                   <a href="#" onclick="RefreshCurrentPanel();  popup_hide(this.parent)">Test This</a>
                   <br />
</div>       

Open in new window

Thanks for this. It sounds very promising. Although I'm getting an error that say 'e is undefined' on this line:

<div onblur="popup_blur(e);" id="pimped" style="display: none; position: absolute;
                    left: 15px;" tabindex="0" class="superDiv">


Am I missing something?
oh sorry remove the "e" param from the function call, it's my fault. Is added by default in w3c compliants browsers, while IE uses window.event. But remember to not remove it from the function declaration.

And i found another error:

popup_hide(this.parent)  should be popup_hide(this.parentNode)

Sorry for that.
Seems that no matter where I click it comes back with element id "pimped". I added an alert to confirm this.

   function popup_blur(e) {  
       e = e || window.event;
       var elem = e.target || e.srcElement;
       alert(elem.id);
       if (elem.id == "pimpin")  {
           popup_hide(elem);
       }  
    }

<a onclick="popup_show(this);" id="pimpin" class="dodoman" href="javascript:;">Click
                    Here To Make Popup Menu Appear</a><br />
                <div onblur="popup_blur();" id="pimped" style="display: none; position: absolute;
                    left: 15px;" tabindex="0" class="superDiv">
                    <asp:Image runat="server" class="imgDodo" ImageUrl="~/images/testme2.png" />
                    <br />
                    <a href="#" id="somespec" onclick="RefreshCurrentPanel();  popup_hide(this.parentNode)">Test This</a>
                </div>

Am i missing something?

Thanks for your help!

Levi
ASKER CERTIFIED SOLUTION
Avatar of bugada
bugada
Flag of Italy image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks for your efforts.

Onmouseout doesn't seem to work either as it fires when hovering over any of the links in the div.  This is exactly what i need here:
<asp:Image runat="server" class="imgDodo" ImageUrl="~/images/testme2.png" />                    

If you check out the two blue boxes on the top right. They work just like a combobox and close when you click away from them. If anyone knows how they are doing this, please let me know.

Levi
I figured out my problem with the onmouseout... once i made the div an explicit height and width, it seemed to resolve the issue. This is the working solution in case anyone is interested. I tested in Firefox, IE, and Safari (for Windows) with no problems...

                <a onclick="popup_show(this);" id="pimpin" class="dodoman" href="javascript:;">Click Here To Make
                    Popup Menu Appear</a><br />
                <div onblur="popup_hide(this);" id="pimped" style="display: none; position: absolute; left: 15px; height: 300px; width: 300px; background-color: Yellow;"
                    tabindex="0" class="superDiv" onmouseover="mDivMOver = true;" onmouseout="mDivMOver = false;">
                    <asp:Image runat="server" class="imgDodo" ImageUrl="~/images/testme2.png" />
                   <br />
                   <a href="#" onclick="javascript:RefreshCurrentPanel();">Test This</a>
                </div>


      function popup_hide(obj)
      {         
          if (!mDivMOver)
          {
                obj.style.display = 'none';
                obj.parentNode.style.border="none";            
                obj.parentNode.className ="";                  
            }
      }
Thanks so much for your help.
Here is the more complete solution. I was also able to verify that this works in Opera.

    <script type="text/javascript">
    var mDivMOver = false;        
   
      function popup_show(obj)
      {
            var el = obj.parentNode.getElementsByTagName('div')[0];            
            el.style.display = 'block';
            obj.parentNode.className ="overme";            
            el.focus();
      }

      function popup_blur(obj)
      {         
          if (!mDivMOver)
          {
            toggleDIV(obj);
            }
      }
      
      function toggleDIV(obj)
      {
        obj.style.display = 'none';
          obj.parentNode.style.border="none";            
          obj.parentNode.className ="";                                 
      }
      
      function RefreshCurrentPanel()
      {                
          toggleDIV(document.getElementById('pimped'));
      }
    </script>



 <table>
        <tr>
            <td>
                <a onclick="popup_show(this);" id="pimpin" class="dodoman" href="javascript:;">Click
                    Here To Make Popup Menu Appear</a><br />
                <div onblur="popup_blur(this);" id="pimped" style="display: none; position: absolute;
                    left: 15px; height: auto; width: auto; background-color: Yellow;" tabindex="0"
                    class="superDiv" onmouseover="mDivMOver = true;" onmouseout="mDivMOver = false;">
                    <asp:Image runat="server" class="imgDodo" ImageUrl="~/images/testme2.png" />
                    <br />
                    <a href="#" onclick="javascript:RefreshCurrentPanel();">Test This</a>
                </div>
            </td>
        </tr>
        <tr>
            <td>
                Bunch of text<br />
                Bunch of text<br />
            </td>
        </tr>
    </table>