新创建的元素上的事件处理程序

时间:2013-06-19 07:32:32

标签: javascript jquery web-applications user-interface web

我有一个带有多个textareas的网络应用程序,如果您愿意,还可以添加更多内容。

当您将焦点从一个textarea转移到另一个textarea时,焦点中的焦点会变为更大的尺寸,其余的会缩小。

当页面加载时,它会完美地处理html文件中最初四个框的动画,但是当你点击按钮添加更多textareas时,动画无法容纳这些新元素......也就是说,除非你放置函数中的初始查询,并从与按钮绑定的addelement函数调用该函数。

但是!当你这样做时,它会在添加新元素时多次查询。所以,如果你快速添加,比方说10,新的textareas,下次你专注于任何textarea时,查询运行10次。

我的设计或jQueries实现中存在问题吗?如果是前者,我可以更好地设计它,如果是后者,我该如何解决它呢?

我试图将代码切换到相关位...我已经尝试了从焦点和模糊到按键的所有内容,最新的是点击。

HTML ::

<html>
<head>
    <link rel="stylesheet" type="text/css" href="./sty/sty.css" />      
    <script src="./jquery.js"></script>
<script>
    $().ready(function() {
        var $scrollingDiv = $("#scrollingDiv");

        $(window).scroll(function(){            
            $scrollingDiv
                .stop()
                //.animate({"marginTop": ($(window).scrollTop() + 30) + "px"}, "slow" );            
                .animate({"marginTop": ($(window).scrollTop() + 30) + "px"}, "fast" );          
        });
    });
</script>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>boxdforstacks</title>
</head>
<body>
    <div class="grid">

        <div class="col-left" id="left">
                        <div class="module" id="scrollingDiv">
            <input type="button" value="add" onclick="addele()" />
            <input type="button" value="rem" onclick="remele()" />
            <p class="display">The value of the text input is: </p>
            </div>
      </div> <!--div class="col-left"-->


        <div class="col-midd">
            <div class="module" id="top">
                            <p>boxa</p>
                            <textarea class="tecksd" placeholder="begin typing here..." id="boxa" ></textarea>
                            <p>boxb</p>
                            <textarea class="tecksd" placeholder="begin typing here..." id="boxb"></textarea>
                            <p>boxc</p>
                            <textarea class="tecksd" placeholder="begin typing here..." id="boxc"></textarea>
                            <p>boxd</p>
                            <textarea class="tecksd" placeholder="begin typing here..." id="boxd"></textarea>
      </div>
        </div> <!--div class="col-midd"-->
    </div> <!--div class="grid"-->

</body>
</html>
    <script type="text/javascript" src="boxd.js"></script> 

JS:

function onit(){
    $('textarea').on('keyup change', function() {
        $('p.display').text('The value of the text input is: ' + $(this).val());
    });

}
$('textarea').on("click",function(){
        //alert(this.id.substring(0,3));
        if ( this.id.substring(0,3)  == 'box' ){
                        $('textarea').animate({ height: "51" }, 1000);
                        $(this).animate({ height: "409" }, 1000);
        } else {
                        $('textarea').animate({ height: "51" }, 1000);
        }
}
    );
var boxfoc="";
var olebox="";
var numb = 0;
onit();

function addele() {

  var tops = document.getElementById('top');
    var num = numb + 1;
    var romu = romanise(num);

  var newbox = document.createElement('textarea');
  var newboxid = 'box'+num;

  newbox.setAttribute('id',newboxid);
    newbox.setAttribute('class','tecksd');
    newbox.setAttribute('placeholder','('+romu+')');

  tops.appendChild(newbox);

    numb = num;
    onit();
} //addele(), add element




function remele(){

  var tops = document.getElementById('top');
  var boxdone = document.getElementById(boxfoc);
  tops.removeChild(boxdone);
} // remele(), remove element



function romanise (num) {
    if (!+num)
        return false;
    var digits = String(+num).split(""),
        key = ["","c","cc","ccc","cd","d","dc","dcc","dccc","cm",
               "","x","xx","xxx","xl","l","lx","lxx","lxxx","xc",
               "","i","ii","iii","iv","v","vi","vii","viii","ix"],
        roman = "",
        i = 3;
    while (i--)
        roman = (key[+digits.pop() + (i * 10)] || "") + roman;
    return Array(+digits.join("") + 1).join("M") + roman;
} // romanise(), turn numbers into roman numerals

