Click to change inner child and other sections with Javascript/ES6 - javascript

So I made this in Jquery:
Game Gallery
However I need to change it in Vanilla/ES6 and I'm a stuck on how to target the parents child on click and also find the index (.eq($(this).parent().index()) for other sections(copy and images section in my case):
My tryout was doing a for loop like:
const mode = document.querySelectorAll('.gamegallery span');
for (let i = 0; i < mode.length; i++) {
mode[i].onclick = function() {
this.parentNode.classList.toggle('active');
};
}
But it seems I'm missing something to get the parent to stay in sync with the icons because it sets .active but stays .active on all icons. I tried:
if {
this.parentNode.classList.add('active');
}
else {
this.parentNode.classList.remove('active');
}
Which does nothing...theres something else Im missing?
Lastly to also change a different section like the content/images I used:
$('.gamegallery .game-images img').eq($(this).parent().index()).addClass('active');
});
I basically need to do the same function all at once. Removing active to icons - content-images parents. Finding the first object and then go to the parents side and go to each index(which is the first one as default). node.parentNode.childNodes; is the one thing I found...I'll keep updating. Not asking to do it but more of what I'm missing from the code I added. Specifically the first part. Coming from a noob EcsMaScript/Modern Vanilla guy.

Rather than traversing the node hierarchy in search of the elements you want to toggle you can simplify it by specifying a target. This comes in handy if your clicked node's index doesn't match your intended target.
Checkout this Fiddle for a Demo
You can use the data- HTML attribute. For example: data-target=".xbox" could be applied to your span.circle element since that is what you're adding your click listener to.
<span class="circle" data-target=".xbox">
and add the class inside data-target to your, well, target:
<div class="swiper-slide xbox"></div>
and
<img src=".." class="xbox">
On click, you can pull your target from the element with: this.dataset and specify what you're looking for. In this case it is: const target = this.dataset.target.
With the target's selector found from the dataset we can find the elements with a selector:
const targets = document.querySelectorAll('.swipe-slider'+target+', .game-images '+target');
Once we have the target we can remove the current active class from our target's neighbors. In this case, though, I've simply removed it from all.
document.querySelectorAll('.swiper-slide, .game-images img').forEach(el => el.classList.remove('active'));
Then we add the active class with:
targets.forEach(target => target.classList.add('active');
Altogether now:
function handleClick(e) {
const target = this.dataset.target;
const targets = document.querySelectorAll('.swiper-slide'+target+', .game-images '+target);
document.querySelectorAll('.swiper-slide, .game-images img').forEach(el => el.classList.remove('active'));
targets.forEach(target => target.classList.add('active'));
}

Related

getElementsByClassName but manipulate only the one that i want

i have multiple div with same classname but i want to change only one of their opacity, the one that i interact with a mouse or touch. How can i do it? The below code changing all of theirs properties, apparently. Full .js code is here if anyone would like to take a look at: https://jsfiddle.net/b7y6mfv4/
var target1 = document.getElementsByClassName('beforeLabel');
var target2 = document.getElementsByClassName('afterLabel');
for (var i=0; i<target1.length; i++) {
target1[i].style.opacity = beforeAfter;
target2[i].style.opacity = beforeAfter2;
}
Based on your fiddle, change document.getElementsByClassName to evt.target.getElementsByClassName and get rid of the loop.
Target lets you reference only the element that is the target of the event.
Your JS is looping through all elements with either of those two class names and applying opacity. What you can do is make use of the mouse events target property, which will give you the specific element which has been interacted with, and apply the opacity to that.
document.addEventListener('mouseover', (event) => {
if (event.target.className.includes("beforeLabel")) {
event.target.style.opacity = 0.5;
}
});
You can see a full working example here.

Grabbing an element by class and then changing it. - Shopify/Plugin

I need a little bit of help with my shopify store. I'm trying to change the class of a button in order to style it from the default class "btn" to "askAQButton". However, the code for the buttons are not in the markup at all and so I can only assume they're generated by JS by the shopify plugin itself.
I figured it should be simple and I should be able to just target the element by "id" with jquery and change class. However, the button doesn't have an ID and neither does the href...
My next thought was okay, target the parent div by id, then target the class of the button and href and change it that way (to avoid targeting duplicate classes).
I just can't seem to get it working.
Here is all the markup I'm given to implement this onto my store page:
Obviously a lot of it is irrelevant (probably all of it besides the parent div) however, when I load my page up after implementing this code it auto-generates this right under the second input:
<div class="wk-ask-order">
<button class="wk-ask-a-question-order btn" style="display: inline-block;">Raise a Query
</button>
View Your Queries
</div>
Can anyone help me with targeting it and changing the class names please.
I'm not sure if I get the question right, but there might be a problem with the button having not yet been injected into the DOM at the time when your script is targeting it.
Try waiting for the DOMContentLoaded event before executing your code:
document.addEventListener('DOMContentLoaded', () => {
const askAQBtn = document.querySelectorAll('.wk-ask-a-question-order')[0]; //there's probably a better selector
askAQBtn.classList.replace('btn', 'askAQButton');
});
If that doesn't work, have a look at MutationObserver to wait for the specific element to exist. I found a snippet for this on Github:
https://gist.github.com/jwilson8767/db379026efcbd932f64382db4b02853e
This was my answer it's a bit lo-fi but I hope it gives you something to work from. I followed your idea regarding the parent div id.
let parent = document.getElementById('wk-askme');
let child_nodes = parent.childNodes;
for (let i = 0; i < child_nodes.length; i++) {
let item = child_nodes[i];
if ($(item).attr('class') == "wk-ask-a-question-order btn") {
$(item).attr('class', 'wk-ask-a-question-order askAQButton');
}
}

Unable to change the class of a div using JavaScript

So I got into JavaScript and tried setting up the following scenario:
I have 2 Buttons on my Site (IDs are buttonWebdev and buttonUXUI), which should trigger an Action when they are hovered upon. If buttonWebdev is hovered upon, it should hide all p', h3's and imgs with the class "classWeb". I wrote this code to do it, but it doesn't work:
HTML:
<h3 class="classWeb">Editierbare Inhalte</h3>
<p class="classWeb">Test</p>
<button class="buttonImg" id="buttonWebdev"><img src="./img/buttonWebdev.png" /></button>
<script type="text/javascript">
var button = document.getElementById('buttonWebdev');
var classWeb = document.getElementsByClassName('classWeb');
button.onmouseover = function() {
classWeb.className = 'webdev';
}
CSS:
.classWeb.webdev {
display: none;
}
First, since there can be more than one element with a given class on a page, getElementsByClassName returns a list of elements instead of a single element. You’ll need to perform your action on every element of that list, with a for…of loop, for example:
for (let element of classWeb) {
element.className = 'webdev';
}
(for…of is relatively new, though, so you might have to use a regular for loop depending on your target browsers.)
After fixing this, you’ll run into another problem. When you assign to className like that, you’re setting the entire list of classes on an object. If the list of classes is 'webdev', it no longer includes 'classWeb'. Modern browsers support an API to add a class without affecting the rest:
for (let element of classWeb) {
element.classList.add('webdev');
}
The way to diagnose these sorts of problems is by opening up your browser’s developer tools, looking for JavaScript errors in the console, and looking at the state of the elements you’re trying to affect in the document tree.
document.getElementsByClassName('classWeb'); this gives collection & to add classes you need to iterate over them & then apply classes.
classWeb[0].className = 'webdev'; would reset class
either use classWeb[i].className += ' webdev'; or classWeb[i].classList.add('webdev');
See below working example
var button = document.getElementById('buttonWebdev');
var classWeb = document.getElementsByClassName('classWeb');
button.onmouseover = function() {
for (var i = 0; i < classWeb.length; i++)
classWeb[i].className += ' webdev';
}
.classWeb.webdev {
display: none;
}
<h3 class="classWeb">Editierbare Inhalte</h3>
<p class="classWeb">Test</p>
<button class="buttonImg" id="buttonWebdev">hover over me</button>
Firstly, the
document.getElementsByClassName('classWeb');
will give you a LIVE list of all the matched elements. That means that when you reassign the class like so:
classWeb[0].className = 'webdev';
the element will be removed from the list, as it no longer corresponds to the original command which was to find all elements with a specific class (which you overrode with 'webdev').
An easier and more friendly api is querySelectorAll which mimics the jQuery selector (which uses css selectors to find elements, thats why there is a # for an id and a . for a class name). The example below shows, how to use it.
var button = document.querySelector('#buttonWebdev');
var classWeb = document.querySelectorAll('.classWeb');
button.onmouseenter = function() {
for (var i = 0; i < classWeb.length; i++) {
classWeb[i].className = 'webdev';
}
}
ps. The querySelectorAll is not a live list, so items will not disappear after you change their class.
ps2. Use onmousenter instead of onmouseover as the onmouseenter is only called when the mouse starts hovering over an element, while onmouseover will be called on every mouse move over the element (even if already hovering).
Good luck!

How to move a div with a dynamically added class name

So currently in class we are trying to make a 15-puzzle using ONLY Javascript, CSS, and basic HTML. I am also not allowed to modify the html at all, fun stuff. Anyway, I was able to add dynamic class names to my html and reference them in the css as follows:
var children = document.getElementById("puzzlearea").childNodes;
//iterates through all children
for (child in children) {
//if children is a div then we do something to it
if (children[child].nodeName == "DIV") {
//add a class that corresponds to a css to the current div child that we are on
children[child].classList.add('a' + i);
i = i + 1;
}
}
In our CSS then we are able to reference it by simply stating .a15 and assigning it the required margin, size, image positioning, and all. However, when I try to move it by referencing its id using document.getElementById(".a15").style.top = "200px" -- or just "a15" -- it does not work. The above mentioned way is the suggestions I have seen on stack in order to move divs.
Currently I am trying something as follows:
document.getElementsByTagName('div')[15].onclick = function () {
alert("work"); //does actually only happen on correct div
this.style.top = "500px" //still doesn't move it
}
However, with this it still does not move it, and of course fetches all divs. As such, the question still stands: "How to move divs with dynamically added class names?
Edit: Got it to move by also mentioning that the position should be relative in the CSS, however I can still only reference it in the above mentioned way and not via direct iD.
You are adding class to those div(s), so when you are referencing them instead of:
document.getElementById(".a15").style.top ...
it should be:
document.getElementsByClassName("a15").style.top ... // without .
Note that getElementsByClassName returns array of elements which has that certain class. So you may have to do something like
var currentDiv = document.getElementsByClassName("a15")[0] // assuming you have only one div with class a15
// then
currentDiv.style.top ...
working example just in case: https://jsfiddle.net/Laf54y1a/3/

jQuery: Toggle class on one element, remove same from all other

new here and deeply hoping I'm not missing a stupid syntax flaw. I was thinking that my problem is a fairly common one, but somehow nothing has helped so far in my specific case.
There is a simple inline-block list of Image Galleries which are zoomable to fill the parent width. As soon as one is zoomed through click on a child, the others should unzoom by stripping of the class which maximizes them. Nothing more to it.
I achieved the first part via the following jQuery (where the problem is hidden in the for-loop, I think):
$(".zoom").click(function() {
var target = $(this);
target.closest('div.product-item').toggleClass('maximized');
var ot = document.getElementsByClassName('product-item');
for (var i = 0; i < ot.length; i++) {
if (ot[i] !== target) {
ot[i].removeClass('maximized');
}
}
});
So: Some .zoom classed element is clicked, its parent is toggled to maximize and a for loop checks all other elements of the same class as the parent and removes the .maximized class.
The reason the script is constructed with a for-loop and a removeClass is so that the same .zoom elements are able to minimize their parent elements, not only to maximize them.
Im not a javascript professional, but to my knowledge this should work in principle. Am I missing anything here?
This post from a year ago addressed a similar problem but didn't help in my case: jQuery onClick: How to add class to element and remove from all others
You can find a pen to see the script in action here.
$(".zoom").on('click',function() {
var target = $(this);
$('div.product-item').removeClass('maximized');
target.closest('div.product-item').toggleClass('maximized');
});
you can use
if(target.closest('div.product-item').hasClass('maximized')){
$('div.product-item').removeClass('maximized');
}else{
$('div.product-item').removeClass('maximized');
target.closest('div.product-item').addClass('maximized');
}
JSFIDDLE

Categories

Resources