Friday, April 8, 2011

How can I get the original text node of the event?

for example ,I have the following html

<HTML>
<HEAD>
<script type="text/javascript">
function trackElement(event){
    event=event||window.event;
    var target = event.explicitOriginalTarget||event.srcElement||document.activeElement;
    var targetText = target.nodeValue||target.innerHTML;
    alert(targetText);
}
</script>
</HEAD>
<BODY onclick="trackElement(event)">
<div>bbbbbb<div>cccccc</div>dddddddddd<div>eeeeeeeee</div></div>
</BODY>
</HTML>

When I clicked "bbbbbb",

  • On firefox ,I got "bbbbbb" alerted which is exactly what I expected.

  • But on IE, I got "bbbbbb<div>cccccc</div>dddddddddd<div>eeeeeeeee</div>"

When I clicked "dddddddddd",

  • On firefox ,I got "dddddddddd" alerted which is exactly what I expected.

  • But on IE, I got "bbbbbb<div>cccccc</div>dddddddddd<div>eeeeeeeee</div>"

How can I get the same result with firefox on IE?

From stackoverflow
  • Please see comment about explicitoriginaltarget in crossbrowser-equivalent-of-explicitoriginaltarget-event-parameter.

    In IE you get the Div element and the second one is in it, does this solution of separating the divs work for you? - the script is the same... (This works both in IE and in FF)

    <BODY onclick="trackElement(event)">
      <div>bbbbbb</div>
      <div>cccccc</div>
    </BODY>
    
    : Thanks Dror,But the html I want to track is no generate by myself,I can't expect what it might be。
  • That's because the property "nodeValue" returns null for element nodes so you return innerHtml instead, which is gonna contain the whole html code inside an element. In Internet Explorer, your target is assigned by event.srcElement and hence is an element node, while it's a text node in FF. One way to solve the problem would be the following code :

    function trackElement(event){
        event=event||window.event;
        var targetText;
        var target = event.explicitOriginalTarget||event.srcElement||document.activeElement;     
        if(target.nodeType==3){
         targetText = target.nodeValue  
        }else{  
         targetText = target.firstChild.nodeValue;
        } 
        alert(targetText);
    }
    

    This way, you'd return the value if your assignment assigned a text node, and the text of the first child (which is what you're after) for an element node.

    EDIT: Turns out I'm wrong. The problem is that event.srcElement returns the whole Element that's being clicked (event.explicitOriginalTarget being mozilla specific). From there, you need to retrieve the text. I see no easy way to do that if there are several texts in the element. If there is only one, it's a matter of iterating over the child nodes and displaying the text ones.

    : Thanks Axelle,But since I can't expect what the html would be,so The text node be clicked might not be the first child.
    Axelle Ziegler : Indeed, sorry. Actually, event.srcElement retrieves the _element_ which was clicked. So I think you pretty much need what you have to retrieve to be included in an element. I might be wrong though, I'm not a huge JS expert.
  • What about just substringing it?

    <script type="text/javascript">
    function trackElement(event){
        event=event||window.event;
        var target = event.explicitOriginalTarget||event.srcElement||document.activeElement;
        var targetText = target.nodeValue||target.innerHTML.substr(0, target.innerHTML.indexOf("<"));
        alert(targetText);
    }
    </script>
    </HEAD>
    <BODY onclick="trackElement(event)">
    <div>bbbbbb<div>cccccc<p>Hellooo</p></div></div>
    

    This seems to work, clicking ccccc returns "cccccc", and so on. Or did I completely miss the point?

    EDIT: You also need to check if the element has any child elements before substringing it...

    : Thanks peirix, I haven't describ my situation clearly.The html in my example was not the invariable.It may be any html.What I want is when any text node of the html is clicked,I can get it.
  • finally,I use offset to check which text node is clicked as below:

    if ($.browser.mozilla) {
        el = event.originalEvent.explicitOriginalTarget;
    }else{
        var parent =event.srcElement;
        var left = event.pageX;
        var top = event.pageY;
        var offset=$(parent).offset();
        for(var i=0;i<parent.childNodes.length;i++){
         var n = parent.childNodes[i];
         if ( n.nodeType == 1 ){
          if($(n).offset().top>offset.top){
           if($(n).offset().top>top){
            el=parent.childNodes[i-1];
            break;
           }
          }else if($(n).offset().top+$(n).height()>offset.top){
           if($(n).offset().left>left){
            el=parent.childNodes[i-1];
            break;
           }
          }
         }
         el=n;
        }
    }
    

0 comments:

Post a Comment