【问题标题】:Doesn't change attribute value of HTML through jQuery不通过 jQuery 更改 HTML 的属性值
【发布时间】:2014-10-02 15:01:12
【问题描述】:

代码的第一部分完美运行,包括:mouseovermouseoutclick id 上的事件,称为#active-to-do-list-28。但是当点击事件改变属性值时,它不会对id做出反应,称为#inactive-to-do-list-28

代码:

<script>
$(document).ready(function(){
  $("#active-to-do-list-28").mouseover(function(){
    $("#active-to-do-number-28").attr("class", "label label-info");
  });
  $("#active-to-do-list-28").mouseout(function(){
    $("#active-to-do-number-28").attr("class", "label label-default");
  });
  $("#active-to-do-list-28").click(function(){
    $("#active-to-do-list-28").attr("class","list-group-item list-group-item-info");
    $("#active-to-do-list-28").attr("id", "inactive-to-do-list-28");
    $("#active-to-do-number-28").attr("class", "label label-info");
    $("#active-to-do-number-28").attr("id", "inactive-to-do-number-28");
  });
  $("#inactive-to-do-list-28").click(function(){
    $("#inactive-to-do-list-28").attr("class", "list-group-item");
    $("#inactive-to-do-list-28").attr("id", "active-to-do-list-28");
    $("#inactive-to-do-number-28").attr("class", "label label-default");
    $("#inactive-to-do-number-28").attr("id", "active-to-do-number-28");
  });
});
</script>

谁能帮我解决这个问题?

【问题讨论】:

  • 由于您正在更改 ID,因此元素被视为新创建的元素并进入动态创建的元素(在您的代码运行时它找不到要绑定的元素)。您需要更改 on() 结构。见stackoverflow.com/a/1207393/2220391

标签: jquery twitter-bootstrap jquery-ui mouseevent mouseclick-event


【解决方案1】:

当您更改 ID 时,新 ID 的事件处理程序不会触发(因为在您尝试在其上注册事件时它们不存在)。如果您必须使用这种代码风格,请使用委托事件处理程序

例如喜欢:

  $(document).on('mouseover', "#active-to-do-list-28", function(){
    $("#active-to-do-number-28").attr("class", "label label-info");
  });

当然这可以缩短,因为第二个选择器是同一个元素:

  $(document).on('mouseover', "#active-to-do-list-28", function(){
    $(this).attr("class", "label label-info");
  });

它通过监听指定的事件来冒泡到一个不变的祖先。如果没有什么更接近,那么document 是默认值。 然后在事件发生时应用 jQuery 选择器,因此在注册事件时对象是否不存在并不重要。

我建议你永远不要更改 ID,而是使用其他类。

请注意,您的大部分代码都可以大大简化,但如果您也提供 HTML 示例会有所帮助。

更新:

  • mouseenter 事件中更改元素的目标存在固有问题。在某些浏览器中,当您有效地将地毯从光标下方拉出时,它可能会或可能不会立即产生 mouseleave 事件!

  • 整个问题似乎是悬停时唯一显示,点击时切换选择。见下文:

JSFiddle:http://jsfiddle.net/TrueBlueAussie/86pv4j51/

如果是这样,基于类的解决方案会做这样的事情:

$(document).ready(function () {
    $('.list-group').on('mouseenter', '.list-group-item', function () {
        $(this).addClass("hover");
    }).on('mouseleave', '.list-group-item', function () {
        $(this).removeClass("hover");
    }).on('click', '.list-group-item', function(){
        $(this).toggleClass("active");
    });
});

注意: 我将它们保留为委托事件,但如果项目是非动态的,您可以使用普通的事件处理程序。

【讨论】:

  • 谢谢,@TrueBlueAussie。简化和优化代码是任务。 2 在我的列表中。但你是对的。单独为每个 ID 创建事件是无效的。我将在几分钟内编写 HTML 代码。
  • 非常简洁的解决方案,尽管就像你说的那样,更改 ID 是个坏主意。使用 data-x 属性发生了什么,我几乎没有看到有人使用它,即使它已经得到广泛支持。
  • @Victor D.:我倾向于一直使用data- 属性来获取信息,并将类留给样式/选择。
【解决方案2】:

jquery .click 事件是在页面加载时进行的,因此所有带有 #inactive-to-do-list-28 的 id 都会受到影响,但是如果您添加具有此 id 的元素或更改具有此 id 的元素,如果您愿意,它将不会发生该事件。像这样的事件:

$(document).on('click','#inactive-to-do-list-28', function(){});

注意:文档不是最好的选择器,您应该使用更接近的元素。更多关于 jquery 的信息.on() 这里:http://api.jquery.com/on/

【讨论】:

  • 永远不要将“body”用于委托事件。它可以被样式化(例如,如果内容是浮动的)并且不会触发事件。如果没有更近的地方,请使用document 作为默认后备。
【解决方案3】:

当您声明一个 jQuery 事件处理程序时,它将在页面中运行并查找与给定选择器匹配的所有元素并将处理程序附加到它。在这种情况下,您的代码位于 document.ready 块中,因此它在页面加载时运行一次。如果之后更改 ID 或创建新元素,这些元素都不会绑定到已声明的处理程序。

