jQuery clone:它应该克隆DOM Level 0事件吗?

时间:2010-01-08 16:05:22

标签: jquery events

在阅读jQuery in Action并使用第一个事件处理示例时,我发现jQuery并不能始终如一地克隆DOM Level 0事件。它克隆内联事件,但不是克隆为属性的事件。阻止内联事件处理程序的使用可能是一件好事,但这是设计的吗?什么人想从遗留页面克隆一些东西?

这是对书中给出的示例的更改,以证明行为。

<!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>

1 个答案:

答案 0 :(得分:1)

“jQuery-1.3.2.js

中第305到312行

“IE”在使用“cloneNode”时复制通过“attachEvent”绑定的事件。在克隆上调用“detachEvent”也会从orignal中删除事件。为了解决这个问题,我们使用“innerHTML”。不幸的是,这意味着对“IE”中实际仅存储为属性的属性的一些修改将不会被复制(例如输入上的name属性)。

由于解释的原因,在IE中不能工作的示例。我们应该修改jQuery的方法“clone”以在IE中使用这个功能

修改

好的,对不起,现在我理解了这个问题,但是从我看到的以及你在“clonedElement_2”中可以查看的内容是“cloneNode”的限制。 我唯一能想到的是改变“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>