Compared with Vanilla JavaScript, does jQuery simplify selecting related nodes? [closed] - javascript

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
In my experience, jQuery simplifies DOM navigation immensely as when compared to using pure JavaScript.
Suppose I have two elements #parentA and #parentB and both these two elements have similar children nodes .x .y .z.
Often times, when I use JavaScript without jQuery, if I want to select #parentA's .x I end up accidentally selecting both #parentA .x as well as #parentB.x.
I suppose this is more of a backend developer's therapy session where I am just letting out my frustration with JS rather than asking a question.
The main reason why I am trying to avoid using jQuery is that I am trying to keep the website page weight as low as possible. What would the JavaScript equivalent be of the jQuery code I have below?
HTML
<h2>Colour 1</h2>
<div id="hairColor" class="color-palette">
<ul>
<li style="background: #fc4c4f;"></li>
<li style="background: #4fa3fc;"></li>
<li style="background: #ecd13f;"></li>
</ul>
</div>
<h2>Colour 2</h2>
<div id="skinColor" class="color-palette">
<ul>
<li style="background: #fc4c4f;"></li>
<li style="background: #4fa3fc;"></li>
<li style="background: #ecd13f;"></li>
</ul>
</div>
SCSS
.color-palette {
background: #384047;
min-height: 60px;
margin: 0 auto;
width: 100%;
border-radius: 5px;
overflow: hidden;
ul {
list-style: none;
margin: 0;
float: left;
padding: 10px 0 20px;
width: 100%;
text-align: center;
li {
display: block;
height: 54px;
width: 54px;
border-radius: 60px;
cursor: pointer;
border: 0;
box-shadow: 0 3px 0 0 #222;
display: inline-block;
margin: 0 5px 10px;
}
.selected {
border: 7px solid #fff;
width: 40px;
height: 40px;
}
}
}
JS
$(".color-palette").on("click", "li", function(){
$(this).siblings().removeClass("selected");
$(this).addClass("selected");
color = $(this).css("background-color");
});
// What would the equivalent code be using vanila JavaScript?
// var colors = document.querySelectorAll("#hairColor ul li");

To make that without something like jQuery, you'll need a few iterators (a for loop or something), is 100% doable and is not that hard but beware, is a larger piece of code.
What that code is doing is assigning the click event to the color-palette container and filtering by the target element to match the LI, if you want you can simplify it by just assigning the click to the li directly and check on the parent.
This is a starting point to replicate the same behavior:
document.querySelectorAll('.color-palette').forEach((palette) => {
palette.addEventListener('click', (e) => {
e.target.parentNode.querySelectorAll('li').forEach((li) => {
li.classList.remove('selected');
})
if (e.target.tagName.toLowerCase() !== 'li') {
return;
}
e.target.classList.add('selected');
})
})
This could be simplified a bit but is a draft and should be working.

Something like this should do the trick:
let triggers = document.querySelectorAll('li')
triggers.forEach(el => {
el.addEventListener('click', () => {
[...triggers].map(x => x.classList.remove('selected'))
el.classList.add('selected');
let color = el.style.backgroundColor;
})
})
First, you add eventlisteners to each li element, and when clicking on one, you create an array of the elements by using the spread ... operator. Chain this array afterwards with the map operator to remove the selected class. And finally, you simply add the selected class to the element you've clicked.

Related

Dynamically change a:before CSS tag [duplicate]

This question already has answers here:
Selecting and manipulating CSS pseudo-elements such as ::before and ::after using javascript (or jQuery)
(26 answers)
Closed 2 years ago.
I'm having some trouble dynamically changing the background field within the .tracking-list li a:before css for each a I'm looping through.
As an example I was able to change the background to "red" below and the name, but I'm unsure how to change the specific field "background" within .tracking-list li a:before.
Any suggestions on how I can dynamically change this? Thanks so much!
style.css
.tracking-list li a:before {
content: "";
background: url("../images/bitmap.svg") no-repeat;
display: inline-block;
width: 22px;
height: 20px;
margin-right: 4px;
vertical-align: middle;
}
JS
//Loop Through Names
var ul = document.getElementById(category);
for (var i = 0; i < data.data.length; i++) {
let record = data.data[i];
let tech_name = record.name;
let logo_image = record.logo;
var listItem = document.createElement("a");
listItem.textContent = tech_name;
listItem.style.background = "red";
ul.appendChild(listItem);
}
You can't target pseudo-classes with inline style.
If you want to change them you need to either:
Modify the stylesheet
Change the conditions which cause the rule to be applied to the pseudo-class in the first place
The latter is usually the simplest approach.
document
.querySelector("button")
.addEventListener("click", changeMiddleLink);
function changeMiddleLink() {
document.querySelector("li:nth-child(2) a").classList.add("changed")
}
.tracking-list li a::before {
content: "";
background: green;
display: inline-block;
width: 22px;
height: 20px;
margin-right: 4px;
vertical-align: middle;
}
.tracking-list li a.changed::before {
background: red;
}
<ul class="tracking-list">
<li>
Test
</li>
<li>
Test
</li>
<li>
Test
</li>
</ul>
<button type="button">Click me</button>

