When storing DOM elements in a javascript variable prior to appending them to the actual DOM is there a way with jQuery to select elements inside the variable?
For example,
I have a list of tweets on my page. Every time I click a refresh button I append a new tweet to the list below.
I add the new tweet like follows:
new tweet
<li class="tweet normal-tweet" data-user-name="Dorothy">
<div class="image">
<img height="48" width="48" src="http://twitter.com/api/users/profile_image?screen_name=Dorothy" alt="" />
</div>
<div class="content">
<div class="user">
<a class="user-name" href="http://twitter.com/Dorothy" title="Dorothy">Dorothy</a>
<div class="full-name"></div>
</div>
<div class="text">Once in a lullaby</div>
<div class="time-stamp" data-time="1322631934000">1322631934000</div>
</div>
</li>
Inside each tweet on the page, not the new tweet yet, I use jQuery to append some elements.
I have:
var actionsMarkup =
"<div class='actions'>
<span class='favorite'>Favorite</span>
<span class='retweet'>Retweet</span>
<span class='reply'>Reply</span>
</div>";
and I append it to the element with the .content class
$(actionsMarkup).appendTo('#tweets .tweet .content');
Now, when I make a new tweet I do the following:
$(document).on('click', '.refresh', function() {
newTweet = $(<new tweet code from above>);
actionsMark = $(actionsMarkup);
$(newTweet.appendTo('#tweets');
I need to be able to append the actionsMark contents to the div with class .content. However, I can't just reapply my prior statement of
$(actionsMarkup).appendTo('#tweets .tweet .content');
because that puts the markup on all .content divs again, even if it is already there.
Is there a way for me to use selectors to access the DOM nodes in my newTweet variable before I append it to the document object?
I am thinking something like
$(actionsMarkup).appendTo( newTweet, '.content');
If there is no way with selectors to do this then what are some other quick ways?
List of Tweets and Tweet container
<ul id="tweets" class="normal-tweet show-promoted-tweets">
<li class="tweet promoted-tweet" data-user-name="Dorothy">
<div class="image">
<img height="48" width="48" src="http://twitter.com/api/users/profile_image?screen_name=Dorothy" alt="" />
</div>
<div class="content">
<div class="user">
<a class="user-name" href="http://twitter.com/Dorothy" title="Dorothy">Dorothy</a>
<div class="full-name">Dorothy</div>
</div>
<div class="text">Somewhere over the rainbow</div>
<div class="time-stamp" data-time="1322631934000">3 minutes ago</div>
</div>
</li>
<li class="tweet promoted-tweet" data-user-name="lion">
<div class="image">
<img height="48" width="48" src="http://twitter.com/api/users/profile_image?screen_name=lion" alt="" />
</div>
<div class="content">
<div class="user">
<a class="user-name" href="http://twitter.com/lion" title="lion">lion</a>
<div class="full-name">Lion</div>
</div>
<div class="text">Way up high,</div>
<div class="time-stamp" data-time="1322631934000">17 minutes ago</div>
</div>
</li>
<li class="tweet normal-tweet" data-user-name="scarecrow">
<div class="image">
<img height="48" width="48" src="http://twitter.com/api/users/profile_image?screen_name=scarecrow" alt="" />
</div>
<div class="content">
<div class="user">
<a class="user-name" href="http://twitter.com/scarecrow" title="scarecrow">scarecrow</a>
<div class="full-name">Scarecrow</div>
</div>
<div class="text">And the dreams that you dreamed of,</div>
<div class="time-stamp" data-time="1322631934000">32 minutes ago</div>
</div>
</li>
</ul>
You can use .last(), to select the last element after you append your new tweet, like below:
$(document).on('click', '.refresh', function() {
newTweet = $(<new tweet code from above>);
$(newTweet).appendTo('#tweets');
var actionsMarkup =
"<div class='actions'>
<span class='favorite'>Favorite</span>
<span class='retweet'>Retweet</span>
<span class='reply'>Reply</span>
</div>";
$("#tweets .tweet").last().find(".content").append(actionsMarkup);
});
if you insist to use appendTo(), you can try using :last-child:
$(actionsMarkup).appendTo('#tweets .tweet:last-child .content');
I was looking to see if you can do the same thing, found this question but the existing answer is not useful in my case as i would like to alter the element before adding.
You can create a new dom element in a variable with jQuery and do operations on it as if it is already in the dom before appending it.
Example:
var newTweet = $('<div></div>');
newTweet.addClass('tweet');
newTweet.append('<span class="username"></span>');
newTweet.find('span.username').html('John Doe');
$('body').append(newTweet);
the following will be appended to the body:
<div class="tweet"><span class="username">John Doe</span></div>
Very handy if you are building a reusable interface element (like a dialogue box) with multiple options.
Related
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>
I'm having difficulty writing the document.querySelector for the following code. Currently I've written this code as querySelector but it does not encompass everything...
Please help me improve this, thank you.
Edit: as there seemed to be some confusion, let me elaborate. I would like all the elements, from div, a, img, everything to be encompassed in the querySelector.
var areaa = document.querySelector("#menu #envelope #links");
<div id="menu">Click here to browse the internet.
<div id="envelope">
<div id="links" >
<div>
<a id="g" class="redirect">
<img id="google" src="assets/google.png" />
</a>
</div>
<div style="width: 20%;"></div>
<div>
<a id="s" class="redirect">
<img id="sava" src="assets/Logo_Sava.png"/>
</a>
</div>
</div>
</div>
</div>
Edit 2 - as more code was required (the href elements are removed / added as needed)...
var menu = document.getElementById("menu");
var areaa = document.querySelectorAll(".areaa");
menu.addEventListener("mouseenter", addHref);
//areaa.addEventListener("mouseleave", remHref);
document.addEventListener("mousemove", function(){
if(this != areaa){
remHref();
}
});
menu.addEventListener("click", addHref);
document.addEventListener("click", function (){
if (this != areaa){
remHref();
}
});
var g = document.getElementById("g");
var s = document.getElementById("s");
function remHref (){
if (g.hasAttribute("href")){
g.removeAttribute("href");
}
if (s.hasAttribute("href")){
s.removeAttribute("href");
}
}
function addHref (){
setTimeout(activate, 250);
}
function activate (){
document.getElementById("g").setAttribute("href", "https://www.google.com");
document.getElementById("s").setAttribute("href", "https://www.example.com");
}
you might want to add a class to all elements you want to be captured, then use document.querySelectorAll
var areaa = document.querySelectorAll(".my-class");
html shoud look like this:
<div id="menu" class="my-class">Click here to browse the internet.
<div id="envelope" class="my-class">
<div id="links" class="my-class">
<div>
<a id="g" class="redirect">
<img class="my-class" id="google" src="assets/google.png" />
</a>
</div>
<div style="width: 20%;"></div>
<div>
<a id="s" class="redirect">
<img id="sava" src="assets/Logo_Sava.png"/>
</a>
</div>
</div>
</div>
If you want to select everything you can use the below:
var areaa = document.querySelectorAll("#menu #envelope #links *");
If you want to be more specific you can do the following (the code below will select all of the anchor tags and images inside #links):
var areaa = document.querySelectorAll("#menu #envelope #links a, #menu #envelope #links img");
You can use querySelectorAll
The Document method querySelectorAll() returns a static (not live) NodeList representing a list of the document's elements that match the specified group of selectors.
Learn more: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
You can use it like this:
var areaa = document.querySelectorAll('*');
This will return all items.
You can replace document with the container if you want to restrict this to a specific div.
2 things, either add a class to every div
<div id="menu" class="area">Click here to browse the internet.
<div id="envelope" class="area">
<div id="links" class="area" >
<div>
<a id="g" class="redirect">
<img id="google" src="assets/google.png" />
</a>
</div>
<div style="width: 20%;"></div>
<div>
<a id="s" class="redirect">
<img id="sava" src="assets/Logo_Sava.png"/>
</a>
</div>
</div>
</div>
</div>
and select all divs by
let areaa = getElementsByClassName("area");
or you can use document.querySelectorAll("yourclassname") to access all divs of that class name
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?