如何在html更改后调用jquery函数

时间:2017-02-16 04:53:50

标签: javascript jquery html

我试图弄清楚为什么我的功能在更改html代码后停止工作。

我有一个div:

<div class="float">
<div class="box" data-speed="3" data-direction="X"><h1>Hola</h1></div>
<div class="box" data-speed="2" data-direction="X"><h1>chau</h1></div>
</div>

和jquery代码:

$(function() {
    $('.box').moveIt();
});    
//move elements in different speeds
$.fn.moveIt = function () {
    var win = $(window);
    var it = $(this);
    var instances = [];

    $(this).each(function (){
        instances.push(new moveItItem($(this)));
    });

    $('.parallax').on('scroll', function() {
        instances.forEach(function(inst){
            var wrap = inst.el.parents('.float');
            var scrol = win.scrollTop()-wrap.offset().top;
            inst.update(scrol);
        });
    });

}

var moveItItem = function(el){
  this.el = $(el);
  this.speed = parseInt(this.el.attr('data-scroll-speed'));
  this.direction = this.el.attr('data-direction');
};

moveItItem.prototype.update = function(scrollTop){
    var pos = scrollTop / this.speed;
    this.el.css('transform', 'translate'+this.direction+'(' + -pos + 'px)');
};

好的,直到这里一切正常,当我滚动元素.box相应地翻译。

但是现在我想在ajax调用之后修改类.float中的html

//after ajax
$.ajax({
    url: 'do_content.php'
}).done(function(result) {
    //result = <div class="box" data-speed="3" data-direction="X"><h1>Como estas?</h1></div>
    $('.float').html(result);
});

当我再次触发滚动后,该功能看起来看起来很破碎,我收到了这条消息:

Uncaught TypeError: Cannot read property 'top' of undefined
    at http://localhost/ophelia/public/js/control.js?v=1487219951:197:45
    at Array.forEach (native)
    at HTMLDivElement.<anonymous> (http://localhost/ophelia/public/js/control.js?v=1487219951:195:13)
    at HTMLDivElement.dispatch (http://localhost/ophelia/public/utilities/jquery/jquery-3.1.1.min.js:3:10315)
    at HTMLDivElement.q.handle (http://localhost/ophelia/public/utilities/jquery/jquery-3.1.1.min.js:3:8342)

我知道只有当我用类.box更改元素时才显示此消息(我试图仅更改h1并且它没有破坏但我想改变所有内容以改变速度)

如何重新启动此功能?

我尝试使用$('.box').moveIt();再次调用它,但仍然收到相同的错误

我知道这是一个很长的问题,但没有找到解释我问题的另一种方法

3 个答案:

答案 0 :(得分:2)

这是因为绑定到侦听器的html元素已被替换。 就像在这里fiddle一样..警报有效,但是在更改html之后,它没有。这是因为旧元素已被新元素替换。

您可以使用jQuery中的on函数来解决此问题,例如fiddle

答案 1 :(得分:1)

您可以绑定div.float上的活动并通过element.children移动每.box

答案 2 :(得分:1)

正如已经指出的那样(但可能不那么清楚),问题是您在特定时刻使用页面中存在的元素附加事件处理程序(我想到instances var)。然后你替换它们,但你的处理程序已经设置为使用类.parallax滚动元素并已使用instances的实例注册,依此类推。

一种方法是使用委托方法重写代码。

来自http://api.jquery.com/on/

  

事件处理程序仅绑定到当前选定的元素;他们   在您的代码调用.on()时必须存在。

     

委派事件的优势在于它们可以处理来自的事件   稍后添加到文档中的后代元素

     

事件委派方法仅将事件处理程序附加到一个   元素,tbody和事件只需要升级一个级别   (从点击的tr到tbody):

 $( "#dataTable tbody" ).on( "click", "tr", function() {

  console.log( $( this ).text() );

});

但它可能很复杂,因为你应该深入重构你的代码。

否则你可以按照以下方式重写你的功能(对不起,我不能制作小提琴)

$(function() {
    $('.parallax').moveIt();
});  

//move elements in different speeds
$.fn.moveIt = function () {
    var win = $(window);
    var it = $(this);
//REMOVED
//var instances = [];


//    $(this).each(function (){
//        instances.push(new moveItItem($(this)));
//    });

    $(this).on('scroll', function() {
        $('.box').each(function(){
            var inst=new moveItItem($(this));
            var wrap = inst.el.parents('.float');
            var scrol = win.scrollTop()-wrap.offset().top;
            inst.update(scrol);
        });
    });

 }

...... and so on