I am struggling put an event listener to 'readMore' and 'readLess' link after loading the page I gotta render the page first with the data from the local storage which is saved in another page.
What I wanna put the code in this files are as below
$(".readMore").click((event) => {
event.target.style.display = "none";
event.target.style.visibility = "collapse";
$(".hidden-plot").css("visibility", "visible");
$(".hidden-plot").css("display", "inline");
$(".readLess").css("visibility", "visible");
$(".readLess").css("display", "block");
});
// when user clicks read less btn, the contents will be collapsed
$(".readLess").click((event) => {
event.target.style.display = "none";
event.target.style.visibility = "collapse";
$(".hidden-plot").css("visibility", "hidden");
$(".hidden-plot").css("display", "none");
$(".readMore").css("visibility", "visible");
$(".readMore").css("display", "block");
});
This is js file what I am working on
import { createCustomObj, isPlotLongOrShort } from "/utils.js";
$(document).ready(() => {
let savedMovies = JSON.parse(localStorage.getItem("movies"));
for(let i=0; i<savedMovies.length; i ){
fetch(`http://www.omdbapi.com/?apikey=2cc10b4e&t=${savedMovies[i]}&plot=full`)
.then((res) => res.json())
.then((data) => {
let newData = createCustomObj(data);
let html = createHtmlCollection(newData)
$( "#result-wrapper" ).append( html );
$(".stars-inner").css("width", newData.Rating "%");
})
}
function createHtmlCollection(obj){
return `<div >
<div >
<img src="${obj.Poster}" alt="" />
</div>
<div >
<div >
<div >
<h3 class='movie-title'>${obj.Title}</h3>
<div >
<div ></div>
</div>
</div>
<div >
<h4 class='movie-genre'>${obj.Genre}</h4>
<h4 class='movie-runtime'>${obj.Runtime}</h4>
</div>
</div>
<div >
<p class='movie-plot-p'>${isPlotLongOrShort(obj.Plot)}</p>
</div>
</div>`
}
});
I treid to put these lines after the loop is over, but it didn't work.
CodePudding user response:
Two suggestions. First, define your listener up front as a delegate - which will work even if the elements being listened to aren't written to the DOM yet:
$("#result-wrapper").on("click", ".readMore", function() {
$(this).css({"display":"none", "visibility":"collapse"});
$(".hidden-plot").css({"visibility":"visible", "display":"inline"});
$(".readLess").css({"visibility":"visible", "display":"block"});
});
The second suggestion is you collapse both read more and less into a single class/function
$("#result-wrapper").on("click", ".moreToggle", function() {
let showmore = $(this).data('readmore') == "1";
$(this).data('readmore', showmore ? '0' : '1')
$(this).text(showmore ? "Read less" : "Read more");
let hideEl = showmore ? '.theless' : '.themore';
let showEl = !showmore ? '.theless' : '.themore';
$(this).closest('.item').find(hideEl).hide();
$(this).closest('.item').find(showEl).show();
});
.themore {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='result-wrapper'>
<p class='item'>
<span class='theless'>This is the short version</span>
<span class='themore'>This is the long long long long long version</span>
<a class='moreToggle' data-readmore='1' href='javascript:void(0)'>Read more</a>
</div>