为focus()设置正确的上下文;

时间:2010-01-23 17:19:00

标签: javascript javascript-events

当我想应用focus()时,如何设置正确的上下文?

我尝试做的基本上是这样的:

elemnt = document.getElementById('someFormField');
elemnt.focus('none');

只有焦点调用才会在脚本中的其他位置生成,排队并在应用程序请求时应用。

function testIt() {
    var queued = {
          elementId: 'someFormField'
        , func: focus
        , args: ['none']};

    elemnt = document.getElementById(queued.elementId);

    queued.func.apply(elemnt, queued.args);
}

上述方法适用于其他功能,但对于焦点方法,我收到错误:

Opera: WRONG_THIS_ERR
Firefox: uncaught exception: [Exception... "Illegal operation on WrappedNative prototype object" (...)]



如何让这个工作?

(我正在努力理解这个问题,所以我对“使用框架X”答案不感兴趣)



更新
关于为什么我将参数传递给focus()似乎存在一些混淆:我只包括参数来证明将参数传递给focus()不会导致错误。

我也可以打字:

document.getElementById('someFormField').focus();



更新(2):
因为Anonymous的答案在IE6中不起作用,我现在使用中间函数来解决问题:

function testIt() {
    var queued = {
              elementId: 'someFormField'
            , func: setFocus
            , args: ['someFormField']};

    elemnt = document.getElementById(queued.elementId);

    queued.func.apply(elemnt, queued.args);
}

function setFocus(elemntId) {
    document.getElementById(elemntId).focus();
}

如果您的需求表中没有IE6兼容性,Anonymous's solution is the answer

2 个答案:

答案 0 :(得分:1)

为了避免让自己混淆什么功能做什么,我总是从闭包开始,直到我需要减少内存使用:

var dofocus = function(){element.focus()};
dofocus();

如果你处于循环中且element正在改变,你可以使用一个返回另一个函数的函数:(function(e,m){return function(){e[m]()}})(element, method)

编辑:在重新阅读问题时,我在想你的代码不起作用的原因是因为你传递了一个名为'focus'的变量的值,而不是字符串方法名称'焦点',或者更确切地说是焦点函数(它是在其他地方定义的吗?)

修改:这有效:

<html><title>test</title><script>
function foo (id, method, args) {
    var d = {"id": id, "method": method, "args": args};
    // ... time passes
    var e = document.getElementById(d.id); // test exists
    var f = e[d.method]; // test exists
    var a = d.args; // test is an array
    f.apply(e, a);
}
</script><body id="thebody">
<p>
    <button onclick="foo('bar', 'setSelectionRange', [4,6]);">select</button>
    <button onclick="foo('bar', 'focus',             []);">focus</button>
    <input type="text" id="bar" value="foo bar baz">
<p>
    <button onclick="foo('thebody', 'appendChild', [document.createTextNode(new Date())]);">body</button>
</body></html>

编辑:如果传递函数是个问题,你总是可以传递一个可选的方法名称并测试该方法是字符串还是函数,然后能够使用'焦点'或者自定义函数,无需将其放在元素上。

答案 1 :(得分:1)

阅读帖子here

从该线程中,我们了解到只使用“焦点”不起作用,如下:

focus.apply(document.getElementById('someElement'));​

(你正在尝试的一个简单的例子)因为“焦点”必须有一个它所绑定的元素。否则,它不是一个绑定函数,而只是一个没有真正引用的本机调用。我的猜测是,任何特定于元素的函数都会出现这种情况。

您需要做的是从目标元素或具有焦点功能的另一个DOM元素中获取焦点元素。例如,这将起作用:

var fn = document.createElement('input').focus;
fn.apply( document.getElementById('someElement') );