求一个超难的动态新增元素的 click 事件无效的解决办法。

感觉这个问题就是比较难,至少对我来说,各种办法都试了,就是定位不了dom,所以掏学费求解决办法。
而且我希望您最好copy到本地运行一下再解决,不然,直接看代码估计比较难解决。
PS:其中的各种js是肯定要用的,也就是说,代码的运行环境和运行流程都不能变化的情况下,把alert中所求的三个变量给算出来(一共四个alert,第一个算是敲门砖,后面就可以登堂入室了~吧? 不确定啊~)。

<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://www.jq22.com/demo/jQueryRatyli20160315/js/jquery.ratyli.js"></script>
<div id="commbox">谁要是每点击一次五星中的任意一颗星,都可以把代码中的四个alert准确的报出来,我就服了谁!!<br><br><br></div>
<div class="heart">先点我这颗爱心吧,放心,不会怀孕。<i class="fa fa-heart"></i></div>
<script>
$(document).ready(function() {
    $(".fa-heart").click(function() {
        var $commbox = $("#commbox");
        var rating_id = 1
        if ($commbox.find("#" + rating_id).length) {
            $commbox.find("#" + rating_id).remove();
            return;
        }
        var $new_p = $("<div id='" + rating_id + "'><label>店长</label><span>王胖子</span><span class='ratyli'></span></div>");
        $commbox.append($new_p);
        $new_p.find(".ratyli").ratyli({
            full: "<i class='fa fa-star'></i>",
            empty: "<i class='fa fa-star-o'></i>",
        });
    });

    //$("#commbox").delegate('.ratyli .rate', 'click', function() {
    $("#commbox").on("click", ".ratyli .rate",
    function() {
        alert("我点击上了,我!我!我!看我,看我,是我,我!!!");
        alert("我还知道<label>里面的字是什么——正确答案:店长。不允许直接写答案,要过程的哦");
        alert("我还知道距离五星最近的<span>里面的字是——正确答案:王胖子。不允许直接写答案,要过程的哦");
        alert("我还取到了五星好评后.ratyli 的data-rate的值——正确答案看你点了第几颗星,点几颗就是几。不允许直接写答案,要过程的哦");
    });

});
</script>
<style>
.ratyli .rate-active{
color:#ff0080;
}
.ratyli i {
font-size: 80px;
color:#800080;
}
.fa-heart {
font-size: 40px;
color:#f00;
}
.heart {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
#commbox {
  position: absolute;
  top: 50px;
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  text-align: center;
}
</style>

拿去用 里面还给你写了注释,有疑问随时问我,点击第几个我这是实现的,至于店长和王胖子不知道是不是你要的结果~~


```javascript

<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://www.jq22.com/demo/jQueryRatyli20160315/js/jquery.ratyli.js"></script>
<div id="commbox">谁要是每点击一次五星中的任意一颗星,都可以把代码中的四个alert准确的报出来,我就服了谁!!<br><br><br></div>
<div class="heart">先点我这颗爱心吧,放心,不会怀孕。<i class="fa fa-heart"></i></div>
<script>
    $(document).ready(function () {
        $(".fa-heart").click(function () {
            var $commbox = $("#commbox");
            var rating_id = 1
            if ($commbox.find("#" + rating_id).length) {
                $commbox.find("#" + rating_id).remove();
                return;
            }
            var $new_p = $("<div id='" + rating_id + "'><label>店长</label><span>王胖子</span><span class='ratyli'></span></div>");
            $commbox.append($new_p);
            $new_p.find(".ratyli").ratyli({
                full: `<i class='fa fa-star'></i>`,
                empty: "<i class='fa fa-star-o'></i>",
                rate: 0, // 初始选中个数
                ratemax: 5, // 最大个数
                disable: false, // 是否禁用
                onRated(index) { // 重点在这里噢,ratyli.js的文档多去看看 找不到就像我一样打印看属性。
                    if (index === 0) return // 默认加载的时候就会触发,这里防止第一次加载就触发。治标不治本...
                    alert(`${$(`#${rating_id} label`)[0].innerText}${$(`#${rating_id} span`)[0].innerText}你点击了第${index}个`)
                },
                onSignClick(){ // 绑定的点击事件 ,ratyli.js 应该是有个缺陷,点击事件参数没有返回rate(选中个数),而其它三个事件加载第一次又会默认执行。
                    console.log(arguments)
                },
                onSignEnter(){ // 绑定的鼠标移入事件
                    console.log(arguments)
                },
                onSignLeave(){ // 绑定的鼠标移出事件
                    console.log(arguments)
                }
            });
            console.log($new_p.find(".ratyli")) // 这里打印一下去找ratyli 的内容,上面基本帮你写完了。估计还有其它api和属性的我就没找了
        });
        //$("#commbox").delegate('.ratyli .rate', 'click', function() {
        // $("#commbox").on("click", '.ratyli .rate',
        //     function () {
        //         alert("我点击上了,我!我!我!看我,看我,是我,我!!!");
        //         alert("我还知道<label>里面的字是什么——正确答案:店长。不允许直接写答案,要过程的哦");
        //         alert("我还知道距离五星最近的<span>里面的字是——正确答案:王胖子。不允许直接写答案,要过程的哦");
        //         alert("我还取到了五星好评后.ratyli 的data-rate的值——正确答案看你点了第几颗星,点几颗就是几。不允许直接写答案,要过程的哦");
        //     });
    });
</script>
<style>
    .ratyli .rate-active {
        color: #ff0080;
    }

    .ratyli i {
        font-size: 80px;
        color: #800080;
    }

    .fa-heart {
        font-size: 40px;
        color: #f00;
    }

    .heart {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }

    #commbox {
        position: absolute;
        top: 50px;
        left: 50%;
        transform: translateX(-50%);
        width: 100%;
        text-align: center;
    }
</style>

```

