4

I have a button that looks like this:

<button class="button-global button-a" id="more" target="1">More Info</button>

It triggers expanded text with this:

$('.p2').hide();
$('#more').click(function (ev) {
  var t = ev.target
  $('#expanded' + $(this).attr('target')).toggle(50, function(){
    console.log(ev.target)
    $(t).html($(this).is(':visible')? 'Simplify' : 'More Info')
  });
  return false;
});

I want this link (only the aboutus link):

<a class="pcnav navlinks" href="#aboutus-target">About Us</a>

to also trigger the expanded text when clicked but not if expanded is already visible, I don't want the text to change on aboutus like it does for the button,

(made it more straightforward for new people seeing the post as it's gotten a bit confusing)

Any help would be great!

JTR
  • 311
  • 2
  • 10

3 Answers3

2

Class Driven jQuery

Multiple <a> & <button> Solution

Each <a>, <button>, & <section class='content...'> has:

  • one "common static class": .x

  • two "shared state classes": .on and .off

In order to control different tags with the same set of classes, CSS/jQuery selectors are declared as combos thereby establishing specific behavior for multiple tags while sharing a class that allows easy access to all of the tags as a group. Review the comments in the CSS section of Demo 2 for details.


Fiddle

Demo 2

Details are commented in demo.

$('.more').on('click', function() {

  // Get the #id of the closest article.p
  var page = $(this).closest('.p').attr('id');
  
  // Toggle .on/.off on all .x within article.p 
  $(`#${page} .x`).toggleClass('on off');
});

/* 
Exclude .link.on to ensure click event is only
triggered when .off class is assigned to .link
*/
$('.link').not('.on').on('click', function() {

  /*+ Expand .content located within the same .p
  
  var page = $(this).closest('.p').attr('id'); 
  $(`#${page} .x`).addClass('on').removeClass('off');
  
  //-*/
  //*- Expand .content located at this.href
  
  var jump = $(this).attr('href');
  $(`${jump} .x`).addClass('on').removeClass('off');
  
  //-*/
  
  // Scroll to this.href
  $('html, body').animate({
    scrollTop: $(jump).offset().top
  }, 550);
});
html {
  overflow-y: scroll;
  overflow-x: hidden;
}

html,
body {
  background: #fff;
  padding: 20px;
  font: 400 small-caps 16px/1.45 Arial;
}

main {
  display: flex;
  flex-flow: column nowrap;
  justify-content: center;
  align-items: center;
}

article {
  background: none;
  display: table;
  width: 100%;
}

nav,
section,
footer {
  background: #222;
  color: #fc3;
  padding: 20px;
  text-align: center;
  font-size: 1rem;
  margin: 0 auto;
  width: 300px;
}

nav {
  padding: 10px 20px;
  margin: 0em auto -0.5em;
  border-top-right-radius: 8px;
  border-top-left-radius: 8px;
}

section p {
  text-align: left;
}

footer {
  padding: 15px 20px 10px;
  margin: -2.8em auto 2.25em;
  border-bottom-right-radius: 8px;
  border-bottom-left-radius: 8px;
}

.link,
footer b {
  font-size: 1.5rem;
  color: #fc3;
}

nav b {
  display: inline-block;
  font-size: 1.5rem;
  width: 1em;
}

button {
  background: #fc3;
  color: #000;
  border: none;
  border-radius: 5px;
  padding: 8px 14px;
  font: inherit;
  font-size: 1.2rem;
  cursor: pointer;
  width: 150px;
}

/*
The next four rulesets demonstrate how only two
classes can be shared between multiple tags and still
provide different behavior and purpose.
*/

.content.off {
  max-height: 0;
  font-size: 0;
  color: transparent;
  opacity: 0;
  transition: color 0.65s, max-height 0.95s, font-size 0.95s, opacity 2.5s;
}

.content.on {
  height: auto;
  max-height: 5000px;
  font-size: 1.1rem;
  color: #fc3;
  opacity: 1;
  transition: all 0.75s;
}

.more.off::before {
  content: 'More Info';
}

.more.on::before {
  content: 'Simplify';
}
<main id='doc'>

  <article id='p1' class='p'>

    <nav>
      <a class="link x off" href="#p2">Next</a>
    </nav>

    <section>
      <button class="more x off"></button>
    </section>

    <section class="content x off">
      <p>A wonderful serenity has taken possession of my entire soul, like these sweet mornings of spring which I enjoy with my whole heart.</p>

      <p>I am alone, and feel the charm of existence in this spot, which was created for the bliss of souls like mine.</p>

      <p>I am so happy, my dear friend, so absorbed in the exquisite...</p>
    </section>

    <footer>
      <b>1</b>
    </footer>

  </article>

  <article id='p2' class='p'>

    <nav>
      <a class="link x off" href="#p1">Prev</a>
      <b>|</b>
      <a class="link x off" href="#p3">Next</a>
    </nav>

    <section>
      <button class="more x off"></button>
    </section>

    <section class="content x off">
      <p>One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin.</p>

      <p>He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections.</p>

      <p>The bedding was hardly...</p>
    </section>
    <footer>
      <b>2</b>
    </footer>
  </article>

  <article id='p3' class='p'>
    <nav>
      <a class="link x off" href="#p2">Prev</a>
    </nav>

    <section>
      <button class="more x off"></button>
    </section>

    <section class="content x off">
      <p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog.</p>

      <p>Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs.</p>

      <p>Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack.</p>
    </section>
    <footer>
      <b>3</b>
    </footer>
  </article>
</main>

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


Single <a> & <button> Solution

Ternary Conditions

The following demo assigns the click event to both button and link individually. A ternary condition is structured like so:

variable = condition ? TRUE : FALSE;

. Also, .class (.more) is used instead of #id (#more) as a better alternative, but it is not necessary.


Demo 1

$('.content').hide();

$('.more').on('click', function() {
  var txt = $(this).text() === 'Simplify' ? 'More Info' : 'Simplify';
  $(this).text(txt);
  $('.content').toggle();
});

$('.navLink').on('click', function() {
  $('.content').show();
  $('.more').text('Simplify');
});
<button class="more">More Info</button><br>

<a class="navLink" href="#about">About Us</a>

<p class='content'>
  Content.
</p>

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

A fork of Ryan Wheale's nicely styled Fiddle.

zer00ne
  • 41,936
  • 6
  • 41
  • 68
  • I'm just trying to get the aboutus nav link to activate the expanded part of the script, and if expanded is already open to leave it open, there's quite a bit I left out to keep it a bit more simple but should've probably explained that better – JTR Dec 11 '18 at 00:08
  • 1
    @JTR I think I understand your objective. Please review the updated answer. – zer00ne Dec 11 '18 at 01:27
  • 1
    You're a genius – JTR Dec 11 '18 at 01:29
  • This results in less DRY code and forces the navigation links to know about the inner behaviors of other buttons on the page. What if you want to change "Simplify" to "Read Less" - you have to do it in two places. What if the `#more` button implements more complex functionality... you have to add it in two places. – Ryan Wheale Dec 11 '18 at 02:54
  • Hi @RyanWheale, if the there was more info -- like for instance the rest of the HTML -- the jQuery can be refactored to a few lines. The ternary was added so that the OP can see how the proper syntax is applied. Other than the ternary, the rest of the code is easily read for beginners to intermediates such as the OP (it took JTR less than 2 min to grok). – zer00ne Dec 11 '18 at 04:19
  • Just saw demo 2 really impressed, could use this for mobile as a work around a hamburger nav even as collapsible content tabs, the way I was using my question was for the home page summary, and underneath was more info which was essentially "about us" so I linked about us to that anchor. Thanks for both demos! – JTR Dec 12 '18 at 23:49
  • You're very welcome. BTW, if you are ever in need of a fast and simple dropdown, consider using [a `
    ` tag and a `` tag](https://www.hongkiat.com/blog/html5-details-summary-tags/). Also, I just posted another answer in which the demo uses a customized [`
    `](https://stackoverflow.com/a/53759295/2813224).
    – zer00ne Dec 13 '18 at 10:25
1

You will want to trigger the click event for the #more button. Something like this:

$('a[href="#aboutus-target"]').click((ev) => {
  ev.preventDefault();
  $('#more').trigger('click');
});

If you only want the nav item to expand the text and never collapse the text, you will need to do something like this:

$('a[href="#aboutus-target"]').click((ev) => {
  ev.preventDefault();
  const $more = $('#more');
  const $targ = $('#expanded' + $more.attr('target'));

  // only if the target is not visible
  if( !$targ.is(':visible') ) {
    $more.trigger('click');
  }
});

Here is a fiddle showing it working:

https://jsfiddle.net/tvbhfom8/

Ryan Wheale
  • 26,022
  • 8
  • 76
  • 96
  • that works to activate the button but it stops the href="#aboutus-target" link from working – JTR Dec 10 '18 at 23:53
  • 1
    then remove the `ev.preventDefault()` part. – Ryan Wheale Dec 10 '18 at 23:54
  • @JTR you can also `return true;` at the end of the function. – Twisty Dec 10 '18 at 23:58
  • That works almost perfect! the link works and it activates the expand text, but if the text is already expanded clicking "aboutus" will close it, preferably I want the aboutus click to always show the full expanded text even if someones been through the site and already opened it, is that possible? looks like the bottom bit to your code had something to do with that – JTR Dec 11 '18 at 00:03
  • Yes, the bottom bit will make sure that the "aboutus" link will only expand the text and should never collapse it. – Ryan Wheale Dec 11 '18 at 00:44
  • I've added it but if someones opened the #more button already it closes the text, is there a way to word it so that the "aboutus" click checks to see if expanded is already visible and if it is visible to not activate, and if it isn't visible to activate expanded? – JTR Dec 11 '18 at 01:12
  • Apologies - I updated the example so it should work now. Here is a fiddle too: https://jsfiddle.net/tvbhfom8/ – Ryan Wheale Dec 11 '18 at 02:48
0

I know it's a little late, but I think this may add something here.

The solution without javascript: use <details> tag:

<details>
  <summary>Epcot Center</summary>
  <p>Epcot is a theme park at Walt Disney World Resort featuring...</p>
</details>
blmayer
  • 300
  • 4
  • 15