简体   繁体   中英

Enable link after hover state on touch devices without affecting normal scroll

I have a figure element, which has a hover state on it which effects other elements within the figure; img , figcaption etc. I've been able to get this effect to "work" on touch devices, by using the following jQuery:

$('.portfolio__img').on("touchEnd", function (e) {
    "use strict"; //satisfy the code inspectors
    var link = $(this); //preselect the link
    if ( $( link ).hasClass( "portfolio__img--taphover" ) ) {
        return true;
    } else {
        link.addClass("portfolio__img--taphover");
        $('.portfolio__img').not(this).removeClass("portfolio__img--taphover");
        e.preventDefault();
        return false; //extra, and to make sure the function has consistent return points
    }
})

// portfolio__img--taphover` has the same CSS rules as `figure:hover, figure:focus`

I've forgotten where I got the code from now, but it was a blog post. This works quite well, however I'm not completely satisfied with it. If you touch and scroll, so scrolling quite a long way down the page, you are likely to miss the hover effect, as the element may not be within the viewport on touchEnd . However, my figure element is 100% width, so using touchStart impacts scrolling, as the instant a user touches the screen the hover effect is applied. I've looked around and there doesn't seem to be a touchTap or similar event. I suppose this is because its extremely difficult to work out if a user is touching (tapping) the screen to reveal something, or touching to swipe and scroll. I tried touchMove but that didn't work well.

I was convinced there would be a way to do it with CSS, for example making my overlay link have a low z-index which only gets higher on hover. Perhaps I could delay the z-index change until after the tap event, but then I still get into the whole issue of detecting a tap vs touch/scroll. Has anyone else encountered this behaviour and been annoyed by it, and/or found a solution?

My HTML:

<figure class="grid__item  mobile--one-half  desk--one-quarter  portfolio__img">

    <img class="portfolio__test" srcset="<?php echo $image_src; ?> 1536w, 
        <?php echo $image_src_1024; ?> 1024w, 
        <?php echo $image_src_900; ?> 900w, 
        <?php echo $image_src_600; ?> 600w,
        <?php echo $image_src_320; ?> 320w"
    sizes="(min-width: 78.75em) 25vw, (min-width: 30em) 50vw, 100vw" 
    alt="<?php the_field( 'portfolio_alt_text' ); ?>">
    <figcaption>
        <div class="table">
            <div class="table-cell">
                <h2><?php the_sub_field( 'portfolio_description' ); ?></h2>
            </div>
        </div>
    </figcaption>
    <a class="portfolio__link" href="<?php the_sub_field( 'portfolio_link' ); ?>">View More</a>

</figure>

Relevent CSS:

.portfolio__link {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    z-index: 1;
}

Cheers. I'll update this question in due course once I find a good solution, in case no one has one!

EDIT: Updated with Codepen example

So I realise I wasn't that clear before so I've made a couple of codepen's that illustrate the issue I'm having:

Without a proper link ( href="#" ) http://codepen.io/patrickwc/pen/yyYVeV

If you touch these links with a touch device, the hover effect works and its very nice. You can still swipe and scroll without triggering the hover effect and when you touch another box after touching a previous box, the effect stops on the previous box and applies to the current box very nicely. I am seeking this behaviour. @Edgar Sanchez you mentioned permorance, its not jank or anything its the fact that with touchstart as soon as you touch the box, the effect triggers. What I want is an effect like the hover effect, which still allows you to swipe and scroll past without triggering the hover state (or --taphover class).

With a proper link (No js) http://codepen.io/patrickwc/pen/jEbVWq

Obviously now the boxes don't work very well. The browser tries to take you to http://www.something.com/ immediately, without respecting the hover state.

Ideally I want some javascript that enables the jac-rollover__link only after the hover state. I guess that could work actually, maybe jquery's hover state could then enable the class to make the z-index of it higher... I'll give it a go now.

I managed to get it working via pure CSS. I put visibility: hidden on the jac-rollover__link , then I used a CSS transition on visibility, with a length of 0s but with a delay of 0.5s, which is the same time the hover effect takes to complete. So, viola no javascript and it works really well on everything I've tested on so far. I suppose pretty much all touch devices with have support for CSS transitions, so it should be fine.

code in case it helps others:

.jac-rollover {
    ...

    &:hover,
    &:focus {

        .jac-rollover__link {
            visibility: visible;
            transition: visibility 0s 0.5s;
        }
    }
}

.jac-rollover__link {
    ...
    visibility: hidden;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM