0

多数のテキストエリアを備えた Web アプリがあり、必要に応じてさらに追加することができます。

あるテキストエリアから別のテキストエリアにフォーカスを移すと、フォーカスのあるテキストエリアがより大きなサイズにアニメーション化され、残りは縮小されます。

ページが読み込まれると、html ファイルの最初の 4 つのボックスのアニメーションは完全に処理されますが、ボタンをクリックしてテキスト領域を追加すると、アニメーションはこれらの新しい要素に対応できません... つまり、最初のクエリを配置しない限り、関数で、ボタンに関連付けられた addelement 関数からその関数を呼び出します。

しかし、これを行うと、新しい要素を追加した回数だけクエリが実行されます。したがって、たとえば 10 個の新しいテキストエリアをすばやく追加すると、次にテキストエリアにフォーカスを置いたときに、クエリが 10 回実行されます。

問題は設計の問題ですか、それとも jQuery の実装ですか? 前者の場合、どのように設計すればよいでしょうか、後者の場合、どのように回避できますか?

コードを関連するビットに切り詰めようとしました...フォーカスとぼかしからキープレスまで、すべてを試しました。最新のものはクリックです。

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;
}
4

3 に答える 3

2

以下を使用する必要があります。

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

は動的に追加されるため、イベント委任を使用してイベント ハンドラーを登録するtextarea必要があります。

于 2013-06-19T07:36:46.323 に答える
1

試す

$(document).on('click', 'textarea', function() {
    // do something
});
于 2013-06-19T07:36:40.013 に答える
0

問題は、ページの読み込み時にのみテキストエリアをバインドしていることです。作業コードで 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();下部近くの線に注目してください。これにより、すべてのクリック ハンドラーがリロードされます。

于 2013-06-19T07:51:56.733 に答える