【问题标题】:Delegated focus event on textarea not fired on tabbing to the elementtextarea 上的委派焦点事件未在元素的选项卡上触发
【发布时间】:2012-10-09 20:21:25
【问题描述】:

我有一些文本区域,其中包含一些通过 AJAX 加载的占位符文本。我希望文本在焦点上消失,所以我将焦点事件委托给一个类。如果我单击文本区域,则会触发焦点事件,并且还会在单击/切换到其他输入元素时触发焦点事件。但是当我标签到 textarea 时它不起作用。这种行为在所有浏览器中都是一致的。这就是我正在做的事情。

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

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

当我将事件直接绑定到文本区域时,它工作得很好。

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

所以我的问题是,文本区域上的焦点事件不是冒泡了吗?如果是这样,我可以实现这一目标的最佳方法是什么?

编辑:我知道在提出问题后改变问题的方式并不像这样。 MikeD 的回答对原始问题完全有效,如果我没有得到更好的答案,我会接受。事情就是这样,

我使用的是 jQuery 1.4.2,我不能使用更高版本,因为我没有将库发送到页面。出于浏览器兼容性的原因,我不能使用 HTML5 占位符。

【问题讨论】:

  • #forms-container 是静态元素吗?不能用占位符属性吗?
  • @undefined - 是的,forms-container 是一个静态元素。我不能使用占位符属性,因为旧浏览器不支持它,而且我不能使用模拟它们的 jquery 插件。
  • @toofast 我已经更新了我的答案。看看这是否适合你。

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


【解决方案1】:

您说得对,它不适用于委托。这很可能是由于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( 事件 [, 选择器] [, 数据], 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; }
    }
});

【讨论】:

  • 感谢您的回复,但是我不能使用最新版本的jQuery。我用的是1.4.2,也不能用浏览器不兼容的方式。
  • 当您确认在更高版本的 jQuery 中使用 on 函数有效时,我正在研究它是如何工作的。但所有这些都没有任何意义(可能是因为我忙于许多其他任务)。您的答案和博客链接都非常有帮助。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2020-07-07
  • 1970-01-01
  • 1970-01-01
  • 2011-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多