附加DOM对象时jQuery丢失.on()事件

时间:2018-05-31 01:21:47

标签: javascript jquery jquery-events

对于下面的代码转储感到抱歉,但这是该问题的所有相关代码,我删除了任何多余或敏感的内容。我正在使用.on('click',function(){})事件侦听器创建一系列按钮,它们似乎在创建事件侦听器和添加到表中的按钮之间的某个时刻丢失。我以前遇到过类似问题,但是DOM对象被分离并重新插入到文档中,我已经尝试了修复,但它没有用。这里整个表在从服务器更新时被清空并重建,因此每次都应该重新创建事件监听器。我对他们迷路的地方感到茫然。

function submitCommand(command, jobID) {
    //Open API connection and submit
    var url = "http://IPADDRESS:8082/api/jobs"
    var xhr = new XMLHttpRequest()
    xhr.open("POST", url, true)
    //xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8')
    xhr.onload = function() {
        var jobs = xhr.responseText
        if(xhr.readyState == 4 && xhr.status == "200") {
            console.table(jobs)
        } else {
            console.error(jobs)
        }
    }
    test = JSON.stringify({"Command":command, "JobID":jobID})
    xhr.send(test)
    console.log(command+" "+jobID)
}
function buildControls(jobID) {
    var div     = document.createElement("div")
    var cont    = $(div).clone(true)
    var restart = $(div).clone(true).css({"display": "inline-block", "width": 20, "height": 20, "background-image": "url(img/refresh.png)", "background-size":"contain"})
    restart.attr("id", "restartButton"+jobID)

    $("#restartButton"+jobID).on('click', function() {
        submitCommand("requeue", jobID)
    })
    $(cont).append(restart)
    return cont
}
function jobRow(jobObject) {
    //create and format table elements
    var row = document.createElement("tr")
    var cel = document.createElement("td")

    //Create cells for data
    var controls = $(cel).clone(true).attr("id", "controls"+jobObject._id).append(buildControls(jobObject._id))

    //Insert cells into row, then return row
    var jobRow   = $(row).clone(true).append(controls)
    return jobRow
}
async function buildJobsView() { 
    //create pane elements
    var tbl = document.createElement("table")
    var row = document.createElement("tr")
    var tth = document.createElement("th")

    //build base table
    var headings = ["Job Controls"]
    var header = $(row).clone(true)
    for(h in headings){
        temp = $(tth).clone(true).append(headings[h])
        header.append(temp)
    }
    baseTable = $(tbl).clone(true).append(header)
    $("#jobsTable").append(baseTable)

    //populate jobs
    let jobList = JSON.parse(await getJobs())
    for(job in jobList) {
        $("#jobsPane table").append(jobRow(jobList[job]))
    }
}

1 个答案:

答案 0 :(得分:2)

您正在附加事件处理程序,如下所示:

$("#restartButton"+jobID).on('click', function() {
    submitCommand("requeue", jobID)
})

...表示"在文档中搜索此ID并附加点击处理程序。"问题是该元素尚未附加到文档,因此它没有找到该元素。因此,不能分配任何处理程序。

由于您正在构建该函数中的元素,因此您已经有了对它的引用。直接将处理程序附加到该元素引用,而不是尝试选择已有的元素。

var restart = $(div)
  .clone(true)
  .css({
    display: "inline-block", 
    width: 20, 
    height: 20, 
    "background-image": "url(img/refresh.png)", 
    "background-size":"contain"
  })
  .attr("id", "restartButton"+jobID)
  .on('click', function() {
    submitCommand("requeue", jobID)
  });