Reputation: 31
I am developing functionality for a website where users can click the screen (a star with a rating next to it) and it will send a call to the backend to like users' stories and also update the front end value displayed on the web page. All of that has been successful using a 'click' event.
After soft-launching my site, I realize that with a touch screen mobile device this functionality has ceased to work. I have scoured the internet for answers, but have found nothing quite clear, on why my new 'touchstart' isn't working on mobile. Here is my client-side javascript:
//HANDLER FUNCTIONS FOR EVENT/////////////////////////
const increaseValue = (postID) => {
let ratingValue = parseInt(
document.getElementById(`${postID}--rating`).innerHTML
);
// UPDATES RATING VALUE ON THE FRONT END
ratingValue += 1;
document.getElementById(`${postID}--rating`).innerHTML = ratingValue;
};
const likePost = (event) => {
// EVENT DELEGATION
let postID = event.target.parentNode.parentNode.parentNode.id;
if (postID) {
increaseValue(postID);
// SENDS TO EXPRESS ROUTE TO UPDATE RATING IN DATABASE
increaseRating(postID); //imported function to route to backend
}
};
// EVENT LISTENERS //////////////////////////////////
// Increase Posts Rating EVENT HANDLER for Home Page
if (document.querySelector('.event-delegation-1')) {
document
.querySelector('.event-delegation-1')
.addEventListener('touchstart', likePost, false);
document
.querySelector('.event-delegation-1')
.addEventListener('click', likePost, false);
} else {
console.log('kaw');
}
Here is a snippet of HTML:
<!-- Main Content -->
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto event-delegation-1">
<% for (var i = 0; i < blogposts.length; i++) { -%>
<div class="post-preview" id="<%=blogposts[i]._id%>">
<a href="/posts/<%= blogposts[i]._id %>">
<h2 class="post-title">
<%= blogposts[i].title %>
</h2>
<h3 class="post-subtitle">
<%- limitStory(blogposts[i].body) %>
</h3>
</a>
<p class="post-meta">
Posted by
<a href="/users/profile/<%=blogposts[i].userid.username%>"
><%= blogposts[i].userid.username %>,
<%=blogposts[i].userid.role %></a
>
<%= blogposts[i].datePosted.toDateString() %>
</p>
<div class="rating-system d-inline-flex align-items-center">
<!-- <a href="#"> -->
<svg
id="<%=blogposts[i].title%>--star"
class="bi bi-star-fill"
width="1em"
height="1em"
viewBox="0 0 16 16"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.283.95l-3.523 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"
/>
</svg>
<!-- </a> -->
<div
class="rating-system__blog-score ml-2"
id="<%=blogposts[i]._id%>--rating"
>
<%= blogposts[i].rating %>
</div>
</div>
</div>
<hr />
...
Any advice would be welcomed regarding this topic. I believe it has something to do with the event listeners, but I can't make heads or tails of the situation.
Upvotes: 0
Views: 2186
Reputation: 380
I think touchend
might be closer to the click
handler, because you need to detect when they finish tapping.
Also, try add console.log(event)
to your likePost
function to see what the actual events are being triggered. It might be that the target is not what you expect.
Also try adding event.preventDefault()
to that function, because it may be that the events are bubbling and triggering on other elements and reversing things at the same time.
Upvotes: 0
Reputation: 460
Looking at the the code you supplied there is no way of knowing if likePost will ever call increaseValue. You're stacking 3 times parentNode but in your html example the event target only has 2 ancestors.
So try logging the postID in likePost immediately after registrering the variable.
You can also try adding an eventlistener for touchstart on the document itself to see if that will trigger. If not you have another underlying issue.
Upvotes: 0