jQuery事件绑定动态创建的DOM元素

时间:2021-05-30 20:21:25

Sorry about the ambiguous title but I couldn't think of anything better.

对于模棱两可的标题感到抱歉,但我想不出更好的事情。

I've been struggling with this issue for a few days and haven't been able to find a way around it. A little background about my code: I have a textbox savedInfo and it stores values from different sessions. So if savedInfo is empty, I'd like to confront the user with another textbox. Once the user inputs info into the textbox and presses enter then the .val() of the textbox goes to savedInfo and the textbox is replaced with a label that has 2 buttons that appear when hovered. These two buttons give the user the ability to remove or save the textbox.

我已经在这个问题上苦苦挣扎了几天,并且无法找到解决方法。关于我的代码的一些背景:我有一个文本框savedInfo,它存储来自不同会话的值。因此,如果savedInfo为空,我想用另一个文本框面对用户。一旦用户将信息输入文本框并按Enter键,文本框的.val()将转到savedInfo,文本框将替换为标签,该标签在悬停时显示2个按钮。这两个按钮使用户能够删除或保存文本框。

The problem I am having is that my code doesn't seem to flow correctly. For instance, I have an if statement that checks if savedInfo is empty and if it isn't then show the label text of savedInfo. Then INSIDE the keypress function I check if one of the hover buttons is pressed but the code doesn't work since it is inside the keypress function. If I take it out of the keypress function then it doesn't work for when the keypress label appears.

我遇到的问题是我的代码似乎没有正确流动。例如,我有一个if语句,检查savedInfo是否为空,如果不是,则显示savedInfo的标签文本。然后INSIDE按下按键功能我检查是否按下了其中一个悬停按钮但代码不起作用,因为它在按键功能内。如果我将其从按键功能中取出,那么当按键标签出现时它不起作用。

Probably best if I explain with pseudo code:

如果我用伪代码解释,可能是最好的:

$(document).ready(function() {
if($("savedInfo").val() != "") {
  someDiv..innerHTML(<label>$("savedInfo").val() + hover shows buttons</label>);
} else {
   //Create textbox id `textbox`
}

$(function() {
    $("#textbox").keypress(function(e) {
        if (e.keyCode == 13) {
        //set innerHTML to a label with text of `textbox`. 
        //Check if button#1 is pressed. If yes, then do something

        //Check if button#2 is pressed. If yes, then do something
        }
    });
 });
});

So the button#1 and button#2 ids are being created inside the if but don't work inside the if because they are inside the keypress.

因此,按钮#1和按钮#2 id正在if中创建,但在if内部不起作用,因为它们位于按键内。

I hope this wasn't too confusing. Any ideas on how to make this work better? Thanks

我希望这不会太混乱。关于如何使这项工作更好的任何想法?谢谢

1 个解决方案

#1


2  

Here's a working example with jQuery based off of your requirements.

这是一个基于您的要求的jQuery的工作示例。

I really don't understand what the use case is here though and it begs a few questions about reuse of the original text-box, whether this is going to occur multiple times on a page or not, why you wouldn't just show the buttons right away (vs assuming the user knows that they must press enter), and whether this could be better solved using templates? Seems that this is more difficult than it should be for such a simple interaction.

我真的不明白这里的用例是什么,它引出了一些关于原始文本框重用的问题,是否会在页面上多次出现,为什么你不会只显示立即按钮(假设用户知道他们必须按回车键),以及是否可以使用模板更好地解决这个问题?似乎这比这种简单的交互更难。

Anyhow, I hope this helps move you forward.

无论如何,我希望这有助于推动你前进。

(function () {

    function promptForInfo(elem) {
        
        var html = "<div id='newInfoContainer'><label>New info: <input id='newInfo' type='text' placeholder='Please provide info...' /></label></div>";
        $(elem).parent().append(html);  
        
        $("#newInfo")
            .focus()
            .on("keydown", function (e) {
                
                if (e.keyCode === 13) {
                    
                    $(elem).val(this.value);
                    $(this).parent().remove();
                    
                    var buttonsHtml = "<div id='buttonContainer'><input class='saveButton' type='button' value='Save' /><input class='removeButton' type='button' value='Remove' /></div>";
                    $(elem).parent().append(buttonsHtml);
                    $(".saveButton").on("click", function (e) { saveInfo(e); });
                    $(".removeButton").on("click", function (e) { removeInfo(e); });
                    
                }            
        });
    }

    function saveInfo(e) {
        $(e.target.parentElement).remove();
        $("body").append("<p>Saved</p>");
    }
    
    function removeInfo(e) {
        $(e.target.parentElement).remove();
        $("#savedInfo").val("");
        $("body").append("<p>Removed</p>");
    }
    
    function inspectSavedInfo() {
        if (!$("#savedInfo").val()) {
            promptForInfo($("#savedInfo"));
        }
    }
    
    $(document).ready(function () {
        
        // Inspect on any change after init
        $("#savedInfo").on("change", function () { inspectSavedInfo(); });
        
        // Trigger Inspection of savedInfo on init 
        inspectSavedInfo(); 
    });

}());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="savedInfoContainer">
    <label>Saved Info: <input id="savedInfo" type="text" value="" /></label>
</div>

#1


2  

Here's a working example with jQuery based off of your requirements.

这是一个基于您的要求的jQuery的工作示例。

I really don't understand what the use case is here though and it begs a few questions about reuse of the original text-box, whether this is going to occur multiple times on a page or not, why you wouldn't just show the buttons right away (vs assuming the user knows that they must press enter), and whether this could be better solved using templates? Seems that this is more difficult than it should be for such a simple interaction.

我真的不明白这里的用例是什么,它引出了一些关于原始文本框重用的问题,是否会在页面上多次出现,为什么你不会只显示立即按钮(假设用户知道他们必须按回车键),以及是否可以使用模板更好地解决这个问题?似乎这比这种简单的交互更难。

Anyhow, I hope this helps move you forward.

无论如何,我希望这有助于推动你前进。

(function () {

    function promptForInfo(elem) {
        
        var html = "<div id='newInfoContainer'><label>New info: <input id='newInfo' type='text' placeholder='Please provide info...' /></label></div>";
        $(elem).parent().append(html);  
        
        $("#newInfo")
            .focus()
            .on("keydown", function (e) {
                
                if (e.keyCode === 13) {
                    
                    $(elem).val(this.value);
                    $(this).parent().remove();
                    
                    var buttonsHtml = "<div id='buttonContainer'><input class='saveButton' type='button' value='Save' /><input class='removeButton' type='button' value='Remove' /></div>";
                    $(elem).parent().append(buttonsHtml);
                    $(".saveButton").on("click", function (e) { saveInfo(e); });
                    $(".removeButton").on("click", function (e) { removeInfo(e); });
                    
                }            
        });
    }

    function saveInfo(e) {
        $(e.target.parentElement).remove();
        $("body").append("<p>Saved</p>");
    }
    
    function removeInfo(e) {
        $(e.target.parentElement).remove();
        $("#savedInfo").val("");
        $("body").append("<p>Removed</p>");
    }
    
    function inspectSavedInfo() {
        if (!$("#savedInfo").val()) {
            promptForInfo($("#savedInfo"));
        }
    }
    
    $(document).ready(function () {
        
        // Inspect on any change after init
        $("#savedInfo").on("change", function () { inspectSavedInfo(); });
        
        // Trigger Inspection of savedInfo on init 
        inspectSavedInfo(); 
    });

}());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="savedInfoContainer">
    <label>Saved Info: <input id="savedInfo" type="text" value="" /></label>
</div>