【问题标题】:Event Handlers On Newly Created Elements新创建元素上的事件处理程序
【发布时间】:2013-06-15 15:23:20
【问题描述】:

我有一个带有许多文本区域的网络应用程序,如果您愿意,可以添加更多内容。

当您将焦点从一个 textarea 转移到另一个 textarea 时,焦点所在的动画会变大,其余的会缩小。

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

但是!当您这样做时,它会查询与您添加新元素一样多的次数。因此,如果您快速添加(例如 10 个)新的 textarea,那么下次您将注意力放在任何 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;
}

【问题讨论】:

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


    【解决方案1】:

    您应该使用以下内容:

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

    由于textarea是动态添加的,所以需要使用event delegation来注册事件处理函数。

    【讨论】:

    • 谢谢,非常感谢活动委托链接
    【解决方案2】:

    试试

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

    【讨论】:

      【解决方案3】:

      问题是您仅在页面加载时绑定文本区域。我用工作代码制作了一个 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();
      

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

      这个函数被调用的地方是在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(); 行。这会重新加载所有点击处理程序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-15
        • 1970-01-01
        • 2013-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多