如何取消绑定元素然后再允许该元素绑定

时间:2016-05-21 22:17:13

标签: javascript jquery html css

我遇到一些使用jQuery取消绑定然后动态绑定元素的问题。

我正在尝试创建一种在移动设备上浏览网站时可以使用的标签系统。我希望用户能够选择右箭头并ul.tube移动margin-left: -300px(工作正常)。左箭头将ul.tube移动margin-left: 300px(也可以正常工作)。

当您点击margin-left的最大-900px时,我问的问题就发生了,代码解除了右箭头的绑定。当你到达-900px后再次点击左箭头重新绑定右箭头时我想要它。这将允许人们在完全向左标签后向右标签。

Example Screenshot

以下是HTML代码示例。

<div id="how-we_set">
    <i class="fa fa-chevron-left left"></i><br>
    <i class="fa fa-chevron-right right"></i><p></p>
    <ul class="tube">
        <li>Discovery</li>
        <li>Discovery 2</li>
        <li>Discovery 3</li>
        <li>Discovery 4</li>
    </ul>
    <div id="tab1">
        <div><span>This is some text</span>This is some text</div>
        <div><span>This is some text</span>This is some text</div>
        <div><span>This is some text</span>This is some text</div>
        <div><span>This is some text</span>This is some text</div>
    </div>
    <div id="tab2">
        <div><span>This is some text</span>This is some text</div>
        <div><span>This is some text</span>This is some text</div>
        <div><span>This is some text</span>This is some text</div>
        <div><span>This is some text</span>This is some text</div>
    </div>
    <div id="tab3">
        <div><span>This is some text</span>This is some text</div>
        <div><span>This is some text</span>This is some text</div>
        <div><span>This is some text</span>This is some text</div>
        <div><span>This is some text</span>This is some text</div>
    </div>
    <div id="tab4">
        <div><span>This is some text</span>This is some text</div>
        <div><span>This is some text</span>This is some text</div>
        <div><span>This is some text</span>This is some text</div>
        <div><span>This is some text</span>This is some text</div>
    </div>
</div>

以下是我到目前为止的Javascript。

// MOBILE DESIGN TAB
$('#how-we_set i.right').click(function handler() {
    $("#how-we_set ul.tube li").addClass("active");
    $("#how-we_set i.left").css('color', 'rgba(0,0,0,1.0)');
    $('#how-we_set ul.tube').animate({
        'marginLeft' : "-=300px"
    },
    function () {
      if ($(this).css ('marginLeft') >= "-900px") {
        $("#how-we_set i.right").unbind('click', handler);
        $("#how-we_set i.right").css('color', 'rgba(0,0,0,0.2)');
      }
    });
});
$('#how-we_set i.left').click(function handler2() {
    $("#how-we_set i.right").css('color', 'rgba(0,0,0,1.0)');
    $('#how-we_set ul.tube').animate({
        'marginLeft' : "+=300px"
    },
    function () {
      if ($(this).css ('marginLeft') >= "0px") {
        $("#how-we_set i.left").unbind('click');
        $("#how-we_set i.left").css('color', 'rgba(0,0,0,0.2)');
      }
    });
    $('#how-we_set i.right').bind(handler);
});

查看示例屏幕截图后,我确信您可以理解我每次点击箭头时都会尝试标记图像和所有内容。

我怎样才能像我期望的那样完成这项工作?有没有更好的方法来解决这个问题?我对新想法持开放态度。

2 个答案:

答案 0 :(得分:1)

只需替换

$('#how-we_set i.right').click(function handler() {

$('#how-we_set).on('click', 'i.right', function() {})

另一个处理程序的方式相同。 这里非常简短jsfiddle

阅读jQuery here中的事件委托。

答案 1 :(得分:1)

尝试这样的事情,使用专用的处理函数:

$('#how-we_set i.right').click(right_click_handler);
$('#how-we_set i.left').click(left_click_handler);

function bind_handlers(element) {
    if (parseInt(element.css('marginLeft')) <= -900) {
        $("#how-we_set i.right").css('color', 'rgba(0,0,0,0.2)');
    } else {
        $("#how-we_set i.right").bind('click', right_click_handler);
    }

    if (parseInt(element.css('marginLeft') >= 0) {
        $("#how-we_set i.left").css('color', 'rgba(0,0,0,0.2)');
    } else {
        $("#how-we_set i.left").bind('click', left_click_handler);
    }
};

function right_click_handler() {
    $("#how-we_set i.right").unbind('click', right_click_handler);
    $("#how-we_set ul.tube li").addClass("active");
    $("#how-we_set i.left").css('color', 'rgba(0,0,0,1.0)');
    $('#how-we_set ul.tube').animate({
        'marginLeft' : "-=300px"
    },
    function () {
        bind_handlers($(this));
    });
};

function left_click_handler() {
    $("#how-we_set i.left").unbind('click', left_click_handler);
    $("#how-we_set i.right").css('color', 'rgba(0,0,0,1.0)');
    $('#how-we_set ul.tube').animate({
        'marginLeft' : "+=300px"
    },
    function () {
        bind_handlers($(this));
    });
};

这些更改仅影响处理程序注册。请注意,在原始jsFiddle中,两个按钮都启用为启用,但应禁用顶部(左)按钮。如果你先点击顶部按钮,由于初始状态,它会变得有点滑稽;单击底部按钮首先工作正常,避免有趣的行为。

您可能会考虑进行一些重构以减少代码中的冗余。我已经像这样重构了它(jsFiddle https://jsfiddle.net/mgaskill/w5kz7e1h/):

var how_we_set = $("#how-we_set");
var ul_tube = how_we_set.find("ul.tube");
var ul_tube_li = ul_tube.find("li");
var right_i = how_we_set.find("i.right");
var left_i = how_we_set.find("i.left");

function right_click_handler() {
    click_handler($(this), "-=300px");
};

function left_click_handler() {
    click_handler($(this), "+=300px");
};

function click_handler(element, amount) {
    right_i.unbind('click', right_click_handler);
    left_i.unbind('click', left_click_handler);

    ul_tube_li.addClass("active");
    ul_tube.animate({
        'marginLeft' : amount
    },
    update_buttons_state);
};

function update_buttons_state() {
    var marginLeft = parseInt(ul_tube.css('marginLeft'));

    right_i.css('color', 'rgba(0,0,0,1.0)');
    left_i.css('color', 'rgba(0,0,0,1.0)');

    if (+marginLeft <= -900) {
      right_i.css('color', 'rgba(0,0,0,0.2)');
    } else {
      right_i.bind('click', right_click_handler);
    }

    if (marginLeft >= 0) {
      left_i.css('color', 'rgba(0,0,0,0.2)');
    } else {
      left_i.bind('click', left_click_handler);
    }
};

update_buttons_state();

这仍然是大约相同数量的代码行,但缓存jQuery查找并重新使用左右按钮之间的所有单击处理逻辑,因此您将在按钮之间保持一致的行为。使用单独的update_buttons_state()函数,您可以在UI第一次运行之前调用此函数,以确保按钮状态不允许由于初始状态不正确而导致奇怪的行为。

更新后的代码还会在animate调用之前取消绑定点击处理程序,以防止在动画运行时应用多次快速点击。此外,与右侧限制(-900px)的比较是通过将像素计数转换为整数来完成的,以便进行适当的比较。