这个题的关键在于在评分组件被点击后,通过jQuery查询当前评分组件的上级元素,再查询这些上级元素中的其他元素。

这里有一个实现方法:

获取评分组件,即$(".ratyli .rate")。
获取评分组件的父元素,即$(".ratyli")。
获取父元素的上一个元素,即$(".ratyli").prev(),即为$
获取父元素的下一个元素,即$(".ratyli").next(),即为$王胖子。
代码示例:


$("#commbox").on("click", ".ratyli .rate", function() {
var $rating = $(this).closest(".ratyli");
var label = $rating.prev().text();
var name = $rating.next().text();

alert("评分标签:" + label);
alert("评分人:" + name);
});

请注意,代码仅供参考,因为缺少完整的页面HTML和CSS,因此可能需要调整以适合您的环境

这个问题需要在绑定click事件时使用事件委托。事件委托是指在父元素上绑定事件,而不是在动态添加的子元素上绑定。这样,当点击动态添加的子元素时,事件仍然能够正常触发。

代码如下:

$(document).ready(function() {
    $(".fa-heart").click(function() {
        var $commbox = $("#commbox");
        var rating_id = 1
        if ($commbox.find("#" + rating_id).length) {
            $commbox.find("#" + rating_id).remove();
            return;
        }
        var $new_p = $("<div id='" + rating_id + "'><label>店长</label><span>王胖子</span><span class='ratyli'></span></div>");
        $commbox.append($new_p);
        $new_p.find(".ratyli").ratyli({
            full: "<i class='fa fa-star'></i>",
            empty: "<i class='fa fa-star-o'></i>",
        });
    });
    // 使用事件委托
    $("#commbox").on("click", ".ratyli .rate", function() {
        alert("我点击上了,我!我!我!看我,看我,是我,我!!!");
        alert("我还知道<label>里面的字是什么——正确答案:店长。不允许直接写答案,要过程的哦");
        alert("我还知道距离五星最近的<span>里面的字是——正确答案:王胖子。不允许直接写答案,要过程的哦");
        alert("我还取到了五星好评后.ratyli 的data-rate的值——正确答案看你点了第几颗星");
    });
});

还望采纳:
在动态新增元素的click事件无效的情况下,使用jQuery的事件委托机制可以解决这个问题。事件委托机制允许把事件监听器绑定到父元素上,当子元素被点击时,事件会传递给父元素,从而父元素能够捕获到事件;
代码如下:

