2010-06-23 81 views
4

我爲我的CMS創建了一個小型jQuery插件,用於設置某些表單輸入類型(只是收音機,此時爲複選框)。它通過隱藏原始表單元素並在輸入的位置放置一個普通的HTML元素(用於CSS樣式化)來工作。然後它檢測元素上的操作並相應地更新原始輸入。此外,它還將在關聯標籤被點擊時起作用。這裏是我的代碼:jQuery:用於檢測複選框是否被檢查的問題

jQuery.fn.ioForm = function() { 
    return this.each(function(){ 
     //For each input element within the selector. 
     $('input', this).each(function() { 
      var type = $(this).attr('type'); 

      //BOF: Radios and checkboxes. 
      if (type == 'radio' || type == 'checkbox') { 
       var id = $(this).attr('id'); 
       checked = ''; 

       if ($(this).attr('checked')) { 
        checked = 'checked'; 
       } 

       //Add the pretty element and hide the original. 
       $(this).before('<span id="pretty_'+ id +'" class="'+ type +' '+ checked +'"></span>'); 
       $(this).css({ display: 'none' }); 

       //Click event for the pretty input and associated label. 
       $('#pretty_'+ id +', label[for='+ id +']').click(function() { 
        if (type == 'radio') { 
         //Radio must uncheck all related radio inputs. 
         $(this).siblings('span.radio.checked').removeClass('checked'); 
         $(this).siblings('input:radio:checked').removeAttr('checked'); 

         //And then check itself. 
         $('#pretty_'+ id).addClass('checked'); 
         $('#'+ id).attr('checked', 'checked'); 
        } else if (type == 'checkbox') { 
         if ($('#'+ id).attr('checked')) { 
          //Checkbox must uncheck itself if it is checked. 
          $('#pretty_'+ id).removeClass('checked'); 
          $('#'+ id).removeAttr('checked'); 
         } else { 
          //Checkbox must check itself if it is unchecked. 
          $('#pretty_'+ id).addClass('checked'); 
          $('#'+ id).attr('checked', 'checked'); 
         } 


        } 
       }); 
      } //EOF: Radios and checkboxes. 


     }); 
    }); 
}; 

這對於無線的偉大工程,但該複選框,似乎點擊複選框標籤第二次時被卡住 - 標籤的第一次點擊它成功地改變到合適的狀態,但再次點擊標籤不會改變它(但複選框本身仍然正常工作)。它在IE8中完美運行。

我檢查了ID是正確的,它是。我也嘗試了其他一些方法,我偶然檢查了複選框是否被選中,但他們要麼給出了相同的結果,要麼完全失敗。 :(

任何幫助將不勝感激。 謝謝:)

更新 下面是HTML,它是由一個PHP類生成。這是jQuery的已運行和在跨度元素的加入後:

<div> 
    <p class="label">Test:</p> 
    <span id="pretty_test_published_field" class="checkbox"></span> 
    <input class="checkbox" id="test_published_field" name="test" type="checkbox" value="published"> 
    <label for="test_published_field" class="radio">Published</label> 
    <span id="pretty_test_draft_field" class="checkbox"></span> 
    <input checked="checked" class="checkbox" id="test_draft_field" name="test" type="checkbox" value="draft"> 
    <label for="test_draft_field" class="radio">Draft</label> 
</div> 

回答

5

只需使用無誤,並極其簡單DOM checked財產。 jQuery對此並不合適,顯然使得最簡單的JavaScript任務之一容易出錯並且令人困惑。這也適用於idtype屬性。

$('input', this).each(function() { 
    var type = this.type; 
    if (type == 'radio' || type == 'checkbox') { 
     var id = this.id; 
     var checked = this.checked ? 'checked' : ''; 

     // Etc. 
    } 
}); 

UPDATE

點擊一個複選框相關的<label>元素的默認操作是切換複選框的checkedness。我還沒有用隱藏的表單元素的標籤自己嘗試過,但是由於您不阻止瀏覽器的默認點擊操作,因此可能仍然會發生切換。請嘗試以下操作:

//Click event for the pretty input and associated label. 
$('#pretty_'+ id +', label[for='+ id +']').click(function(evt) { 
    if (type == 'radio') { 
     //Radio must uncheck all related radio inputs. 
     $(this).siblings('span.radio.checked').removeClass('checked'); 
     $(this).siblings('input:radio:checked').each(function() { 
      this.checked = false; 
     }); 

     //And then check itself. 
     $('#pretty_'+ id).addClass('checked'); 
     $('#'+ id)[0].checked = true; 

     evt.preventDefault(); 
    } else if (type == 'checkbox') { 
     if ($('#'+ id).attr('checked')) { 
      //Checkbox must uncheck itself if it is checked. 
      $('#pretty_'+ id).removeClass('checked'); 
      $('#'+ id)[0].checked = false; 
     } else { 
      //Checkbox must check itself if it is unchecked. 
      $('#pretty_'+ id).addClass('checked'); 
      $('#'+ id)[0].checked = true; 
     } 

     evt.preventDefault(); 
    } 
}); 
+1

+1用於思考外部jQuery :) – alex 2010-06-23 13:16:49

+0

剛試過這個,它沒有任何區別。問題似乎是它沒有更新檢查的狀態,或者沒有檢測到它。我也按照吉姆的建議使用了現場,但這也沒有什麼區別。如果它有所作爲,那麼checked屬性不會在Chrome開發人員工具的元素顯示中出現或消失。如果我在我的「漂亮」旁邊顯示原始複選框,它仍會像「漂亮」一樣檢查/取消選中。此外,這個問題似乎只是從我把它變成一個jQuery函數開始。 – Fourjays 2010-06-23 13:47:19

+0

修改我的回答。 – 2010-06-23 14:21:23

3

我已經對奇accassion發現,我需要使用的替代:

$("#checkboxID").is(':checked'); 

這可能是或不是在你的情況下的替代方案,但值得注意。此外,如果發生對dom的更改,則可能必須添加「實時」事件,而不是「點擊」。即

.click(function() 

.live('click', function() 

吉姆

+0

不幸的是沒有任何區別。 :( – Fourjays 2010-06-23 13:49:12

+0

通常用於與我一起工作的checboxes。:D – workdreamer 2011-09-12 19:22:43

0

您能向我們展示HTML嗎?我正在查看是否爲HTML中的複選框設置了value屬性。有可能破壞它。

<input type="checkbox" value="This May Break Checkbox" /> 
<input type="checkbox" name="This Checkbox Works" /> 
+0

添加了HTML到我原來的問題。它確實有一個值來自PHP類。我現在已經改變了這個類,所以它不再爲複選框添加一個值。雖然沒有改變。 :( 但是,當單擊標籤時,複選框本身(用於測試的顯示旁邊)現在不會改變,但「漂亮」的人在卡住前會更新一次(因爲複選框沒有被實際選中/取消選中) 所以看來問題是通過標籤實際檢查複選框。 – Fourjays 2010-06-23 14:24:33

1

複選框的checked屬性被映射到defaultChecked屬性和checked屬性。改爲使用prop()方法。

如果elem是複選框,使用:

elem.checked 

$(elem).prop("checked") 

這給我們的複選框,並變化的狀態變化的正確狀態信息。

這似乎是在許多情況下混淆的原因。因此,請記住背後的根本原因。

相關問題