1

1 つの水平線に次の DOM 要素があります。

  1. テキスト行を含む div。つまり、「ハローワールド」です。この div の幅は、含まれるテキストと同じです。
  2. 2 つの div を入れ替えるボタン。
  3. リストボックスを含む div。この div の幅は、含まれているリストボックスと同じです。

floatまたはI を使用position:absoluteすると、これらの要素を 1 行に正しく配置できます。ただし、ユーザーがスワップ ボタンをクリックすると、div は場所を交換する必要があります。DOM から div を削除したり、互いの場所に再度追加したりしたくありません。これは、要素が実際には Javascript オブジェクト (具体的には Google Closure Library コンポーネント) であり、変数を保持し、イベント ハンドラーが関連付けられているためです。div に静的な幅を割り当てずに、CSS を使用して div を交換することは可能ですか?

簡単な例:

<div style="position:relative; height:60px;">
  <div style="float:left;">Our Team</div>
  <div style="float:left;"><button onclick="swap();">swap home/away</button></div>
  <div style="float:left;"><select><option>Opponent A</option><option>Opponent B</option></select></div>
</div>
<div style="clear:both;"></div>

ユーザーがボタンをクリックすると、できれば DOM から要素を削除せずに、最初 (私たちのチーム) と 3 番目 (対戦相手) の div がブラウザーで視覚的に交換されます。

4

3 に答える 3

4

DOM から div を削除したり、互いの場所に再度追加したりしたくありません。これは、要素が実際には Javascript オブジェクト (具体的には Google Closure Library コンポーネント) であり、変数を保持し、イベント ハンドラーが関連付けられているためです。

最善の解決策は、代わりに DOM 内の要素を移動することです。これを行うと、既存のイベント ハンドラーが保持されます。つまり、コードは引き続き機能するはずです。

http://jsfiddle.net/thirtydot/LGGW2/

function swap() {
    var target1 = document.querySelector('#swapMe > :first-child');
    var target2 = document.querySelector('#swapMe > :last-child');

    var parent = target1.parentNode;
    parent.insertBefore(target1, null);
    parent.insertBefore(target2, parent.firstChild);
}​

交換したい要素への参照が既にあると仮定しているので、document.querySelector行を適切なものに置き換えることができます。

この回答を書いた後、より一般的な「スワップ」関数を検索したところ、見栄えの良いこれが見つかりました: Swap 2 html elements and preserve event listeners on them

于 2012-11-26T13:03:14.120 に答える
1

HTML両方の div が同じ(style="float:left;")であるclassか、どちらでもない両方の dividのみを交換できます。HTML

function swap(e)
{
    e  = e || window.event, target = e.target || e.srcElement;
    var nEl=getElem(target.parentNode, 'next');
    var pEl=getElem(target.parentNode, 'prev');
    var pElHtml=pEl.innerHTML, nElHtml=nEl.innerHTML;
    pEl.innerHTML=nElHtml;
    nEl.innerHTML=pElHtml;
}

function getElem(elem, which) {
    if(which==='next') which='nextSibling';
    else if((which==='prev')) which='previousSibling'; 
    do{
        elem = elem[which];
    }
    while (elem && elem.nodeType != 1);
    return elem;        
}​

デモ

于 2012-11-26T12:20:53.140 に答える
0

あなたの問題に対するいくつかの解決策があります。1つまたは2つはあなたのスタイルに関係しています. 私があなただったら、(javascript によって追加されない限り) インライン スタイルを削除し、すべての「フローティング」要素に同じクラスを追加します。

より更新されたブラウザーの場合、これは完全に機能します。

.floaters{
    display:inline-block;
}

ただし、古いブラウザー (つまり、5.5、6、7、8) の場合は、適用する必要があります。

.floaters{
    display:inline;
    float:left;
    height:60px;/*set a default height*/
}

swap();機能のために。これをどのように適用するかはわかりませんが、要素を変更して要素を交換しますinnerHTML();

function swap(){
    var ele1HTML = document.getElementById('ele1').innerHTML();
    var ele3HTML = document.getElementById('ele3').innerHTML();
    document.getElementById('ele1').innerHTML(ele3HTML);
    document.getElementById('ele3').innerHTML(ele1HTML);
}

ただし、上記の次のコードでは、ID 属性を div に追加する必要があります。次に例を示します。

<div id="menu">
  <div id="ele1" class="floater">
      Our Team
  </div>
  <div id="ele2" class="floater">
      <button onclick="swap();">swap home/away</button>
  </div>
  <div id="ele3" class="floater">
      <select>
          <option>Opponent A</option>
          <option>Opponent B</option>
      </select>
  </div>
</div>
<div id="anotherDiv"></div>

ただし、スタイルを再適用することを忘れないでください。

#menu{
    position:relative;
    height:60px; /*not needed for the older browser as I've set the child elements to 60px;*/
}
#anotherDiv{
    clear:both;
}
于 2012-11-26T12:20:53.347 に答える