Javascript 一组单选按钮上的onfocus事件如何像单个控件一样工作?

Javascript 一组单选按钮上的onfocus事件如何像单个控件一样工作?,javascript,html,javascript-events,Javascript,Html,Javascript Events,考虑以下HTML和JavaScript,也在这里: 无标题页 var i=0; 函数_focus(){ var message=document.getElementById(“消息”); message.value=message.value+++i++“.Focus\r\n”; } 函数_blur(){ var message=document.getElementById(“消息”); message.value=message.value+++i++“.Blur\r\n”; }

考虑以下HTML和JavaScript,也在这里:


无标题页
var i=0;
函数_focus(){
var message=document.getElementById(“消息”);
message.value=message.value+++i++“.Focus\r\n”;
}
函数_blur(){
var message=document.getElementById(“消息”);
message.value=message.value+++i++“.Blur\r\n”;
}


我想要的行为如下:

  • 第一次单击aqua div区域中的任何位置时(无论是否单击单选按钮),都会触发onfocus事件
  • 在aqua div中单击后,如果在其他位置单击,则会触发onblur事件
  • 每当您在aqua div区域内的任何位置多次单击时,即使从一个单选按钮单击到另一个单选按钮,也不应触发任何事件
它在Chrome中似乎运行良好,但在Firefox8或IE9中却不行

关于如何修复代码以使其正常工作,有什么建议吗

谢谢,
Stephen

只有一些元素可以被聚焦,例如,我讨厌使用计时器,因为它们非常粗糙,我想出了一个解决方案,使用计时器

这是如何工作的,它使用一个定时器来调用模糊事件,并在我将焦点放回某个单选按钮或包含单选按钮的div时取消定时器

<!DOCTYPE html>
<html>
<head>
    <title>Untitled Page</title>
<script type="text/javascript">
  var i = 0;

  var focused = false;

  var blurTimer = null;

  function startBlurTimer() {
    blurTimer = window.setTimeout("blurTimerFinished()", 1);
  }

  function cancelBlurTimer() {
    if (blurTimer != null) {
      clearTimeout(blurTimer);
      blurTimer = null;
    }
  }

  function blurTimerFinished() {
    cancelBlurTimer();
    focused = false;
    var message = document.getElementById("message");
    message.value = message.value + ++i + ". Blur\r\n";
  }

  function _focus() {
    if (blurTimer == null) {
      focused = true;
      var message = document.getElementById("message");
      message.value = message.value + ++i + ". Focus\r\n";
    }
    else
      cancelBlurTimer();
  }

  function _blur() {
    if (focused) {
      startBlurTimer();
    }
  }  
</script>
</head>
<body>
<div style="background-color: Aqua; width: 100px; height: 50px" onfocus="_focus()" onblur="_blur()" tabindex="0">
  <input onfocus="_focus()" onblur="_blur()" name="rb" type="radio" /><br />
  <input onfocus="_focus()" onblur="_blur()" name="rb" type="radio" />
</div>
<br />
<textarea id="message" rows="15" cols="50"></textarea>
</body>
</html>

无标题页
var i=0;
var=false;
var-timer=null;
函数startBlurTimer(){
blurTimer=window.setTimeout(“blurTimerFinished()”,1);
}
函数取消计时器(){
如果(blurTimer!=null){
清除超时(模糊定时器);
模糊定时器=空;
}
}
函数blurTimerFinished(){
取消计时器();
聚焦=假;
var message=document.getElementById(“消息”);
message.value=message.value+++i++“.Blur\r\n”;
}
函数_focus(){
如果(blurTimer==null){
专注=正确;
var message=document.getElementById(“消息”);
message.value=message.value+++i++“.Focus\r\n”;
}
其他的
取消计时器();
}
函数_blur(){
如果(聚焦){
startBlurTimer();
}
}  



另一种解决方案

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <title></title>
</head>
<body onload="test()">
    <input>
    <div style="background-color: Aqua; width: 100px; height: 50px" id='area'>
        <input id="rb1" name="rb" type="radio">Foo<br>
        <input id="rb2" name="rb" type="radio">Bar
    </div>
    <input>
    <pre id='dump'></pre>
    <script type='text/javascript'>
'use strict';
function dump(data) {
    document.getElementById('dump').appendChild(document.createTextNode(data + '\n'));
}

function addEvent(node, evtType, callback)
{
    if('addEventListener' in node)
        node.addEventListener(evtType, callback, false);
}

function removeEvent(node, evtType, callback)
{
    if('removeEventListener' in node)
        node.removeEventListener(evtType, callback, false);
}    