css:

.tecksd {
    width: 97%;
    height: 51;
    resize: none;
    outline: none;
    border: none;
    font-family: "Lucida Console", Monaco, monospace;
    font-weight: 100;
    font-size: 70%;
    background: white;
/*  box-shadow: 1px 2px 7px 1px #0044FF;*/
}

.tecksded {
    width: 97%;
    resize: none;
    outline: none;
    border: none;
    overflow: auto;
    position: relative;
    font-family: "Lucida Console", Monaco, monospace;
    font-weight: 100;
    font-size: 70%;
    background: white;
/*  box-shadow: 1px 2px 7px #FFDD00;*/
}


/*#postcomp {
    width: 500px;
}*/


* {
  @include box-sizing(border-box);
}

$pad: 20px;

.grid {
  background: white;
  margin: 0 0 $pad 0;

  &:after {
    /* Or @extend clearfix */
    content: "";
    display: table;
    clear: both;
  }
}

[class*='col-'] {
    float: left;
  padding-right: $pad;
  .grid &:last-of-type {
    padding-right: 0;
  }
}
.col-left {
    width: 13%;
}
.col-midd {
    width: 43%;
}
.col-rght {
    width: 43%;
}

.module {
  padding: $pad;


}

/* Opt-in outside padding */
.grid-pad {
  padding: $pad 0 $pad $pad;
  [class*='col-']:last-of-type {
    padding-right: $pad;
  }
}

body {
    padding: 10px 50px 200px;
  background: #FFFFFF;
  background-image: url('./backgrid.png');

}
h1 {
  color: black;
    font-size: 11px;
    font-family: "Lucida Console", Monaco, monospace;
    font-weight: 100;
}
p {
  color: white;
    font-size: 11px;
    font-family: "Lucida Console", Monaco, monospace;
    font-weight: 100;
}

3 个答案:

答案 0 :(得分:2)

您应该使用以下内容:

// New way (jQuery 1.7+) - .on(events, selector, handler)
$(document).on("click", "textarea", function () {
    event.preventDefault();
    alert('testlink'); 
});

由于textarea是动态添加的,因此您需要使用event delegation来注册事件处理程序。

答案 1 :(得分:1)

尝试

$(document).on('click', 'textarea', function() {
    // do something
});

答案 2 :(得分:0)

问题是你只在页面加载时绑定textareas。我创建了一个带有工作代码的JSFiddle:http://jsfiddle.net/VpABC/

这是我改变的内容: 我包裹着:

$('textarea').on("click", function () {
        //alert(this.id.substring(0,3));
        if (this.id.substring(0, 3) == 'box') {
            $('textarea').animate({
                height: "51"
            }, 1000);
            $(this).animate({
                height: "409"
            }, 1000);
        } else {
            $('textarea').animate({
                height: "51"
            }, 1000);
        }
    });

在一个函数中,它看起来像这样:

function bindTextAreas() {
    $('textarea').unbind("click");
    $('textarea').on("click", function () {
        //alert(this.id.substring(0,3));
        if (this.id.substring(0, 3) == 'box') {
            $('textarea').animate({
                height: "51"
            }, 1000);
            $(this).animate({
                height: "409"
            }, 1000);
        } else {
            $('textarea').animate({
                height: "51"
            }, 1000);
        }
    });
}
bindTextAreas();

这样做是允许您在创建新的textarea时调用此函数bindTextAreas。这将取消绑定所有当前事件而不是重新绑定它们。这将使你的新textarea具有点击处理程序设置。

调用此函数的位置在addele函数中,如下所示:

function addele() {

    var tops = document.getElementById('top');
    var num = numb + 1;
    var romu = romanise(num);

    var newbox = document.createElement('textarea');
    var newboxid = 'box' + num;

    newbox.setAttribute('id', newboxid);
    newbox.setAttribute('class', 'tecksd');
    newbox.setAttribute('placeholder', '(' + romu + ')');

    tops.appendChild(newbox);

    numb = num;
    onit();
    bindTextAreas();
} //addele(), add element

注意底部附近的bindTextAreas();行。这会重新加载所有点击处理程序。