i fixed the old question ty for helping this is my second question
There's one more thing i need to know. How can i select a child of "user chat_user"?
var anchors = document.getElementsByClassName("user chat_user");
for(var i = 0; i < anchors.length; i++) {
var anchor = anchors[i];
anchor.onclick = function() { setTimeout(function() {
var ok = document.getElementsByClassName("user-dropdown")[0];
var za = document.createElement("li");
za.className = "user-dropdown-entry";
za.innerText = "Mention";
ok.append(za);}, 10);
}
}
You have to ensure your element is defined/exists.
Try this:
let ok = document.querySelector(".user-dropdown");
// Ensure the class `.user-dropdown` exists
if (ok) {
// Only loop through how many exist, no more
Array.from(document.getElementsByClassName("user chat_user")).forEach(anchor => {
anchor.onclick = () => {
// Use querySelector to select only the first of child here
let za = document.createElement("li");
za.className = "user-dropdown-entry";
za.innerText = "Mention";
ok.append(za);
}
});
}
.user.chat_user {
border: 1px solid black;
display: inline-block;
}
<dive class="user-dropdown">user dropdown</div>
<ul class="messages">
<li class="chat_msg msg-user-message">
<div class="colorbar user"></div>
<span class="user chat_user">
<span class="chat_user_prof">
<img src="https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/e8/e852c40b62be21a16b9f6d69a584e742d7364abb.jpg"></span>
<span class="xp_70">
<i class="icon"></i>
<span class="level_val">79</span>
</span>
<a class="chat_user_name">ChickenİX * 1</a>
<span class="chat_user_ico">
<i class="icon-gammdom-symbol"></i>
<span class="chat_user_colen">:</span>
</span>
</span>
<span class="chat_cont">İg diyon xd</span>
</li>
</ul>
Related
Actually, I'm learning DOM Manipulation. As you can see, I created the li element but the issue is it is not applying the fontSize to the li.
const title = document.querySelector("#main-heading");
title.style.color = "red";
const listItems = document.querySelectorAll(".list-items");
for (i = 0; i < listItems.length; i++) {
listItems[i].style.fontSize = "2rem";
}
const ul = document.querySelector("ul");
const li = document.createElement("li");
ul.append(li);
li.innerText = "X-men"
li.setAttribute('class' , 'list-items' )
<div class="container">
<h1 id="main-heading">Favourite Movie</h1>
<ul>
<li class="list-items">The Matric</li>
<li class="list-items">Star Wars</li>
<li class="list-items">Harry Potter</li>
<li class="list-items">Lord of the Rings</li>
<li class="list-items">Marvel</li>
</ul>
</div>
The order you do things matters.
You find all the items matching .list-items
You change their font size
You create a new list item that matches .list-items
The item you create at step 3 didn't exist when you did the search at step 1 so wasn't changed by step 2.
Use a style sheet instead of inline style (which is what you modify with ...style.fontSize.
Remove setting the font-size value inside for loop. Instead have it as separate css.
.list-items {
font-size: 2rem;
}
Append the newly created li after the class is added.
ul.append(li);
Forked Example:
const title = document.querySelector("#main-heading");
title.style.color = "red";
const listItems = document.querySelectorAll(".list-items");
const ul = document.querySelector("ul");
const li = document.createElement("li");
li.innerText = "X-men"
li.setAttribute('class' , 'list-items');
ul.append(li);
.list-items {
font-size: 2rem;
}
<div class="container">
<h1 id="main-heading">Favourite Movie</h1>
<ul>
<li class="list-items">The Matric</li>
<li class="list-items">Star Wars</li>
<li class="list-items">Harry Potter</li>
<li class="list-items">Lord of the Rings</li>
<li class="list-items">Marvel</li>
</ul>
</div>
I made this favImages array and added some image objects to it. Then I am trying to append a paragraph element(removeButton) to each of them which will be triggered by clicking the images.
var favImages = new Object();
for (var i = 0; i < 5; i++) {
favImages[i] = document.getElementById("fav" + (i + 1));
}
var removeButton = document.createElement("p");
removeButton.id = "removebutton";
removeButton.innerHTML = "Remove Image";
for (var i = 0; i < 5; i++) {
var newImage = document.getElementById(favImages[i].id);
newImage.addEventListener("click", function() {
newImage.appendChild(removeButton)
}, false);
}
Don't use a loop. Use an event listener on the container and test what was clicked using event.target. You cannot add a child to an image
You COULD use a div, put the image as a background and the span to click as content
Anyway here are some examples
document.getElementById("container").addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("remove")) tgt.closest("div").remove()
})
#container div {
width: 200px
}
.remove {
float: right
}
<div id="container">
<div>
<span class="remove">X</span>
<img src="https://via.placeholder.com/150/0000FF/000888?text=image1" />
</div>
<div>
<span class="remove">X</span>
<img src="https://via.placeholder.com/150/FF00FF/000888?text=image2" />
</div>
<div>
<span class="remove">X</span>
<img src="https://via.placeholder.com/150/FF0000/000888?text=image3" />
</div>
</div>
From an array:
const images = [
"https://via.placeholder.com/150/0000FF/000888?text=image1",
"https://via.placeholder.com/150/FF00FF/000888?text=image2",
"https://via.placeholder.com/150/FF0000/000888?text=image3"
];
const container = document.getElementById("container");
container.innerHTML = images.map(img => `<div><span class="remove">X</span>
<img src="${img}" /></div>`).join("");
container.addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("remove")) tgt.closest("div").remove()
})
#container div {
width: 200px
}
.remove {
float: right
}
<div id="container">
</div>
I'm using this JS for tabs. However, it continually makes the selected tab box scroll to the top of the page when clicked.
I can't figure out what part of it is doing that and am trying to get rid of it. Essentially I just want it to function as a normal tab clicker without causing the entire page to scroll.
Any help?
I added a snippet with a large top margin so you can see what happens when you click the tab. I just want those boxes to change without the page physically scrolling to them on its own.
'use strict';
function Tabs() {
var bindAll = function() {
var menuElements = document.querySelectorAll('[data-tab]');
for (var i = 0; i < menuElements.length; i++) {
menuElements[i].addEventListener('click', change, false);
}
}
var clear = function() {
var menuElements = document.querySelectorAll('[data-tab]');
for (var i = 0; i < menuElements.length; i++) {
menuElements[i].classList.remove('active');
var id = menuElements[i].getAttribute('data-tab');
document.getElementById(id).classList.remove('active');
}
}
var change = function(e) {
clear();
e.target.classList.add('active');
var id = e.currentTarget.getAttribute('data-tab');
document.getElementById(id).classList.add('active');
}
bindAll();
}
var connectTabs = new Tabs();
.b-box {margin-top: 1500px;}
.b-tab {
padding: 20px;
border: 1px solid #000;
display: none
}
.b-tab.active {
display: block;
}
.b-nav-tab {
display: inline-block;
padding: 20px;
}
.b-nav-tab.active {
color: #ff4200;
}
<a href="#orange" data-tab="orange" class="b-nav-tab active">
Orange
</a>
<a href="#green" data-tab="green" class="b-nav-tab">
Green
</a>
<a href="#blue" data-tab="blue" class="b-nav-tab">
Blue
</a>
<div class="b-box">
<div id="orange" class="b-tab active">
Orange tab content
</div>
<div id="green" class="b-tab">
Green tab content
</div>
<div id="blue" class="b-tab">
Blue tab content
</div></div>
I updated your code.
Actually you was showing # sign in href so it redirect the position to that box. I removed it.
Good Luck.
'use strict';
function Tabs() {
var bindAll = function() {
var menuElements = document.querySelectorAll('[data-tab]');
for (var i = 0; i < menuElements.length; i++) {
menuElements[i].addEventListener('click', change, false);
}
}
var clear = function() {
var menuElements = document.querySelectorAll('[data-tab]');
for (var i = 0; i < menuElements.length; i++) {
menuElements[i].classList.remove('active');
var id = menuElements[i].getAttribute('data-tab');
document.getElementById(id).classList.remove('active');
}
}
var change = function(e) {
clear();
e.target.classList.add('active');
var id = e.currentTarget.getAttribute('data-tab');
document.getElementById(id).classList.add('active');
}
bindAll();
}
var connectTabs = new Tabs();
.b-tab {
padding: 20px;
border: 1px solid #000;
display: none;
}
.b-tab.active {
display: block;
}
.b-nav-tab {
display: inline-block;
padding: 20px;
}
.b-nav-tab.active {
color: #ff4200;
}
<a href="javascript:void(0)" data-tab="orange" class="b-nav-tab active">
Orange
</a>
<a href="javascript:void(0)" data-tab="green" class="b-nav-tab">
Green
</a>
<a href="javascript:void(0)" data-tab="blue" class="b-nav-tab">
Blue
</a>
<div id="orange" class="b-tab active">
Orange tab content
</div>
<div id="green" class="b-tab">
Green tab content
</div>
<div id="blue" class="b-tab">
Blue tab content
</div>
One way would be to add this e.preventDefault(); to your change function and the other way would be to replace href="#orange" with href="javascript:void(0)". All the same with other hrefs.
How can I get the JavaScript loop associated with the liList variable to effect the DOM whist not over-riding any other styles?
I would like my menu items to still be orange and for the first list item to hold onto the styleAbbr variable that was created in JavaScript.
//JavaScript style to effect HTML abbr
var styleAbbr = document.createElement('style');
styleAbbr.type = 'text/css';
styleAbbr.innerHTML = '.myAbbr {font-style: italic; letter-spacing: .4em;}';
document.getElementsByTagName('head')[0].appendChild(styleAbbr);
document.querySelector('abbr').className = 'myAbbr';
//the JavaScript for the loop
var msg = '';
var i = 0;
var liList = document.querySelectorAll('li.menuItem');
if (i < liList.length) {
for (var i = 0; i < liList.length; i++) {
//liList[i].textContent gets the text form the li element in the DOM
var listWording = liList[i].textContent;
//liList.innerHTML applies my style and pushes listWording into the DOM
msg += '<li style="background: red; margin-top: 10px;">'
+ listWording
+ '</li>';
}
}
//I believe that the issue is that .innerHTML = msg.
document.getElementById('mMain').innerHTML = msg;
ul {
font-size: 1.4em;
list-style: none;
}
ul li a {
text-decoration: none;
color: #e69b1e;
}
<ul id="mMain">
<li class="menuItem">
<a href="#">
<abbr title="HyperText Markup Language">HTML</abbr>
</a>
</li>
<li class="menuItem">
About
</li>
<li class="menuItem">
Gallery
</li>
<li class="menuItem">
Contact
</li>
</ul>
Ideally I would like to have my JavaScript style in its own variable and loop that into the "menuItem" class whilst not effecting any other predefined class's however I am not quite sure how I would call that variable into a loop.
var menuItemClass = document.createElement('style');
menuItemClass.type = 'text/css';
menuItemClass.innerHTML = '.menuStyle {background: red; margin-top: 10px;}';
document.getElementsByTagName('head')[0].appendChild(menuItemClass);
Im also aware I could have a class in my CSS do all of this and then reference that.
However I am interested how this can be achieved in JavaScript.
Thank you.
I found a solution to referencing my JavaScript defined style.
var styleAbbr = document.createElement('style');
styleAbbr.type = 'text/css';
styleAbbr.innerHTML = '.myAbbr {font-style: italic; letter-spacing: .4em;}';
document.getElementsByTagName('head')[0].appendChild(styleAbbr);
document.querySelector('abbr').className = 'myAbbr';
var menuItemClass = document.createElement('style');
menuItemClass.type = 'text/css';
menuItemClass.innerHTML = '.menuStyle {background: red; margin-top: 10px;}';
document.getElementsByTagName('head')[0].appendChild(menuItemClass);
var msg = '';
var i = 0;
var liList = document.querySelectorAll('li.menuItem');
if (i < liList.length) {
for (var i = 0; i < liList.length; i++) {
liList[i].className = 'menuStyle';
}
}
ul li {
font-size: 1.4em;
list-style: none;
}
ul li a {
text-decoration: none;
color: #e69b1e;
}
<ul id="mMain">
<li class="menuItem">
<a href="#">
<abbr title="HyperText Markup Language">HTML</abbr>
</a>
</li>
<li class="menuItem">
About
</li>
<li class="menuItem">
Gallery
</li>
<li class="menuItem">
Contact
</li>
</ul>
I am answering how to add class to each li element created dynamically without effecting predefined. So create class according to the menu item innerText and take background color for the class from array defined colors
//JavaScript style to effect HTML abbr
var styleAbbr = document.createElement('style');
styleAbbr.type = 'text/css';
styleAbbr.innerHTML = '.myAbbr {font-style: italic; letter-spacing: .4em;}';
document.getElementsByTagName('head')[0].appendChild(styleAbbr);
document.querySelector('abbr').className = 'myAbbr';
//the JavaScript for the loop
var msg = '';
var i = 0;
var liList = document.querySelectorAll('li.menuItem');
//defining background colours
var colors = ['red', 'orange', 'green', 'brown', 'blue'];
var j = 0;
if (i < liList.length) {
for (var i = 0; i < liList.length; i++) {
//creating class as the innerText content
if (j >= colors.length) {
j = 0
}
var menuItemClass = document.createElement('style');
menuItemClass.type = 'text/css';
menuItemClass.innerHTML = '.' + liList[i].innerText + ' {background: ' + colors[j] + '; margin-top: 10px;}';
document.getElementsByTagName('head')[0].appendChild(menuItemClass);
j++;
//liList[i].textContent gets the text form the li element in the DOM
var listWording = liList[i].textContent;
//liList.innerHTML applies my style and pushes listWording into the DOM
if (i == 0) {
msg += liList.innerHTML =
'<li class="myAbbr ' + listWording + '">' +
listWording +
'</li>';
} else {
msg += liList.innerHTML =
'<li class=" ' + listWording + '">' +
listWording +
'</li>';
}
}
}
//I believe that the issue is that .innerHTML = msg.
document.getElementById('mMain').innerHTML = msg;
ul {
font-size: 1.4em;
list-style: none;
}
ul li a {
text-decoration: none;
color: #e69b1e;
}
<ul id="mMain">
<li class="menuItem">
<a href="#">
<abbr title="HyperText Markup Language">HTML</abbr>
</a>
</li>
<li class="menuItem">
About
</li>
<li class="menuItem">
Gallery
</li>
<li class="menuItem">
Contact
</li>
</ul>
I have a array of div elements as follows:-
var accdata = [];
for(var i = 0;i < returndata1.length;++i){
accdata.push(
<div className="data-main" onMouseEnter={this.toggleHover} onMouseLeave={this.toggleHover}>
<span className="data-child">{returndata1[i].Project}</span>
<span className={this.state.cls}>
<span className="flag"></span>
<span className="share"></span>
<span className="star"></span>
</span>
</div>
);
}
//toggle function
toggleHover(){
this.setState({hover: !this.state.hover})
if(this.state.hover === true){
this.setState({cls: 'icon-display'})
}
else{
this.setState({cls: ''})
}
}
but on mouseover the span element of all the divisions disappears. how can I set like if we mouseover a particular row only the span element of that row disappears?
The easiest way to achieve this is using css. Here's an example using some generic css classes: http://jsfiddle.net/9utga8ya/2/
React:
var accdata = [];
for(var i = 0;i < returndata1.length;++i){
accdata.push(
<div className="data-main">
<span className="data-child">{returndata1[i].Project}</span>
<span className="icon-display">
<span className="flag"></span>
<span className="share"></span>
<span className="star"></span>
</span>
</div>
);
}
CSS:
.data-main .icon-display {
display: inline;
}
.data-main:hover .icon-display {
display: none;
}