How to change the class of div according to the screen width using jquery [duplicate]

This question already has answers here:
jQuery ID selector works only for the first element
(7 answers)
Closed 3 years ago.
I am displaying the products on my HTML page. Some products have large details and some have minor details. When I show those products the div of products with large details have greater height than the products with minor details. To fix this issue I assigned height to the div but it didn't work because when I open my page in mobile view the details of the product overflow from its div. Then I tried to change the class of a div using media query: if width is < 991px change col-md-6 to col-md-12. I made this change using jquery but it only affect the first div.
What is the Standard solution of this problem?.
$(window).resize(function() {
if ($(window).width() < 991) {
alert("window");
$( "product612" ).removeClass( "col-md-6" ).addClass( "col-md-12" );
$("product612").toggleClass('col-md-6 col-md-12');
}
});
.product{
background-color: rgba(92, 90, 90, 0.096);
word-wrap:break-word;
position: relative;
text-align: center;
padding: 40px 20px;
margin: 15px 0px;
height: 433.4px !important;
}
.product:after {
content: "";
background-color: rgba(2, 2, 2, 0.781);
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 0%;
z-index: -1;
-webkit-transition: 0.2s width;
transition: 0.2s width;
}
.product:hover p{
color: white !important;
}
.product:hover:after
{
width: 100%;
height: auto;
}
.product p{
color: rgb(80, 80, 80) !important;
font-size: 17px;
line-height: 18px;
font-weight: 500;
font-family: Avant Garde, Avantgarde, Century Gothic, CenturyGothic, AppleGothic, sans-serif;
}
.product>img {
height: 150px;
width: 250px;
margin: 0px auto 12px auto;
margin-left: auto;
border-radius: 15%;
}
<div class="container" >
<div class="row">
<div class="section-header text-center" >
<h1 class="glow title">Products</h1>
</div>
{% for product in products %}
<div id="product612" class="col-md-6 col-sm-12 col-xs-12">
<div class="product">
<img src="{{product.image.url}}" class="img-responsive " alt="product picture">
<h4>{{product.name}}</h4>
<p>{{product.detail}}</p><br>
</div>
</div>
{% endfor %}
</div>
</div>
Two things before answering the question you actually asked:
Bootstrap's grid system is supposed to make it possible to avoid doing things like this, so you might want to post a new question with a MCVE of what you're doing and ask how to avoid having to change the col-md-x class.
ids must be unique in the document, so that's the first thing you need to fix.
Answering the question you asked, though:
You've said:
i made this change using jquery but it only affect the first div.
but the code you've shown uses
$( "product612" ).removeClass( "col-md-6" ).addClass( "col-md-12" );
$("product612").toggleClass('col-md-6 col-md-12');
which won't do anything, because $("product612") won't match anything (you meant $("#product612"), and I guess you must have used that at one point if you saw one change).
Use a class instead of the id, and then in your resize function:
$(window).resize(function() {
var isNarrow = $(window).width() < 991;
$(".the-class")
.toggleClass("col-md-6", !isNarrow)
.toggleClass("col-md-12", isNarrow);
});
You might use matchMedia instead of resize for this so you only run your callback when the size change actually matters rather than on every tiny resize change, e.g.:
(function() {
function widthUpdate(mqle) {
$(".the-class")
.toggleClass("col-md-6", !mqle.matches)
.toggleClass("col-md-12", mqle.matches);
}
var mql = window.matchMedia('(max-width: 990px)');
mql.addListener(widthUpdate);
widthUpdate(mql);
})();
It doesn't fire the listener when you first hook it up, so you have to do that manually.
(Given the duplicate identified by Pete and the Bootstrap stuff, I deleted this at first. But then decided maybe it will be useful to someone later. Don't want to get any rep from it, though, so I marked it a Community Wiki.)

vanilla js remove id box [duplicate]

This question already has answers here:
Onclick event not firing on jsfiddle.net [closed]
(2 answers)
Closed 5 years ago.
I know how to do it with JQuery but I would like to remove a box with an onClick element (x) with vanilla JS. According to this I need to remove child element. As far as to this is my attempt:
function remove() {
var element = document.getElementById("box");
element.parentNode.removeChild(element);
}
#box {
background-color: lightgrey;
color: white;
width: 20em;
height: 20em;
border: 25px solid green;
padding: 25px;
margin: 25px;
}
.remover {
font-size: 10em;
align
}
<div id="box">
<div id="removeBox" onclick="remove()">
<span class="remover">x</span>
</div>
</div>
Would you mind to help me to remove whole box with just clicking the 'x'?
jsfiddle
Thank you so much
Don't use onclick, it's bad practice, here is why:
mixes code and markup
code written this way goes through eval
runs in the global scope while directly written functions run in user scope
Use event binding like:
document.getElementById("box").addEventListener('click', function() {
var element = document.getElementById("box");
element.parentNode.removeChild(element);
});
Here is an entire fiddle:
fiddle