function addHandler(element, focus, blur)
{
  var event = {
    focused: false,
    element: element,
    focus: focus,
    blur: blur,
    onClick: function(e) {
      event.targetNode(e).focus();  // Because Chrome doesn't focus when clicked
    },
    onFocus: function(e) {
      if (event.focused)
        return;

      event.focused = true;

      addEvent(document, 'click', event.onBlur);
      addEvent(document, 'keyup', event.onBlurIfTab);

      focus();
    },
    onBlur: function(e) {
      if (!event.focused)
        return;
      if (event.thisElement(event.targetNode(e)))
        return;

      event.focused = false;
      removeEvent(document, 'click', event.onBlur);
      removeEvent(document, 'keyup', event.onBlurIfTab);

      blur();
    },
    onBlurIfTab: function(e) {
      if (e.keyCode === 9) { event.onBlur(e) }
    },
    targetNode: function(e) {
      return 'target' in e ? e.target : e.srcElement;
    },
    thisElement: function(node) {
      // Test to see if we're on the element node
      while (node) {
        if (node == event.element) {
          return true;
        }
        node = node.parentNode;
      }
      return false;
    },
    findButtons: function() {
      var buttons = [];
      event.innerButtons(event.element, buttons);
      return buttons;
    },
    innerButtons: function(node, results) {
      if (node.nodeName == "INPUT") {
        results.push(node);
      }
      else
        if (node.childNodes) {
        var children = node.childNodes;
        for (var i in children)
          event.innerButtons(children[i], results);
      }
    }
  };
  var buttons = event.findButtons();
  for (var i = 0; i < buttons.length; i++) {
    addEvent(buttons[i], 'focus', event.onFocus);
    addEvent(buttons[i], 'click', event.onClick);
  }
}

function focus()
{
    dump('focus');
}

function blur()
{
    dump('blur');       
}

function test()
{
    var area = document.getElementById('area');
    addHandler(area, focus, blur);
}
    </script>
</body>
</html>

