2016-09-23 129 views
0

为什么我的函数运行多次?Javascript点击事件触发多次?

var s, 
getData = { 

    settings: { 
     gender: $("input[name='gender']"), 
     age: $("input[name='age']") 
    }, 

    init: function() { 
     s = this.settings; 
     this.getInput(); 
    }, 

    getInput: function() { 
     for (i in s) { 
      s[i].on("click", function() { 
       s[i].off(); 
       console.log(this.getAttribute('value')) 
      }); 
     } 
    }, 
}; 

我觉得奇怪的是,当我不点击相同的输入两次它只运行一次。举例来说,如果我点击“男”,然后“女”它会显示在控制台

(1) male 
(2) female 

这在逻辑上是有意义的我,如果我点击“男性” 5次,然后我得到

(14) male 

它只是越来越大。

编辑: JSFiddle如果打开控制台,您可以看看会发生什么

+1

为什么复杂的代码? – madalinivascu

+0

发布您的代码? – passion

+0

@madalinivascu为什么它很复杂?它是模块化的代码,这是更清洁的imo。 –

回答

2

发生了什么事是getInput被称为每次点击的事件,这意味着该循环运行的每个时间,再次注册事件。因此,每次单击单选按钮时,循环都会将事件再次附加到DOM元素。 您应该只注册事件一次https://jsfiddle.net/2jbLdo9n/

删除输入的onclick事件:

<div class="right-item"> 
    <input id="male" type="radio" name="gender" value="male"> 
    <label class="left-m" for="male"><span></span> Male </label> 
</div> 
<div class="right-item"> 
    <input id="female" type="radio" name="gender" value="female"> 
    <label for="female"><span></span> Female </label> 
</div> 

然后,在JavaScript,只需拨打getData.init();

getData.init(); 
+0

@DanielContreras看到我的答案。 –

+0

哦,我还没有意识到,onclick这样工作。我会在html中没有onclick()的情况下尝试。但是,表单将如何动态检索任何更改?我的脚本不像JSFiddle那样内联,我只是这样做,因为getInput函数不起作用。但是,JavaScript不会一直听它吗? –

+0

@DanielContreras每次单击表单时,都会动态检索这些值。而且您可以访问点击处理程序中的值,即循环中的值。 –

2

绑定一个单一的点击事件,如果调用此多的时间,然后第一个再次取出单击事件和追加或使用one()

尝试以下操作:

var s, 
getData = { 

    settings: { 
     gender: "input[name='gender']", 
     age: "input[name='age']" 
    }, 

    init: function() { 
     s = this.settings; 
     this.getInput(); 
    }, 

    getInput: function() { 

      $(s.gender+','+s.age).on("click", function() { 
       console.log($(this).val()); 
      }); 
    }, 
}; 

删除点击事件,并在文件准备

发起呼叫

看到演示:https://jsfiddle.net/qzrfwc3g/

或做它的正常方式3行代码:

$("input[name='gender'],input[name='age']").on("click", function() { 
    console.log($(this).val()); 
}); 
+0

我试过.one()函数,但它仍然有奇怪的行为。但是,它确实停止了对我的函数的多次调用。 –

+0

你是什么意思奇怪? – madalinivascu

+0

等待您从点击事件创建点击事件,为什么? – madalinivascu

1

我不知道为什么你想这样做,因为你编码,我认为这里有一个错误。

for (i in s) { 
    s[i].on("click", function() { 
     s[i].off(); 
     console.log(this.getAttribute('value')) 
    }); 
} 

您声明i全球,当事件触发,i是指相同的值。你可以试试这个:

for (let i in s) { 
     s[i].on("click", function() { 
      s[i].off(); 
      console.log(this.getAttribute('value')) 
     }); 
    } 
+0

你是对的,每次函数调用后i变量都没有被重置。我不知道我的变量是一个全局变量。我对JS相当陌生,所以我仍然试图学习它。感谢您的建议。 –

0

您添加多个点击事件,以相同的元素就是为什么你会得到多个控制台.log点击一次。要解决这个问题,只需在分配事件列表之前添加一个条件。

var s, 
    getData = { 

     cacheDOM: { 
     gender: $("input[name='gender']"), 
     age: $("input[name='age']") 
     }, 

     init: function() { 
     if(!s){ 
      s = this.cacheDOM; 
      this.getInput(); 
     } 
     }, 

     getInput: function() { 
     for (i in s) { 
      s[i].on("click", function() { 
      s[i].off(); 
      console.log(this.getAttribute('value')) 
      }); 
     } 
     }, 
    };