在textarea上的委托焦点事件没有触发对元素的标签

时间:2012-10-19 08:46:02

标签: jquery focus textarea keyboard-events event-delegation

我有一些textareas,其中一些占位符文本通过AJAX加载。我希望文本在焦点上消失,所以我将焦点事件委托给了一个类。如果我单击textarea并在单击/ Tabbing到其他输入元素时触发焦点事件。但是当我选择到textarea时,它不起作用。此行为在所有浏览器中都是一致的。这就是我正在做的事情。

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

hasInstructions是我的输入元素上的类,带有占位符文本。

当我将事件直接绑定到textarea时,它可以正常工作。

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

所以我的问题是,textareas上的焦点事件是不是已经冒出来了?如果是这样,我能做到这一点的最佳方式是什么?

编辑:我知道在提出问题之后改变问题的方式并不是真的。 MikeD的答案完全适用于原始问题,如果我没有得到更好的答案,我会接受它。所以这就是事情,

我正在使用jQuery 1.4.2并且我无法使用更高版本,因为我没有将库发送到页面。出于浏览器兼容性原因,我无法使用HTML5占位符。

1 个答案:

答案 0 :(得分:3)

你是完全正确的,它不适用于委托。这很可能是由于reasons given here,但这只是猜测。以下是一些建议的解决方法。

没有jQuery

你可以使用事件捕获而不是事件冒泡来使这项工作成为discussed in this blog entry(对于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支持focusin和focusout事件,它们可以满足您的需求。

这意味着通过添加两个事件处理程序,您可以在所有情况下处理此场景:

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

HTML 5技术

符合HTML 5的更好技术can be found here。来自博客:

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