如何使用选择器选择父级

时间:2016-07-05 15:58:26

标签: javascript jquery

我有一个动态悬停,根据隐藏元素是否存在而激活。我正在更新我的代码以合并动态创建的元素,但遇到了一个问题,并且不知道如何选择父级。

之前我使用$(".infotip").parent().hover但已更新为:

$(document).on("mouseenter", ".parent-selector", function() {
  $(this).find(".infotip").addClass("active");
});
$(document).on("mouseleave", ".parent-selector", function() {
  $(this).find(".infotip").removeClass("active");
});

所以我需要".parent-selector"表现得像$(".infotip").parent()

4 个答案:

答案 0 :(得分:1)

由于内容是动态的,并且您提到在创建内容时无法向父级添加类,因此我认为执行此操作的唯一方法是查看已添加的任何新元素,然后绑定您的事件

此函数会定期查找.infotip类中没有自定义events_bound属性的任何元素。如果找到一个,它将添加该属性,然后将鼠标事件绑定到父级。我用动态内容说明了这一点。

//check for changes in the dom
setInterval(function() {
  $('.infotip:not([events_bound])').each(function() {
    //add attribute so that we don't re-bind to this element
    $(this).attr('events_bound', true);

    //now bind the events to the parent
    $(this).parent().mouseenter(function() {
      $(this).find(".infotip").addClass("active");
    })
    $(this).parent().mouseleave(function() {
      $(this).find(".infotip").removeClass("active");
    })
  });
}, 500);

https://jsfiddle.net/ybrwv0c8/1/

当然,如果有任何可识别父母的内容,那么最好的方法是为on使用选择器。例如,如果动态生成的ID具有parent_13835723等标准结构,则可以执行部分​​属性选择器,如$('[id^=parent_]')

您也可以像这样使用jquery :has伪选择器。但是,这会搜索所有后代以查找元素,这可能无法正常运行,具体取决于DOM的结构。

$(document).on("mouseenter", ":has('.infotip')", function() {
    $(this).children('.infotip').addClass("active");
});
$(document).on("mouseleave", ":has('.infotip')", function() {
    $(this).children('.infotip').removeClass("active");
});

但是,根据这里的jquery文档http://api.jquery.com/has-selector/

  

如果$( "div:has(p)" )存在于任何地方,则表达式<div><p>匹配   在其后代中,不仅仅是一个直接的孩子。

     

因为:has()是一个jQuery扩展而不是CSS的一部分   规范,查询使用:has()无法利用   本机DOM querySelectorAll()提供的性能提升   方法。为了在现代浏览器中获得更好的性能,请改用$( "your-pure-css-selector" ).has( selector/DOMElement )

我不确定:hassetInterval方法是否会有更好的效果。

答案 1 :(得分:0)

怎么样

$(".infotip").parent().mouseleave(function() {
    $(this).find(".infotip").addClass("active");
}

$(".infotip").parent().mouseleave(function() {
    $(this).find(".infotip").addClass("active");
}

参考:https://api.jquery.com/mouseleave/

答案 2 :(得分:0)

就像

一样简单
jQuery(".child").parent().on('mouseenter', function(){
  jQuery(this).css('background', '#f00');
});
jQuery(".child").parent().on('mouseleave', function(){
  jQuery(this).css('background', '#0ff');
});

DEMO

编辑: - 根据进一步说明,

您可以在创建对象时将事件附加到对象。如果要在不同时间将相同事件绑定到多个对象,只需创建一个命名函数。

OR

一个真正肮脏的黑客就是在每次向DOM添加一个雇用元素时解除绑定并重新绑定事件。

这样的东西
var init = function() {
   jQuery(".child").parent().off().on('mouseenter', function(){
    jQuery(this).css('background', '#f00');
   });
  jQuery(".child").parent().off().on('mouseleave', function(){
   jQuery(this).css('background', '#0ff');
  });
};

每次向DOM添加内容时,只需调用方法init即可。

答案 3 :(得分:0)

您可以使用jQuery's custom :has selector

$('document').on('mouseenter', ':has(.infotip)', function () {
  $(this).find(".infotip").addClass("active");
});
$('document').on('mouseleave', ':has(.infotip)', function () {
  $(this).find(".infotip").addClass("active");
});

我还没有对此进行测试,因为问题中没有提供HTML,但文档似乎表明它会做你想要的。