解决此问题的快速方法是在更改 ID 时重新绑定事件处理程序。例如:

将 document.ready 中的所有代码放入一个函数中,然后每当您执行更改元素 ID 或类的操作时,再次调用此函数。

function eventsBinder(){
  $("#active-to-do-list-28").mouseover(function(){
    $("#active-to-do-number-28").attr("class", "label label-info");
  });
  $("#active-to-do-list-28").mouseout(function(){
    $("#active-to-do-number-28").attr("class", "label label-default");
  });
  $("#active-to-do-list-28").click(function(){
    $("#active-to-do-list-28").attr("class","list-group-item list-group-item-info");
    $("#active-to-do-list-28").attr("id", "inactive-to-do-list-28");
    $("#active-to-do-number-28").attr("class", "label label-info");
    $("#active-to-do-number-28").attr("id", "inactive-to-do-number-28");
    eventsBinder();
  });
  $("#inactive-to-do-list-28").click(function(){
    $("#inactive-to-do-list-28").attr("class", "list-group-item");
    $("#inactive-to-do-list-28").attr("id", "active-to-do-list-28");
    $("#inactive-to-do-number-28").attr("class", "label label-default");
    $("#inactive-to-do-number-28").attr("id", "active-to-do-number-28");
    eventsBinder();
 });
}

然后我们在文档就绪事件上调用这个函数

$(document).ready(function(){
  eventsBinder();
})

这应该可以解决问题。理想情况下,您希望在附加新事件之前删除以前绑定到这些元素的事件,以避免它们被调用两次;但在这种特殊情况下,它不会造成任何麻烦(除了可能增加几毫秒的处理时间)。

希望对你有帮助。

【讨论】:

  • 重新连接此类事件的人为错误的可能性非常高(您很容易以多次注册结束)。为安全起见,您将确保它们被转为 off 然后 on,但委托事件旨在处理动态元素更改。
  • @TrueBlueAussie 确实很有可能最终导致单个事件触发多个处理程序。这就是为什么我建议在添加新的处理程序之前删除处理程序。我想在他已经存在的代码中添加尽可能少的代码,因为触发的多个事件无论如何都不会破坏这里的显示。也许我应该编辑我的答案并添加它?
  • 啊,是的,我现在看到您确实提到了删除它们。该示例的问题在于该注释很容易被忽略(正如我不小心证明的那样)。 :)
  • 您能否简单地解释一下代码的总体目标是什么?你似乎有大约 10 倍的代码需要做任何事情,但我的目标逃脱了(因为我缺少匹配的样式,你也可以添加):)
【解决方案4】:

非常感谢大家。它有帮助。

现在,正如@TrueBlueAussie 所注意到的,我的代码可能要简单得多,但我不知道哪种优化和简单化最好。

这是我的 HTML:

    <ul class="list-group" align="left"><li class="list-group-item" id="active-to-do-list-1" style="padding-bottom: 14px; line-height: 20px;"><span style="margin-right: 12px;"><span class="label label-default" id="active-to-do-number-1">1</span></span>Task1
                <div class="text-right" style="float: right;">
                    <a href="#deleteTodoDialog" class="open-DeleteTodo btn btn-danger" data-toggle="modal" data-id="1" style="height: 26px; padding-top: 4px; padding-bottom: 2px; margin-right: 5px; width: 40px;"><span class="glyphicon glyphicon-minus-sign"></span></a>
                    <a href="#editTodoDialog" class="open-EditTodo btn btn-warning" data-toggle="modal" data-id='{"id":1,"todo":"task1)"}' style="height: 26px; padding-top: 4px; padding-bottom: 2px; margin-right: 5px; width: 40px;"><span class="glyphicon glyphicon-edit"></span></a>
                    <a href="#doneTodoDialog" class="open-DoneTodo btn btn-success" data-toggle="modal" data-id="1" style="height: 26px; padding-top: 4px; padding-bottom: 2px; margin-right: 5px; width: 40px;"><span class="glyphicon glyphicon-ok-sign"></span></a>
                </div>
    </ul>

你会推荐什么?

【讨论】:

  • 一句话... Eeeek! :) 我没想到 PHP 中有硬连线的 HTML。你能把浏览器的输出 HTML 保存下来,让我省去很多精神上的痛苦吗?
  • 当然,你去:)
  • 我不确定我必须以哪种方式将数据从这些&lt;a href&gt; 传递给 jQuery 脚本。可能,有很多解决方案..
  • 您的 HTML 在输出中仍然有一个 PHP(?) $todo_id...您确定您从浏览器中保存了它,因为它与您的代码不匹配。 :)
  • 添加了潜在的清洁解决方案。我不得不猜测逻辑,但希望这会有所帮助:)
猜你喜欢
  • 2012-08-28
  • 2017-11-29
  • 2021-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-24
  • 2017-04-16
  • 1970-01-01
相关资源
最近更新 更多