I am looking to use jQuery to view a bunch of <div> elements which all have the same class name, and check to see if the h3 within these <div> elements has any content. I was thinking this would work (as below) but its not... what am I doing wrong?
$('.wrapperDIV').each(function (i) {
if( $(this).closest('h3').val().length == 0 ) {
$(this).addClass('.hideME');
}
});
Markup is:
<div class="wrapperDIV">
<span class="ItemNo">5.</span>
<img src="" title="" alt="">
<h3></h3>
<div class="composer-button">
Read more
</div>
</div>
Try to use get text instead of value
$('.wrapperDIV').each(function (i) {
if( $(this).find('h3').text() === "" ) {
$(this).addClass('.hideME');
}
});
<div class="wrapperDIV">
<span class="ItemNo">5.</span>
<img src="" title="" alt="">
<h3></h3>
<div class="composer-button">Read more</div>
</div>
Try to use .find('h3') instead of .closest('h3').
Also when using .addClass() you dont need to include the dot.
$('.wrapperDIV').each(function (i) {
if( $(this).find('h3').val().empty()) {
$(this).addClass('hideME');
}
});
<div class="wrapperDIV">
<span class="ItemNo">5.</span>
<img src="" title="" alt="">
<h3></h3>
<div class="composer-button">Read more</div>
</div>
This should solve your problem.
For more info, read this
post or the jQuery .addClass() Documentation.
You can achieve this effect using CSS alone, by using the :empty pseudo-class:
.wrapperDIV h3:empty {
display: none;
}
Further Reading:
https://developer.mozilla.org/en-US/docs/Web/CSS/:empty
You may try this workable code in vanilla JavaScript:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test1</title>
<script>
window.onload = function(){
let div = document.getElementsByClassName('wrapperDIV');
let ch = div[0].children;
for(let i=0;i<ch.length; i++){
if ( ch[i].tagName=='H3' ){
let text = ch[i].textContent;
if (!text) console.log('It\'s h3 without text')
}
}
}
</script>
</head>
<body>
<div class="wrapperDIV">
<span class="ItemNo">5.</span>
<img src="" title="" alt="">
<h3></h3>
<div class="composer-button">
Read more
</div>
</div>
</body>
</html>
In jQuery you may use the code as under:
$(document).ready(function(){
let h3 = $(".wrapperDIV > h3");
if ( !h3.textContent ) console.log('h3 has no text contents');
});
Related
I have about 30 options that a user can select. When they click the option it opens/highlights a content/html box for that selection and hides the others (similar to a picture lightbox but instead of thumbnails and main pic I need html).
I've found this Jquery code example: http://jsfiddle.net/EhtrR/1238/
<img id="img1"/>
<img id="img2"/>
<img id="img3"/>
<img id="img4"/>
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
$("#img1").on('click', function() {
$("#div1").fadeIn();
$("#div2,#div3,#div4").fadeOut();
});
$("#img2").on('click', function() {
$("#div2").fadeIn();
$("#div1,#div3,#div4").fadeOut();
});
$("#img3").on('click', function() {
$("#div3").fadeIn();
$("#div1,#div2,#div4").fadeOut();
});
$("#img4").on('click', function() {
$("#div4").fadeIn();
$("#div1,#div2,#div3").fadeOut();
});
(Please note the images are just example. These can be div boxes or span.)
but as I'll need 20-30 of these options I was wondering how I can make it more efficient or do you suggest another way? I noticed on Mobile touch taps the clicks were fairly slow with the Jquery.
To DRY and simplify the logic you could put each set of elements in containers, grouped by their behaviour. Then apply common classes to them and relate them on click by their indexes. Try this:
let $contents = $('.content');
$('.trigger').on('click', e => {
let $target = $contents.eq($(e.target).index()).fadeToggle();
$contents.not($target).fadeOut();
});
.content { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="trigger-container">
<img src="01.jpg" class="trigger" />
<img src="02.jpg" class="trigger" />
<img src="03.jpg" class="trigger" />
<img src="04.jpg" class="trigger" />
</div>
<div class="content-container">
<div class="content">1</div>
<div class="content">2</div>
<div class="content">3</div>
<div class="content">4</div>
</div>
for(let i=0;i<=4;i++){
$("#img"+i).on('click', function() {
$("#div"+i).fadeIn();
for(var num=0; num<=4; num++)
{
if(num!=i)
{
$("#div"+num).fadeOut()
}
}
});
}
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 display only the first image in each div.className.
This...
<div class="className">
<p>Yo yo yo</p>
<p><img src="snoop.jpg" /></p>
</div>
<div class="className">
Helloooooo
<img src="biggie.jpg" />
<img src="tupac.jpg" />
<img src="coolio.jpg" />
Blah blah blah
</div>
<div class="className">
<div><img src="dmx.jpg" /></div>
<div><img src="willsmith.jpg" /></div>
</div>
Would display as...
[snoop.jpg]
[biggie.jpg]
[dmx.jpg]
ONLY the first image of each div.className would display, without all of the other content. The content is dynamic and changes frequently.
jQuery I've tried:
var imgarray = $(".className").find("img:first").attr('src');
for(i = 0; i < imgarray.length; i++){
$('body').append('<img src=\"'+imgarray[i]+'\">');
}
...
(to try to get the SRC of each image...)
$('.className').each(function() {
alert( $('img').attr('src') );
});
Nothing is working. Thanks for the help (in advance)! BTW, I'm very front-end HTML/CSS and not great at jQuery.
EDIT: Fixed typos (left out quote marks after image SRC's)
EDIT: Thanks so much everyone! Here's how I implemented the checked answer to work for me:
<style type="text/css">
.className {
display: none;
}
</style>
<div class="className">
<p>Yo yo yo</p>
<p><img src="snoop.jpg" /></p>
</div>
<div class="className">
Helloooooo
<img src="biggie.jpg" />
<img src="tupac.jpg" />
<img src="coolio.jpg" />
Blah blah blah
</div>
<div class="className">
<div><img src="dmx.jpg" /></div>
<div><img src="willsmith.jpg" /></div>
</div>
<script type="text/javascript">
$('.className').each(function() {
var imagesrc = $(this).find('img').first().attr('src') ;
$('body').append( '<img src=\"' + imagesrc + '\">');
});
</script>
You have to use .find() along with .first() to accomplish what you want.
Try,
$('.className').each(function() {
alert( $(this).find('img').first().attr('src') );
});
You can use .find() and the :first-selector
$('.className').find('img:first').show()
Demo: Fiddle
Here is a JavaScript solution that will do a linear search on each of the child nodes of the element with the class name className. The one question that needs to be asked is: By default, is each image hidden?
<div class="className">
<img style="display:none;" src="x" />
<img style="display:none;" src="x" />
</div>
<div class="className">
<img style="display:none;" src="x" />
<img style="display:none;" src="x" />
</div>
<div class="className">
<img style="display:none;" src="x" />
<img style="display:none;" src="x" />
</div>
<script>
var el = document.getElementsByClassName('className');
for(var a = 0; a < el.length; a++) {
for (var i = 0; i < el[a].childNodes.length; i++) {
if(el[a].childNodes[i].tagName == "IMG") {
el[a].childNodes[i].style.display="block";
console.log(el[a].childNodes[i].src);
break;
}
}
}
</script>
Demo: Fiddle
After clarifying your question, I made my answer in three parts.
Firstly, wrap text in hide span
$('.className').contents().filter(function(){
return this.nodeType == 3 && $.trim(this.nodeValue).length;
}).wrap('<span class="spanhide" style="display: none;" />');
Secondly, hide all images
$('img', '.className').each(function () {
var img = $(this);
console.log("hide->" + img.attr('src'));
img.hide();
});
Third, display first image in each className div
$('img:first', '.className').each(function () {
var img = $(this)
console.log("show->" + img.attr('src'));
img.show();
});
Till now I can grab the src of the image and display it in a fixed division, kind of like a pop up. But I want to hide the div element when the mouse is clicked outside the div. Please guide me how to do it, and also please correct me if my code can be improved. Thanks!
js:
$(document).ready(function () {
$(".pic").hide();
$(".screen").click(function () {
display($(this));
});
});
function display($this) {
var source = $("img", $this).attr("src");
$(".pic img").attr("src",source);
$(".pic img").css("width","450px");
$(".pic").show();
}
html:
<div id="album">
<div class="pic">
<img src="" />
</div>
<div class="screen">
<h1 class="title">Photo 1</h1>
<img src="images/1 png.png" class="image" />
<p class="description">This is a description</p>
</div>
<div class="screen">
<h1 class="title">Photo 1</h1>
<img src="images/2 png.png" class="image" />
<p class="description">This is a description</p>
</div>
<span class="clear_left"></span>
</div>
blur event of jquery can be used
$(".screen").bind('blur',function () {
hide($(this));
});
function display($this) {
$(".pic").hide();
}
Try like this
$(document).click(function () {
if ($(this).class != "pic") {
$(".pic").hide();
}
});
Live Demo
Okay, so I am in the process of recreating this feature:
http://www.w3.org/html/logo/#the-technology
I current have it so when you click on a link, it will add a class to the image that relates to that link (href="#one" on the <a> and then id="#one" on the <img>), however it is currently not going through each <a> tag and only one. And also it is not removing the class I requested.
Code follows:
JS
$(document).ready(function() {
var container = '#portfolio #text_container';
var img_container = '#portfolio #image_container';
$(container).children('a').bind('click', function() {
var this_attr = $(this).attr('href');
var this_img = $(img_container).find('img').attr('id');
if(this_attr == this_img) {
//$(img_container).find('img').hasClass('current').removeClass('current');
// ^^^ This line isn't working, any ideas? :/
$(img_container + ' img[id*="' + this_attr + '"]').addClass('current');
}
else {
alert(this_img + ' this img');
alert(this_attr + ' this attr');
}
});
});
And the HTML is as follows
<div id="portfolio">
<div id="image_container">
<img src="http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif" alt="" class="current" id="#one" />
<img src="http://static.jquery.com/files/rocker/images/btn_downloadLarge.gif" alt="" id="#two" />
</div>
<div id="text_container">
Item 1
Item 2
<p id="#one" class="current">A bunch of text!</p>
<p id="#two">The second bunch of text!</p>
</div>
</div>
Please let me know if you need any more information :)
rcravens fixed this with the following code..
JS
$(document).ready(function() {
$('#text_container a').click(function(evt) {
evt.preventDefault();
$('.current').removeClass('current');
var href = $(this).attr('href');
$("." + href).addClass('current');
});
And the HTML..
<div id="portfolio">
<div id="image_container">
<img src="http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif" alt="" class="one current" />
<img src="http://static.jquery.com/files/rocker/images/btn_downloadLarge.gif" alt="" class="two" />
</div>
<div id="text_container">
Item 1
Item 2
<p class="one current">A bunch of text!</p>
<p class="two">The second bunch of text!</p>
</div>
</div>
My interpretation of what you are trying to do is here:
http://jsfiddle.net/rcravens/wMhEC/
The code is changed a bit. You shouldn't have multiple elements with the same id.
Bob
The reason this isn't working:
if(this_attr == this_img)
is because this_attr is a URL and this_img is an ID attribute value.