简体   繁体   中英

jQuery clone : should it clone DOM Level 0 Events?

While reading the book jQuery in Action and playing with the first events handling example, I discovered that jQuery doesn't consistently clone DOM Level 0 events. It clones the inline events, but not those defined as a property. It could be a good thing to discourage the use of inline event handlers, but is is by design? What is one wants to clone something from a legacy page ?

Here is an alteration of the example given in the book, to demonstrate the behavior.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <title>DOM Level 0 Events Example</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js">
    </script>
<script type="text/javascript">
  $(function(){
    $('#testElement')[0].onclick = function(event) {
      say(this.id + ' Click ASSIGN [DOM 0]');
    }
            $('#testElement').click(function() { say(this.id + ' Click JQUERY [DOM 2]');});
            $('#testElement').clone(true).attr('id',"clonedElement").insertAfter($('#testElement'));
  });

  function say(text) {
    $('#console').append('<div>'+text+'</div>');
  }
  </script>
  </head>

  <body>
    <div id="testElement" style="border: solid brown 1px; margin: 10px; width : 100px; height: 100px;" onclick="say(this.id + ' Click INLINE [DOM 0]')">&nbsp;</div>
<div id="console"></div>
 </body>
</html>

Line 305 to 312 in "jQuery-1.3.2.js

"IE" copies events bound via "attachEvent" when using "cloneNode". Calling "detachEvent" on the clone will also remove the events from the orignal. In order to get around this, we use "innerHTML". Unfortunately, this means some modifications to attributes in "IE" that are actually only stored as properties will not be copied (such as the the name attribute on an input).

The example to pasate not work in IE for the reason explained. We should make a modification to the method "clone" of jQuery to have this functionality in IE

EDIT:

ok, I'm sorry, now I understand the problem, but from what I see and what you can view in "clonedElement_2" is a limitation of "cloneNode". The only thing I can think of is to change the method "clone" of "jQuery"

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
    <script language="JavaScript">

        (function($){

            $.fn.__extendClone = $.fn.clone;
            $.fn.clone = function(events){

                var ret = $(this).__extendClone(events);

                if (events){

                    var listEvents = ["onabort", "onblur", "onchange", "onclick", "ondblclick", "onerror", "onfocus", 
                        "onkeydown", "onkeypress", "onkeyup", "onload",  "onmousedown", "onmousemove", "onmouseout", 
                        "onmouseover", "onmouseup", "onreset", "onresize", "onselect", "onsubmit", "onunload"];

                    for (var inde in listEvents){
                        if ($.isFunction($(this)[0][listEvents[inde]])){
                            $(ret)[0][listEvents[inde]] = $(this)[0][listEvents[inde]];
                        }
                    }
                }

                return ret;

            };

        })(jQuery);     

        $(function()
        {
            //work
            var mytestElement = document.getElementById("testElement")
            mytestElement.setAttribute("style", "border: solid green 2px; margin: 10px; width : 100px; height: 100px;");

            //don't twork
            $('#testElement')[0].onclick = function(event) {
                say(this.id + ' Click ASSIGN [DOM 0]');
            }

            $('#testElement').click(function() { say(this.id + ' Click JQUERY [DOM 2]');});

            //clone jquery
            $('#testElement').clone(true).attr('id',"clonedElement").insertAfter($('#testElement'));

            //clone js
            var myNode = document.getElementById("testElement").cloneNode(true);
            myNode.setAttribute("id", "clonedElement_2");
            myNode.setAttribute("style", "border: solid blue 2px; margin: 10px; width : 100px; height: 100px;");
            document.getElementById("container").appendChild(myNode);

        });

        function say(text) {
            $('#console').append('<div>'+text+'</div>');
        }

    </script>
</head>
<body>
    <div id="testElement" style="border: solid brown 2px; margin: 10px; width : 100px; height: 100px;" onclick="say(this.id + ' Click INLINE [DOM 0]')">&nbsp;</div>
    <div id="container"></div>
    <div id="console"></div>
</body>
</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM