Greg M
Greg M

Reputation: 140

How to get a:focus ~ .class css selector with jquery?

This is a simplified version of my html:

<li>
<a href="#" data-src="song Name.mp3">
<img src="front.jpg">Song Name.mp3</a>
<div class="hidden album">Album Name</div>
<div class="hoverdir">Path to album directory</div>
<div class="hidden artist">Artist Name</div>
</li>

At the moment if "a" has focus, .hoverdir is shown. I'm using:

.hoverdir {display: none;}    
a:focus ~ .hoverdir {display: block;}

in my css to achieve this and it's working fine.

I want to be able to replace some text contained in the hoverdir, but I can't figure out the right selector in jquery.

There are loads of these that are dynamically created that I need to replace part of the text in it if certain conditions are met. This one is just an example.

Any help would be greatly appreciated.

Upvotes: 1

Views: 121

Answers (5)

Greg M
Greg M

Reputation: 140

I got it working. In my example, because the .hoverdir div is two elements below the "a" element I used:

$(this).next().next()

To find the .hoverdir div.

I used a technique from this question: JQuery: replace a string inside a div

oldhtml = $(this).next().next().html();
var newhtml = oldhtml.replace(/album/g, "");
$(this).next().next().html(newhtml);

not sure if it's the best way to do it but it works for my situation.

Upvotes: 0

Clint
Clint

Reputation: 1073

select the a when it has focus, find parent li tag, then find child with class hoverdiv, replace text

$("a").on("focus",function() {

$(this).parent("li").find(".hoverdir").text("replacement text");

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li>
<a href="#" data-src="song Name.mp3">
<img src="front.jpg">Song Name.mp3</a>
<div class="hidden album">Album Name</div>
<div class="hoverdir">Path to album directory</div>
<div class="hidden artist">Artist Name</div>
</li>

Upvotes: 1

Mark Schultheiss
Mark Schultheiss

Reputation: 34168

Some CSS you have not provided and you indicate "show" but it IS shown so I make a broad assumption your .hidden CSS is display:none and use that class. I added a "song" class just to aid in my visualization of the problem and use that on the link.

You did not indicate what you wished to do on focus out but I added that just to show how you might save the OLD text and restore it.

NOTE: no reason why you could not "pre adapt" it also - i.e. process all the changes with a $("a.song").trigger('process'); on startup, so I have also shown that.

$("a.song").on("focus process", function() {
  let hd = $(this).siblings(".hoverdir");
  //uncomment to save  hd.data("oldtext", hd.text());
  hd.text("New Text");
}).trigger('process');
/* uncomment to activate this
.on("focusout", function() {
  let hd = $(this).siblings(".hoverdir");
  let oldtext = hd.data("oldtext");
  console.log(oldtext);
  hd.text(oldtext);
});
*/
.hidden {
  display: none;
}

a.song:focus~.hoverdir {
  display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
  <li>
    <a class="song" href="#" data-src="song Name.mp3">
      <img src="front.jpg">Song Name.mp3</a>
    <div class="hidden album">Album Name</div>
    <div class="hidden hoverdir">Path to album directory</div>
    <div class="hidden artist">Artist Name</div>
  </li>
  <li>
    <a class="song" href="#" data-src="song Name.mp3">
      <img src="front.jpg">Song Name.mp3</a>
    <div class="hidden album">Album Name</div>
    <div class="hidden hoverdir">Path2 to album directory</div>
    <div class="hidden artist">Artist Name</div>
  </li>
</ul>

Upvotes: 0

connexo
connexo

Reputation: 56754

If you want to simply strip the "Audio/Albums" part from all .hoverdir, iterate over them when the DOM is parsed (onDOMContentLoaded). This is easy to do with Javascript only, no jQuery necessary for that.

document.addEventListener('DOMContentLoaded', function() {
  var hoverdirs = document.getElementsByClassName('hoverdir');

  for (var hoverdir of hoverdirs) {
    hoverdir.textContent = hoverdir.textContent.replace('Audio/Albums', '');
  }
})
.hoverdir {
  display: none;
}

a[data-src]:hover ~ .hoverdir {
  display: block;
}
<ul>
  <li>
    <a href="#" data-src="song Name.mp3">
    Song Name.mp3</a>
    <div class="hidden album">Album Name</div>
    <div class="hoverdir">Audio/AlbumsVarious Artists/Album Name</div>
    <div class="hidden artist">Artist Name</div>
  </li>
</ul>

You can exchange text via CSS as well:

a[data-src] ~ .hoverdir::before {
  content: attr(data-text);
}

a[data-src]:hover ~ .hoverdir::before {
  content: attr(data-hover-text);
}
<ul>
  <li>
    <a href="#" data-src="song Name.mp3">
    Song Name.mp3</a>
    <div class="hidden album">Album Name</div>
    <div class="hoverdir" data-text="Path to album directory" data-hover-text="Alternate text for link hover"></div>
    <div class="hidden artist">Artist Name</div>
  </li>
</ul>

Of course you would have to put the proper text in the data-attributes.

Upvotes: 0

If you really want it through jquery you can use the following:

$("a").on("focus",function() {
  $(this).nextAll(".hoverdir").text("New TExt").show();
}).focusout(function() {
  $(this).nextAll(".hoverdir").hide();
})

Demo

$("a").on("focus",function() {
  $(this).nextAll(".hoverdir").text("New TExt").show();
}).focusout(function() {
  $(this).nextAll(".hoverdir").hide();
})
.hoverdir{
display:none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li>
  <a href="#" data-src="song Name.mp3">
    <img src="front.jpg">Song Name.mp3</a>
  <div class="hidden album">Album Name</div>
  <div class="hoverdir">Path to album directory</div>
  <div class="hidden artist">Artist Name</div>
</li>

Upvotes: 1

Related Questions