click event on li its not work perfect

2019-08-28 02:19发布

this is my xml file:-

<?xml-stylesheet href="b.xsl" type="text/xsl"?>
<root>
  <child_1 entity_id = "1" value="Game" parent_id="0">
    <child_2 entity_id="2" value="Activities" parent_id="1">
      <child_3 entity_id="3" value="Physical1" parent_id="2">
        <child_6 entity_id="6" value="Cricket" parent_id="3">
          <child_7 entity_id="7" value="One Day" parent_id="6"/>
        </child_6>
      </child_3>
      <child_4 entity_id="4" value="Test1" parent_id="1">
        <child_8 entity_id="8" value="Test At Abc" parent_id="4"/>
      </child_4>
      <child_5 entity_id="5" value="Test2" parent_id="1">
        <child_9 entity_id="9" value="Test At Xyz" parent_id="5"/>
      </child_5>
    </child_2>
</child_1>
</root>

this is my xslt code:-

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" indent="yes" omit-xml-declaration="yes"/>

  <xsl:template match="*" mode="item">
    <xsl:choose>
      <xsl:when test="self::node()/child::*">
        <li>
          <xsl:value-of select="@value"/>
          <xsl:apply-templates select="current()[*]"/>
        </li>
      </xsl:when>
      <xsl:otherwise>
        <li onclick="final()">
          <xsl:value-of select="@value"/>
          <xsl:apply-templates select="current()[*]"/>
        </li>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="*/*/*">
    <ul>
      <xsl:apply-templates select="*[1] | node()[current()/ancestor::*[3]]" mode="item"/>
    </ul>
  </xsl:template>
</xsl:stylesheet>

here i try to get Activities from xml file
and if a last li then set there one function as a attribute type like :-

<li onclick ="final()">One Day</li>

it only set last li which no have child...
now i am create one javascript file for getting xslt and html output.:-

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <title>Untitled Page</title>
    <script>
    function final(){
        $('li:not(:has(*))').click(function(){
        alert('click');
        $('#result').text($(this).text());
        });
        }
    </script>
    <script>
        var xml = loadXMLDoc("final.xml");
        var xsl = loadXMLDoc("b.xsl");



        function loadXMLDocOther(location) {
            xhttp = new XMLHttpRequest();
            xhttp.open("GET", location, false);
            xhttp.send("");
            return xhttp.responseXML;
        }

        function loadXMLDoc(dname) {
            if (window.ActiveXObject) {
                return loadXMLDocActiveX(dname);
            }
            else if (window.XMLHttpRequest) {
                return loadXMLDocOther(dname);
            }
        }        
        function transformOther(xml, xsl, target, selected) {
            var xsltProcessor = new XSLTProcessor();
            xsltProcessor.importStylesheet(xsl);

            if (selected) {
                xsltProcessor.setParameter(null, "selected", selected);
            }

            var resultDocument = xsltProcessor.transformToFragment(xml, document);
            target.innerHTML = "";
            target.appendChild(resultDocument);
        }

        function displayResult() {
            var targetElement = document.getElementById("load");

            // code for IE
            if (window.ActiveXObject) {
                transformActiveX(xml, xsl, targetElement);
            }
            // code for Mozilla, Firefox, Opera, etc.
            else if (document.implementation && 
                     document.implementation.createDocument) {
                transformOther(xml, xsl, targetElement);
            }
        }


    </script>
</head>
<body onload="displayResult()">
    <div id="load">
    </div>
    <div id="result">result</div>
</body>

this is my javascript code to click on last li its value append in <div id="result">

<script>
        function final(){
            $('li:not(:has(*))').click(function(){
            alert('click');
            $('#result').text($(this).text());
            });
            }
        </script>

now problem is i am click on last li its work but its work something like for loop. i got this problem when i try to one alert.

1条回答
淡お忘
2楼-- · 2019-08-28 03:22

It is quite hard to know what you are trying to. Therefor here first an explanation what you are doing. You generate a html fragment like this (via xlst):

<ul>
    <li>Physical1<ul>
        <li>Cricket<ul>
            <li onclick="final()">One Day</li>
        </ul>
        </li>
    </ul>
    </li>
</ul>

There is one onlclick handlder (onclick="final()) at the li element without children.

function final(){
        $('li:not(:has(*))').click(function(){
        alert('click');
        $('#result').text($(this).text());
        });
        } 

Firs click on "One Day" item calls final(). The final function than sets new onclick handler to all li elements with not children. Which is the same and only element which has already an final as onclick hanlder Because of event propagation the next click calls the new hanlder and afterward final. Which installs again a new onclick handler. Now wee have already three handler on the element. And each click add one more. To stop this can you try to use event.stopPropagation(); or to remove the event handler attr('onclick', '').off('click');

function final() {
    var lis = $('li:not(:has(*))');
    lis.attr('onclick', '').off('click');
        $('li:not(:has(*))').click(function(event) {
              $('#result').text($(this).text());
        });
    }

But I more suspect that the selector is wrong $('li:not(:has(*))').
Some more comments:
- It would not make lot sense to set event handler to your parent <li> elements either. Because the li elements include each other (what is correct!) clicking on an child will also trigger the handler of the parent elements.
- Therefore (perhaps) you should add elements around the content (text) of the li elements. (<li><span>Physical1</span><ul><li>...)
- Than you can add the onclick handler the span elements.
- If only the "final" elements should trigger an event, you do not need to set any new click functions.

function final(){
        alert('click');
        $('#result').text($(this).text());
        } 
查看更多
登录 后发表回答