Click and Hold event listener with Javascript [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I want to make a page with Click and Hold event effect, like http://andeinerseite.video/ or http://2016.makemepulse.com/, I'm interested in what framework uses to create those effects.
You can use Javascript's setTimeout function and bind it to mousedown events. Have a look at the snippet below:
// click and hold event listener
var timeout_id = 0,
hold_time = 1000,
hold_menu = $('.hold_menu'),
hold_trigger = $('.hold_trigger');
hold_menu.hide();
hold_trigger.mousedown(function() {
timeout_id = setTimeout(menu_toggle, hold_time);
}).bind('mouseup mouseleave', function() {
clearTimeout(timeout_id);
});
function menu_toggle() {
hold_menu.toggle();
}
ul.hold_menu {
list-style: none;
padding: 0;
margin: 0;
}
ul.hold_menu a, div.hold_trigger {
display: inline-block;
padding: 5px 15px;
border: 1px solid #ccc;
width: 300px;
}
ul.hold_menu a:link, ul.hold_menu a:visited {
color: black;
text-decoration: none;
}
ul.hold_menu a:active, ul.hold_menu a:hover {
background: #ff0;
text-decoration: none;
}
div.hold_trigger {
color: black;
cursor: pointer;
}
div.hold_trigger:hover {
background: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="hold_trigger">Click and hold to toggle the menu</div>
<ul class="hold_menu">
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
</ul>
Hope this helps!
With plain javascript you can do something like this:
selector.addEventListener('mousedown', function(event) {
// simulating hold event
setTimeout(function() {
// You are now in a hold state, you can do whatever you like!
}, 500);
});
You can tweak the 500ms value to any timespan fits your needs.

Variable Width Media Queries [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have done quite a bit of digging, and can't seem to find how people handle content restructuring for a variable width element.
For example, if I have a dynamically created horizontal menu it may only have 3 items..
<div>
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
And this menu will only have a small width, let's say 400px. I can create a media query to adjust the way it is displayed when the window falls below 400px, however..
If a user adds another item..
<div>
<ul>
<li>Home</li>
<li>About</li>
<li>Location</li>
<li>Contact</li>
</ul>
</div>
Suddenly this menu is larger then 400 px, and so on. My question is, how can I structure my code to handle a variable element width and still control the way that is displayed?
EDIT: When I re-size the browser window on my horizontal menu, at a certain variable width, the inline-block li elements drop below the rest of the menu. Instead of letting each element drop as the screen is compressed I would prefer to make the entire menu drop to a vertical orientation. I cannot simply use a media query, since there are variable amounts of menu items. To illustrate the issue try re-sizing the example code in this fiddle: https://jsfiddle.net/f5Lv73hp/
I don't understand your question, so, consider editing your post with more information, including what do you espect...
By the way:
Horizontal Menu, if you need to keep all list-items with the same width, you can use display-table, there aren't any javascript requirements, just set the list as a table ( see .menu-horizontal css ).
function CasesCtrl($) {
var case1 = $('#case1');
$('button', case1).click(function() {
var list = $('ul', case1);
var len = $('li', list).length;
var newItem = '' +
'<li class="menu-item">' +
'<a class="menu-item-link">Item '+ (len + 1) +'</a>' +
'</li>'
;
list.append(newItem);
});
}
jQuery(document).ready(CasesCtrl);
article {
width: 100%;
padding: 2px;
border: 1px solid black;
margin-bottom: 2em;
overflow: hidden;
}
.menu {
list-style: none;
margin: 0;
padding: 0;
}
.menu-item {
}
.menu-item-link {
background: lightseagreen;
margin: 2px;
padding: 2px 5px;
display: block;
text-transform: uppercase;
line-height: 1;
}
.menu-horizontal {
display: table;
}
.menu-horizontal .menu-item {
display: table-cell;
width: 1%;
white-space: nowrap;
overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<article id="case1">
<ul class="menu menu-horizontal">
<li class="menu-item">
Item 1
</li>
<li class="menu-item">
Item 2
</li>
<li class="menu-item">
Item 3
</li>
</ul>
<button type="button">Add Menu Item</button>
</article>
Be more specific and I'll edit my answer as you need!
Are you looking for something like this? https://jsfiddle.net/4p18mxg9/2/
I am using javascript to get the width of the ul and applying the width to to media query, that way when you add more li it is not dependent on the content.
var width = document.getElementById('ul').offsetWidth;
document.querySelector('style').textContent +=
"#media screen and (max-width:" + width + "px) { li{float: none; width: 100%; background-color: blue; color: white;}}"
Added some color, to see easier: https://jsfiddle.net/4p18mxg9/3/

Categories

Resources