<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://www.jq22.com/demo/jQueryRatyli20160315/js/jquery.ratyli.js"></script>
<div id="commbox">谁要是每点击一次五星中的任意一颗星,都可以报出代码中的四个alert准确的报出来,我就服了谁!!<br><br><br></div>
<div class="heart">先点我这颗爱心吧,放心,不会怀孕。<i class="fa fa-heart"></i></div>
<script>
$(document).ready(function() {
    $(".fa-heart").click(function() {
        var $commbox = $("#commbox");
        var rating_id = 1
        if ($commbox.find("#" + rating_id).length) {
            $commbox.find("#" + rating_id).remove();
            return;
        }
        var $new_p = $("<div id='" + rating_id + "'><label>店长</label><span>王胖子</span><span class='ratyli'></span></div>");
        $commbox.append($new_p);
        $new_p.find(".ratyli").ratyli({
            full: "<i class='fa fa-star'></i>",
            empty: "<i class='fa fa-star-o'></i>",
        });
    });

    $("#commbox").on("click", ".ratyli .rate", function() {
        alert("我点击上了,我!我!我!看我,看我,是我,我!!!");
        alert("我还知道<label>里面的字是什么——正确答案:店长。不允许直接写答案,要过程的哦");
        alert("我还知道距离五星最近的<span>里面的字是——正确答案


修改代码如下,直接运行可用:

<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://www.jq22.com/demo/jQueryRatyli20160315/js/jquery.ratyli.js"></script>
<div id="commbox">谁要是每点击一次五星中的任意一颗星,都可以把代码中的四个alert准确的报出来,我就服了谁!!<br><br><br></div>
<div class="heart">先点我这颗爱心吧,放心,不会怀孕。<i class="fa fa-heart"></i></div>

<script>
$(document).ready(function() {
    $(".fa-heart").click(function() {
        var $commbox = $("#commbox");
        var rating_id = 1
        if ($commbox.find("#" + rating_id).length) {
            $commbox.find("#" + rating_id).remove();
            return;
        }
        var $new_p = $("<div id='" + rating_id + "'><label>店长</label><span>王胖子</span><span class='ratyli'></span></div>");
        $commbox.append($new_p);
        $new_p.find(".ratyli").ratyli({
            full: "<i class='fa fa-star'></i>",
            empty: "<i class='fa fa-star-o'></i>",
        });
    });
 
});

    //$("#commbox").delegate('.ratyli .rate', 'click', function() {
    $(document).on("click", ".rate",
    function() {
        alert("我点击上了,我!我!我!看我,看我,是我,我!!!");
        alert("我还知道<label>里面的字是什么——正确答案:店长。不允许直接写答案,要过程的哦");
        alert("我还知道距离五星最近的<span>里面的字是——正确答案:王胖子。不允许直接写答案,要过程的哦");
        alert("我还取到了五星好评后.ratyli 的data-rate的值——正确答案看你点了第几颗星,点几颗就是几。不允许直接写答案,要过程的哦");
    });
</script>
<style>
.ratyli .rate-active{
color:#ff0080;
}
.ratyli i {
font-size: 80px;
color:#800080;
}
.fa-heart {
font-size: 40px;
color:#f00;
}
.heart {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
#commbox {
  position: absolute;
  top: 50px;
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  text-align: center;
}
</style>

有事件处理器onSignClick可以处理的:


    $(document).ready(function () {
        $(".fa-heart").click(function () {
            var $commbox = $("#commbox");
            var rating_id = 1
            if ($commbox.find("#" + rating_id).length) {
                $commbox.find("#" + rating_id).remove();
                return;
            }
            var $new_p = $("<div id='" + rating_id + "'><label>店长</label><span>王胖子</span><span class='ratyli'></span></div>");
            $commbox.append($new_p);
            $new_p.find(".ratyli").ratyli({
                full: "<i class='fa fa-star'></i>",
                empty: "<i class='fa fa-star-o'></i>",
                onSignClick: function () {
                    alert("我点击上了,我!我!我!看我,看我,是我,我!!!");
                    alert("我还知道<label>里面的字是什么——正确答案:店长。不允许直接写答案,要过程的哦");
                    alert("我还知道距离五星最近的<span>里面的字是——正确答案:王胖子。不允许直接写答案,要过程的哦");
                    alert("我还取到了五星好评后.ratyli 的data-rate的值——正确答案看你点了第几颗星,点几颗就是几。不允许直接写答案,要过程的哦");
                }
            });
        });

    });



不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^