Foo
酒吧 "严格使用",; 函数转储(数据){ document.getElementById('dump').appendChild(document.createTextNode(data+'\n')); } 函数addEvent(节点、evtType、回调) { if(节点中的“addEventListener”) addEventListener(evtType,callback,false); } 函数removeEvent(节点、evtType、回调) { if(节点中的“removeEventListener”) removeEventListener(evtType,callback,false); } 函数addHandler(元素、焦点、模糊) { var事件={ 重点:错, 元素:元素, 焦点:焦点, 模糊:模糊, onClick:函数(e){ event.targetNode(e.focus();//因为Chrome在单击时不聚焦 }, 聚焦:功能(e){ if(以事件为中心) 返回; event.focused=true; addEvent(文档“单击”,事件.onBlur); addEvent(文档“keyup”,event.onBluiftab); 焦点(); }, onBlur:函数(e){ 如果(!事件聚焦) 返回; if(event.thisElement(event.targetNode(e))) 返回; event.focused=false; removeEvent(文档“单击”,事件.onBlur); removeEvent(文档'keyup',event.onBluLiftab); 模糊(); }, onBluiftab:函数(e){ 如果(e.keyCode==9){event.onBlur(e)} }, targetNode:函数(e){ 在e?e.target:e.src元素中返回'target'; }, thisElement:函数(节点){ //测试以查看我们是否在元素节点上 while(节点){ if(node==event.element){ 返回true; } node=node.parentNode; } 返回false; }, findButtons:function(){ var按钮=[]; event.innerButtons(event.element,按钮); 返回按钮; }, innerButtons:函数(节点、结果){ 如果(node.nodeName==“输入”){ 结果:推送(节点); } 其他的 if(node.childNodes){ var children=node.childNodes; for(儿童中的变量i) 事件。内部按钮(子项[i],结果); } } }; var buttons=event.findButtons(); 对于(变量i=0;i
您的代码似乎在Chrome 15中工作,但在FF 7中不工作。点击FF7中的单选按钮会触发模糊事件,你不希望它发生。啊。。。是的,它似乎在Chrome中工作。但在IE 9中不起作用:(为什么不使用jQuery或任何其他框架使浏览器兼容,并使用能在所有浏览器上工作的
bind
功能呢?我很想使用jQuery,但这是我第一次从事这个相当庞大的项目,出于某种原因,自代码诞生以来一直在从事这项工作的人们都知道他们在做什么我们已经决定不这样做。我的微小改变可能不是改变它的充分理由。很好。它几乎完全符合我的要求,我会给你一个+1,但它不会响应通常会触发onBlur的任何其他事件。例如:如果我点击另一个浏览器窗口,或者如果我使用tab键继续到另一个控件。@Lost Hobbit:我更新了它(和JSFIDLE)的窗口模糊和tab键。每次调用
区域.parentNode.click();
都有点麻烦。也许有更好的解决方案。你最好用一个额外的空
.Super来包装它。谢谢
<div style="background-color: Aqua; width: 100px; height: 50px" id='area'>
    <input name="rb" type="radio">Foo<br>
    <input name="rb" type="radio">Bar
</div>
<script type='text/javascript'>
var id = addFocusToElem(document.getElementById('area'), {
    onFocus: function(e) {
        // statements
    },
    onBlur: function(e) {
        // statements
    }
});
// removeFocusByID(id);
</script>
<!DOCTYPE html>
<html>
<head>
    <title>Untitled Page</title>
<script type="text/javascript">
  var i = 0;

  var focused = false;

  var blurTimer = null;

  function startBlurTimer() {
    blurTimer = window.setTimeout("blurTimerFinished()", 1);
  }

  function cancelBlurTimer() {
    if (blurTimer != null) {
      clearTimeout(blurTimer);
      blurTimer = null;
    }
  }

  function blurTimerFinished() {
    cancelBlurTimer();
    focused = false;
    var message = document.getElementById("message");
    message.value = message.value + ++i + ". Blur\r\n";
  }

  function _focus() {
    if (blurTimer == null) {
      focused = true;
      var message = document.getElementById("message");
      message.value = message.value + ++i + ". Focus\r\n";
    }
    else
      cancelBlurTimer();
  }

  function _blur() {
    if (focused) {
      startBlurTimer();
    }
  }  
</script>
</head>
<body>
<div style="background-color: Aqua; width: 100px; height: 50px" onfocus="_focus()" onblur="_blur()" tabindex="0">
  <input onfocus="_focus()" onblur="_blur()" name="rb" type="radio" /><br />
  <input onfocus="_focus()" onblur="_blur()" name="rb" type="radio" />
</div>
<br />
<textarea id="message" rows="15" cols="50"></textarea>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <title></title>
</head>
<body onload="test()">
    <input>
    <div style="background-color: Aqua; width: 100px; height: 50px" id='area'>
        <input id="rb1" name="rb" type="radio">Foo<br>
        <input id="rb2" name="rb" type="radio">Bar
    </div>
    <input>
    <pre id='dump'></pre>
    <script type='text/javascript'>
'use strict';
function dump(data) {
    document.getElementById('dump').appendChild(document.createTextNode(data + '\n'));
}

function addEvent(node, evtType, callback)
{
    if('addEventListener' in node)
        node.addEventListener(evtType, callback, false);
}

function removeEvent(node, evtType, callback)
{
    if('removeEventListener' in node)
        node.removeEventListener(evtType, callback, false);
}    

function addHandler(element, focus, blur)
{
  var event = {
    focused: false,
    element: element,
    focus: focus,
    blur: blur,
    onClick: function(e) {
      event.targetNode(e).focus();  // Because Chrome doesn't focus when clicked
    },
    onFocus: function(e) {
      if (event.focused)
        return;

      event.focused = true;

      addEvent(document, 'click', event.onBlur);
      addEvent(document, 'keyup', event.onBlurIfTab);

      focus();
    },
    onBlur: function(e) {
      if (!event.focused)
        return;
      if (event.thisElement(event.targetNode(e)))
        return;

      event.focused = false;
      removeEvent(document, 'click', event.onBlur);
      removeEvent(document, 'keyup', event.onBlurIfTab);

      blur();
    },
    onBlurIfTab: function(e) {
      if (e.keyCode === 9) { event.onBlur(e) }
    },
    targetNode: function(e) {
      return 'target' in e ? e.target : e.srcElement;
    },
    thisElement: function(node) {
      // Test to see if we're on the element node
      while (node) {
        if (node == event.element) {
          return true;
        }
        node = node.parentNode;
      }
      return false;
    },
    findButtons: function() {
      var buttons = [];
      event.innerButtons(event.element, buttons);
      return buttons;
    },
    innerButtons: function(node, results) {
      if (node.nodeName == "INPUT") {
        results.push(node);
      }
      else
        if (node.childNodes) {
        var children = node.childNodes;
        for (var i in children)
          event.innerButtons(children[i], results);
      }
    }
  };
  var buttons = event.findButtons();
  for (var i = 0; i < buttons.length; i++) {
    addEvent(buttons[i], 'focus', event.onFocus);
    addEvent(buttons[i], 'click', event.onClick);
  }
}

function focus()
{
    dump('focus');
}

function blur()
{
    dump('blur');       
}

function test()
{
    var area = document.getElementById('area');
    addHandler(area, focus, blur);
}
    </script>
</body>
</html>