I have started some blogs using Weebly now I want to do several changes to the blog UI, everything went well until I wanted to do this. I wanted to get the image path from the image inside blog-content and set it on the blog-post-image. In my head, this jquery looks logical, but somewhere error lays.
Few things to care about, I should use each because there are many of the blog posts and I cannot use ids because of the same reason, cannot use the same id multiple times.
HTML:
$('.blog-post-image').each(function() {
var $me = $(this);
var blogPostImage = $me.siblings('.blog-content').children('img').attr('src');
$me.attr('src', blogPostImage);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="blog-post-746510653886732592" class="blog-post">
<div class="blog-header">
<div class="blog-post-container">
<h2 class="blog-title">
</h2>
<p class="blog-date">
<span class="date-text">
15/6/2021
</span>
</p>
<div>
<img class="blog-post-image" />
</div>
</div>
</div>
<div class="blog-content">
<div>
<div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center">
<a>
<img src="/uploads/7/7/9/0/77909082/820610853.jpg" alt="Picture" style="width:100%;max-width:1100px">
</a>
<div style="display:block;font-size:90%">
</div>
</div>
</div>
.blog-post-image doesn't have any siblings. Siblings are immediate children of the same parent element, but there are no other elements in the div containing <img class="blog-post-image" />.
You need to go up to the .blog-header to get its sibling.
Also, instead of using .each(), you can use a function in .attr(). It automatically loops, and assigns the return value to the attribute.
$('.blog-post-image').attr('src', function() {
return $(this).closest('.blog-header').siblings('.blog-content').find('img').attr('src');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="blog-post-746510653886732592" class="blog-post">
<div class="blog-header">
<div class="blog-post-container">
<h2 class="blog-title">
</h2>
<p class="blog-date">
<span class="date-text">
15/6/2021
</span>
</p>
<div>
<img class="blog-post-image" />
</div>
</div>
</div>
<div class="blog-content">
<div>
<div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center">
<a>
<img src="/uploads/7/7/9/0/77909082/820610853.jpg" alt="Picture" style="width:100%;max-width:1100px">
</a>
<div style="display:block;font-size:90%">
</div>
</div>
</div>
Two things:
1.) .blog-content is not a sibling of .blog-post-image
2.) .children() only looks one level deep to find the element you are looking for.
What you need to do is traverse upwards to find a sibling of .blog-content and then use the .find() function to do a deep search of the given DOM node to find what you're looking for.
$('.blog-post-image').each(function() {
var me = $(this);
var blogPostImage = me.parent().parent().parent().siblings('.blog-content').find('img').attr('src');
me.attr('src', blogPostImage);
});
<head>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<div id="blog-post-746510653886732592" class="blog-post">
<div class="blog-header">
<div class="blog-post-container">
<h2 class="blog-title">
</h2>
<p class="blog-date">
<span class="date-text">15/6/2021</span>
</p>
<div>
<img class="blog-post-image" />
</div>
</div>
</div>
<div class="blog-content">
<div>
<div class="wsite-image wsite-image-border-none " style="padding-top:10px;padding-bottom:10px;margin-left:0;margin-right:0;text-align:center">
<a>
<img src="/uploads/7/7/9/0/77909082/820610853.jpg" alt="Picture" style="width:100%;max-width:1100px">
</a>
<div style="display:block;font-size:90%">
</div>
</div>
</div>
</div>
</div>
</body>
Related
I've been struggling to understand how to overcome this problem. I've been tasked to retrieve user input, and on keystroke see if user input matches any amount of .tags If not, hide the .thumb-display.
So far, I've been able to gather that I'll need to add/remove the classlist "hidden" as well use the event handler "input", however I don't quite understand how to use event handler "input" in this context as well as change event.
This is for homework so I'd much rather have an explanation for an answer, rather than just an answer so I can understand what I currently can't. Even a hint could be vital and set me on the right track! Rules are: no changing HTML and must use JavaScript.
Here is the HTML:
<form class="frm-filter">
<div class="frm-group">
<a class="reset hidden" href="#">Reset</a>
<input class="frm-control" type="text" id="filter" name="filter" placeholder="tag filter" />
</div>
</form>
</nav>
<section class="gallery">
<div class="row">
<h1>Gallery</h1>
</div>
<div class="row">
<div class="thumb-display">
<img src="img/thumbs/african_road_to_the_mountain.jpg" alt="african road to the mountain" />
<p class="tags">#africa #mountain #road</p>
</div>
<div class="thumb-display">
<img src="img/thumbs/beach_and_palms.jpg" alt="beach and palms" />
<p class="tags">#palmbeach #distantpeaks</p>
</div>
<div class="thumb-display">
<img src="img/thumbs/beach_road.jpg" alt="beach road" />
<p class="tags">#oceanbeach #mountainroad</p>
</div>
<div class="thumb-display">
<img src="img/thumbs/calm_lake.jpg" alt="calm lake" />
<p class="tags">#lake #clearskies #onthewater</p>
</div>
<div class="thumb-display">
<img src="img/thumbs/fall_bridge.jpg" alt="fall bridge" />
<p class="tags">#fallcolors #bridgecrossing #river</p>
</div>
</div>
</section>
You need to listen on input keyup event and retrieve value from input then check if that value matches any tags and show/hide `parentNode
document.addEventListener('DOMContentLoaded', () => {
const inputEl = document.getElementById('filter');
const tags = Array.from(document.querySelectorAll('.tags'));
inputEl.addEventListener('keyup', () => {
const value = inputEl.value;
tags.forEach(tag => {
if (tag.textContent.includes(value)) {
tag.parentNode.style.display = 'block'
} else {
tag.parentNode.style.display = 'none'
}
})
})
})
<form class="frm-filter">
<div class="frm-group">
<a class="reset hidden" href="#">Reset</a>
<input class="frm-control" type="text" id="filter" name="filter" placeholder="tag filter" />
</div>
</form>
<section class="gallery">
<div class="row">
<h1>Gallery</h1>
</div>
<div class="row">
<div class="thumb-display">
<img src="img/thumbs/african_road_to_the_mountain.jpg" alt="african road to the mountain" />
<p class="tags">#africa #mountain #road</p>
</div>
<div class="thumb-display">
<img src="img/thumbs/beach_and_palms.jpg" alt="beach and palms" />
<p class="tags">#palmbeach #distantpeaks</p>
</div>
<div class="thumb-display">
<img src="img/thumbs/beach_road.jpg" alt="beach road" />
<p class="tags">#oceanbeach #mountainroad</p>
</div>
<div class="thumb-display">
<img src="img/thumbs/calm_lake.jpg" alt="calm lake" />
<p class="tags">#lake #clearskies #onthewater</p>
</div>
<div class="thumb-display">
<img src="img/thumbs/fall_bridge.jpg" alt="fall bridge" />
<p class="tags">#fallcolors #bridgecrossing #river</p>
</div>
</div>
</section>
You need to get user input. So you need to listen for an event. Add Event Listener to the rescue. Which event, though? How about "change".
Ok, so you can get what they typed, good. Now you need to compare it to the tags. So it's time to find all of those. You can get all of the ".tags" with a querySelector. That will get you a list of nodes that you can loop through to collect the innerText. You can check if the innerText includes the input that the user typed. If it doesn't, then you find the closest ".thumb-display" and set a style attribute to hide it. If the input IS in the innerText, then you need to remove any style attribute that is hiding the closest parent.
Boom, done. Maybe, I didn't try it an I almost never get it right the first time. But it would be something along those lines.
I have the following html:
<div class="avatars">
<div class="avatar">
<div>
<svg data-jdenticon-value="Oamar Kanji"></svg>
</div>
<h3 class="name">Oamar Kanji</h3>
</div>
<div class="avatar">
<div>
<svg data-jdenticon-value="Oamar Kanji"></svg>
</div>
<h3 class="name">Jane Doe</h3>
</div>
</div>
I am getting a specific element like so and trying to display it inside another element:
<div id="display-here"/>
<script>
let someAvatar = document.getElementsByClassName("avatar").item(0)
document.getElementById('display-here').innerHTML = someAvatar
</script>
This does not work..
You need to use cloneNode
More info here: link
let someAvatar = document.getElementsByClassName("avatar").item(0)
console.log(someAvatar);
var clonedElem = someAvatar.cloneNode(true);
document.getElementById("display-here").appendChild(clonedElem);
<div class="avatars">
<div class="avatar">
<div>
<svg data-jdenticon-value="Oamar Kanji"></svg>
</div>
<h3 class="name">Oamar Kanji</h3>
</div>
<div class="avatar">
<div>
<svg data-jdenticon-value="Oamar Kanji"></svg>
</div>
<h3 class="name">Jane Doe</h3>
</div>
</div>
<div id="display-here">
</div>
Use the following line inside script:
let someAvatar = document.getElementsByClassName("avatar").item(0).innerHTML;
instead of
let someAvatar = document.getElementsByClassName("avatar").item(0)
Now someAvatar will have the HTML content inside of the div. Previously your were having the whole div HTML node.
I want to get the text on click with a certain class but nothing works. I have a div with 2 p tags and I want to get both separate. Also, I want to append them. .append() appends but just keeps adding all targeted events. empty().append() gives me random results (on first click it works, on second I get half of the text etc). Ive tried most of what I could find on stack overflow but nothing helped. Any help would be great!
Ive tried:
$(event.target).text(); //that gives me the text, but not both p elements separate
$(this).hasClass('.video-title'); //only returns to me true/false
var title= document.getElementsByClassName("video-title")[0].innerHTML; //doesn't give me the current element.
$('p.video-title').innerHTML; //doesnt help either
HTML
<div class="video-container">
<iframe id="vid_frame" src="https://www.youtube.com/embed/xxx?rel=0&showinfo=0&autohide=1" width="900" height="450"></iframe>
<div id="video-info"></div>
</div>
<div class="col-sm-4 video-col">
<div class="video-wrapper" onClick="attachSrc('yyy', event)">
<img src="assets/images/thumbnail/yourHeart_official.jpg" width="260" height="160">
<div class="overlay">
<p class="video-title">title 1</p>
<p class="video-author">author 1</p>
</div>
</div>
</div>
<div class="col-sm-4 video-col">
<div class="video-wrapper" onClick="attachSrc('xxx', event)">
<img src="assets/images/thumbnail/yourHeart_karaoke.jpg" width="260" height="160">
<div class="overlay">
<p class="video-title">title 2</p>
<p class="video-author">author 2</p>
</div>
</div>
</div>
<script>
function attachSrc(id, event) {
var text = $(event.target).text();
$('#video-info').append(text);
}
</script>
As you are using jQuery, I would recommend you to use unobtrusive event handler and use .on() to attach event handlers.
Here in example I have attached event with wrapper element and DOM traversal method to traverse and target desired element.
And to persists arbitrary data use data-* prefixed custom attribute which can be fetched using .data(key)
<div class="video-wrapper" data-id="yyy">
Script
$('.video-col').on('click', '.video-wrapper', function() {
var elem = $('#video-info').empty();
var title = $(this).find('.video-title').text();
elem.append(title);
console.log(title);
var author= $(this).find('.video-author').text();
elem.append(author);
console.log(author);
console.log($(this).data('id'));// To fetch custom data associated with element
});
$(function() {
$('.video-col').on('click', '.video-wrapper', function() {
console.clear();
var elem = $('#video-info').empty();
var title = $(this).find('.video-title').text();
elem.append(title);
console.log(title);
var author = $(this).find('.video-author').text();
elem.append(author);
console.log(author);
console.log($(this).data('id')); // To fetch custom data associated with element
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="video-container">
<div id="video-info"></div>
</div>
<div class="col-sm-4 video-col">
<div class="video-wrapper" data-id="yyy">
<img src="assets/images/thumbnail/yourHeart_official.jpg" width="260" height="160">
<div class="overlay">
<p class="video-title">title 1</p>
<p class="video-author">author 1</p>
</div>
</div>
</div>
<div class="col-sm-4 video-col">
<div class="video-wrapper" data-id="xxx">
<img src="assets/images/thumbnail/yourHeart_karaoke.jpg" width="260" height="160">
<div class="overlay">
<p class="video-title">title 2</p>
<p class="video-author">author 2</p>
</div>
</div>
</div>
I am showing a set of products via shortcode in WordPress. The display has an image and button.
Problem: Only the photo contains the link to single product page. The associated button does not have the link to the single product page.
This is the current code:
<div class="display-products">
<div class="wpb_wrapper">
<div class="displayProduct-shortcode displayProduct-Container">
<div class="product_grid dp-section dp-group woocommerce" id="displayProduct">
<div class="dp_product_item dp-col dp-col_1_of_6 firstcol">
<div class="dp_images">
<a class="dp-product-image" title="Custom Made Wedding Cabinet" href="yahoo.com">
<div class="he-wrap tpl1">
<div class="dp-img-wrapper"> <img width="192" height="264" alt="#" class="attachment-display_product_thumbnail size-display_product_thumbnail wp-post-image" src="img_src"> </div>
</div> <span data-id="696" class="dpquickview dp_quickview_button"><img src="img_src"></span> </a>
</div>
<div class="dp-product-information clearfix">
<h2 class="product-name">
<a title="Custom Made Wedding Cabinet" href="#">Custom Made Wedding Cabinet</a>
</h2>
<div class="dp-stock"></div>
<div class="dp-grid-button"> <a class="single_add_to_cart_button button alt db_customButton" href="#">READ MORE</a> </div>
<div style="clear: both;"></div>
</div>
</div>
</div>
</div>
</div>
</div>
Desired Output: I want to somehow iterate over each .single_add_to_cart_button and copy the link of every product-name to each READ MORE button
This is my current jquery code:
j('.display-products .displayProduct-shortcode .dp-product-information .dp-grid-button .single_add_to_cart_button').each(function() {
var getProductLink = j('.display-products .displayProduct-shortcode .dp-product-information .product-name > a').attr('href');
j(this).attr('href', getProductLink);
});
Set the href attribute value using the elements context. Use closest() to traverse up to dp-product-information element then find the desired anchor element the read its attribute and set the value.
Use
j('.display-products .displayProduct-shortcode .dp-product-information .dp-grid-button .single_add_to_cart_button').attr('href', function(){
return j(this).closest('.dp-product-information').find('.product-name>a').attr('href');
});
$(function() {
$('.dp-product-information .dp-grid-button .single_add_to_cart_button').attr('href', function() {
return $(this).closest('.dp-product-information').find('.product-name > a').attr('href');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="dp-product-information clearfix">
<h2 class="product-name">
<a title="Custom Made Wedding Cabinet" href="#Test">Custom Made Wedding Cabinet</a>
</h2>
<div class="dp-stock"></div>
<div class="dp-grid-button">
<a class="single_add_to_cart_button button alt db_customButton" href="#">READ MORE</a>
</div>
<div style="clear: both;"></div>
</div>
Instead of assigning value for the different buttons with the links I would like to suggest you to use a common class (if you can) then trigger the click event for them:
$('.selector').on('click',function(){
$('.a-selector').trigger('click');
});
I am new to jQuery and am trying to write a script that will run through a menu list and display the correct background image based on the menu item. The menu list is going to be randomly populated so a script is necessary to load the correct image.
The problem is that the attribute where I am able to see which item the menu belongs to is not on the list item itself but on a div contained inside the list item. My question is is it possible to select a child element of the already selected element ?
E.g (the menuli a segment)
$(document).ready( function() {
$(menuli).each( function(index) {
$itemnumber = $(menuli a).attr("href");
switch($itemnumber) {
case 1:
$(this).css("background-image", "image01.jpg");
break;
}
});
});
This is more or less the script I am trying to get, where each list item is iterated through and depending on the href of the link inside the list item a background image is set to that list item.
EDIT
Here is my html:
<div id="divMenuSportGSXSports">
<div class="VociMenuSportG">
<div class="ImgSport" style="background-image:url(../ImgSport.ashx?IDBook=53&IDSport=468&Antepost=0&)">
<img src="buttons_void.png">
</div>
<div class="NomeSport">
<a id="h_w_PC_cSport_repSport_ctl00_lnkSport" href="/Sport/Groups.aspx?IDSport=468&Antepost=0">
<span title="SOCCER">SOCCER</span>
</a>
</div>
</div>
<div class="VociMenuSportG">
<div class="ImgSport" style="background-image:url(../ImgSport.ashx?IDBook=53&IDSport=520&Antepost=0&)">
<img src="buttons_void.png">
</div>
<div class="NomeSport">
<a id="h_w_PC_cSport_repSport_ctl01_lnkSport" href="/Sport/Groups.aspx?IDSport=520&Antepost=0">
<span title="BASEBALL">BASEBALL</span>
</a>
</div>
</div>
<div class="VociMenuSportG">
<div class="ImgSport" style="background-image:url(../ImgSport.ashx?IDBook=53&IDSport=544&Antepost=0&)">
<img src="buttons_void.png">
</div>
<div class="NomeSport">
<a id="h_w_PC_cSport_repSport_ctl02_lnkSport" href="/Sport/Groups.aspx?IDSport=544&Antepost=0">
<span title="CRICKET">CRICKET</span>
</a>
</div>
</div>
<div class="VociMenuSportG">
<div class="ImgSport" style="background-image:url(../ImgSport.ashx?IDBook=53&IDSport=525&Antepost=0&Tema=Supabets)">
<img src="buttons_void.png">
</div>
<div class="NomeSport">
<a id="h_w_PC_cSport_repSport_ctl03_lnkSport" href="/Sport/Groups.aspx?IDSport=525&Antepost=0">
<span title="BASKETBALL">BASKETBALL</span>
</a>
</div>
</div>
<div class="VociMenuSportG">
<div class="ImgSport" style="background-image:url(../ImgSport.ashx?IDBook=53&IDSport=534&Antepost=0&)">
<img src="buttons_void.png">
</div>
<div class="NomeSport">
<a id="h_w_PC_cSport_repSport_ctl04_lnkSport" href="/Sport/Groups.aspx?IDSport=534&Antepost=0">
<span title="ICE HOCKEY">ICE HOCKEY</span>
</a>
</div>
</div>
<div class="VociMenuSportG">
<div class="ImgSport" style="background-image:url(../ImgSport.ashx?IDBook=53&IDSport=523&Antepost=0&)">
<img src="buttons_void.png">
</div>
<div class="NomeSport">
<a id="h_w_PC_cSport_repSport_ctl05_lnkSport" href="/Sport/Groups.aspx?IDSport=523&Antepost=0">
<span title="TENNIS">TENNIS</span>
</a>
</div>
</div>
</div>
Yes you can, use find
var parentElement = $('#someElement');
var childElement = parentElement.find('.child'); //where .child should be your child selector
Where as example code is not clear, I just gave answer to your question.
try to change this:
$(this).css("background-image", "image01.jpg");
to this:
$(this).children("div").css("background-image", "image01.jpg");
If you want to target the direct child of the element, better to use children() than find()
Please refer to this: What is fastest children() or find() in jQuery?