最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Uncaught TypeError: Cannot read properties of null (reading 'checked') - Stack Overflow

programmeradmin2浏览0评论

I try to get the value of Checkbox through the following function:

function sickness_selection() {
    var element = event.target.id;
    // console.log( event.target.checked);
    element = document.getElementById(element);
    if (element.checked === true) {
        element.parentElement.classList.add("asanism-selected-radio");
    } else {
        element.parentElement.classList.remove("asanism-selected-radio");
    }
}

the function works but receives the following error in the console:

Uncaught TypeError: Cannot read properties of null (reading 'checked')
    at sickness_selection (js_cEGLc76e0OdunEJf9-WqG_aDsYoNtkkBvpRxiXeaSmg.js:1701:17)
    at HTMLDivElement.onclick (create:1:1)

because the value does not render in the HTML file while changing the input:

<div class="js-form-item js-form-type-checkbox checkbox form-check js-form-item-sickness7 form-item-sickness7">
            <label class="form-check-label">
            <input data-drupal-selector="edit-sickness7" type="checkbox" id="edit-sickness7--iViLtzwqW-A" name="sickness7" value="1" class="form-checkbox form-check-input" required="">
              &nbsp;<label for="edit-sickness7--iViLtzwqW-A" class="option">somthing</label>
          </label>
              </div>

is there any solutions for error?

I try to get the value of Checkbox through the following function:

function sickness_selection() {
    var element = event.target.id;
    // console.log( event.target.checked);
    element = document.getElementById(element);
    if (element.checked === true) {
        element.parentElement.classList.add("asanism-selected-radio");
    } else {
        element.parentElement.classList.remove("asanism-selected-radio");
    }
}

the function works but receives the following error in the console:

Uncaught TypeError: Cannot read properties of null (reading 'checked')
    at sickness_selection (js_cEGLc76e0OdunEJf9-WqG_aDsYoNtkkBvpRxiXeaSmg.js:1701:17)
    at HTMLDivElement.onclick (create:1:1)

because the value does not render in the HTML file while changing the input:

<div class="js-form-item js-form-type-checkbox checkbox form-check js-form-item-sickness7 form-item-sickness7">
            <label class="form-check-label">
            <input data-drupal-selector="edit-sickness7" type="checkbox" id="edit-sickness7--iViLtzwqW-A" name="sickness7" value="1" class="form-checkbox form-check-input" required="">
              &nbsp;<label for="edit-sickness7--iViLtzwqW-A" class="option">somthing</label>
          </label>
              </div>

is there any solutions for error?

Share Improve this question asked Mar 28, 2022 at 8:51 Hassan MonfaredHassan Monfared 691 gold badge3 silver badges9 bronze badges 3
  • How is sickness_selection being triggered? – Nitheesh Commented Mar 28, 2022 at 8:59
  • @Nitheesh - That information is hidden away in the stack trace (would have been much better if it had been shown directly): It's a click handler on the div (well, on a div, I'm assuming it's that one). – T.J. Crowder Commented Mar 28, 2022 at 9:05
  • By far, the best way to find out what's going wrong here (as in almost all other cases) is to use the debugger built into your IDE and/or browser. Put a breakpoint on the first line of the event handler and click the element. Then, step through the function, looking at the values of variables, etc. Using a debugger is not an advanced skill. More here and here. – T.J. Crowder Commented Mar 28, 2022 at 9:09
Add a ment  | 

1 Answer 1

Reset to default 1

The error is telling you that element is null, because getElementById returned null. The only reason getElementById returns null is that no element with that id exists (see this question's answers).

But just that isn't the root of the problem. You're using a click handler on a div element (from the error message), then using event.target.id to find the input element using getElementById. There are two problems there:

  1. If event.target.id were the correct ID, you'd already have the element: event.target.

  2. It's entirely possible to click somewhere in the div that isn't the input element. event.target is the element that was clicked (in your case, that might be the div, the label, or the input itself). I suspect that's what's happening, you're clicking an element (a label, for instance) that doesn't have an id, so you're passing undefined into getElemntById, so it's looking for id="undefined" and not finding it.

Instead, given the structure of your HTML, you should look for the input within the div using querySelector:

const div = event.currentTarget;
const checkbox = div.querySelector("input[type=checkbox]");

Also note that if (element.checked === true) is more idiomatically written as simply if (element.checked).

So doing all of the above:

function sickness_selection() {
    const div = event.currentTarget;
    const checkbox = div.querySelector("input[type=checkbox]");
    // assert(checkbox !== null);
    const label = checkbox.parentElement;
    if (checkbox.checked) {
        label.classList.add("asanism-selected-radio");
    } else {
        label.classList.remove("asanism-selected-radio");
    }
}

If you don't need to support Internet Explorer, you could use the second argument to classList.toggle instead:

function sickness_selection() {
    const div = event.currentTarget;
    const checkbox = div.querySelector("input[type=checkbox]");
    // assert(checkbox !== null);
    const label = checkbox.parentElement;
    label.classList.toggle("asanism-selected-radio", checkbox.checked);
}

The above assumes that the handler function is hooked on the div that's immediately around the checkbox (again, this is an asumption I'm making from the error message). But in a ment you've asked how to handle multiple checkboxes, which suggests to me it may be on a div deeper in the document that contains multiple copies of the structure you've shown.

If so, the code above won't work (it'll always find the first input[type=checkbox] in that outer div). Instead, starting from the target, find that inner div to start with (see the *** line):

function sickness_selection() {
    const div = event.target.closest("div"); // ***
    const checkbox = div.querySelector("input[type=checkbox]");
    // assert(checkbox !== null);
    const label = checkbox.parentElement;
    label.classList.toggle("asanism-selected-radio", checkbox.checked);
}

Internet Explorer doesn't have that closest method. You can probably find a polyfill for it. Or just replace it with a loop:

// If you really need IE support
function sickness_selection() {
    let div = event.target;
    while (div && !div.matches("div")) {
        div = div.parentElement;
    }
    // assert(div !== null);
    const checkbox = div.querySelector("input[type=checkbox]");
    // assert(checkbox !== null);
    const label = checkbox.parentElement;
    if (checkbox.checked) {
        label.classList.add("asanism-selected-radio");
    } else {
        label.classList.remove("asanism-selected-radio");
    }
}

Finally: It looks like your HTML has a label within a label. That's invalid HTML:

label

...

Content model:

Phrasing content, but with no descendant labelable elements unless it is the element's labeled control, and no descendant label elements.

(my emphasis)

发布评论

评论列表(0)

  1. 暂无评论