I'm trying to add a Class to an img when the mouse is over an element and remove the class when the mouse is no longer over the element. I'm using object literal notation. I can't see to select the correct image, can anyone see where i'm going wrong?
let Cc = {
bindEvent: function() {
$('.title.em-below').hover( function() {
let selectedtitle = $(this);
Cc.scaleThumbnail(selectedtitle);
})
},
scaleThumbnail: function(selectedtitle) {
let $thumbnail = selectedtitle.siblings('.image-thumbnail')
let img = $thumbnail.children('img');
console.log(img);
img.addClass('thumbnail-active');
img.removeClass('thumbnail-active');
},
}
.thumbnail-active {
transform: scale(1.1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="title em-below">
Title
</div>
<a class="image-thumbnail">
<div class="wide-thumbnail em-below">
<img src="https://via.placeholder.com/350x150"/>
</div>
</a>
</div>
You need to call CC.bindEvent() to bind the event handler. And your hover function needs to toggle the class, not add it and then immediately remove it.
The img element is not a child of $thumbnail, it's the grandchild. Use .find() instead of .children().
let Cc = {
bindEvent: function() {
$('.title.em-below').hover( function() {
let selectedtitle = $(this);
Cc.scaleThumbnail(selectedtitle);
})
},
scaleThumbnail: function(selectedtitle) {
let $thumbnail = selectedtitle.siblings('.image-thumbnail')
let img = $thumbnail.find('img');
//console.log(img.attr('src'));
img.toggleClass('thumbnail-active');
},
}
Cc.bindEvent();
.thumbnail-active {
transform: scale(1.1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="title em-below">
Title
</div>
<a class="image-thumbnail">
<div class="wide-thumbnail em-below">
<img src="https://via.placeholder.com/350x150"/>
</div>
</a>
</div>
The problem is with this line, because of which the img tag is not captured.
$thumbnail.children('img');
.children only traverses its immediate child which is .wide-thumbnail.em-below.
Use .find instead
$thumbnail.find('img');
Related
I need a button called #btn-limone to remove filter: "grayscale(100%)" on first click and on the second click to restore it. I need it to be done through styles and not classes. How can I do this?
jQuery("#btn-limone").on("click", function () {
jQuery("#agrumi_box, #frutta_polpa_bianca_box, #limone_box").removeAttr("style");
});
With this I can remove the style but I would like that at the second click it would be brought back to 100%.
Thank you to anyone who wants to help me
You can check it has style attribute or not, if id doesn't have you can add your style, if it has style you can remove it. like this:
const items = $('.item');
function toggleFilter(button, relevantIndexes) {
const toggleOn = button.attr('data-toggle') == 'on'
button.attr('data-toggle', toggleOn ? 'off' : 'on')
$.each(items, function(index, item) {
if (!relevantIndexes.includes(index)) return;
const style = item.getAttribute('style');
if (toggleOn) {
item.removeAttribute('style');
} else {
item.setAttribute('style', 'filter:grayscale(100%)');
}
});
}
$('#btn-limone').on('click', function() {
const relevantIndexes = [0, 1, 3];
toggleFilter($(this), relevantIndexes);
});
$('#btn-lime').on('click', function() {
const relevantIndexes = [1, 2, 3];
toggleFilter($(this), relevantIndexes);
});
.item {
display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<div class="item">
<img src="https://fakeimg.pl/200x100/a10000/?text=Lemone" />
</div>
<div class="item">
<img src="https://fakeimg.pl/200x100/a10000/?text=Lemone-Lime" />
</div>
<div class="item">
<img src="https://fakeimg.pl/200x100/a10000/?text=Lime" />
</div>
<div class="item">
<img src="https://fakeimg.pl/200x100/a10000/?text=Lemone-Lime" />
</div>
</div>
<button class="btn" id="btn-limone" data-toggle="off">Limone</button>
<button class="btn" id="btn-lime" data-toggle="off">Lime</button>
I'm learning JavaScript and this is a practice scenario for me.
What I have already is a button that clones content, and within that content that has been cloned, there is a button to remove it.
When I click the button that prompts you to remove the content, it removes the first set of content.
What I want to happen is when you click the button that prompts you to remove the content, it removes the content related to that button and nothing else.
This is the CodePen link.
https://codepen.io/JosephChunta/pen/YzwwgvQ
Here is the code.
function addContent() {
var itm = document.getElementById("newContent");
var cln = itm.cloneNode(true);
document.getElementById("placeToStoreContent").appendChild(cln);
}
function removeContent() {
var x = document.getElementById("content").parentNode.remove();
}
// This is for debug purposes to see which content is which
document.getElementById('orderContent')
.addEventListener('click', function(e) {
const orderedNumber = document.querySelectorAll('.thisIsContent');
let i = 1;
for (p of orderedNumber) {
p.innerText = '' + (i++);
}
});
.contentThatShouldBeHidden {
display: none;
}
<div id="placeToStoreContent">
</div>
<button id="orderContent" onclick="addContent()">Add Content</button>
<div class="contentThatShouldBeHidden">
<div id="newContent">
<div id="content">
<p class="thisIsContent">This is a prompt</p>
<button onclick="removeContent()">Remove this</button>
<hr />
</div>
</div>
</div>
When you'r trying to remove by ID, it takes the first ID it finds.
To remove the correct content, send this onclick.
<button onclick="removeContent(this)">Remove this</button>
And handle it in your function:
function removeContent(el) {
el.parentNode.remove();
}
Example:
function addContent() {
var itm = document.getElementById("newContent");
var cln = itm.cloneNode(true);
document.getElementById("placeToStoreContent").appendChild(cln);
}
function removeContent(el) {
el.parentNode.remove();
}
// This is for debug purposes to see which content is which
document.getElementById('orderContent')
.addEventListener('click', function(e) {
const orderedNumber = document.querySelectorAll('.thisIsContent');
let i = 1;
for (p of orderedNumber) {
p.innerText = '' + (i++);
}
});
.contentThatShouldBeHidden { display: none; }
<div id="placeToStoreContent">
</div>
<button id="orderContent" onclick="addContent()">Add Content</button>
<div class="contentThatShouldBeHidden">
<div id="newContent">
<div id="content">
<p class="thisIsContent">This is a prompt</p>
<button onclick="removeContent(this)">Remove this</button>
<hr />
</div>
</div>
</div>
In your remove button, do this:
<!-- The "this" keyword is a reference to the button element itself -->
<button onclick="removeContent(this)">Remove this</button>
And in your javascript:
function removeContent(element) {
element.parentNode.remove();
}
I'm trying to loop through divs and set the content of a div inside the outer div. I tried this.
Here is the HTML div's I want to loop through and I want to set the content of div with class content-detail with the value for its attribute data-form data.
//the javascript code I used is this
$(function($) {
for (var i of $(".item .content-detail")) {
var container = document.querySelector($(i)[0]);
var formData = $(i).attr("data-formdata");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<div class="item">
<div class="down-div"> </div>
<div class="detail">
<h4>Detail</h4>
<div id="div_" class="content-detail" data-formdata="my Item">
</div>
<div class="text-center">
<button class="btn btn-blue center"> SET !</button>
</div>
</div>
</div>
<div class="item">
<div class="down-div"> </div>
<div class="detail">
<h4>Detail</h4>
<div id="div_" class="content-detail" data-formdata="my Item">
</div>
<div class="text-center">
<button class="btn btn-blue center"> SET !</button>
</div>
</div>
</div>
But am stuck at this point var container = document.querySelector($(i)[0]);
I don't know how to get the jquery selector of that current div to a variable.
This may need some tweaks, but it should be close...
$(function ($) {
$(".item .content-detail").each(function(index, element) {
element.text($(element).attr("data-formdata"))
})
});
Take a look at the .each() method
$(function($) {
for (var i of $(".item .content-detail")) {
//var container = document.querySelector($(i)[0]);
var container = i;
var formData = $(i).attr("data-formdata");
}
});
I just needed the element
If you want to set the content of each DIV, you don't need a for loop. The .text() method takes a callback function, and it will be called on each element that matches the selector. The returned value is used as the new content.
$(".item .content-detail").text(function() {
return $(this).data("formdata");
});
This works.
$(function($) {
$(".item .content-detail").text(function(){
return $(this).attr("data-formdata");
})
});
Can you not just use JS like this:
[UPDATED]
function test() {
var divs = document.getElementsByTagName("div");
for (var i = 0; i < divs.length; i++) {
var divsSub = divs[i].getElementById("div_").querySelectorAll(".content-detail");;
for (var iS = 0; iS < divsSub.length; iS++) {
var x = divsSub[iS].getAttribute("data-formdata");
divsSub[iS].innerHTML = x;
}
}
}
I'm working with HTML and JavaScript and I need to make two instances of a toggle link. Here is my code for a single one:
<script language="javascript">
function toggle() {
var ele = document.getElementById("toggleText");
var text = document.getElementById("displayText");
if(ele.style.display == "block") {
ele.style.display = "none";
text.innerHTML = "link1";
}
else {
ele.style.display = "block";
text.innerHTML = "link1";
}
}
</script>
<body> <a id="displayText" href="javascript:toggle()" style="font-size:160%;">link1</a>
<div id="toggleText" style="display: none; font-size:160%;"><p>paragraph1</p></div><br></body>
I need the two toggle links to independently show/hide different paragraphs of text when each one is clicked. How can I add a second instance below the first?
Add an event handler and a data-toggle-id attribute to each link. In your event handler, get the value of the data-toggle-id and use that to find the paragraph that you would like to show. Then use the toggle method of the element's classList to add/remove a class that shows the paragraph.
var links = document.querySelectorAll('[data-toggle-id]');
for (var ix = 0; ix < links.length; ix++) {
links.item(ix).addEventListener('click', function() {
document.getElementById(this.dataset.toggleId).classList.toggle('show');
});
}
.toggleText {
display: none;
}
.show {
display: block;
}
<link href="//cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css" rel="stylesheet" />
<div class="container">
<a data-toggle-id="paragraph1">link1</a>
<div class="toggleText" id="paragraph1">
<p>paragraph1</p>
</div>
</div>
<div class="container">
<a data-toggle-id="paragraph2">link2</a>
<div class="toggleText" id="paragraph2">
<p>paragraph2</p>
</div>
</div>
<div class="container">
<a data-toggle-id="paragraph3">link3</a>
<div class="toggleText" id="paragraph3">
<p>paragraph3</p>
</div>
</div>
If you hate for loops, you can use Nick's suggestion and convert the NodeList to and array and use the forEach method:
Array.prototype.slice.call(document.querySelectorAll('[data-toggle-id]')).forEach(function(element) {
element.addEventListener('click', function(){
document.getElementById(this.dataset.toggleId).classList.toggle('show');
});
});
I am making an image slider with two arrows on either side of the slider. For instance, when .click() the .rightArrow, a class is added ( .addClass() ) called .moveRight.
.moveRight{
transform: translate(760px,0);
-webkit-transform: translate(760px,0); /** Safari & Chrome **/
-o-transform: translate(760px,0); /** Opera **/
-moz-transform: translate(760px,0); /** Firefox **/
}
The problem is that this click event only triggers once. I imagine this is because I am telling the moveable element to go to a specific location.
I want to the element to keep moving right for a certain amount of px every time I .click() the .rightArrow.
The jQuery
$( document ).ready(function() {
$('.rightArrow').click( function() {
$('.imgGluedToThis').removeClass("moveLeft");
$('.imgGluedToThis').addClass("moveRight");
});
$('.leftArrow').click( function() {
$('.imgGluedToThis').removeClass("moveRight");
$('.imgGluedToThis').addClass("moveLeft");
});
});
Here is the HTML
<img src="rightArrow.png" class="rightArrow">
<img src="leftArrow.png" class="leftArrow">
<div class="pictures-container">
<div class="imgGluedToThis">
<div class="picture-container">
<a href="#openModal1">
<img src="house.png" class="picture">
</a>
</div>
<div class="picture-container">
<a href="#openModal1">
<img src="building.png" class="picture">
</a>
</div>
<div class="picture-container">
<a href="#openModal1">
<img src="house2.png" class="picture">
</a>
</div>
<div class="picture-container">
<a href="#openModal1">
<img src="house.png" class="picture">
</a>
</div>
<div class="picture-container">
<a href="#openModal1">
<img src="building.png" class="picture">
</a>
</div>
<div class="picture-container">
<a href="#openModal1">
<img src="house2.png" class="picture">
</a>
</div>
</div>
</div>
Use css() method in jQuery
$(document).ready(function() {
$('.rightArrow').click( function() {
$('.imgGluedToThis').css('left','+=10px');
});
$('.leftArrow').click( function() {
$('.imgGluedToThis').css('left','-=10px');
});
});
FIDDLE
Or use animate() method
$(document).ready(function() {
$('.rightArrow').click( function() {
$('.imgGluedToThis').animate({'left':'+=10px'});
});
$('.leftArrow').click( function() {
$('.imgGluedToThis').animate({'left':'-=10px'});
});
});
FIDDLE
The click event is triggering correctly every time - translate will move an element to a specific position. If it is already 760px across and click is called again to move it to 760px, nothing appears to happen.
You could set up a few classes to define where the leftmost, rightmost etc images should display, updating the classes for each element accordingly.
If the slider needs to be infinite, you will need to update the DOM too to set the elements to the correct order, updating the classes again once you have done so.
If you want to use translate, specifically, you will need to track it and change it with code, perhaps like this:
jQuery(function ($) {
// closures
var iImageIndex = 0;
var iSlideWidth = 760;
var iImageMax = $('.picture-container').size();
var $slides = $('.imgGluedToThis');
var fTranslate = function (iDirection) {
iDirection = (iDirection && (iDirection < 0) ) ? -1 : 1; // normalize direction
iImageIndex = iImageIndex + iDirection; // increment direction
iImageIndex = iImageIndex < 0 ? iImageMax + iImageMax : iImageIndex; // check left end
iImageIndex = iImageIndex % iImageMax; // check right end
$slides.css('transform', 'translate(' + (iSlideWidth * iImageIndex) + 'px, 0)');
}
// event methods (closures)
var fClickLeft = function () {
fTranslate(-1);
};
var fClickRight = function () {
fTranslate(1);
};
// event handlers
$('.rightArrow').click(fClickRight);
$('.leftArrow').click(fClickLeft);
});