【问题标题】:Angular click event: how to select a checkbox within an a element?角度单击事件:如何选择元素中的复选框?
【发布时间】:2020-01-16 15:37:08
【问题描述】:

在我的 Angular 应用中,我有以下菜单:

如您所见,我有项目(即a 元素)以及每个项目中的复选框和标签:

<span class="caption">RAM</span>
<a class="item">
    <div class="item-checkbox">
        <input type="checkbox" tabindex="0" class="hidden">
        <label>4 GB</label>
    </div>
</a>
<a class="item">
    <div class="item-checkbox">
        <input type="checkbox" tabindex="0" class="hidden">
        <label>8 GB</label>
    </div>
</a>
<a class="item">
    <div class="item-checkbox">
        <input type="checkbox" tabindex="0" class="hidden">
        <label>16 GB</label>
    </div>
</a>

我应该如何将(click) 添加到每个项目以正确处理事件捕获,以便如果用户单击标签或整个项目我会选中相关复选框?

...或者你知道更好的方法来达到我的意思吗?

【问题讨论】:

    标签: javascript angular checkbox onclick event-capturing


    【解决方案1】:

    为确保单击标签会切换复选框,请在标签内包含输入元素(如MDN 中所述):

    <a class="sub-item item">
      <div class="item-checkbox">
        <label><input type="checkbox" tabindex="0" class="hidden">4 GB</label>
      </div>
    </a>
    

    如果您还希望标签填充锚元素,请按如下所示定义 CSS。使用此样式后,单击锚点将切换复选框。

    .ui.secondary.menu a.item {
      padding: 0px;
    }
    
    div.item-checkbox {
      width: 100%;
      height: 100%;
    }
    
    div.item-checkbox > label {
      display: block;
      padding: .78571429em .92857143em;
    }
    
    div.item-checkbox > label > input {
      margin-right: 0.25rem;
    }
    

    请参阅this stackblitz 以获取演示。

    【讨论】:

    • 这看起来是最好的答案。无论如何如何将点击扩展到a 元素?因此,单击a 将切换复选框。请看看我的堆栈闪电战:stackblitz.com/edit/semantic-ui-udkfhf。谢谢
    • 我更新了答案和 stackblitz 以确保单击锚点会切换复选框。
    【解决方案2】:

    如果您可以将所有复选框放在一个容器中,您可以在容器上设置一个 click 事件侦听器,event.target 将为您提供单击的元素,previousElementSibling 将选择同级输入。

    function doSomething() {
        const selectedInput = event.target.previousElementSibling;
        selectedInput.checked = selectedInput.checked? false : true;
    }
    

    但是,如果您将来记录结构更改的可能性,例如,如果其他元素进入输入和标签之间,或者它们的顺序发生变化,那么同级选择器将失败。要解决此问题,您可以改用父选择器并选择其中的 chechbox 输入元素。

    document.getElementById('container').addEventListener('click', doSomething);
    
    function doSomething() {
        const selectedElement = event.target.parentElement.querySelector('input[type="checkbox"]');
        selectedElement.checked = selectedElement.checked? false:true;
    }
    <div id= 'container'>
      <span class="caption">RAM</span>
      <a class="item">
          <div class="item-checkbox">
              <input type="checkbox" tabindex="0" class="hidden" value="4 GB">
              <label>4 GB</label>
          </div>
      </a>
      <a class="item">
          <div class="item-checkbox">
              <input type="checkbox" tabindex="0" class="hidden" value="8 GB">
              <label>8 GB</label>
          </div>
      </a>
      <a class="item">
          <div class="item-checkbox">
              <input type="checkbox" tabindex="0" class="hidden" value="16 GB">
              <label>16 GB</label>
          </div>
      </a>
    </div>

    【讨论】:

    • 我不清楚,很抱歉。我说的是“事件捕获”。我已经编辑了我的问题。如果您单击标签或整个项目,则在您的 sn-p 中,我没有选中相关复选框。
    【解决方案3】:

    首先你应该使用 *ngFor 来列出你所有的选项:

    html:

    <a class="item" *ngFor="let choice of checks; let i=index">
        <div class="item-checkbox">
            <input type="checkbox" tabindex="0" class="hidden" [value]="choice.value" (change)="onCheckChange($event)">
            <label>{{choice.title}}</label>
        </div>
    </a>
    

    组件:

    public checks: Array<choices> = [
      {title: '4 GB', value: '4'},
      {title: "8 GB", value: '8'},
      {title: "16 GB", value: '16'}
    ];
    
    public onCheckChange(event) {
        // do some things here
    }
    

    此外,您应该使用响应式表单来验证您的选择: https://angular.io/guide/reactive-forms

    【讨论】:

    • 是的,我正在使用 ReactiveForms,是的,我正在使用 *ngFor。我的问题中的代码只是一个示例......无论如何,我还不够清楚,我已经编辑了我的问题。请再读一遍。谢谢!
    • 如果你只是想让你的 span 也触发整个复选框,如何使用material.angular.io/components/checkbox/overview
    • 我没有使用 Material。
    【解决方案4】:

    您必须创建一个布尔数组并将其绑定到您的复选框。

    .ts 文件

      myArray: any[] = [
     {
          "size": "2GB",
          "value":false
        },
        {
          "size": "4GB",
          "value":false
        },
        {
          "size": "8GB",
          "value":false
        }
    ]
    

    .html 文件

    <div *ngFor="let data of myArray">
     <a class="item">
        <div class="item-checkbox">
            <input type="checkbox" tabindex="0" class="hidden" [(ngModel)]="data.value" (ngModelChange)="changeHandler()">
            <label>{{data.size}}</label>
        </div>
     </a>
    </div>
    

    工作演示:link

    【讨论】:

    • 我不清楚,很抱歉。我说的是“事件捕获”。我已经编辑了我的问题。如果您单击标签或整个项目,则在您的 sn-p 中,我没有选中相关复选框。
    【解决方案5】:

    你可以这样做:

    const ramOptions = [
      {
        id: 1,
        size: '4 GB'
      },
      {
        id: 2,
        size: '8 GB'
      },
      {
        id: 3,
        size: '16 GB'
      }
    ]
    

    在 html 中:

    <a class="item" *ngFor="let option of ramOptions">
        <div class="item-checkbox">
            <input type="checkbox" tabindex="0" class="hidden" (change)="onSelect(option.id)">
            <label>{{option.size}}</label>
        </div>
    </a>
    

    如果在 .js/.ts 文件中,您可以创建一个接口来定义处理程序。就像:

    onSelect(id: string) {
      ...
    }
    

    【讨论】:

    • 我不清楚,很抱歉。我说的是“事件捕获”。我已经编辑了我的问题。
    • 你可以把函数调用放在 元素上
    猜你喜欢
    • 2021-02-21
    • 1970-01-01
    • 2010-11-26
    • 2018-02-06
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多