不能将方法与jQuery变量一起使用

时间:2019-02-09 20:02:28

标签: jquery

我在弄清楚为什么我的代码无法正常工作时遇到了一些麻烦。在以下示例html中,我具有三个nav-tab元素。我试图定位第二个元素(“产品”标签),以进行以下更改:

  1. 在悬停时的div.nav-tab元素中添加红色边框(仅“产品”标签)
  2. 将“产品”的文本更改为“商品”

我知道可以通过更改CSS和HTML轻松完成此操作,但我正尝试仅使用jQuery。

在我的脚本中,我尝试创建一个jQuery变量,然后在其上使用.hover和.find方法,但始终收到错误消息“ .find-或-.hover不是函数”。

此外,我可能希望稍后在导航栏的开头添加更多标签,因此,我不想使用类选择器之类的东西来定位第二个元素,因为稍后再添加更多标签时,这最终将不针对“产品”标签。例如...

$( ".nav-tab" )[1].hover...

我敢肯定有一种简单的方法可以做到这一点。有人可以就如何最好地使用jQuery做出一些建议提供一些建议吗?预先感谢!

我已经创建了一个示例fiddle

<nav>
    <div class="nav-tab">
        <a class="nav-link" data-name="About">
            <div class="item-menu">
                <span>About</span>
            </div>
        </a>
    </div>
    <div class="nav-tab">
        <a class="nav-link" data-name="Products">
            <div class="item-menu">
                <span>Products</span>
            </div>
        </a>
    </div>
    <div class="nav-tab">
        <a class="nav-link" data-name="Contact">
            <div class="item-menu">
                <span>Contact</span>
            </div>
        </a>
    </div>
</nav>

<script>
$( document ).ready(function() {
    let products = $( ".nav-tab" ).has( '[data-name="Products"]' ).get( 0 );
    products.hover(
        function() {$(this).addClass("red-border")},
        function() {$(this).removeClass("red-border")}
    );
    products.find('span').innerText="Merchandise";
});
</script>

4 个答案:

答案 0 :(得分:1)

当您使用$(“。nav-tab”) [1] 时,您正在将jQuery的包装器转义为对象,这就是为什么它不允许使用未经测试的jQuery相关项目的原因但是您可以尝试通过像$($(“。nav-tab”)[1])。hover()那样再次包装来解决此问题,但这不是您应该这样做的方式。

最好的方法是结合使用CSS选择器和jQuery的.parent()函数,如下所示:

let products = $("[data-name='Products']").parent();

这样,您只需选择上述找到的元素的第一个父级即可。

还可以在上面添加一个特定的选择器,使它像这样(虽然不是必需的):

let products = $("[data-name='Products']").parent(".nav-tab");

https://api.jquery.com/parent/

对于文本更改,只需使用jQuery的.text()函数:

products.find("span").text("Merchandise");

https://api.jquery.com/text/

也可以查看此方法以选择多个对象中的第一个对象 jQuery https://api.jquery.com/first/

编辑:由于您正在获取第二个对象,因此上面的.first()不相关,.get()是您想要的,但这仍然不是您应该这样做的方式,因为正如您提到的,如果附加另一个nav-tab,那么它将破坏所有内容。

答案 1 :(得分:1)

使用此代码:

$( document ).ready(function() {
    var products = $( ".nav-tab").find("[data-name='Products']");
  products
  .mouseover(function(){
    $(this).find("span").text("Merchandise").closest(".nav-tab").addClass("red-border");
  })
  .mouseout(function(){
    $(this).parent(".nav-tab").removeClass("red-border");
    //Again if you want to replace "Merchandise" to "Product" then active this commanded line
    //$(this).closest(".nav-tab").removeClass("red-border").find("span").text("Products");
  });
});

我在提琴手中更新了您的代码:https://jsfiddle.net/Arif2009/gksoynLq/31/

答案 2 :(得分:1)

Dereferencing jQuery Objects

使用... .get(0)(或... [0])时,您将取消引用jQuery对象,从而将其更改为普通的JavaScript对象。对方的方法都不能“看到”任何对象。不要使用.get(0),只需将jQuery Object存储在一个变量中通常就足够了。

IMO .hover()方法存在问题,很容易被CSS伪类:hover取代。作为jQuery解决方案,具有.on()mouseenter事件的mouseleave方法更好,因此您可以分别处理每个事件。 .innerText是无法识别jQuery对象的普通JavaScript属性,请改用jQuery方法.text()

此外,请使用border而不是CSS outline属性。 outline不会增加其长度,而border却会增加其长度。


演示

详细信息已在演示中进行了评论。

$(document).ready(function() {
  // Reference as a jQuery Object
  const products = $('[data-name="Products"]');
  // Register both events on element...
  products.on('mouseenter mouseleave', function(event) {
    // if the type of event is 'mouseenter...
    if (event.type === 'mouseenter') {
      // Get it's descendant <span>, change it's text, then add .red-border to it
      $(this).find('span').text("Merchandise").addClass("red-border");
      // Otherwise do the opposite
    } else {
      $(this).find('span').text("Product").removeClass("red-border");
    }
  });
});
.red-border {
  outline: 3px dashed red
}
<nav>
  <div class="nav-tab">
    <a class="nav-link" data-name="About">
      <div class="item-menu">
        <span>About</span>
      </div>
    </a>
  </div>
  <div class="nav-tab">
    <a class="nav-link" data-name="Products">
      <div class="item-menu">
        <span>Products</span>
      </div>
    </a>
  </div>
  <div class="nav-tab">
    <a class="nav-link" data-name="Contact">
      <div class="item-menu">
        <span>Contact</span>
      </div>
    </a>
  </div>
</nav>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

答案 3 :(得分:-1)

尝试一下:

$( document ).ready(function() {
var products =  $(".nav-tab a[data-name=Products]");
  $(products).hover(function(){
    $(this).addClass('red-border');
    }, function(){
    $(this).removeClass('red-border');
  });
  $('span',products)[0].innerText="Merchandise";
});