• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3823
  • Last Modified:

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

0
VirtualLNK
Asked:
VirtualLNK
  • 7
  • 4
1 Solution
 
bugadaCommented:
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.

0
 
VirtualLNKAuthor Commented:
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.



      
0
 
bugadaCommented:
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

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
VirtualLNKAuthor Commented:
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?
0
 
bugadaCommented:
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.
0
 
VirtualLNKAuthor Commented:
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
0
 
bugadaCommented:
Well I was wrong, I'm sorry. Your problem is not related to bubbling but to an odd event handling in IE: the onblur event ovverides the onclick event.

In your case initially your div has focus, then when you click on an internal link the focus passes to it, and the div raises the onBlur event. After executing the blur event IE doesn't execute the onclick event.

Since other events are handled correctly, you can substituite your click event with onfocus, onmousedown or onmouseup, but in general this will not handle properly keyboard navigation or will disable it  (by  placing a tabindex="-1" attribute in your links you can avoid keyboard focus).

Finally, I don't know your intentions, but the onblur event on the DIV element works only in Internet Explorer.

To be crossbrowser I suggest you to rethink your widget using standard events on the div like onmouseover/onmouseout/onmouseclick.

0
 
VirtualLNKAuthor Commented:
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
0
 
VirtualLNKAuthor Commented:
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 ="";                  
            }
      }
0
 
VirtualLNKAuthor Commented:
Thanks so much for your help.
0
 
VirtualLNKAuthor Commented:
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>
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 7
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now