2016-05-03 8 views
0

折りたたみ可能なコンテンツを表示/非表示するために、ブートストラップ折りたたみプラグインに接続されたクリック可能なdivがあります。このdivの中には、ノックアウトサブミットハンドラを持つフォームがあります。フォームのsubmit-buttonをクリックすると、knockout submit-handlerの前にcollapseのクリックハンドラが呼び出されます。私の理解のようクリックハンドラがネストされたノックアウトフォーム送信ハンドラの前に呼び出される

<div data-toggle="collapse" data-target="#collapse1"> 
    ... 
    <form data-bind="submit: submitForm"> 
    <input type="number" /> 
    <input type="submit" /> 
    </form> 
</div> 

<div class="collapse" id="collapse1"> 
    ... 
</div> 

、崩壊のクリックハンドラは(あなたが崩壊データ-APIを見ている場合)の文書にバインドされ、ノックアウト提出-ハンドラはフォーム要素にバインドされています。送信ボタンをクリックするか(または入力でEnterキーを押す)、送信イベントが送信ハンドラに最初に到達すべきではありませんか?フォームの時点では、原点から最も近い親ですか?

$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e){ 
... 
}) 

私の質問:ノックアウトが提出ハンドラを前はなぜ崩壊のクリックハンドラが呼び出されましたか?

は、より良い例えばjsfiddle参照:https://jsfiddle.net/knekk/oocxfgmq/

答えて

0

あなたはDIV要素にトグルイベントをバインドしています。

はコード

あなたのイベントがバブリングさ

var viewModel = function() { 
 
    this.formSubmit = function(){ 
 
    \t alert('submit'); 
 
    }; 
 
    
 
    $('#collapse1').on('show.bs.collapse', function(e){ 
 
    \t alert('show content'); 
 
    }).on('hide.bs.collapse', function(e){ 
 
    \t alert('hide content'); 
 
    }); 
 
}; 
 

 
ko.applyBindings(new viewModel());
<div class="container"> 
 
    <div class="list-group-item list-group-item-danger" > 
 
    <div class="row form-inline"> 
 
     <div class="col-xs-6"> 
 
     <strong>Collapse</strong> 
 
     </div> 
 
     <div class="col-xs-6 text-right"> 
 
     <form data-bind="submit: formSubmit"> 
 
      <input type="number" /> 
 
      <input type="submit" role="button" data-toggle="collapse" data-target="#collapse1" /> 
 
     </form> 
 
     </div> 
 
    </div> 
 
    </div> 
 

 
    <!-- Collapse content --> 
 
    <div class="collapse" id="collapse1"> 
 
    <p> 
 
    Lorem ipsum dolor sit amet, cum etiam labitur diceret id, ex sale omnium neglegentur cum. Ad nec eirmod definiebas argumentum, eam te oratio disputando. In errem volumus cum, virtute platonem persequeris ei quo. Ex has reformidans consequuntur. Consetetur cotidieque et mea, in qui bonorum blandit. 
 

 
Nemore essent his an. Te hinc wisi consulatu usu, fuisset conceptam ius cu. Eam id mazim altera argumentum. At ridens moderatius his, in posse tollit moderatius vim, in vel dico recteque. Cum illum dissentias in, ex stet aliquip salutatus eum. 
 
    </p> 
 
    </div> 
 
</div>

+0

私は申し訳ありませんが、それは私でした古いフィドルバージョン。私はjsfiddleを更新しました。また、divをクリックすると折り畳みを開くことができるはずです。私の質問は、なぜサブミットイベントがクリックイベントの後に発生するのかです。 – Knekki

+1

IE <9以外のすべてのブラウザでは、2つのステージのイベント処理があります。 イベントが最初にダウンします。これはキャプチャと呼ばれ、その後バブルアップします。この動作は、W3C仕様では標準化されています。 W3C要素イベントは がダウンキャプチャ注文 - >「子」 - - >「グランド・チャイルド」 バブルアップ - 「グランド・チャイルド」を通して - >「子」 - 「親」を通じて>「親」 –

+0

はい確かに、その後、最初にサブミットハンドラを呼び出すべきではないでしょうか?最初の提出の最も近い親として/クリック?折りたたみプラグインを見ると、clickハンドラはdivにではなくドキュメントにアタッチされますか? submitイベントが発生する前にクリックイベントが発生してドキュメントに到達していますか? – Knekki

0

上に試してみてください。 JQueryは、あなたのKOが別のものを発射しているdivにイベントをバインドしています。だからjquery>ノックアウト、クリックイベントの特定の順序で。

http://knockoutjs.com/documentation/click-binding.html

また、CSSでそれを "ハック"、および崩壊要素の上にフォームを移動できます。

var viewModel = function() { 
 
    this.formSubmit = function() { 
 
    alert('submit'); 
 
    }; 
 

 
    $('#collapse1').on('show.bs.collapse', function(e) { 
 
    alert('show content'); 
 
    }).on('hide.bs.collapse', function(e) { 
 
    alert('hide content'); 
 
    }); 
 
}; 
 

 
ko.applyBindings(new viewModel());
.container { 
 
    position: relative; 
 
} 
 
form { 
 
    position: absolute; 
 
    top: 7px; 
 
    right: 80px; 
 
    z-index: 1; 
 
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet" /> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/js/bootstrap.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<div class="container"> 
 
    <form data-bind="submit: formSubmit"> 
 
    <input type="number" /> 
 
    <input type="submit" /> 
 
    </form> 
 
    <div class="list-group-item list-group-item-danger" role="button" data-toggle="collapse" data-target="#collapse1"> 
 
    <div class="row form-inline"> 
 
     <div class="col-xs-6"> 
 
     <strong>Collapse</strong> 
 
     </div> 
 
    </div> 
 
    </div> 
 

 
    <!-- Collapse content --> 
 
    <div class="collapse" id="collapse1"> 
 
    <p> 
 
     Lorem ipsum dolor sit amet, cum etiam labitur diceret id, ex sale omnium neglegentur cum. Ad nec eirmod definiebas argumentum, eam te oratio disputando. In errem volumus cum, virtute platonem persequeris ei quo. Ex has reformidans consequuntur. Consetetur 
 
     cotidieque et mea, in qui bonorum blandit. Nemore essent his an. Te hinc wisi consulatu usu, fuisset conceptam ius cu. Eam id mazim altera argumentum. At ridens moderatius his, in posse tollit moderatius vim, in vel dico recteque. Cum illum dissentias 
 
     in, ex stet aliquip salutatus eum. 
 
    </p> 
 
    </div> 
 
</div>

+0

要素自体にバインドされた誤解を招くリスナーのjsfiddleを更新しました。折りたたみプラグイン(更新されたjsfiddleに表示されています)を見ると、クリックハンドラが要素自体ではなくドキュメントにバインドされていることがわかります。イベントは実際にバブリングしていますが、送信ボタンをクリックするとノックアウトのサブミットイベントが最初に起動されるべきではありませんか?サブミットハンドラは要素にバインドされており、元の親から最も近い親にバインドされているので、 – Knekki

+0

これはhttp://javascript.info/tutorial/bubbling-and-capturingを明確にするのに役立ちます。 – kasperoo

関連する問題