jQuery: 克隆元素和事件

20
每当我使用ajax动态创建新内容时,.clone(),append()等,新元素会丢失我编程的任何触发器和事件=(
复制后,简单的事情在其他元素上起作用(比如添加一个类到),在复制的元素上不再起作用。任何新的ajax内容都不起作用。命令按钮不再起作用。我该怎么办?
我正在克隆这个HTML,命令按钮不再起作用。在克隆的元素上不再起作用的是样式化的span元素。
<div name="shows" id="x"><br/> <!-- The ID depends on the database-->
    <div name="shows" id="x">
        ID: <input disabled="disabled" size="7" value="x" name="id" />
        Status: 
        <select name="status" >
          <option selected="selected" >Display</option>
          <option >Hide</option>
        </select>
        <br/><br/>
        <span class="required" id="date_txt">*Date: </span><input type="text" value="" name="date" />
        &nbsp;&nbsp;
        <span class="required" id="title_txt">*Title: </span><input type="text" size="65" value="" name="title" />
        <br/>
        <span class="required" id="venue_txt">*Venue: </span><input type="text" size="45" value="" name="venue" />
        Telephone: <input type="text" value="" name="tel" />
        <br/>
        URL: <input type="text" size="100" value="" name="url" />
        <br/><br/>
        Address: <input type="text" size="45" value="" name="address" />
        &nbsp;&nbsp;
        <span class="required" id="city_txt">*City: </span><input type="text" value="" name="city" />
        <br/>
        State: <input type="text" value="" name="state" />
        ZIP: <input type="text" value="" name="zip" />
        <span id="country_txt">*Country: </span><input type="text" value="United States" name="country" />
        <br/>
        <br/>Comments: <br/>
        <textarea cols="80" rows="8" name="comments" ></textarea>
    </div>
    <!-- START OF:commands  -->
    <div id="commands" >
        <button name="edit" id="edit" >Edit</button> 
        <button name="delete" id="delete" >Delete</button>
    <br />
    <hr />
    <br />
    </div>
    <!-- END OF:commands  -->
</div>
<!-- END OF:new -->

新的评论已添加,11/03/2011:
好的,我找到了问题所在,我的jQuery代码出错了。现在,当我添加.clone( true )时,几乎一切都正常工作。
我的新问题是UI日期选择器。 在克隆HTML后,当我点击新克隆的日期字段时,焦点会转移到克隆数据的(旧)日期字段上。而且,如果我选择一个日期,值会被发送到旧日期字段,而不是新克隆的日期字段。

这是我的ajax代码(成功提交后):

UI日期选择器代码:

$("input[name='date']").datepicker({ dateFormat: 'yy-mm-dd', changeMonth: true, changeYear: true, numberOfMonths: 3, showButtonPanel: true});

Ajax:
    ...ajax code...
function(data)
{
var $msg = eval(data);
if( $msg[0] == 1 )
    {
    //#var.new
        $id = '#'+$msg[1];
        $data = $("#new");
    $new = $data.clone(true);
    $new.find('input.datefield').datepicker();


        $new.attr("id", $id);
        $new.children('[name="id"]').val($id);
        $new.children('[name="id"]').attr("value", $id);
        $new.children(":input").each(function() { var $value = $(this).val(); $(this).attr("value", $value); });
        $new.prepend( "<br/>" );

        $commands = $("#blank").children("#commands").clone(true);
        $commands.children("#add").text("Update");
        $commands.children("#add").attr("pk", $id);
        $commands.children("#add").attr("name", "update");
        $commands.children("#add").attr("id", "update");

        $commands.children("#reset").text("Delete");
        $commands.children("#reset").attr("pk", $id);
        $commands.children("#reset").attr("name", "delete");
        $commands.children("#reset").attr("id", "delete");

        $new.append( $commands );

        //#animation
        //blank.slideUp
        $("#blank").slideUp(2500, function(){
        $("#ADDNEW").html("&#9658; New:");
        //$("#blank").clone().prependTo( $("#active") );
        //$("#blank").prependTo( "#active" );

        //active.slideUp
        $("#active").slideUp("slow", function(){
        $("#ON").html("&#9658; Active:");
        $("#active").prepend( $new );
        $('#reset').trigger('click');

        //active.slideDown
        $("#active").slideDown(8500, function(){
        $("#ON").html("&#9660; Active:");
        
        //blank.slideDown
        $("#blank").slideDown(3500, function(){
        $("#ADDNEW").html("&#9660; New:");
        load_bar(0);

        }); //end: anumation.#blank.slideDown
        }); //end: anumation.#active.slideDown
        }); //end: anumation.#blank.slideUp
        }); //end: anumation.#active.slideUp
        
        //$("#new").fadeOut(2000, function(){
        //START: blank
        //alert( $("#blank").html() );
        //$dad = $("#new");
        //$dad.children('input[name!="id"][name!="country"], textarea').val('');
        //$dad.children('[name="country"]').val("United States");
        //$dad.children('[name="date"]').focus();
        //END: blank
        //$("#new").fadeIn(2000, function(){
        //alert( $msg );
        //}); //end: anumation.fadeIn
        //}); //end: anumation.fadeOut
        } //end: if
    else
        {
        //var varMSG = data;
        //alert( "Hello" );
        alert( $msg );
        
        //$("#add").attr("disabled", false);
        //$("#reset").attr("disabled", false);
        load_bar(0);
        } //end: if.else
    }//end: $.post.function
); //END:$.post
}); 
//END:ajax

1
你能发一些JavaScript的示例代码吗? - rossipedia
以上的HTML是替换已经在页面上存在的内容还是添加到它上面?因为任何使用元素ID的JS如果您正在添加具有相同ID的其他副本,则不会正常工作(例如,button上的id =“edit”)。请展示您的JS。 - nnnnnn
“不再工作”是什么意思? - RobG
4个回答

51

我使用了 .clone(true) 但仍然不起作用。根据输入的更改,span 元素应该更改颜色(切换类 .required)。但是它们没有。 - Omar
@Omar,你可以发布一下克隆并附加这些元素的JavaScript代码吗? - Šime Vidas
1
从他的问题听起来,他应该选择clone(true, true) - hugomg
2
@missingno 不需要两次使用 true,因为第二个参数的值默认与第一个参数的值匹配... - Šime Vidas

1

你好,我有一个类似的用例,我有一些动态生成的内容,其中包含一个按钮,点击事件响应原始按钮而不是生成的按钮,我之前做过:

$('.someclass').on('click', function() {

但我通过将 "on" 替换为 "live" 来解决了我的问题,就像这样:

$('.someclass').live('click', function() {

太棒了!.live方法对我有用。我试过.clone(true)但是无法弄清楚如何或在哪里使用。谢谢! - FrankDraws
1
注意,自jQuery 1.7版本起,.live()已被弃用。参考:https://api.jquery.com/live/ - UncaughtTypeError

0

我终于成功地让UI日期选择器正常工作了。在克隆元素之前,我不得不完全删除日期选择器,然后在克隆元素之后再添加它。UI的开发人员应该让这更容易些。想想看!

在克隆之前:

//#datepicker
$("input[name='date']").datepicker( "destroy" );
$("input[name='date']").removeClass("hasDatepicker").removeAttr('id');

克隆之后:

$("input[name='date']").datepicker({ dateFormat: 'yy-mm-dd', changeMonth: true, changeYear: true, numberOfMonths: 3, showButtonPanel: true});

0
如果您的处理程序是使用以下方式设置的: $('.class').click( ... )
请尝试改用以下方式: $('.class').live('click', ...)
Live适用于可能尚不存在的具有该类的元素。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接