为什么此javascript复选框始终保持未选中状态?

时间:2020-05-18 09:19:56

标签: javascript

我对以下js有问题。听起来很愚蠢,但以下js一直未选中第2个复选框(在<div id="shortcut1"></div><div id="shortcut2"></div>中)。 我使用其他选项测试了脚本,更改了cmdInfo中的参数。我的结论是,无论脚本是什么,都永远不会在末尾选中2 first复选框。

您对此问题有任何想法吗?我花了几个小时,但我不知道。 非常感谢您的帮助!

https://jsfiddle.net/bqaude3h/2/

const URL_PLACEHOLDER = 'your url'

let commands = [
    { name: "shortcut1", description: null, shortcut: "Alt+W" },
    { name: "shortcut2", description: null, shortcut: "Alt+Q" },
    { name: "shortcut3", description: null, shortcut: "Alt+S" }
]
let cmdInfo = {
    "shortcut1": {
        "storeSearchHistory": true,
        "url": "https://test.com",
        "history": ['test']
    },
    "shortcut2": {
        "storeSearchHistory": false,
        "url": ""
    },
    "shortcut3": {
        "storeSearchHistory": true,
        "url": ""
    }
}

let html, div, existingHistory;
commands.forEach(cmd => {

    html = `
    <div id="${cmd.name}" class="sc-div">
        <div class="flex-container">
            <input type="text" class="shortcut" value="${cmd.shortcut}" />
            <input type="url" class="url" placeholder="${URL_PLACEHOLDER}"
                    value="${cmdInfo[cmd.name].url}" />
        </div>
        <div class="history-div">
            <button>View search history</button>
            <input type="checkbox" class="store-search-history" />
            <label><small>Save search history</small></label>
        </div>
    </div>
    `
    document.querySelector('#shortcuts').innerHTML += html;

    try {
        existingHistory = Boolean(cmdInfo[cmd.name].history.length)
    } catch {
        existingHistory = false;
    }

    div = document.getElementById(cmd.name);
    div.querySelector('button').disabled = !existingHistory;

    div.querySelector('.store-search-history').checked = cmdInfo[cmd.name].storeSearchHistory;
});

2 个答案:

答案 0 :(得分:2)

问题在于此行: document.querySelector('#shortcuts').innerHTML += html;

您可以阅读有关 Why is “element.innerHTML+=” bad code? 的信息。基本上,浏览器会多次重新解析构造的DOM,这可能会导致引用中断。

这是一个有效的示例:

let commands = [{
    name: "shortcut1",
    description: null,
    shortcut: "Alt+W"
  },
  {
    name: "shortcut2",
    description: null,
    shortcut: "Alt+Q"
  },
  {
    name: "shortcut3",
    description: null,
    shortcut: "Alt+S"
  }
]
let cmdInfo = {
  "shortcut1": {
    "storeSearchHistory": true,
    "url": "https://some_url.com"
  },
  "shortcut2": {
    "storeSearchHistory": false,
    "url": ""
  },
  "shortcut3": {
    "storeSearchHistory": true,
    "url": ""
  }
}

let html, div, existingHistory, URL_PLACEHOLDER;
commands.forEach(cmd => {

  html = `
    <div id="${cmd.name}" class="sc-div">
        <div class="flex-container">
            <input type="text" class="shortcut" value="${cmd.shortcut}" />
            <input type="url" class="url" placeholder="${URL_PLACEHOLDER}"
                    value="${cmdInfo[cmd.name].url}" />
        </div>
        <div class="history-div">
            <button>
                <img src="icons/box-open-solid.svg"> View search history
            </button>
            <input type="checkbox" class="store-search-history" />
            <label><small>Save search history</small></label>
        </div>
    </div>
    `
  //document.querySelector('#shortcuts').innerHTML += html;
  document.querySelector('#shortcuts').insertAdjacentHTML('beforeend', html);

  try {
    existingHistory = Boolean(cmdInfo[cmd.name].history.length)
  } catch (e) {
    existingHistory = false;
  }

  div = document.getElementById(cmd.name);
  div.querySelector('button').disabled = !existingHistory;
  div.querySelector('.store-search-history').checked = cmdInfo[cmd.name].storeSearchHistory;
});
<div id='shortcuts'>

</div>

答案 1 :(得分:1)

您可以对输入标签使用条件渲染。


let commands = [
    { name: "shortcut1", description: null, shortcut: "Alt+W" },
    { name: "shortcut2", description: null, shortcut: "Alt+Q" },
    { name: "shortcut3", description: null, shortcut: "Alt+S" }
]
let cmdInfo = {
    "shortcut1": {
        "storeSearchHistory": true,
        "url": "https://some_url.com"
    },
    "shortcut2": {
        "storeSearchHistory": false,
        "url": ""
    },
    "shortcut3": {
        "storeSearchHistory": true,
        "url": ""
    }
    }

let html, div, existingHistory;
let URL_PLACEHOLDER="your placeholder"
commands.forEach(cmd => {

    html = `
    <div id="${cmd.name}" class="sc-div">
        <div class="flex-container">
            <input type="text" class="shortcut" value="${cmd.shortcut}" />
            <input type="url" class="url" placeholder="${URL_PLACEHOLDER}"
                    value="${cmdInfo[cmd.name].url}" />
        </div>
        <div class="history-div">
            <button>
                <img src="icons/box-open-solid.svg"> View search history
            </button>
            ${
                cmdInfo[cmd.name].storeSearchHistory?
                '<input type="checkbox" checked >'
                :'<input type="checkbox"  >'
            }
            <label><small>Save search history</small></label>
        </div>
    </div>
    `
    document.querySelector('#shortcuts').innerHTML += html;

    try {
        existingHistory = Boolean(cmdInfo[cmd.name].history.length)
    } catch {
        existingHistory = false;
    }

    div = document.getElementById(cmd.name);
    div.querySelector('button').disabled = existingHistory;
    // div.querySelector('.store-search-history').checked = cmdInfo[cmd.name].storeSearchHistory;
});