I'm using jQuery to de-dupe identical links that are close together, for keyboard users. I still want mouse users to be able to click the 'more' link if they want, so I'm putting the link back on hover.
What I've done is working, but it seems like a bit of a palaver. I read in the Jquery api that replaceWith() returns the replaced values, but where's it keeping them? How can I get them back when needed?
I understood that the original values go into some sort of array. It looks like it should be possible to create a named array in the first function, then access its correct values in the second. I'm really bad with arrays & will welcome any assistance.
jQuery(function ($) {
// dedupe links in post list widgets
$( ".widget li" ).each(function( i ) {
var firstA = $(this).children( 'a:first-child' );
var myH = $( firstA ).attr( 'href' );
var dupeA = $( firstA ).siblings( 'a' );
var dupeH = $( dupeA ).attr( 'href' );
if( dupeH == myH ) {
$( dupeA ).replaceWith( '<span class="more-link">Open</span>' );
}
});
// replace link if needed
$( '.widget li' ).hover(function( i ) {
var myH = $(this).children( 'a:first-child' ).attr( 'href' );
$(this).children( 'span.more-link' ).replaceWith( '<a href="' + myH + '" class="more-link">Open</a>' ).addClass( 'hover' );
});
});
ul {
list-style-type: none;
}
li, li > * {
float: left;
clear: left;
display: block;
}
li {
padding-bottom: 1em;
}
li a:first-child ~ * {
padding-left: 1em;
}
.more-link {
border: 1px solid red;
padding: .3em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="widget">
<ul class="index-widget">
<li>
<a href="https://stackoverflow.com">Stack Overflow</a>
<time>14 May 2018</time>
<span class="index-excerpt">Answers questions</span>
<a href="https://stackoverflow.com" class="more-link">Open</a>
</li>
<li>
<a href="https://jquery.com">jQuery</a>
<time>15 May 2018</time>
<span class="index-excerpt">Prompts questions</span>
<a href="https://jquery.com" class="more-link">Open</a>
</li>
</ul>
</div>
</body>
Further edit: Code on here now. Thanks, zer00ne.
You just need to get the returning value of the replaceWith
function so you could reuse it later.
For example:
var replaced = $( dupeA ).replaceWith( '<span class="more-link">Open</span>' );
replaced
will then be a reference to the replaced dupeA
element. So later you could just simply do:
$(this).children( 'span.more-link' ).replaceWith( replaced );
to put dopeA
back on.
You will be aware of the scope of the variables to be able of using replaced
in the place you need it. In you example you would need to have replaced
defined as a global variable or defined in the scope where both event functions are binded (main executed function).
More info about replaceWith
function can be found here.
Hope it helps!
Edit I've applied the function to your case, with minor improvements.
jQuery(function ($) {
$('.widget li').each(function(i, e) {
var firstA = $(this).children('a:first-child');
var myH = $(firstA).attr('href');
var dupeA = $(firstA).siblings('a');
var dupeH = $(dupeA).attr('href');
var replaced = false; // Set a variable to check if the item has been replaced
var repA; // Stored the replaced item
if(dupeH == myH) {
// Replaces the item and stores the item in a variable
repA = $(dupeA).replaceWith($('<span class="more-link">Open [replaced]</span>'));
// Only if replaced, the mouseneter event is set
$(e).mouseenter(function() {
// If the element has not been replaced yet
if(replaced === false) {
// Sets the element as replaced
replaced = true;
// Put back the replaced element
$(this).children('span.more-link').replaceWith(repA.addClass('hover'));
}
});
}
});
});
ul {
list-style-type: none;
}
li, li > * {
float: left;
clear: left;
display: block;
}
li {
padding-bottom: 1em;
}
li a:first-child ~ * {
padding-left: 1em;
}
.more-link {
border: 1px solid red;
padding: .3em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="widget">
<ul class="index-widget">
<li>
<a href="https://stackoverflow.com">Stack Overflow</a>
<time>14 May 2018</time>
<span class="index-excerpt">Answers questions</span>
<a href="https://stackoverflow.com" class="more-link">Open</a>
</li>
<li>
<a href="https://jquery.com">jQuery</a>
<time>15 May 2018</time>
<span class="index-excerpt">Prompts questions</span>
<a href="https://jquery.com" class="more-link">Open</a>
</li>
</ul>
</div>
</body>