0

AJAX 経由で読み込まれたプレースホルダー テキストを含むテキストエリアがいくつかあります。フォーカス時にテキストを非表示にしたいので、フォーカス イベントをクラスに委任しました。テキストエリアをクリックするとフォーカスイベントが発生し、他の入力要素へのクリック/タブ移動でも発生します。しかし、テキストエリアにタブで移動しても機能しません。この動作は、すべてのブラウザーで一貫しています。これが私がやっていることです。

$('#forms-container').delegate('.hasInstructions', 'focus', clearInstructions)

hasInstructionsプレースホルダーテキストを持つ入力要素のクラスです。

以下のようにイベントをテキストエリアに直接バインドすると、問題なく動作します。

<textarea class="hasInstructions" onfocus="clearInstructions()">foo</textarea>

だから私の質問は、テキストエリアのフォーカスイベントがバブルアップしていませんか? もしそうなら、これを達成するための最良の方法は何ですか?

編集:質問した後に質問を変更する方法はあまり好きではないことはわかっています。MikeD の回答は元の質問に対して完全に有効であり、より良い質問が得られない場合は受け入れます。これが問題です

私はjQuery 1.4.2を使用していますが、ライブラリをページに出荷していないため、より高いバージョンを使用できません。ブラウザーの互換性の理由から、HTML5 プレースホルダーを使用することはできません。

4

1 に答える 1

3

あなたはそれがデリゲートで動作しないことはかなり正しいです。これはおそらくここに示した理由によるものですが、それは単なる推測です。いくつかの推奨される回避策を次に示します。

jQueryなし

このブログエントリで説明されているように、イベントバブリングの代わりにイベントキャプチャを使用してこの作業を行うことができます(IEのサポートについては、以下の警告を参照してください)。

次のHTMLで...

<p id='parent'>
    Enter some values:<br/>
    <input type='text' id='requiredValue'/>
    <input type='text'/>
</p>
<div id='output'>
</div>

...このJavaScriptは、正しい場所でキャッチされているイベントを表示します。

var outputDiv = document.getElementById('output'),
    parentDiv = document.getElementById('parent'),
    inputDiv = document.getElementById('requiredValue');

parentDiv.addEventListener('focus', function() {
    outputDiv.innerHTML = outputDiv.innerHTML + "<p>parent</p>";
}, true);
inputDiv.addEventListener('focus', function() {
    outputDiv.innerHTML = outputDiv.innerHTML + "<p>input</p>";
}, true);

IEでこれを機能させる

イベントキャプチャはIEでは機能しませんが、上記のブログでは、IEが必要なことを実行するフォーカスインイベントとフォーカスアウトイベントをサポートしていることがわかります。

これは、さらに2つのイベントハンドラーを追加することで、すべての場合にこのシナリオを処理できることを意味します。

parentDiv.onfocusin = function() {
    outputDiv.innerHTML = outputDiv.innerHTML + "<p>parent</p>";
};
inputDiv.onfocusout = function() {
    outputDiv.innerHTML = outputDiv.innerHTML + "<p>input</p>";
};

最新バージョンのjQueryを使用する

この機能は、「on」関数を使用して期待どおりに機能します。

.on(events [、selector] [、data]、handler(eventObject))

'on'の関数パラメーターでセレクターを指定することは、'on'がイベント委任を使用することを意味します。ドキュメントから:

セレクターが提供されている場合、イベントハンドラーは委任されたものと呼ばれます。イベントがバインドされた要素で直接発生した場合、ハンドラーは呼び出されませんが、セレクターに一致する子孫(内部要素)に対してのみ呼び出されます。jQueryは、イベントターゲットからハンドラーがアタッチされている要素(つまり、最も内側の要素から最も外側の要素)までイベントをバブルし、セレクターに一致するパスに沿ったすべての要素に対してハンドラーを実行します。

次のHTMLの場合

<p id='parent'>
    Enter some values:<br/>
    <input type='text' class='requiredValue'/>
    <input type='text'/>
</p>

以下のJavaScriptコードは期待どおりに機能します

$(document).ready(function() {
    var initialText = "Enter a value";
    $('.requiredValue').val(initialText);

    $('#parent').on('focus', '.requiredValue', function() {
        var contents = $(this).val();
        if (contents === initialText) {
            $(this).val("");
        }
    });

    $('#parent').on('blur', '.requiredValue', function() {
        var contents = $(this).val();
        if (contents.length == 0) {
            $(this).val(initialText);
        }
    });
});

HTML5テクニック

HTML 5に準拠したより優れた手法は、ここにあります。ブログから:

<input type="text" name="first_name" placeholder="Your first name...">

必要なのは、選択した一般的なテキストでプレースホルダー属性を追加することだけです。この効果を作成するのにJavaScriptが必要ないのはいいですね。

プレースホルダーは新しい機能であるため、ユーザーのブラウザーでサポートを確認することが重要です。

function hasPlaceholderSupport() {
    var input = document.createElement('input');
    return ('placeholder' in input);
}

ユーザーのブラウザがプレースホルダー機能をサポートしていない場合は、MooTools、Dojo、または選択したJavaScriptツールキットでフォールバックを使用する必要があります。

/* mootools ftw! */
var firstNameBox = $('first_name'),
message = firstNameBox.get('placeholder');
firstNameBox.addEvents({
    focus: function() {
        if(firstNameBox.value == message) { searchBox.value = ''; }
    },
    blur: function() {
        if(firstNameBox.value == '') { searchBox.value = message; }
    }
});
于 2012-10-19T09:38:44.280 に答える